TBone
June 13th, 2008, 17:23
So I'm trying to get back into the swing of this whole "reversing" business. I've been messing around for while just downloading dozens of trial versions of random software packages from your friendly local megalithic shareware site(s) and trying to see how many of them I can..."liberate". 
I'm having a heck of a hard time with this one, though. PEID (using Neil's UserDB) claims that it's packed with:
ASProtect 1.2x - 1.3x [Registered] -> Alexey Solodovnikov [Overlay]
RDG says that it's ASProtect 2.xx. I'm no expert, but to me it looks like 2.xx. Then again, I'm not really sure how to tell. Here's my problem:
First of all, the usual ASProtect approach (count the number of times it breaks on an exception before running) doesn't work at all. This program runs immediately without throwing any exceptions. And yes, I have ollydbg configured not to ignore any exceptions - not even memory access violations in kernel32. It literally does not throw any exceptions before displaying the programs main window. The "MO" is definitely ASProtect, though.
I've back-traced through the code to what I believe is the OEP. It doesn't look like there are any stolen bytes. That is, it looks like fairly standard prologue:
At this point, the call stack is empty and the main thread's stack frame looks like it would return to a section of dynamically allocated memory created by the packer code. This is the stack from the ground up (er...top down?):
If there are stolen bytes, I can't think of any way to find them short of manually tracing through the entire packer code, an exercise that would surely cost me my precious remaining sanity
When I look at the IAT, it's clear that large portions of it have been deliberately smashed. For example:
The address at 00666738 isn't a redirection into packer code. It's just a bad pointer entirely; that memory isn't even mapped to anything. The addresses surrounding it all are function entry points in user32.dll. If you look at the thunk table, there's a corresponding "hole" where ASProtect has ripped code:
I can't figure out how to straighten these out. I tried setting memory breakpoints on the addresses in question so that I could watch them every time the packer modified them. This doesn't appear to be a case of the packer smashing the imports "after the fact", but rather the original imports are never constructed in the first place.
I tried to follow one of these calls into the API dlls, and I thought that I had identified one of them as ultimately being a call to kernel32.GetCurrentProcessId. I patched the IAT and thunk table so that it called GetCurrentProcessId directly instead of calling into the ASProtect code. The call was successful, but the program crashed before returning. Apparently I didn't identify the call correctly.
I've read several ASProtect 2.xx tutorials (mostly the stuff from ARTeam) but I've gotta tell you - all this business about reversing and analyzing virtual.dll is going way over my head. At this point, I just really don't know what to do. Maybe I should work on something simpler, but frankly I don't seem to be getting any better at this. The easier stuff is all too easy, but all of the "real" protections seem to be way too hard. There seems to be very little middle ground out there, and I just don't know how to proceed.
I've been on a sort of hiatus from this hobby for a while because I was getting frustrated with the entire thing. I thought if I took some time off and came back with a fresh perspective that I might be able to make some progress again. But it doesn't seem like anything's changed. I'm still just banging my head against the same old walls. And I think it's really bothering me because -- at the risk of sounding arrogant -- I've honestly never had trouble learning anything before. Sure, some things have been harder to learn than others, and I've felt the mental strain of grappling with complex subjects before. But I've never said to myself "I'm not sure I can learn this". Until now
.

