[英]Assembly - jump instruction in machine code
短跳轉使用添加到JMP
之后的指令地址的有符號偏移量。
例如,第一個JMP L2
的偏移量為FE
等於-2
,並將其添加到JMP
JMP
地址。
但是,第一個JMP L
不是這種情況,因為需要的偏移量是E8
(第二個JMP L
也不正確,它應該具有偏移量E6
)。 如果您跳到在線 x86 匯編器站點(例如這個站點)並輸入:
mov ecx,2
l: mov edx,0
inc edx
sub ecx,1
nop
nop
nop
setz al
shl al,1
mov byte [l1+1],al
l1: jmp l
jmp l
mov byte [l2+1],al
l2: jmp l
jmp l2
mov eax,edx
ret
你會注意到那些額外的三個NOP
行,它們是因為匯編器選擇了SUB ECX,1
的較短變體,我只是想讓地址與你所擁有的保持一致。 匯編出來的代碼如下:
0: b9 02 00 00 00 mov ecx,0x2
00000005 <l>:
5: ba 00 00 00 00 mov edx,0x0
a: 42 inc edx
b: 83 e9 01 sub ecx,0x1
e: 90 nop
f: 90 nop
10: 90 nop
11: 0f 94 c0 sete al
14: d0 e0 shl al,1
16: a2 1c 00 00 00 mov ds:0x1c,al
0000001b <l1>:
1b: eb e8 jmp 5 <l>
1d: eb e6 jmp 5 <l>
1f: a2 25 00 00 00 mov ds:0x25,al
00000024 <l2>:
24: eb fe jmp 24 <l2>
26: eb fc jmp 24 <l2>
28: 89 d0 mov eax,edx
2a: c3 ret
很明顯,前兩個跳轉的編碼在您發布的代碼中不正確。 它們應該是EbE8/EbE6
而不是EBBD/EBEB
。 事實上,如果他們要去其他label,后一對甚至沒有意義,因為如果他們跳到同一個label,他們之間的差異應該正好是兩個。
但是需要注意的一件事是:如果您仔細檢查代碼,您會發現它實際上是在自我修改,因為JMP
指令是用如下語句修改的:
MOV BYTE [L1 + 1], AL
(在L1
改變指令的偏移量)。 自修改代碼可用於混淆目的,或難以對軟件進行逆向工程,並且可能是代碼已經經歷了將要應用的更改。
在進行自我更改時動態觀察代碼會很有用,以了解它們如何影響代碼,但我的static分析的粗略結果如下:
Address Effect
------- ------
00 ecx = 2
05 edx = 0
0a edx = 1
0b ecx = 1, zflag=F
11 al = 0 (because zflag=F)
14 al stays 0
16 instruction at 1b becomes eb00, jmp 1d
1b jumps to 1d
1d jumps to 0a
0a edx = 2
0b ecx = 0, zflag=T
11 al = 1 (because zflag=T)
14 al = 2
16 instruction at 1b becomes eb02, jmp 1f
1b jumps to 1f
1f instruction at 24 becomes eb02, jmp 28
24 jumps to 28
28 eax = 2
2a returns
基於此, L1
的指令永遠不應該變成EBBD
(它只會更改為EB00
或EB02
),因此您所擁有的文本更有可能是簡單的錯誤打印(特別是考慮到第二個JMP L
中的錯誤永遠不會被修改)。 我猜作者並不比我們的 rest 更完美:-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.