プロセスコール(nanosleep()など)にあるときに、ptrace(PTRACE_ATTACH ...)を使用してプロセスに接続しています。PTRACE_GETREGSを使用してレジスタの内容を取得できます。eipは予想される場所(__kernel_vsyscall内)にあります。ただし、eaxおよびorig_eaxレジスタには予期しない内容が含まれています。eaxには通常-516が含まれ、orig_eaxは通常0です。
これは私が使用したテストプログラムです(http://www.linuxjournal.com/article/6210から取得し、わずかに変更しました):
#include <stdlib.h>
#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/user.h>
int main(int argc, char *argv[])
{
pid_t traced_process;
struct user_regs_struct regs;
long ins;
if(argc != 2) {
printf("Usage: %s <pid to be traced>\n",
argv[0]);
exit(1);
}
traced_process = atoi(argv[1]);
ptrace(PTRACE_ATTACH, traced_process,
NULL, NULL);
wait(NULL);
ptrace(PTRACE_GETREGS, traced_process,
NULL, ®s);
printf("eax: %lx (%d); orig_eax: %lx\n",
regs.eax, (int)regs.eax, regs.orig_eax);
ins = ptrace(PTRACE_PEEKTEXT, traced_process,
regs.eip, NULL);
printf("EIP: %lx Instruction executed: %lx\n",
regs.eip, ins);
ptrace(PTRACE_DETACH, traced_process,
NULL, NULL);
return 0;
}
別の端末で実行されている「sleep10000」コマンドに接続する場合の出力:
eax: fffffdfc (-516); orig_eax: 0
EIP: b7711424 Instruction executed: c3595a5d
eaxの値はどういう意味ですか?orig_eaxに元のシステムコール番号(162など)が含まれていないのはなぜですか?この場合、実際にシステムコール番号を取得するにはどうすればよいですか?
また、gdbが「print $ orig_eax」に対して「162」を正しく表示するのはなぜですか?
ところで。これは、カーネル3.2.0を使用するUbuntu12.04にあります。
- uname -a: "Linux edgebox 3.2.0-24-generic-pae#37-Ubuntu SMP Wed Apr 25 10:47:59 UTC 2012 i686 athlon i386 GNU / Linux"
- / proc / cpuinfo:「AMDAthlon(tm)IINeoK345デュアルコアプロセッサ」
- ファイル
which sleep
: "/ bin / sleep:ELF 32ビットLSB実行可能ファイル、Intel 80386、バージョン1(SYSV)、動的リンク(共有ライブラリを使用)、GNU / Linux 2.6.24、BuildID [sha1] = 0x0965431bde4d183eaa2fa3e3989098ce46b92129、削除済み"。
つまり、これは32ビットPAEカーネルと64ビットCPUへの32ビットUbuntuインストールです。