5
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <linux/user.h> /* For constants
ORIG_EAX etc */
int main()
{ pid_t child;
long orig_eax;
child = fork();
if(child == 0) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl("/bin/ls", "ls", NULL);
}
else {
wait(NULL);
orig_eax = ptrace(PTRACE_PEEKUSER,
child, 4 * ORIG_EAX,
NULL);
printf("The child made a "
"system call %ld\n", orig_eax);
ptrace(PTRACE_CONT, child, NULL, NULL);
}
return 0;
}
私はORIG_EAX
は正確に、なぜ何であるかについては疑問を持っています4*ORIG_EAX
がptraceコールに渡されます。最初に、ORIG_EAX
,EBX
,ECX
などは、レジスタの値が格納される特定の構造体へのオフセットであると仮定しました。
私はprintf("origeax = %ld\n", ORIG_EAX);
を使って待機の直後にORIG_EAXの値を表示することに決めました。値は11
でした。だから、私のオフセットに関する私の前提は間違っていた。
私はwait
の呼び出しが子が状態変更(この場合、システムコールを発行)し、ORIG_EAXにシステムコール番号が含まれているときに終了することを理解します。
しかし、なぜORIG_EAX * 4がptraceコールに渡されますか?
32ビットと64ビットの間の差はどうですか?コンパイル時にそれを行うべきではありませんか? –
さらに、このptrace x86のみですか?そうでない場合は、これを行うためのより一般的なターゲットに依存しない方法が必要です。 –
AMD64の 'user_regs_struct'の定義は間違いありませんが、アーキテクチャーを混ぜ合わせることができるかどうかはわかりません。 IIRCの 'ptrace'のコメントでは、別々のヘッダーが問題であると述べています。 'ptrace'はシステムコールですので、手動で各アーキテクチャのオフセットを切り替えなければならないかもしれませんが、これまで試みたことはありません。 –