2
.text:00401000 push ebp
.text:00401001 mov ebp, esp
.text:00401003 push ebx
.text:00401004 push esi
.text:00401005 push edi
.text:00401006 lea esi, [401012h]
.text:0040100C push esi
.text:0040100D jmp 401017
.text:0040100D ; This would seem to be a simple branch -
.text:0040100D ; what could possibly be unusual in it? However, it's not
.text:0040100D ; a simple branch, but a masked function call. How
.text:0040100D ; do we know this? Let's go to address 0x401017 and see.
.text:0040100D ; .text:00401017 push ebp
.text:0040100D ; .text:00401018 mov ebp, esp
.text:0040100D ; .text:0040101A pop ebp
.text:0040100D ; .text:0040101B retn
.text:0040100D ; What do you think - where does this ret return control?
.text:0040100D ; Naturally, to the address that lies on the top of the
.text:0040100D ; stack. And what do we have there? PUSH EBP from line
.text:0040100D ; 401017 is popped back by the POP from line 40101B.
.text:0040100D ; Well... let's return back to the JMP instruction
.text:0040100D ; and begin slowly scrolling the disassembler window up,
.text:0040100D ; tracing all calls to the stack. Here it is!
.text:0040100D ; The PUSH ESI instruction from line 401000C throws the
.text:0040100D ; contents of the SI register onto the top of the stack,
.text:0040100D ; and the register takes the value of 0x401012,
.text:0040100D ; which is simply the address of the beginning
.text:0040100D ; of the function called by the JMP instruction.
.text:0040100D ; (To be more exact, it's not an address but an offset.
.text:0040100D ; But this isn't of great importance.)
.text:00401012 pop edi
.text:00401013 pop esi
.text:00401014 pop ebx
.text:00401015 pop ebp
.text:00401016 retn
作者在注释的最后说0x401012是jmp跳去的函数的开始,那不是函数返回的应该执行的语句吗?