同一程序的汇编代码输出之间的差异
我一直在尝试复制本文中的缓冲区溢出示例3 aleph one
我这样做是作为我正在参加的计算机安全课程中的一个项目的练习,所以拜托,我非常需要你的帮助。我一直在遵循这个例子,边做边执行任务。我的问题是我的计算机中的 gdb
转储的汇编代码(我在 VM Ware 上运行的 debian linux 映像上执行此操作)与本文中的示例不同。我觉得有些结构令人困惑。
这是文章中的内容...
Dump of assembler code for function main:
0x8000490 <main>: pushl %ebp
0x8000491 <main+1>: movl %esp,%ebp
0x8000493 <main+3>: subl $0x4,%esp
0x8000496 <main+6>: movl $0x0,0xfffffffc(%ebp)
0x800049d <main+13>: pushl $0x3
0x800049f <main+15>: pushl $0x2
0x80004a1 <main+17>: pushl $0x1
0x80004a3 <main+19>: call 0x8000470 <function>
0x80004a8 <main+24>: addl $0xc,%esp
0x80004ab <main+27>: movl $0x1,0xfffffffc(%ebp)
0x80004b2 <main+34>: movl 0xfffffffc(%ebp),%eax
0x80004b5 <main+37>: pushl %eax
0x80004b6 <main+38>: pushl $0x80004f8
0x80004bb <main+43>: call 0x8000378 <printf>
0x80004c0 <main+48>: addl $0x8,%esp
0x80004c3 <main+51>: movl %ebp,%esp
0x80004c5 <main+53>: popl %ebp
0x80004c6 <main+54>: ret
0x80004c7 <main+55>: nop
正如您所看到的,两者之间存在差异。我很困惑,无法完全理解计算机上的汇编代码。我想知道两者之间的区别。
pushl
与 push
、mov vs movl
等有何不同...
表达式 0xhexavalue(%register) 有何不同
是什么意思?
抱歉,如果我问得太多,但我非常需要你的帮助。
更新:
为什么函数“function”的参数被转换为不同的汇编代码:
从文章中,我相信参数 1, 2, & 3 函数被推入堆栈。
在我的计算机中,参数被移动到寄存器“esp”,并带有一些偏移量。
它们有什么不同吗?谢谢
真的谢谢你的帮助...
I have been trying to replicate the buffer overflow example3 from this article aleph one
I'm doing this as a practice for a project in a computer security course i'm taking so please, I badly need your help. I've been the following the example, performing the tasks as I go along. My problem is the assembly code dumped by gdb
in my computer (i'm doing this on a debian linux image running on VM Ware) is different from that of the example in the article. There are some constructs which I find confusing.
Here is the one from my computer:
here is the one from the article...
Dump of assembler code for function main:
0x8000490 <main>: pushl %ebp
0x8000491 <main+1>: movl %esp,%ebp
0x8000493 <main+3>: subl $0x4,%esp
0x8000496 <main+6>: movl $0x0,0xfffffffc(%ebp)
0x800049d <main+13>: pushl $0x3
0x800049f <main+15>: pushl $0x2
0x80004a1 <main+17>: pushl $0x1
0x80004a3 <main+19>: call 0x8000470 <function>
0x80004a8 <main+24>: addl $0xc,%esp
0x80004ab <main+27>: movl $0x1,0xfffffffc(%ebp)
0x80004b2 <main+34>: movl 0xfffffffc(%ebp),%eax
0x80004b5 <main+37>: pushl %eax
0x80004b6 <main+38>: pushl $0x80004f8
0x80004bb <main+43>: call 0x8000378 <printf>
0x80004c0 <main+48>: addl $0x8,%esp
0x80004c3 <main+51>: movl %ebp,%esp
0x80004c5 <main+53>: popl %ebp
0x80004c6 <main+54>: ret
0x80004c7 <main+55>: nop
As you can see, there are differences between the two. I'm confuse and I can't understand totally the assembly code from my computer. I would like to know the differences between the two.
How is pushl
different from push
, mov vs movl
, and so on...
what does the expression 0xhexavalue(%register)
means?
I am sorry If I'm asking a lot, But I badly need your help.
UPDATE:
Why is it that the parameter to the function 'function' got translated to different assembly code:
From the article, I believe that the parameters 1, 2, & 3 to the function got pushed to the stack..
In the one from my computer, the parameters were moved to the register 'esp' with some offset.
Are they different? Thanks
Thanks for the help really...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
没有什么真正的区别。 'movl' 的意思是“长移”——即移动 32 位值。文章中的代码每次都使用这种显式形式。如果可以从操作数推导出来,则您反汇编的代码将省略“l”(例如,当您将一个值移入 EAX 时,它必须是一个 32 位值,因为 EAX 是一个 32 位寄存器,当当你压入 ECX 时,你必须压入一个 32 位值,因为 ECX 也是一个 32 位寄存器)。
当然,代码之间确实存在差异,但这纯粹是每个代码使用的符号不同。
There is no real difference. 'movl' means "move long" -- i.e. to move a 32-bit value. The code in the article uses this explicit form every time. The code you've disassembled leaves off the 'l' if it can be deduced from the operands (e.g., when you move a value into EAX, it has to be a 32-bit value because EAX is a 32-bit register, when you push ECX you must be pushing a 32-bit value because ECX is also a 32-bit register).
Of course, there are real differences between the code, but that one is purely of the notation each is using.
在我看来,您的编译器和/或系统与本文中使用的不同。当然,您的代码的生成方式有所不同。
push
与pushl
只是推送(可能)不同数量的数据 - 您需要查看汇编器文档,了解它们在芯片中映射到哪些指令。查看机器操作码可以提供帮助。 英特尔手册将帮助您解决这个问题。mov
和movl
也是如此。它们很可能是相同的,并且您的反汇编程序只是在不需要清楚时将l
保留掉。表达式
0xhexvalue(%register)
正在访问距register
中的值偏移hexvalue
处的内存。将其想象为 C 代码*(register + hexvalue)
。It looks to me like your compiler and/or system are different from the ones used in the article. Certainly your code has been generated differently.
push
vs.pushl
are just pushing (potentially) different amounts of data - you'll need to look at your assembler documentation for what instructions they map to in the chip. Looking at the machine opcode can help there. The Intel manual will help you figure that out. Same goes formov
andmovl
. It is quite possible that they are the same, and your disassembler is just leaving thel
off when it's not needed for clarity.The expression
0xhexvalue(%register)
is accessing the memory at offsethexvalue
from the value inregister
. Imagine it as the C code*(register + hexvalue)
.如果我没记错的话,Aleph One 的文章发表于 96 年。所以经过14年的发展,GCC构建可执行文件的方式不同,因此有效代码也会不同。尝试在关闭所有优化的情况下进行编译(gcc -O0)并在(gcc -g)中调试代码,也许代码会更干净/更简单。
The Aleph One article came out in '96 if I remember correctly. So after 14 years of development, GCC builds executables differently, thus the effective code will be different. Try compiling with all the optimizations turned off (gcc -O0) and with debugging code in (gcc -g), maybe the code will be a bit cleaner/simpler.