递归汇编调用,虽然源代码中没有递归
我有一个来自转储的代码片段,我想理解它。 最让我困扰的是(看似)递归调用,例如
bd604: e8 fc ff ff ff call bd605 + 0xb5
他们做了什么? 我在原始函数中没有使用递归。
谢谢@schnaader
看起来好像调用使 cld 并跳转到 EAX
编辑:我的函数的完整 dmp
00bd550 <SendData>:
SendData():
bd550: 55 push %ebp
bd551: 57 push %edi
bd552: 56 push %esi
bd553: 53 push %ebx
bd554: 83 ec 20 sub $0x20,%esp
bd557: 8b 35 74 a2 06 00 mov 0x6a274,%esi
bd55d: 8b 1d ac a2 06 00 mov 0x6a2ac,%ebx
bd563: dd 44 24 40 fldl 0x40(%esp,1)
bd567: 66 c7 44 24 0e 00 00 movw $0x0,0xe(%esp,1)
bd56e: 83 eb 18 sub $0x18,%ebx
bd571: 85 f6 test %esi,%esi
bd573: dd 5c 24 18 fstpl 0x18(%esp,1)
bd577: dd 44 24 48 fldl 0x48(%esp,1)
bd57b: dd 5c 24 10 fstpl 0x10(%esp,1)
bd57f: 0f 85 b2 00 00 00 jne bd637 <SendData+0xe7>
bd585: 8b 7c 24 38 mov 0x38(%esp,1),%edi
bd589: 89 dd mov %ebx,%ebp
bd58b: c1 fd 02 sar $0x2,%ebp
bd58e: 85 ff test %edi,%edi
bd590: 0f 8e 99 00 00 00 jle bd62f <SendData+0xdf>
bd596: 8d 76 00 lea 0x0(%esi),%esi
bd599: 8d bc 27 00 00 00 00 lea 0x0(%edi,1),%edi
bd5a0: 0f b7 74 24 0e movzwl 0xe(%esp,1),%esi
bd5a5: 39 ef cmp %ebp,%edi
bd5a7: 89 e8 mov %ebp,%eax
bd5a9: 0f 4e c7 cmovle %edi,%eax
bd5ac: dd 44 24 18 fldl 0x18(%esp,1)
bd5b0: 89 c5 mov %eax,%ebp
bd5b2: 8d 1c ad 00 00 00 00 lea 0x0(,%ebp,4),%ebx
bd5b9: 29 ef sub %ebp,%edi
bd5bb: 01 c6 add %eax,%esi
bd5bd: a1 a8 a2 06 00 mov 0x6a2a8,%eax
bd5c2: 8d 56 ff lea 0xffffffff(%esi),%edx
bd5c5: dd 58 08 fstpl 0x8(%eax)
bd5c8: 66 89 50 06 mov %dx,0x6(%eax)
bd5cc: 0f b7 54 24 0e movzwl 0xe(%esp,1),%edx
bd5d1: 66 89 50 04 mov %dx,0x4(%eax)
bd5d5: 8b 54 24 3c mov 0x3c(%esp,1),%edx
bd5d9: 89 10 mov %edx,(%eax)
bd5db: dd 44 24 10 fldl 0x10(%esp,1)
bd5df: dd 58 10 fstpl 0x10(%eax)
bd5e2: 8b 54 24 34 mov 0x34(%esp,1),%edx
bd5e6: 0f bf 44 24 0e movswl 0xe(%esp,1),%eax
bd5eb: 89 5c 24 08 mov %ebx,0x8(%esp,1)
bd5ef: 83 c3 18 add $0x18,%ebx
bd5f2: 8d 04 82 lea (%edx,%eax,4),%eax
bd5f5: 89 44 24 04 mov %eax,0x4(%esp,1)
bd5f9: a1 a8 a2 06 00 mov 0x6a2a8,%eax
bd5fe: 83 c0 18 add $0x18,%eax
bd601: 89 04 24 mov %eax,(%esp,1)
bd604: e8 fc ff ff ff call bd605 <SendData+0xb5>
bd609: a1 a8 a2 06 00 mov 0x6a2a8,%eax
bd60e: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp,1)
bd615: 00
bd616: 89 5c 24 04 mov %ebx,0x4(%esp,1)
bd61a: 89 04 24 mov %eax,(%esp,1)
bd61d: e8 fc ff ff ff call bd61e <SendData+0xce>
bd622: 85 ff test %edi,%edi
bd624: 66 89 74 24 0e mov %si,0xe(%esp,1)
bd629: 0f 8f 71 ff ff ff jg bd5a0 <SendData+0x50>
bd62f: 83 c4 20 add $0x20,%esp
bd632: 5b pop %ebx
bd633: 5e pop %esi
bd634: 5f pop %edi
bd635: 5d pop %ebp
bd636: c3 ret
bd637: dd 44 24 18 fldl 0x18(%esp,1)
bd63b: dd 1c 24 fstpl (%esp,1)
bd63e: e8 fc ff ff ff call bd63f <SendData+0xef>
bd643: 85 c0 test %eax,%eax
bd645: 74 e8 je bd62f <SendData+0xdf>
bd647: e9 39 ff ff ff jmp bd585 <SendData+0x35>
bd64c: 8d 74 26 00 lea 0x0(%esi,1),%esi
I have a code fragment from a dump which I want to understand.
What bothers me most, are the (seemingly) recursive calls like
bd604: e8 fc ff ff ff call bd605 + 0xb5
What do they do? I don't use recursion in the original function.
Thanks@schnaader
it seems as if the calls make cld and jump to EAX
EDIT: full dmp of my function
00bd550 <SendData>:
SendData():
bd550: 55 push %ebp
bd551: 57 push %edi
bd552: 56 push %esi
bd553: 53 push %ebx
bd554: 83 ec 20 sub $0x20,%esp
bd557: 8b 35 74 a2 06 00 mov 0x6a274,%esi
bd55d: 8b 1d ac a2 06 00 mov 0x6a2ac,%ebx
bd563: dd 44 24 40 fldl 0x40(%esp,1)
bd567: 66 c7 44 24 0e 00 00 movw $0x0,0xe(%esp,1)
bd56e: 83 eb 18 sub $0x18,%ebx
bd571: 85 f6 test %esi,%esi
bd573: dd 5c 24 18 fstpl 0x18(%esp,1)
bd577: dd 44 24 48 fldl 0x48(%esp,1)
bd57b: dd 5c 24 10 fstpl 0x10(%esp,1)
bd57f: 0f 85 b2 00 00 00 jne bd637 <SendData+0xe7>
bd585: 8b 7c 24 38 mov 0x38(%esp,1),%edi
bd589: 89 dd mov %ebx,%ebp
bd58b: c1 fd 02 sar $0x2,%ebp
bd58e: 85 ff test %edi,%edi
bd590: 0f 8e 99 00 00 00 jle bd62f <SendData+0xdf>
bd596: 8d 76 00 lea 0x0(%esi),%esi
bd599: 8d bc 27 00 00 00 00 lea 0x0(%edi,1),%edi
bd5a0: 0f b7 74 24 0e movzwl 0xe(%esp,1),%esi
bd5a5: 39 ef cmp %ebp,%edi
bd5a7: 89 e8 mov %ebp,%eax
bd5a9: 0f 4e c7 cmovle %edi,%eax
bd5ac: dd 44 24 18 fldl 0x18(%esp,1)
bd5b0: 89 c5 mov %eax,%ebp
bd5b2: 8d 1c ad 00 00 00 00 lea 0x0(,%ebp,4),%ebx
bd5b9: 29 ef sub %ebp,%edi
bd5bb: 01 c6 add %eax,%esi
bd5bd: a1 a8 a2 06 00 mov 0x6a2a8,%eax
bd5c2: 8d 56 ff lea 0xffffffff(%esi),%edx
bd5c5: dd 58 08 fstpl 0x8(%eax)
bd5c8: 66 89 50 06 mov %dx,0x6(%eax)
bd5cc: 0f b7 54 24 0e movzwl 0xe(%esp,1),%edx
bd5d1: 66 89 50 04 mov %dx,0x4(%eax)
bd5d5: 8b 54 24 3c mov 0x3c(%esp,1),%edx
bd5d9: 89 10 mov %edx,(%eax)
bd5db: dd 44 24 10 fldl 0x10(%esp,1)
bd5df: dd 58 10 fstpl 0x10(%eax)
bd5e2: 8b 54 24 34 mov 0x34(%esp,1),%edx
bd5e6: 0f bf 44 24 0e movswl 0xe(%esp,1),%eax
bd5eb: 89 5c 24 08 mov %ebx,0x8(%esp,1)
bd5ef: 83 c3 18 add $0x18,%ebx
bd5f2: 8d 04 82 lea (%edx,%eax,4),%eax
bd5f5: 89 44 24 04 mov %eax,0x4(%esp,1)
bd5f9: a1 a8 a2 06 00 mov 0x6a2a8,%eax
bd5fe: 83 c0 18 add $0x18,%eax
bd601: 89 04 24 mov %eax,(%esp,1)
bd604: e8 fc ff ff ff call bd605 <SendData+0xb5>
bd609: a1 a8 a2 06 00 mov 0x6a2a8,%eax
bd60e: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp,1)
bd615: 00
bd616: 89 5c 24 04 mov %ebx,0x4(%esp,1)
bd61a: 89 04 24 mov %eax,(%esp,1)
bd61d: e8 fc ff ff ff call bd61e <SendData+0xce>
bd622: 85 ff test %edi,%edi
bd624: 66 89 74 24 0e mov %si,0xe(%esp,1)
bd629: 0f 8f 71 ff ff ff jg bd5a0 <SendData+0x50>
bd62f: 83 c4 20 add $0x20,%esp
bd632: 5b pop %ebx
bd633: 5e pop %esi
bd634: 5f pop %edi
bd635: 5d pop %ebp
bd636: c3 ret
bd637: dd 44 24 18 fldl 0x18(%esp,1)
bd63b: dd 1c 24 fstpl (%esp,1)
bd63e: e8 fc ff ff ff call bd63f <SendData+0xef>
bd643: 85 c0 test %eax,%eax
bd645: 74 e8 je bd62f <SendData+0xdf>
bd647: e9 39 ff ff ff jmp bd585 <SendData+0x35>
bd64c: 8d 74 26 00 lea 0x0(%esi,1),%esi
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可能通过反汇编目标文件 (.o) 获得此转储。 正如OSDev中提到的,
e8 fc ff ff ff
序列对应于一个函数在链接阶段之前调用,在您调用的函数的最终地址(在可执行文件中)已知之前。 在此阶段,有关此调用目的地的信息存储在目标文件的重定位表中,等待链接器将可执行文件放在一起。为了避免此问题,您应该分析最终可执行文件的转储,而不是目标文件之一的转储。 这里链接器的工作将完成,CALL 操作数将对应于它们的真实目的地。
You probably got this dump from disassembling an object file (.o) . As mentioned here on OSDev the
e8 fc ff ff ff
sequence corresponds to a function call before the linking phase, before the final address (in the executable) of the function you are calling is known. At this stage the information about this call's destination is stored in the relocation table of the object file, waiting for the linker to put the executable together.To avoid this issue you should analyse a dump of the final executable, not of one of the object files. Here the linker's job will be done and the CALL operands will correspond to their real destinations.
使用GRDB(实模式调试器),这会转换为“call -1”因此 bd603 处的字节将决定将执行哪个命令。 例如,如果该字节是 FF,则下一个命令将是“jmp ax”,这可能会递归。
不管怎样,这看起来像是一些反调试/自修改代码,而不是真正有意义的。
Using GRDB (a real mode debugger), this translates to "call -1" so the byte at bd603 will determine which command will be executed. For example, if this byte is FF, the next command will be "jmp ax" which could get recursive.
Anyway, this rather looks like some anti-debugging/self-modifying code than really making sense.