2016-01-24 20 views
2

在运行与GDB的ELF程序,我目前正在经历一个相当意外的行为,为特定的加法指令:大会/ GDB:添加行为

Intel语法:add cl,BYTE PTR [eax]

AT & T语法:add (%eax),%cl

我希望这条指令的含义与gdb的set $cl=$cl+*((char*) $eax)(无论触发标志是什么)具有相同的含义。但是某个调试会话的行为不同(参见下文):(char)* $ eax的值是0xb8,$ cl的值是0,但$ cl的结果值是0xcc。

我的问题是:这个0xcc来自哪里?为什么结果不是0xb8?

这个程序只是另一个破解程序,可能是here

要回答以下小丑​​的评论,下面的GDB会话可以作为人们的预料之中:

(gdb) b *0x08048119 
Breakpoint 1 at 0x8048119 
(gdb) r 
Starting program: /tmp/ch20.bin 
Welcome to Root-Me Challenges 
Pass: foo 

Breakpoint 1, 0x08048119 in ??() 
(gdb) x/i $eip 
=> 0x8048119: add (%eax),%cl 
(gdb) x/bx $eax 
0x8048080:  0xb8 
(gdb) p/x $cl 
$1 = 0x0 
(gdb) si 
0x0804811b in ??() 
(gdb) p/x $cl 
$2 = 0xb8 

但我不明白,为什么下面的人不产生相同的结果:

(gdb) b *0x8048080 
Breakpoint 1 at 0x8048080 
(gdb) r 
Starting program: /home/baz1/Downloads/ch20.bin 

Breakpoint 1, 0x08048080 in ??() 
(gdb) ni 
0x08048085 in ??() 
(gdb) 
0x0804808a in ??() 
(gdb) 
0x0804808f in ??() 
(gdb) 
0x08048094 in ??() 
(gdb) 
Welcome to Root-Me Challenges 
Pass: 0x08048096 in ??() 
(gdb) 
0x0804809b in ??() 
(gdb) 
0x0804809d in ??() 
(gdb) 
0x080480a2 in ??() 
(gdb) 
0x080480a7 in ??() 
(gdb) 

0x080480a9 in ??() 
(gdb) 
0x080480ab in ??() 
(gdb) 
0x080480b0 in ??() 
(gdb) 
0x080480b5 in ??() 
(gdb) 
0x08048115 in ??() 
(gdb) 
0x08048117 in ??() 
(gdb) 
0x08048119 in ??() 
(gdb) x/i $eip 
=> 0x8048119: add (%eax),%cl 
(gdb) x/bx $eax 
0x8048080: 0xb8 
(gdb) p/x $cl 
$1 = 0x0 
(gdb) si 
0x0804811b in ??() 
(gdb) p/x $cl 
$2 = 0xcc 

非常感谢您的帮助。

+0

发布完整的gdb会话记录。检查你是否只加一条指令。还要确保内存中的值不会改变(例如,由于多线程程序或访问无效内存)。 – Jester

+0

该网站似乎已关闭或链接已损坏。至于gdb日志,我希望看到你的声明(寄存器和内存之前和指令本身)的证明。作为一个裂缝,它可能会做一些棘手的事情:) – Jester

+0

我上传了我的vps文件并更改了链接;它现在应该工作。 – cymbaz

回答

2

b *0x8048080将软件断点放入内存中,该内存碰巧是带有操作码0xccint3指令。然后add指令将读取此内容而不是原始内存。您可以在断点被删除后删除断点或使用不修改代码的硬件断点。

+0

非常感谢您的回答小丑! 我想程序不会经常阅读他们的代码,以证明额外的检查来防止这种问题。 我仍然觉得很奇怪,尽管gdb在评估* $ eax时会执行检查;它会在我们看到的和从指令的角度看实际发生的事情之间产生某种不一致...... – cymbaz