Я пытался изменить поведение системного вызова на удаленный процесс с помощью ptrace
в Arm linux, пока процесс имеет доступ write
системный вызов
ptrace. c
#include <errno.h>
#include <sys/ptrace.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <asm/ptrace.h>
#include <sys/user.h>
void main(int argc, char**argv){
int pid = atoi (argv[1]);
int retval;
int i = 0 ;
if((retval = ptrace(PTRACE_ATTACH, pid, NULL ,NULL)) ==-1) {
printf("error PTRACE_ATTACH \n");
}
wait(NULL);
struct user_regs attack_regs;
while(1)
{
if((retval = ptrace(PTRACE_SYSCALL, pid, NULL ,NULL)) ==-1) {
printf("error PTRACE_SYSCALL \n");
}
wait(NULL);
if((retval = ptrace(PTRACE_GETREGS, pid, NULL ,&attack_regs)) ==-1) {
printf("error PTRACE_GETREGS \n");
return;
}
printf("call : command = %lu , r0 = %lu , r1 = %lu , r2 = %lu \n",attack_regs.ARM_r7 , attack_regs.ARM_r0 , attack_regs.ARM_r1, attack_regs.ARM_r2);
if(attack_regs.ARM_r7 ==4 ) //write syscall
{
i++;
if(i % 3 ==0)
{
attack_regs.ARM_r2=2 ; //edit write count
if((retval = ptrace(PTRACE_SETREGS, pid, NULL ,&attack_regs)) ==-1) {
printf("error PTRACE_SETREGS \n");
return;
}
}
}
if((retval = ptrace(PTRACE_SYSCALL, pid, NULL ,NULL)) ==-1) {
printf("error PTRACE_SYSCALL \n");
}
wait(NULL);
if((retval = ptrace(PTRACE_GETREGS, pid, NULL ,&attack_regs)) ==-1) {
printf("error PTRACE_GETREGS \n");
return;
}
printf("result : command = %lu , r0 = %lu , r1 = %lu , r2 = %lu \n",attack_regs.ARM_r7 , attack_regs.ARM_r0 , attack_regs.ARM_r1, attack_regs.ARM_r2);
}
if((retval = ptrace(PTRACE_DETACH, pid, NULL ,NULL)) ==-1) {
printf("error PTRACE_DETACH\n");
}
}
test. c
#include <stdio.h>
#include <unistd.h>
void main ()
{
char * bu ="123456789";
int i = 0;
while (1)
{
sleep(1);
write(1,bu+(i%10),1);
i++;
}
}
test. c печать каждого se c. только 1 символ (1..2 ... 3 ..).
Когда я присоединяюсь к тестовому pid с помощью ptrace, каждые 3 раза при системном вызове write
я изменяю, что он печатает 2 символа вместо 1 символа (отредактируйте регистр r2 attack_regs.ARM_r2=2 ;
), который работает нормально.
Сейчас я попытался отредактировать номер системного вызова, чтобы другой системный вызов вызывался с помощью edit r7 register
, например attack_regs.ARM_r7=0x18
(getuid
syscall) или другим, но это не сработало.
Даже я вижу, что r7
действительно редактируется, системный вызов diffrent не вызывается.
Почему это так?