我一直在遵循一些关于如何使用 ptrace 的说明,这些说明被发现 here 。我使用的是 ubuntu 14.04,x64,并且我一直在更改示例代码的一些位以在我的 x64 机器上工作,例如将 eax 更改为 rax,并在适当的情况下将 4s 更改为 8s。第四个示例应该反转 ls 的输出,但事实并非如此。我明白了:
bin Debugger.depend dummy1.s main_tut2.cpp main_tut4.cpp obj
Debugger.cbp Debugger.layout main_tut1.cpp main_tut3.cpp main_tut5.cpp
bin Debugger.depend dummy1.s main_tut2.cpp main_tut4.cpp obj
Debugger.cbp Debugger.layout main_tut1.cpp main_tut3.cpp main_tut5.cpp
而且我相信如果我的代码正常工作,我应该将其逆转,如下所示:
jbo ppc.4tut_niam ppc.2tut_niam s.1ymmud dneped.reggubeD nib
ppc.5tut_niam ppc.3tut_niam ppc.1tut_niam tuoyal.reggubeD pbc.reggubeD
jbo ppc.4tut_niam ppc.2tut_niam s.1ymmud dneped.reggubeD nib
ppc.5tut_niam ppc.3tut_niam ppc.1tut_niam tuoyal.reggubeD pbc.reggubeD
我在上面链接的页面 ( here ) 中打印的代码中发现了一个错误,该错误位于我的代码中从底部向上 20 行的位置,但我认为我已经更正了该错误。这是错误的行:
str = (char *)calloc((params[2] + 1) * sizeof(char));
它有一个争论,但需要两个。我认为应该是:
str = (char *)calloc(params[2] + 1, (params[2] + 1) * sizeof(char));
但如果我有错,我很乐意得到纠正。我也尝试过:
str = (char *)calloc(1, (params[2] + 1) * sizeof(char));
我仍然不确定哪个是正确的,如果...
这就是它不起作用的原因吗?或者是其他问题,也许是另一个我没有考虑到的与 x64 相关的问题?如果有人能告诉我 calloc 在这种情况下做了什么以及为什么第二个争论是这样的,那就加分。
编辑:
我刚刚尝试在反转之前和之后打印 str...这只是一堆问号。当我调试时,似乎str的全部内容都是-1。这进一步表明我对 calloc() 的调用有问题...
无论如何,这是我的代码版本:
#include <iostream>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h> // For fork()
//#include <linux/user.h> // For constants ORIG_EAX for 32bit etc
#include <sys/user.h> // For constants ORIG_RAX for 64bit etc
#include <sys/reg.h>
#include <sys/syscall.h> // For SYS_write etc
#include <cstring> // For strlen()
/** ptrace(enum __ptrace_request, // behaviour of ptrace
pid_t pid, // Process ID
void *addr, // Address to read in user area
void *data); //
**/
/**
PTRACE_TRACEME, PTRACE_PEEKTEXT, PTRACE_PEEKDATA, PTRACE_PEEKUSER, PTRACE_POKETEXT,
PTRACE_POKEDATA, PTRACE_POKEUSER, PTRACE_GETREGS, PTRACE_GETFPREGS, PTRACE_SETREGS,
PTRACE_SETFPREGS, PTRACE_CONT, PTRACE_SYSCALL, PTRACE_SINGLESTEP, PTRACE_DETACH
**/
const int long_size = sizeof(long);
void reverse(char *str) {
int i, j;
char temp;
for (i = 0, j = strlen(str) - 2; i <= j; i++, j--) {
temp = str[i];
str[i] = str[j];
str[j] = temp;
}
}
void getData(pid_t child, long addr, char *str, int len) {
char *laddr;
int i, j;
union u {
long val;
char chars[long_size];
} data;
i = 0;
j = len / long_size;
laddr = str;
while(i < j) {
data.val = ptrace(PTRACE_PEEKDATA, child, addr + i * 8, NULL);
memcpy(laddr, data.chars, long_size);
i++;
laddr += long_size;
}
j = len % long_size;
if (j != 0) {
data.val = ptrace(PTRACE_PEEKDATA, child, addr + i * 8, NULL);
memcpy(laddr, data.chars, j);
}
str[len] = '\0';
}
void putData(pid_t child, long addr, char *str, int len) {
char *laddr;
int i, j;
union u {
long val;
char chars[long_size];
} data;
i = 0;
j = len / long_size;
laddr = str;
while(i < j) {
memcpy(data.chars, laddr, long_size);
ptrace(PTRACE_POKEDATA, child, addr + i * 8, data.val);
i++;
laddr += long_size;
}
j = len % long_size;
if (j != 0) {
memcpy(data.chars, laddr, j);
ptrace(PTRACE_POKEDATA, child, addr + i * 8, data.val);
}
}
int main()
{
pid_t child;
child = fork();
if (child == 0) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl("/bin/ls", "ls", NULL);
} else {
long orig_rax;
long params[3];
int status;
char *str, *laddr;
int toggle = 0;
while(1) {
wait(&status);
if (WIFEXITED(status))
break;
orig_rax = ptrace(PTRACE_PEEKUSER, child, 8 * ORIG_RAX, NULL);
if (orig_rax == SYS_write) {
if (toggle == 0) {
toggle = 1;
params[0] = ptrace(PTRACE_PEEKUSER, child, 8 * RBX, NULL);
params[1] = ptrace(PTRACE_PEEKUSER, child, 8 * RCX, NULL);
params[2] = ptrace(PTRACE_PEEKUSER, child, 8 * RDX, NULL);
str = (char *)calloc(params[2] + 1, (params[2] + 1) * sizeof(char));
getData(child, params[1], str, params[2]);
reverse(str);
putData(child, params[1], str, params[2]);
} else {
toggle = 0;
}
}
ptrace(PTRACE_SYSCALL, child, NULL, NULL);
}
}
execl("/bin/ls", "ls", NULL);
return 0;
}
任何帮助将不胜感激!
最佳答案
感谢@melpmene 和@MarkPlotnick 的回答。我一直在努力找出涵盖同一主题的其他一些答案,并且我发现建议如何将 x32 代码转换为 x64 代码的另一个资源并不完全准确(至少对于我的系统而言),所以这就是我的内容需要做的事情:
1)
str = (char *)calloc(params[2] + 1 * sizeof (char))
应该是
str = (char *)calloc(params[2] + 1, sizeof (char))
2)
EBX、ECX 和 EDX 应替换为 RDI、RSI 和 RDX
关于c - 使用 ptrace 反转 ls 读数似乎不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40387270/