Ok, basically the idea when you dump the process is to dump while as close as possible to the OEP. Let's trace through the code from OEP (before dumping) and see what the first piece of code we can dump at is. We start here:
Code:
00613654 . 55 PUSH EBP
00613655 . 8BEC MOV EBP,ESP
00613657 . 83EC 10 SUB ESP,10
0061365A . B8 9C2D6100 MOV EAX,Resbldr2.00612D9C
0061365F . E8 3C3DDFFF CALL Resbldr2.004073A0
00613664 . 33C0 XOR EAX,EAX
00613666 . 55 PUSH EBP
00613667 . 68 B6366100 PUSH Resbldr2.006136B6
0061366C . 64:FF30 PUSH DWORD PTR FS:[EAX]
Following the CALL at 61365F, we come to the following procedure:
Code:
004073A0 /$ 53 PUSH EBX
004073A1 |. 8BD8 MOV EBX,EAX
004073A3 |. 33C0 XOR EAX,EAX
004073A5 |. A3 C4406100 MOV DWORD PTR DS:[6140C4],EAX
004073AA |. 6A 00 PUSH 0
004073AC |. E8 2BFFFFFF CALL Resbldr2.004072DC
004073B1 |. A3 68666200 MOV DWORD PTR DS:[626668],EAX
004073B6 |. A1 68666200 MOV EAX,DWORD PTR DS:[626668]
004073BB |. A3 D0406100 MOV DWORD PTR DS:[6140D0],EAX
004073C0 |. 33C0 XOR EAX,EAX
004073C2 |. A3 D4406100 MOV DWORD PTR DS:[6140D4],EAX
004073C7 |. 33C0 XOR EAX,EAX
004073C9 |. A3 D8406100 MOV DWORD PTR DS:[6140D8],EAX
004073CE |. E8 C1FFFFFF CALL Resbldr2.00407394
004073D3 |. BA CC406100 MOV EDX,Resbldr2.006140CC
004073D8 |. 8BC3 MOV EAX,EBX
004073DA |. E8 25D6FFFF CALL Resbldr2.00404A04
004073DF |. 5B POP EBX
004073E0 \. C3 RETN
Ah! We see the CALL at 4073AC lands at 4072DC, which is the first place we land at with the TC EIP<900000 you ran earlier (all the code we saw before coming to 4072DC was emulated/implemented in some fashion by ASProtect, including usage of the stolen bytes). When you were dumping at 613664 before, you were dumping much farther from OEP than 4072DC, because you don't get to 613664 until all the code in this procedure executes and returns (which a run trace shows as totaling 332335 instructions, not counting system code... No small amount!). In fact, the code in this subroutine does some data morphing (using the data block between 612D9C (note a key part of our stolen bytes) and 61364C), and doing that before dumping causes the dumped exe to fail. But, it's Delphi code doing the morphing (standard code for any Delphi program), not ASProtect code like you thought. Lets investigate this a little further... Lets follow the call at 4073AC:
Code:
004072DC $-FF25 1CA36200 JMP DWORD PTR DS:[62A31C]
004072E2 8BC0 MOV EAX,EAX
004072E4 $-FF25 18A36200 JMP DWORD PTR DS:[62A318]
004072EA 8BC0 MOV EAX,EAX
004072EC $-FF25 14A36200 JMP DWORD PTR DS:[62A314]
004072F2 8BC0 MOV EAX,EAX
004072F4 $-FF25 10A36200 JMP DWORD PTR DS:[62A310]
004072FA 8BC0 MOV EAX,EAX
The data at/surrounding 62A31C is actually a thunk in the import table. Before fixing the IAT, this jumps to 1261C64 (you will see where it jumps to after fixing the IAT in a minute..), which as you had said earlier, is ASProtect code. Let's follow it, and we see this procedure:
Code:
01261C64 55 PUSH EBP
01261C65 8BEC MOV EBP,ESP
01261C67 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
01261C6A 85C0 TEST EAX,EAX
01261C6C 75 13 JNZ SHORT 01261C81
01261C6E 813D A47A2601 00004000 CMP DWORD PTR DS:[1267AA4],400000 ; ASCII "MZP"
01261C78 75 07 JNZ SHORT 01261C81
01261C7A A1 A47A2601 MOV EAX,DWORD PTR DS:[1267AA4]
01261C7F EB 06 JMP SHORT 01261C87
01261C81 50 PUSH EAX
01261C82 E8 3135FFFF CALL 012551B8 ; JMP to kernel32.GetModuleHandleA
01261C87 5D POP EBP
01261C88 C2 0400 RETN 4
So, it does some stuff, then calls 12551B8, which as Olly noted, is a thunk jumping to 77E7AD86, which is in GetModuleHandleA. Well, one of the protection mechanisms ASProtect uses is kernel32 function emulation. Basically, certain kernel32 functions in the IAT are redirected into ASProtect code which has some arbitrary instructions then turns around and calls the kernel32 function itself.
So, at 4073AC and 4072DC, though it looks like some ASProtect code is getting called, really, it is just GetModuleHandleA getting called.
Now do you understand why you need to dump at 4072DC?
Regards,
Satyric0n