【发布时间】:2014-08-04 23:41:35
【问题描述】:
在大多数架构上,指令都是固定长度的。这使得程序加载和执行变得简单。在 x86/x64 上,指令是可变长度的,因此反汇编程序可能如下所示:
File Type: EXECUTABLE IMAGE
00401000: 8B 04 24 mov eax,dword ptr [esp]
00401003: 83 C4 04 add esp,4
00401006: FF 64 24 FC jmp dword ptr [esp-4]
0040100A: 55 push ebp
0040100B: E8 F0 FF FF FF call 00401000
00401010: 50 push eax
00401011: 68 00 30 40 00 push 403000h
00401016: E8 0D 00 00 00 call 00401028
0040101B: 83 C4 08 add esp,8
0040101E: 33 C0 xor eax,eax
00401020: 5D pop ebp
00401021: 83 C4 04 add esp,4
00401024: FF 64 24 FC jmp dword ptr [esp-4]
00401028: FF 25 00 20 40 00 jmp dword ptr ds:[00402000h]
Summary
1000 .data
1000 .rdata
1000 .reloc
1000 .text
似乎很难想象 CPU 是如何“知道”一条指令在哪里结束以及下一条指令在哪里开始的。例如,如果我将字节 0x90 (NOP) 添加到 XOR EAX,EAX 操作码的中间,则程序将反汇编为:
File Type: EXECUTABLE IMAGE
00401000: 8B 04 24 mov eax,dword ptr [esp]
00401003: 83 C4 04 add esp,4
00401006: FF 64 24 FC jmp dword ptr [esp-4]
0040100A: 55 push ebp
0040100B: E8 F0 FF FF FF call 00401000
00401010: 50 push eax
00401011: 68 00 30 40 00 push 403000h
00401016: E8 0D 00 00 00 call 00401028
0040101B: 83 C4 08 add esp,8
0040101E: 33 90 C0 5D 83 C4 xor edx,dword ptr [eax+C4835DC0h]
00401024: 04 FF add al,0FFh
00401026: 64 24 FC and al,0FCh
00401029: FF
0040102A: 25
0040102B: 00 20 add byte ptr [eax],ah
0040102D: 40 inc eax
Summary
1000 .data
1000 .rdata
1000 .reloc
1000 .text
可以预见的是,它在运行时会崩溃。
我很好奇指令解码器究竟看到了什么额外的字节,这使得它认为0040101E 行有 6 个字节长,而最初位于00401028 的行是四个单独的指令。
【问题讨论】:
-
CPU 的工作方式与反汇编程序完全相同。
-
是的,但我在问为什么他们都用额外的字节完全搞砸了解码后续指令
-
同样的道理,把“10 32 5”改成“10132 5”,“10”和“32”只要换个空格就变了。
-
至于 0xFF/0x25,目前可能未定义。到目前为止,没有搞砸 - 你看到的是这些字节现在编码的内容。在运行时,CPU 将触发无效指令错误(假设它尚未在
xor上进行 AV 处理)并且永远不会执行add/inc对。
标签: assembly x86 decode instructions