На большинстве архитектур все инструкции имеют фиксированную длину. Это упрощает загрузку и выполнение программы. В 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
Довольно сложно представить, как ЦП «знает», где заканчивается одна инструкция и начинается следующая. Например, если я добавлю байт 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
представляет собой четыре отдельные инструкции.
xor
) и никогда не выполнит паруadd/inc
. - person 500 - Internal Server Error   schedule 05.08.2014