I'm having a heck of a hard time with this one, though. PEID (using Neil's UserDB) claims that it's packed with:
ASProtect 1.2x - 1.3x [Registered] -> Alexey Solodovnikov [Overlay]
RDG says that it's ASProtect 2.xx. I'm no expert, but to me it looks like 2.xx. Then again, I'm not really sure how to tell. Here's my problem:
First of all, the usual ASProtect approach (count the number of times it breaks on an exception before running) doesn't work at all. This program runs immediately without throwing any exceptions. And yes, I have ollydbg configured not to ignore any exceptions - not even memory access violations in kernel32. It literally does not throw any exceptions before displaying the programs main window. The "MO" is definitely ASProtect, though.
I've back-traced through the code to what I believe is the OEP. It doesn't look like there are any stolen bytes. That is, it looks like fairly standard prologue:
Code:
0065ABD4 0C6D6200 dd <censored>.00626D0C
0065ABD8 20B06200 dd <censored>.0062B020
0065ABDC F0AF6200 dd <censored>.0062AFF0
0065ABE0 00 db 00
0065ABE1 00 db 00
0065ABE2 00 db 00
0065ABE3 00 db 00
0065ABE4 88A06500 dd <censored>.0065A088
0065ABE8 . 55 push ebp ; <--- OEP?
0065ABE9 . 8BEC mov ebp, esp
0065ABEB . B9 05000000 mov ecx, 5
0065ABF0 > 6A 00 push 0
0065ABF2 . 6A 00 push 0
0065ABF4 . 49 dec ecx
0065ABF5 .^ 75 F9 jnz short <censored>.0065ABF0
At this point, the call stack is empty and the main thread's stack frame looks like it would return to a section of dynamically allocated memory created by the packer code. This is the stack from the ground up (er...top down?):
Code:
0012FF68 00B3CC60 ; <--- ESP
0012FF6C 00400000 ASCII "MZP"
0012FF70 30E992D6
0012FF74 027FCF3C
0012FF78 0012FF98
0012FF7C 00F3DE99 RETURN to 00F3DE99 from 00F3DCDC ; <--- EBP
0012FF80 0012FFE0
0012FF84 00F3E41E
0012FF88 0012FF98
0012FF8C 00F20000
0012FF90 00EE0000
0012FF94 00F3E3BC
0012FF98 0078D419 RETURN to <censored>.0078D419 from <censored>.0078D419 ; imports and reloc. section
0012FF9C 00000000
0012FFA0 0078D82D <censored>.0078D82D ; ditto
0012FFA4 00000000
0012FFA8 00000000
0012FFAC 0012FFF0
0012FFB0 0012FFC4
0012FFB4 7FFDE000
0012FFB8 7C8285EC ntdll.KiFastSystemCallRet
0012FFBC 0012FFB0
0012FFC0 00000000
0012FFC4 77E6F23B RETURN to kernel32.77E6F23B
0012FFC8 00000000
0012FFCC 00000000
0012FFD0 7FFDE000
0012FFD4 00000000
0012FFD8 0012FFC8
0012FFDC A6C24CE4
0012FFE0 FFFFFFFF End of SEH chain
0012FFE4 77E61A60 SE handler
0012FFE8 77E6F248 kernel32.77E6F248
0012FFEC 00000000
0012FFF0 00000000
0012FFF4 00000000
0012FFF8 00401000 <censored>.<ModuleEntryPoint>
0012FFFC 00000000
If there are stolen bytes, I can't think of any way to find them short of manually tracing through the entire packer code, an exercise that would surely cost me my precious remaining sanity

When I look at the IAT, it's clear that large portions of it have been deliberately smashed. For example:
Code:
00666730 BC 69 38 77 79 0D 39 77
00666738 05 A0 6C B0 B8 27 39 77
00666740 9A 45 39 77 02 FF 39 77
The address at 00666738 isn't a redirection into packer code. It's just a bad pointer entirely; that memory isn't even mapped to anything. The addresses surrounding it all are function entry points in user32.dll. If you look at the thunk table, there's a corresponding "hole" where ASProtect has ripped code:
Code:
00408230 $- FF25 3C676600 jmp near [dword ds:66673C] ; user32.RedrawWindow
00408236 8BC0 mov eax, eax
00408238 $ E8 C37DDB00 call 011C0000 ; Should be 0666738...
0040823D B8 db B8 ; Maybe the tail end of the original address?
0040823E 8BC0 mov eax, eax
00408240 $- FF25 34676600 jmp near [dword ds:666734] ; user32.RegisterWindowMessageA
00408246 . 8BC0 mov eax, eax
00408248 .- FF25 30676600 jmp near [dword ds:666730] ; user32.RegisterHotKey
I can't figure out how to straighten these out. I tried setting memory breakpoints on the addresses in question so that I could watch them every time the packer modified them. This doesn't appear to be a case of the packer smashing the imports "after the fact", but rather the original imports are never constructed in the first place.
I tried to follow one of these calls into the API dlls, and I thought that I had identified one of them as ultimately being a call to kernel32.GetCurrentProcessId. I patched the IAT and thunk table so that it called GetCurrentProcessId directly instead of calling into the ASProtect code. The call was successful, but the program crashed before returning. Apparently I didn't identify the call correctly.
I've read several ASProtect 2.xx tutorials (mostly the stuff from ARTeam) but I've gotta tell you - all this business about reversing and analyzing virtual.dll is going way over my head. At this point, I just really don't know what to do. Maybe I should work on something simpler, but frankly I don't seem to be getting any better at this. The easier stuff is all too easy, but all of the "real" protections seem to be way too hard. There seems to be very little middle ground out there, and I just don't know how to proceed.
I've been on a sort of hiatus from this hobby for a while because I was getting frustrated with the entire thing. I thought if I took some time off and came back with a fresh perspective that I might be able to make some progress again. But it doesn't seem like anything's changed. I'm still just banging my head against the same old walls. And I think it's really bothering me because -- at the risk of sounding arrogant -- I've honestly never had trouble learning anything before. Sure, some things have been harder to learn than others, and I've felt the mental strain of grappling with complex subjects before. But I've never said to myself "I'm not sure I can learn this". Until now
