A short jump uses a signed offset added to the address of the instruction following the JMP.
For example, the first JMP L2 has an offset of FE which equates to -2, and adding that to the address of the instruction following that JMP gives you the address of that JMP.
However, that's not the case for the first JMP L since the offset needed there would be E8 (the second JMP L is also incorrect, it should have the offset E6). You can confirm this if you hop on to an online x86 assembler site such as this one and enter:
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
Run Code Online (Sandbox Code Playgroud)
You'll notice those extra three NOP lines, they're because the assembler chooses a shorter variant of SUB ECX,1 and I just want to keep the addresses lined up with what you have. The assembled code out of that is as follows:
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
Run Code Online (Sandbox Code Playgroud)
It's evident from that that the encoding of the first two jumps is incorrect in your posted code. They should be EbE8/EbE6 rather than EBBD/EBEB. In fact, the latter pair wouldn't even make sense if they were going to some other label, since the difference between them should be exactly two if they're jumping to the same label.
One thing to be wary of however: if you examine the code closely, you'll see that it's actually self modifying, as the JMP instructions are modified with statements like:
MOV BYTE [L1 + 1], AL
Run Code Online (Sandbox Code Playgroud)
(changing the offset of the instruction at L1). Self-modifying code can be used for the purposes of obfuscation, or making it difficult to reverse-engineer software, and it may be that the code has already undergone the changes that will be applied.
It would be useful to watch that code dynamically as the self-changes are made, to see how they affect the code, but the rough outcome of my static analysis follows:
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
Run Code Online (Sandbox Code Playgroud)
Based on that, the instruction at L1 should never become EBBD (it's only ever changed to EB00 or EB02) so it's far more likely that what you have there is a simple misprint of the text (especially given the error in the second JMP L which is never modified). I'd guess authors are no more perfect than the rest of us :-)
| 归档时间: |
|
| 查看次数: |
436 次 |
| 最近记录: |