2

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

2 番目のチェック:

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

問題は、命令「inc ax」が正確に 65536 回実行されるため、上記の結果が両方とも 65536 になることです。問題は、私のコードに誤りがあるのか​​、それとも ptrace のバグの問題なのかということです。よろしくお願いいたします。

4

2 に答える 2

3

私はvirtualboxとvmwareの両方で同じプログラムを試しましたが、正しい結果が得られるのはvmwareだけのようですが、virtualboxにはあなたと同じ問題があります。私はvirtualbox4.2.1を使用しました。

于 2012-10-20T17:02:11.210 に答える
0

eip は、ユーザー空間の「現在の命令」へのアドレスです。実際の命令を取得するには、ptrace(...PEEKDATA, ...)、つまり ptrace(...GETREGS, ...) の後に必要です。また、ptrace(...PEEKDATA, ...) を使用すると、常に機械語を取得することに注意してください。実際のオペコードは通常、その下位 16/32 ビットのみを占有します。

于 2011-11-18T00:58:31.900 に答える