Как изменить разветвленный процесс трассировки EIP?

Я работаю над приложением Linux, включающим ptrace, чтобы наблюдать за другим процессом, созданным системным вызовом fork().

Строго говоря: я хочу реализовать внедрение ошибок в разветвленный процесс (процесс чили или «трассировку»).

Как вы можете видеть на рисунке ниже:

введите здесь описание изображения

введите здесь описание изображения

трассировщик получает структуру regs (struct_user_regs) от трассируемого с помощью запроса PTRACE_GETREGS. после этого трассировщик изменяет значение EIP трассируемого (когда ядро ​​переключается на трассируемое, выполнение ордера будет нарушать так называемую ошибку потока управления CFE). затем запрос PTRAC E_CONT будет отправлен трассируемому, чтобы продолжить его выполнение.

К сожалению, после изменения трассировки EPI трассировка не продолжает выполнение из-за (ошибки сегментации). Как я могу указать другое подходящее значение для трассируемого EIP?

вот код

#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include<sys/user.h>
#include<sys/reg.h>
#include<stdlib.h>
#include<stdio.h>
#include <asm/ptrace-abi.h>

 int main()

 { 

  pid_t child;
  int status;
  int sum=0;
  struct user_regs_struct regs;


    child = fork();
    if(child == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);

         printf("hello world 1\n");
         printf("hello world 2\n");
         raise (SIGINT); // just to move control to the tracer 
         printf("hello world 3\n");
         printf("hello world 4\n");
         printf("hello world 5\n");

         exit(EXIT_SUCCESS);
     }
    else {

          wait(NULL);
          ptrace(PTRACE_GETREGS, child,NULL, &regs);
          printf("\n EIP @  0x %#lx\n",regs.eip);
          //get the tracee EIP
          long int new_eip=ptrace(PTRACE_PEEKTEXT, child,regs.eip,NULL);
          //chabge EIP and poke it again
          new_eip += ???; // make change that let to jump to another tracee instruction address (say to print hello world 5)
          ptrace(PTRACE_POKETEXT, child,regs.eip,new_eip);
          ptrace(PTRACE_CONT, child, NULL, NULL);

          }

    return 0;
}

есть идеи? Спасибо за вашу помощь.


person husin alhaj ahmade    schedule 05.08.2016    source источник
comment
Вам нужно показать свой код, если вы ожидаете, что кто-то поймет, что вы делаете неправильно.   -  person Barmar    schedule 05.08.2016
comment
@Barmar, код добавлен :)   -  person husin alhaj ahmade    schedule 05.08.2016
comment
Используя отладчик, такой как gdb или отладчик Qt, я не могу отлаживать трассировку.   -  person husin alhaj ahmade    schedule 05.08.2016


Ответы (2)


Вы не изменяете EIP, вы добавляете что-то к значению инструкции в EIP и, вероятно, получаете неверную ссылку на адрес. Чтобы изменить EIP, используйте PTRACE_SETREGS

      wait(NULL);
      ptrace(PTRACE_GETREGS, child,NULL, &regs);
      printf("\n EIP @  0x %#lx\n",regs.eip);
      regs.eip += ???;
      ptrace(PTRACE_SETREGS, child, NULL, &regs);
      ptrace(PTRACE_CONT, child, NULL, NULL);
person Barmar    schedule 05.08.2016
comment
Да вы правы. Но какое подходящее значение, чтобы добавить его в EIP, чтобы указать на следующую или любую инструкцию. Я пробовал: неподписанная инструкция_=ptrace(PTRACE_PEEKTEXT,child,regs.eip.NULL); затем regs.eip+=sizeof(инструкция); Я также объявил инструкцию_ как long int, но это тоже не сработало. - person husin alhaj ahmade; 06.08.2016
comment
Добавьте количество байтов в инструкции. Это зависит от архитектуры ЦП и даже от того, какая инструкция в текущем EIP, если инструкции имеют разную длину. - person Barmar; 06.08.2016

Да, это полностью зависит от платформы. Я прочитал много материалов, в которых описывался системный вызов ptrace и то, как мы можем использовать его для захвата EIP следующей инструкции, которая будет выполняться после того, как ptrace отправит какой-либо запрос (например, PTRACE_CONT) приостановленному трассируемому объекту. Я всегда вижу, что значение EIP выглядит примерно так:

 80484a6:
 80484a7:   
 80484ac:   
 80484b2:
 80484b4:
 80484b6:
 80484b8:

Я тестирую простой код (просто печатаю значение EIP и соответствующую выполняемую инструкцию). но результат был таким, как показано ниже:

EIP: b773cbe0 Instruction executed: c3595a5d
EIP: b773cbe1 Instruction executed: ccc3595a
EIP: b773cbe0 Instruction executed: c3595a5d
hello world 5
EIP: b773cbe0 Instruction executed: c3595a5d
EIP: b773cbe1 Instruction executed: ccc3595a
EIP: b773cbe0 Instruction executed: c3595a5d
hello world 6
EIP: b773cbe0 Instruction executed: c3595a5d
EIP: b773cbe1 Instruction executed: ccc3595a
EIP: b773cbe0 Instruction executed: c3595a5d

что это (b773cbe0)??!!! Я перешел на gdb и просмотрел файл дампа с помощью этой командной строки (objdump -d a.out), результат отличается от предыдущих результатов.

 8048864:   8b 6c 24 20             mov    0x20(%esp),%ebp
 8048868:   8d b3 0c ff ff ff       lea    -0xf4(%ebx),%esi
 804886e:   e8 41 fb ff ff          call   80483b4 <_init>
 8048873:   8d 83 08 ff ff ff       lea    -0xf8(%ebx),%eax
 8048879:   29 c6                   sub    %eax,%esi
 804887b:   c1 fe 02                sar    $0x2,%esi
 804887e:   85 f6                   test   %esi,%esi
 8048880:   74 23                   je     80488a5 <__libc_csu_init+0x55>
 8048882:   8d b6 00 00 00 00       lea    0x0(%esi),%esi
 8048888:   83 ec 04                sub    $0x4,%esp
 804888b:   ff 74 24 2c             pushl  0x2c(%esp)
 804888f:   ff 74 24 2c             pushl  0x2c(%esp)
 8048893:   55                      push   %ebp
 8048894:   ff 94 bb 08 ff ff ff    call   *-0xf8(%ebx,%edi,4)
 804889b:   83 c7 01                add    $0x1,%edi
 804889e:   83 c4 10                add    $0x10,%esp
 80488a1:   39 f7                   cmp    %esi,%edi
 80488a3:   75 e3                   jne    8048888 <__libc_csu_init+0x38>
 80488a5:   83 c4 0c                add    $0xc,%esp
 80488a8:   5b                      pop    %ebx
 80488a9:   5e                      pop    %esi
 80488aa:   5f                      pop    %edi
 80488ab:   5d                      pop    %ebp
 80488ac:   c3                      ret    
 80488ad:   8d 76 00                lea    0x0(%esi),%esi

Я действительно смущен этим.

person husin alhaj ahmade    schedule 07.08.2016
comment
@ Бармар, что это (b773cbe0)? а почему другой результат? - person husin alhaj ahmade; 07.08.2016