Я следовал некоторым инструкциям по использованию ptrace, которые можно найти здесь а>. У меня 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
Я обнаружил ошибку в коде, напечатанном на странице, на которую я ссылался выше (здесь), что на 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 равно -1s. Это также говорит о том, что что-то не так с моим вызовом 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;
}
Будем очень благодарны любой помощи!
str = calloc(params[2] + 1, sizeof (char));
, ноsizeof (char)
всегда равно 1, поэтому вы можете встроить это. - person melpomene   schedule 02.11.2016