我正在尝试反转 Linux 模块。在ioctl
例程中,我有以下指令序列(由 生成objdump -M intel -d test.ko
):
3f9: 74 3b je 436 <device_ioctl+0x46>
...
436: e8 00 00 00 00 call 43b <device_ioctl+0x4b>
43b: 48 98 cdqe
43d: c3 ret
我不确定跳转完成后会发生什么。
首先,我们有一个call
指令。操作码是E8 00
对下一条指令的接近调用。EIP 寄存器(包含下一条指令的地址)也被压入堆栈。
然后,我们继续cdqe
指令。它将 EAX 寄存器的符号扩展到 RAX。换句话说,它什么都不做。顺便提一下,EAX/RAX 寄存器从例程开始就没有被修改。
最后,ret
执行指令。它将堆栈弹出到对应于前一条指令的 EIP 中,我们从该点继续执行例程。
因此,cdqe
再次执行(什么都不做)并ret
再次调用该指令。这一次,我们离开ioctl
例程并返回到被调用者。
我说这没有任何作用是对的吗?如果是这样,该代码的重点是什么?
这是完整的例程:
00000000000003f0 <device_ioctl>:
3f0: 48 89 d7 mov rdi,rdx
3f3: 81 fe 03 b0 fe ca cmp esi,0xcafeb003
3f9: 74 3b je 436 <device_ioctl+0x46>
3fb: 77 18 ja 415 <device_ioctl+0x25>
3fd: 81 fe 01 b0 fe ca cmp esi,0xcafeb001
403: 74 39 je 43e <device_ioctl+0x4e>
405: 81 fe 02 b0 fe ca cmp esi,0xcafeb002
40b: 75 39 jne 446 <device_ioctl+0x56>
40d: e8 00 00 00 00 call 412 <device_ioctl+0x22>
412: 48 98 cdqe
414: c3 ret
415: 48 c7 c0 00 00 00 00 mov rax,0x0
41c: 48 c7 c2 ff ff ff ff mov rdx,0xffffffffffffffff
423: 48 2d 00 00 00 00 sub rax,0x0
429: 81 fe 04 b0 fe ca cmp esi,0xcafeb004
42f: 89 c0 mov eax,eax
431: 48 0f 45 c2 cmovne rax,rdx
435: c3 ret
436: e8 00 00 00 00 call 43b <device_ioctl+0x4b>
43b: 48 98 cdqe
43d: c3 ret
43e: e8 00 00 00 00 call 443 <device_ioctl+0x53>
443: 48 98 cdqe
445: c3 ret
446: 48 83 c8 ff or rax,0xffffffffffffffff
44a: c3 ret
这是来自pbctf 2021的夜总会挑战赛。