到目前为止我所理解的是子指令在堆栈上分配了空间。 那么eax中的任何内容都会被移动到堆栈中。那么mov和lea的组合让我很困惑。我的直觉告诉我,指针存储在堆栈中以便以后使用。或者它可能是某种数学函数正在我提供的数字上执行。在函数的开头我发现eax有我输入的数字。 我发现的另一件事是做x / s 0x804a819给了我“%d%d%d%d%d%d”。这是将六位数移动到0x4(%esp)吗?我从movl指令找到了地址0x804a819。 就在调用sscanf之前有mov%eax,(%esp) 我假设程序正在保存堆栈指针的位置供以后使用?我尝试过的一件事是在调用0x80488d0< __ isoc99_sscanf @ plt>之后。执行后我执行p $ eax = 0x7以便指令cmp $ 0x5,%eax将设置正确的标志,以便指令jg 0x80495b5跳过调用explode_bomb。但不管是什么explode_bomb被调用。所以我确信有一些我缺少的东西,甚至可能都不在这个功能中。
其他一些问题。 函数局部变量存储在堆栈上是否正确?
sub $0x2c,%esp
mov 0x34(%esp),%eax
lea 0x14(%eax),%edx
mov %edx,0x1c(%esp)
lea 0x10(%eax),%edx
mov %edx,0x18(%esp)
lea 0xc(%eax),%edx
mov %edx,0x14(%esp)
lea 0x8(%eax),%edx
mov %edx,0x10(%esp)
lea 0x4(%eax),%edx
mov %edx,0xc(%esp)
mov %eax,0x8(%esp)
movl $0x804a819,0x4(%esp)
mov 0x30(%esp),%eax
mov %eax,(%esp)
call 0x80488d0 <__isoc99_sscanf@plt>
cmp $0x5,%eax
jg 0x80495b5 <read_six_numbers+76>
call 0x804941c <explode_bomb>
add $0x2c,%esp
ret
答案 0 :(得分:0)
记住在i386上,函数参数在堆栈上传递可能会有所帮助。在函数输入时,如果你在堆栈指针的地址读取内存字,你会找到调用者的返回地址。
看起来你的神秘功能需要两个参数。所以当它说
时sub $0x2c,%esp
mov 0x34(%esp),%eax
从堆栈指针中减去0x2c后,我们可以在*(esp + 0x2c)
找到调用者保存的eip,我们可以在*(esp + 0x30)
找到第一个参数,我们可以在{{1}找到第二个参数}}。你可以在这里看到对第二个参数的引用,
*(esp + 0x34)
这将格式字符串的地址存储在地址(0x804a819)*(esp + 4) - 这将成为movl $0x804a819,0x4(%esp)
mov 0x30(%esp),%eax
mov %eax,(%esp)
call 0x80488d0 <__isoc99_sscanf@plt>
的第二个参数。然后它将第一个参数加载到你的神秘函数(sscanf()
)并将其存储在*(esp + 0x30)
- 所以它将是*(esp)
的第一个参数。
希望这足以帮助理解功能而不会太有帮助。 :)