Почему ptrace SINGLESTEP не работает должным образом? - PullRequest
2 голосов
/ 08 октября 2011

Я пытаюсь отследить небольшую программу, используя ptrace API. Я понял, что каждый раз, когда запускается трассировщик, он дает плохие результаты. Это разборка короткой программы, которую я хочу отследить:

$ objdump -d -M intel inc_reg16
inc_reg16:     file format elf32-i386

Disassembly of section .text:

08048060 <.text>:
 8048060:   b8 00 00 00 00          mov    eax,0x0
 8048065:   66 40                   inc    ax
 8048067:   75 fc                   jne    0x8048065
 8048069:   89 c3                   mov    ebx,eax
 804806b:   b8 01 00 00 00          mov    eax,0x1
 8048070:   cd 80                   int    0x80

и вот код самого трассировщика:

// ezptrace.c
#include <sys/user.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>

int main() {
    pid_t child;
    child = fork();
    if (child == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execv("inc_reg16", NULL);
    }
    else {

        int status;
        wait(&status);
        struct user_regs_struct regs;
        while (1) {
            ptrace(PTRACE_GETREGS, child, NULL, &regs);
            printf("eip: %x\n", (unsigned int) regs.eip);
            ptrace(PTRACE_SINGLESTEP, child, NULL, NULL);
            waitpid(child, &status, 0);
            if(WIFEXITED(status)) break;
        }
        printf("end\n");
    }
    return 0;
}

Работа трассировщика состоит в том, чтобы пошагово выполнить программу inc_reg16 и записать адрес каждой встреченной инструкции процессора. Когда я запускаю и проверяю, сколько раз встречалась инструкция 'inc ax', оказывается, что числа различаются при каждом запуске трассировщика:

$ gcc ezptrace.c -Wall -o ezptrace
$ ./ezptrace > inc_reg16.log
$ grep '8048065' inc_reg16.log | wc -l
65498

второй чек:

$ ./ezptrace > inc_reg16.log
$ grep '8048065' inc_reg16.log | wc -l
65494

Проблема в том, что приведенные выше результаты должны быть как 65536, так как инструкция inc inc выполняется ровно 65536 раз. Теперь вопрос: есть ли ошибка в моем коде или это какая-то ошибка в ptrace? Ваша помощь очень ценится.

Ответы [ 2 ]

3 голосов
/ 20 октября 2012

Я пробовал одну и ту же программу под virtualbox и vmware, похоже, только vmware имеет правильный результат, тогда как virtualbox имеет ту же проблему, что и вы.Я использовал виртуальную коробку 4.2.1.

0 голосов
/ 18 ноября 2011

eip - это адрес «текущей инструкции» в пространстве пользователя.Вам нужна ptrace (... PEEKDATA, ...), то есть после ptrace (... GETREGS, ...), чтобы получить фактическую инструкцию.Также имейте в виду, что с помощью ptrace (... PEEKDATA, ...) вы всегда получаете машинное слово, фактические коды операций обычно занимают только младшие 16/32 его битов.

...