2016-03-31 14 views
1

This GDBを使用してメモリ内の値を変更する方法を示していますが、与えられた例では、以前に使用されていなかった値を設定するアドレスを選択します。メモリ内の値を変更するアドレスを選択する

例えば

、22に戻り値を変更するために、著者は

set {unsigned char}0x00000000004004b9 = 22 

しかし、なぜこのアドレス0x00000000004004b9は、変更するアドレスになりますでしょうか? disas/rの出力を見ると、アドレス0x00000000004004b9は使用されていないので、なぜこれを22に設定するのですか?私はどのアドレスが(この例では)disas/rの出力がそれを表示しない場合、戻り値を変更するに変更する必要があるかを知る方法を理解しようとしています。

コード

$ cat t.c 
int main() 
{ 
    return 42; 
} 

$ gcc t.c && ./a.out; echo $? 
42 

$ gdb --write -q ./a.out 
(gdb) disas/r main 
Dump of assembler code for function main: 
    0x00000000004004b4 <+0>:  55  push %rbp 
    0x00000000004004b5 <+1>:  48 89 e5  mov %rsp,%rbp 
    0x00000000004004b8 <+4>:  b8 2a 00 00 00 mov $0x2a,%eax 
    0x00000000004004bd <+9>:  5d  pop %rbp 
    0x00000000004004be <+10>: c3  retq 
End of assembler dump. 
(gdb) set {unsigned char}0x00000000004004b9 = 22 
(gdb) disas/r main 
Dump of assembler code for function main: 
    0x00000000004004b4 <+0>:  55  push %rbp 
    0x00000000004004b5 <+1>:  48 89 e5  mov %rsp,%rbp 
    0x00000000004004b8 <+4>:  b8 16 00 00 00 mov $0x16,%eax <<< ---changed 
    0x00000000004004bd <+9>:  5d  pop %rbp 
    0x00000000004004be <+10>: c3  retq 
End of assembler dump. 
(gdb) q 

$ ./a.out; echo $? 
22 <<<--- Just as desired 

答えて

1

私はdisas/Rの出力がない場合は、戻り値を変更します(この例では)に変更する必要があるアドレスを知る方法を理解しようとしていますそれを示す。

これを理解するには、instruction encodingを理解する必要があります。ここでの命令は、「即値32ビット定数をレジスタに移動」です。定数は命令の部分です(つまり、「即時」が意味するものです)。代わりに、これをコンパイルするために役立つことがあります。あなたがはっきり命令ストリーム中の各バイトをどこで見ることができる今

(gdb) disas/r foo 
Dump of assembler code for function foo: 
    0x00000000004004ed <+0>:  55  push %rbp 
    0x00000000004004ee <+1>:  48 89 e5  mov %rsp,%rbp 
    0x00000000004004f1 <+4>:  b8 44 43 42 41 mov $0x41424344,%eax 
    0x00000000004004f6 <+9>:  5d  pop %rbp 
    0x00000000004004f7 <+10>: c3  retq 
End of assembler dump. 
(gdb) disas/r bar 
Dump of assembler code for function bar: 
    0x00000000004004f8 <+0>:  55  push %rbp 
    0x00000000004004f9 <+1>:  48 89 e5  mov %rsp,%rbp 
    0x00000000004004fc <+4>:  b8 48 47 46 45 mov $0x45464748,%eax 
    0x0000000000400501 <+9>:  5d  pop %rbp 
    0x0000000000400502 <+10>: c3  retq 
End of assembler dump. 

:あなたはそれをコンパイルするとき

int foo() { return 0x41424344; } 
int bar() { return 0x45464748; } 
int main() { return foo() + bar(); } 

は、あなたがに似たものが表示されるはずです即時定数が常駐しています(また、x86ではリトルエンディアンエンコーディングが使用されています)。

x86の命令エンコードに関する標準リファレンスは、Intel instruction set referenceです。 3-358ページの0xB8命令を参照してください。

関連する問題