Log in

View Full Version : +Splaj Awave tutorial revisited.


WaxfordSqueers
January 21st, 2005, 05:15
Howdy,

I decided to try +Splaj's Awave tute because I'm setting up Ice 4.3.1 on XP Sp2 and wanted to put it through it's paces. Much to my chagrin, it seems Alexey has been hard at work with a different revision.

I tried the BPX on GetVersion but only got the program coming up. I didn't know if it was Ice's breakpoints not sticking, or what. I finally got one to stick on IsDebuggerPresent. But I couldn't F12 out of the call because SXS.dll was being ornery.

New strategy. I changed the file attributes to F0000060 and loaded via symbol loader and it broke at the program entry point. IDA could not make hide nor hair of it, though, on disassembly due to copious amounts of SMC. Then I tried GetVersion, but no luck. I got a messagebox telling me my file was corrupted. After many bright ideas, I decided to go cold turkey and trace in.

I've looked in the memory image PE header to see if i could change my file attributes back after loading with ice loader. I can't seem to find them. I wonder if Alexey hid them till the file's nearly loaded?

Got to a point where there are about 6 calls in a row, I mean one after the other. The message box always showed up in the last one. Took me a long time to see what it was. Alexey's pretty smart. He set up the following statement:

XOR [EAX], EAX

which causes an exception, because [EAX] is -1 and EAX is 0. I don't know why, but it does a good job. There's about 10 of these little beauties that I've found and all are buried in self modifying code.

My first problem comes when I inadvertantly hit an exception and the message box shows up. I have to reload from scratch and NOP each XOR statement in memory. Is there a better way out of these exceptions? I have tried tracing through them and F12ing out, but I always crash.

I feel that I'm pretty close to paydirt, but my latest crash is not an obvious exception. I'm at the point after the code is decompressed and loaded, and something is happening with respect to to the path and file name. I'm using Iceext and the IsDebuggerPresent doesn't seem to see it. So, I'm thinking it's a flag issue because there's no XOR's around. There are a couple of CMP's I need to check.

BTW...I found the group of imports +Splaj mentioned but they're not near where he said they'd be. When I try his search trick, about a couple dozen POPADS show up. I'm thinking Alexey may have seeded them. Also, he's built XOR exception producers around the imports, like land mines. It's getting dangerous to trace through the dark code woods.

For the longest time, I've tried to understand how to convert 8xxxxxxx numbers to the 04xxxxxx equivalent. I've read a lot on descriptors, and understand the segmentation pretty decently with the selector and offset, but the conversion still eludes me. Could one of you gurus say something about it?

For example, when I do the search, the results come back as something like 28:83579230. How do I convert that into the selectorffset like cs:eip.

thanks

doug
January 21st, 2005, 09:02
First, when you reach a breakpoint, you can always set another breakpoint on the return address (bpx *esp). I don't know the details of why you can't keep on tracing (did you try F11 / G @SS:ESP when you are at the first instruction of the API?), but if you do the return address bpx, you'll be able to continue tracing after IsDebuggerPresent.

Simply NOP'ing out the exceptions will not work if useful work is being done inside the exception handler. Check what exception handler is being installed before these exceptions occur (tip: look for instructions dealing with fs segment).

WaxfordSqueers
January 21st, 2005, 10:31
Quote:
[Originally Posted by doug]First, when you reach a breakpoint, you can always set another breakpoint on the return address (bpx *esp). I don't know the details of why you can't keep on tracing (did you try F11 / G @SS:ESP when you are at the first instruction of the API?), but if you do the return address bpx, you'll be able to continue tracing after IsDebuggerPresent.


Hey Doug. My problem is that I'm tracing through Asprotect wrapper code. There aren't any breakpoints to speak of, and when you get close to paydirt, Alexey has the good BP's protected with exception traps. So, if I use the GetVersion BP suggested by +Splaj, I get hit by several exceptions before the BP triggers. The exceptions are calling the messagebox with an error message, and that's probably because I altered the PE header to make the file executable.

If I don't alter the the file attributes, it wont break on anything. That's where i need advice from you more-senior types.

I'm wondering if the exceptions are re-entrant. I'm used to kernel32 tracing, and what you'd see there is a call to K32, and a subsequent call back into the calling code from the K32 call. I've tried to trace into the exception code, but I get BSOD's, or hit by the message box. I'm thinking the message box must belong to Awave, so the exception is probably calling it along the way.

I have read through the softice manual many times, and looked through the archives, but I'm still foggy on the more advanced use of BP's. I've been using F12 to force a return from a call, but I use <T> <Enter> and <P> <Enter> for single-stepping and jumping over functions. I guess the next thing is to get serious with those, but I have so many things to refresh and learn I find it hard knowing where to spend my time.

I'm very comfortable with BMSG and BPX, and I've used BPR and BPM extensively. You got me there with the F11 / G @SS:ESP, so instead of hypothesizing, I'll go have a read. The BPX *ESP is a good idea and I'll need to check that out. Thanks.

The obvious thing is that normal code execution isn't bothered by the bad code. So, it must be throwing an exception and having control returned after the exception. In my case, though, because I altered the PE file, it's diverting me to the Awave message box. I have no idea where that is happening, or how to attack it.


Quote:

Simply NOP'ing out the exceptions will not work if useful work is being done inside the exception handler. Check what exception handler is being installed before these exceptions occur (tip: look for instructions dealing with fs segment).


I'll check the fs segment thingy. Thanks.

The NOPing gets me past the bad code statement. I was thinking about the problem, and an XOR needs positive logic. You need a +1 or 0. If you give it a -1, it goes, "Hmmmm??!!". If I don't NOP it, I'd need to trace into every exception. But what you've said indicates I need to read more on exceptions.

I was reading the Intel 1 manual, and on the first pages, they define an exception as mainly a fault due to a bad instruction. What we're seeing with the SEH seems to be an improvised fault based on software. That kind of threw me, being a computer tech, because I tend to think of exceptions like interrupts, which they are. But they're controlled interrupts in that sense. Any other interrupt I know of is more decisive, whereas the SEH's are a more forgiving type.

crUsAdEr
January 21st, 2005, 17:21
Hi,

The way to avoid except all together is
faults off

it is in softice manual...


However while tracing if you happen to encounter a
xor [eax], eax
trap in asprotect, do NOT NOP it since asprotect CRC check will generate an error...
the way to skip over it is
r eip eip+2

the best way to understand how aspr seh works is do dump the asprotect.dll file, how to dump it ? well i suppose a few tutorial search wont hurt ya...

WaxfordSqueers
January 21st, 2005, 18:42
Quote:
[Originally Posted by crUsAdEr]Hi, The way to avoid except all together is faults off
it is in softice manual...


Thanks for reply. I'm fairly decent with Sice all around, but I just have to bear down and learn those grey areas. I read a lot about SEH's today, especially Jeremy Gordon's treatise. It didn't make much sense till I tackled Asprotect. Also, I just happened to read about the 'faults off' today as well.

Quote:

However while tracing if you happen to encounter a xor [eax], eax
trap in asprotect, do NOT NOP it since asprotect CRC check will generate an error...the way to skip over it is r eip eip+2


thanks for that one. That's probably the error I'm encountering near the end.
The only way i seem to be able to get in using XP is to set the flags to E0000060. I left the 6 in there because LordPE had it set already. I've been setting the flags back to C0000040 in the PE section of the memory image, but i wonder if it's too late by then.

Quote:
the best way to understand how aspr seh works is do dump the asprotect.dll file, how to dump it ? well i suppose a few tutorial search wont hurt ya...


I've read so many tutes and forum posts the past few days that my eyes are like two pee holes in the snow. My head hurts. In fact, I was reading one of your threads from 2002 in which you were talking about SEH's and a loader. I saw another from Clandestiny in which he was talking about writing a tute on SEH's, but I haven't come across it yet.

NicolasTesla seems to have a good grasp on them. It would be nice if he wrote a tute on SEH's (hint, hint).

crUsAdEr
January 21st, 2005, 19:04
Code:

3. AsProtect.dll seh tricks

Here is how a typical seh is set up in AsProtect and you will know that seh is used not less than 30 times in this dll. It used to stop newbies like me from tracing AsProtect code but not anymore once you understand what is going on. Before you read this, please read some essential information about seh (I suggest Jeremy Gordon's excellent paper on seh).

004106B2 E8 49 C6 FF FF call Clear_API_emu_code ; upper limit
004106B7 E8 25 00 00 00 call set_seh_3
004106BC
004106BC seh_3_handler: ;
004106BC 8B 44 24 0C mov eax, [esp+0Ch] ; get context to eax
004106C0 83 80 B8 00 00 00+ add dword ptr [eax+0B8h], 2 ; add context.eip by 2
004106C7 51 push ecx
004106C8 31 C9 xor ecx, ecx
004106CA 89 48 04 mov [eax+4], ecx ; clear debug register 0
004106CD 89 48 08 mov [eax+8], ecx ; clear debug register 1
004106D0 89 48 0C mov [eax+0Ch], ecx ; clear debug register 2
004106D3 89 48 10 mov [eax+10h], ecx ; clear debug register 3
004106D6 C7 40 18 55 01 00+ mov dword ptr [eax+18h], 155h ; context.dr7 := 155
004106DD 59 pop ecx
004106DE 31 C0 xor eax, eax ; exception handled, continue
004106E0 C3 retn
004106E0 set_seh_1 endp ; sp = 4
004106E1
004106E1 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
004106E1
004106E1 set_seh_3 proc near ; CODE XREF: set_seh_1+25p
004106E1 31 C0 xor eax, eax
004106E3 64 FF 30 push dword ptr fs:[eax] ; set up seh 3
004106E6 64 89 20 mov fs:[eax], esp
004106E9 31 00 xor [eax], eax ; cause seh 3
004106E9 ; this seh clear debug register
004106EB 64 8F 05 00 00 00+ pop large dword ptr fs:0 ; remove seh struc
004106F2 58 pop eax
004106F3 E8 CC 1F FF FF call @System@Randomize$qqrv ; System::Randomize(void)

The seh is set up in a slightly different way which makes it harder to detect but with IDA everything becomes very clear!

004106B7 call set_seh_3 ; this is equivalent to push handler and move eip to 4106E1 same as

; push 4106BC (our seh handler)

004106E1 xor eax, eax
004106E3 push dword ptr fs:[eax] ; set up seh 3
004106E6 mov fs:[eax], esp
004106E9 xor [eax], eax ; cause seh 3
004106E9 ; this seh clear debug register
004106EB pop large dword ptr fs:0 ; remove seh struc
004106F2 pop eax
Thus when we trace over 4106E9, the seh is triggered and our context is retrieved to eax, where eip is adjusted by increasing it by 2 to point to the next working instruction, also debug registers are cleared the same way. (this is posted by R!sc before)

This is interesting indeed! For example when you are tracing and you are at 4106B7, if you trace into with F8 you will meet the faulty instruction at 4106E9 and be lost in kernel seh code! if you trace over with F10, sice will place a break point at the next instruction which happen to be the seh handler and then you will soon meet the "ret" at 4106E0 and again you will be lost in seh kernel code! Now that we know how this whole seh scheme works, we can trace anywhere we want, simply do a "r eip eip+2" at the faulty instruction and seh handler will be skipped altogether!


Lol, dig out some old notes for you

WaxfordSqueers
January 21st, 2005, 23:01
Quote:
[Originally Posted by crUsAdEr][CODE] 3. AsProtect.dll seh tricks


Thanks Crusader. I just found your full essay, and it's pretty impressive. It's amazing how you dumped that dll and pieced it together again with a spare Delphi header you had lying around.

It will take me quite a while to digest what you're saying. I have seen some of those routines as I traced through the app. I made the mistake of not approaching it with a fresh mind. I had done a Petit unpack a while back and this app reminded me a lot of that. So, I kind of ignored all the unpacking with the intention of getting to the other side of it.

That was my downfall. I was looking for a nice clean 'test eax, eax' and a jump to paydirt. I couldn't figure out how I was ending up in SEH-ville. I did find the imports listed by you and +Splaj, and I also found a structure of large numbers that looked like they could have been keys. They were all being moved at once with individual MOV instructions, and whereas some seemed random in order, others were straight, like 01234567, or 89ABCDEF.

What happened to Damien's site? Was it anticrack.de? I was interested in what you said in your essay about his papers on anti-debugging.

WaxfordSqueers
January 29th, 2005, 19:30
Quote:
[Originally Posted by doug]First, when you reach a breakpoint, you can always set another breakpoint on the return address (bpx *esp). I don't know the details of why you can't keep on tracing (did you try F11 / G @SS:ESP when you are at the first instruction of the API?), but if you do the return address bpx, you'll be able to continue tracing after IsDebuggerPresent.


I don't know if you'll see this Doug, but I've done a fair bit more since you replied. I've tried what you suggested above but the app doesn't like the use of F11. I can sometimes use the G [address] instruction to send it over an exception, but things get tricky once I'm inside. Also, I can reach addresses using the G [address] from the code entry point. The G instruction happily jumps over the exceptions.

Basically all they are doing in some exceptions is setting up the handler and issuing one bad instruction, XOR [EAX], EAX. That send it to the system exception handler. There is obviously a point in there where the system sends it back to the app handler, and it seems that handler is wiping out any breakpoints that are set.

I've tried single-stepping through the system code and got to watch a BSOD forming. It's kind of neat when you see the INT 3 then the blue screen. Doesn't seem as formidable that way. I'd like to know how to get to the app handler while it's executing. I'm still a bit fuzzy on what I can do regarding single-stepping and setting breakpoints.

The code below is typical of the exceptions, and the XOR statement is used 31 times throughout the app. Of course, it's all SMC....note the CD 20 at 40F383 and the jmp before it. Also the data byte at 40F38A.

I recognize the PUSH at 40F385 as the beginning of the exception, but I'm still not clear as to what it does. According to Jeremy Gordon, assuming they are using a per threadhandler, "A per-thread handler is installed at run-time and is pointed to by the first dword in the Thread Information Block whose address is at FS:[0]". In the code below, EAX = 0, therefore it is FS:0, and the value being pushed should be both the TIB address and the address of the handler.

My understanding is that once the bad instruction is hit, it should flag an exception and the system should examine it and call the app handler. It seems to me, however, things get complicated due to the use of breakpoints and/or single-stepping. I can jump over the exception using G [address], but I can't using F11. F12 (P ret) used in the exception causes a BSOD. Also, if I set any breakpoint before the first exception, it gets wiped out.

40F37F 31 C0 xor eax, eax
40F381 EB 02 jmp short loc_40F385
40F381 ; ---------------------------------------
40F383 CD 20 db 0CDh, 20h
40F385 ; ---------------------------------------
40F385
40F385 loc_40F385:
40F385 64 FF 30 push dword ptr fs:[eax]
40F388 EB 01 jmp short loc_40F38B
40F388 ; ----------------------------------------
40F38A E9 db 0E9h
40F38B ; ----------------------------------------
40F38B
40F38B loc_40F38B:
40F38B 64 89 20 mov fs:[eax], esp
40F38E 31 00 xor [eax], eax
40F390 EB 01 jmp short loc_40F393

Quote:

Simply NOP'ing out the exceptions will not work if useful work is being done inside the exception handler. Check what exception handler is being installed before these exceptions occur (tip: look for instructions dealing with fs segment).


Crusader suggested r eip eip+2 which I have used since. Maneuvering through the code becomes tricky because there are 31 exceptions alone using the bad XOR instruction.

I've already unassembled the handler code in softice and I see the RtlUnwind at the end of it. But I can't see what the registers say. I'd like to reach that code as it's executing. A thought just occured to me. Maybe I'll try the G [address] on it. Hmmmm.

doug
January 30th, 2005, 12:01
You are missing an instruction that places the exception handler on the stack.
Remember that exceptions are chained. If the top exception doesn't handle the fault, there might be another exception handler that can. The instructions that you see, are building this chain.

Usually this is what you have:
Code:

push offset Handler
push fs:[0]
mov fs:[0], esp


Before single stepping over the exception, you can check what exception handler will execute first, and bpx it.
? *(fs:0)
u cs:esp->4 // don't forget that softice remembers the last segment prefix
// d cs:esp->0 would show you the next exception handler 'block'
// and u cs:esp->0->4 would list the next exception handler code.

Quote:

Crusader suggested r eip eip+2 which I have used since. Maneuvering through the code becomes tricky because there are 31 exceptions alone using the bad XOR instruction.

This will only work if:
(1) The exception handler doesnt do anything useful. Some protections use exception handlers as part of the protection (i.e: they put some decryption in there)
(2) The exception handler was going to return immediately after the instruction that caused the exception. It's not uncommon to see protections use exceptions as redirection mechanism.

What I mean here, is you should really inspect the exception handler before deciding what you do.

You might also be interested in http://www.woodmann.com/forum/showthread.php?t=5022 for both the debug register access & how windows dispatches exceptions. (hint: nice place to hook)

I'm not a big ollydbg user myself, but I think it allows you to skip these exceptions?

blabberer
January 31st, 2005, 05:28
ollydbg can skip all exceptions to the handler
all you need to do is go to debug option --> (ctrl+o) exception and check mark the
exception you want olly to skip to the original handler

also if there are custom exceptions generated like
exception DeadCafe,BeefBabe,badbabe2,ace1ace1
you can use add last exception and olly will happily skip them too

anyway if you are interested in breaking on all and sundry exceptions but dont want to set a break in the executable load the symbols for ntdll.dll
and
set a break here
CALL ntdll.RtlpExecuteHandlerForException

if you single step into this call you will see a call near ecx which invaribaly
always calls the exception handler

if you are using ollydbg you can press enter and follow there and study the handler for its actions without stepping there
if you are not interested in looking at the handler but just wish to know where the handler lies so that you will dead list the location later
you can set a conditional breakpoint which logs the ecx in these cases

Log data
Address Message
00401002 Access violation when writing to [00000000]
77F92536 COND: 77EA13FD
77F92538 Breakpoint at ntdll.77F92538

the seh chain in my case
SEH chain of main thread
Address SE handler
0012FC30 ntdll.77F8A896
0012FFE0 KERNEL32._except_handler3 (here this is what is called now by 77ea13fd)

77EA13FD KERNEL32._except_handler3 $ 55 PUSH EBP ; Structured exception handler

WaxfordSqueers
February 3rd, 2005, 01:10
Quote:
[Originally Posted by doug]You are missing an instruction that places the exception handler on the stack.


Sorry for delay in replying. I checked out what you're saying, and there are back to back routines. The first routine is set up exactly as I indicated, with no handler address. The second one does have the handler. Thanks for pointing that out.

I was getting irritated by my lack of progress so I decided to brute force it to the OEP. After a while I began to see a pattern using P ret and it became like a game in which you crash and have to restart. Anyway, I came out of this fogbank of crypted SMC and there it was. I nearly ran right past it. Essentially, I've traced from the program entry point to the OEP of the protected app, using a divide and conquer approach. I had to keep reminding myself that the app will run properly on it's own, exceptions and all, so it should be possible to trace it.

So, I've been busy dumping, pasting , making IAT's and tweaking. Besides, the trial version was running out of time and I needed to get the wrapper removed. I'll get back to the SEH's a little later. I did go back and retrace the IAT formation, but I understand from an essay by AndreaGeddon that what I thought was the IAT is just a bridge, as he calls it, and the real IAT is further along. That's a project for another day. Meanwhile, I used Revirgin for my IAT.

This should probably be a new thread, but I'm having trouble with the unwrapped app. It starts fine with symbol loader, and I can trace through the initialization code, but it crashes abruptly on a very innocent looking statement, something like MOV AL, [ESI]. ESI points to an address in the rsrc section but nothing is there. It seems to be an illegal memory access (full of ??? characters) and generates a C0000005 exception. I can jump over it and carry on, perhaps stupidly, but it is the memory access to resources that is the issue and several crashes follow that one.

I have double checked my PE header in Lord PE and manually. I find that Lord PE sometimes doesn't save when you press 'Save'. IDA seems to approve since it's created a beautiful .idata section which used to have only 5 imports. And it lists all the sections in the right place.

I have to do more research, but I thought I'd mention it just in case you've come across that. I'm not clear on the subject of relocations, for example. I was under the impression you're supposed to wipe them out after a dump. Also, some of the imports may have been switched. Alexey is a clever guy.

Quote:
Before single stepping over the exception, you can check what exception handler will execute first, and bpx it.

I tried that Doug, but it wont take. They seem to be doing something in the handler to clear off BPX and BPM. The only function I can use is the G address, but even it wont take inside the exception handler. Unless, of course, I'm feeding it the wrong address. I need to go back sometime and trace into the system handler.

Ding, Ding!! Bells go off. I changed contexts going into the system handler, didn't I, he says as he smacks himself up the side of his hard hat? Doesn't eveybody wear a hard hat while reversing?? The new version of softice doesn't like that. I recall reading of a way to turn that off.
Quote:

You might also be interested in http://www.woodmann.com/forum/showthread.php?t=5022 for both the debug register access & how windows dispatches exceptions. (hint: nice place to hook)

I checked that out earlier and tried using the accompanying exe file. It doesn't crash or anything, but I think it might have issues with Iceext. Don't quote me on that, but something froze up till I shut down Yates' app. I will investigate further, but he may have written it for an earlier version of softice.

WaxfordSqueers
February 3rd, 2005, 01:20
Quote:
[Originally Posted by blabberer]ollydbg can skip all exceptions to the handler

Sorry for delay in replying. I'm a bit of a masochist...I like tracing through places I'm not supposed to be. I was getting quite intimate with K32 till they changed it on me for XP. I appreciate that feature in Olly but I like to see how things tick.
Quote:
anyway if you are interested in breaking on all and sundry exceptions but dont want to set a break in the executable load the symbols for ntdll.dll
and set a break here CALL ntdll.RtlpExecuteHandlerForException

yeah...thanks for that tip...I'll give it a go. I'm going to trace right through it one day, system and all. I have no idea what to look for at this point with respect to flags, however. XP specializes in the BSOD if you don't treat it nice.
Quote:
if you single step into this call you will see a call near ecx which invaribaly always calls the exception handler
nice to know what to look for in advance...thanks. Thanks for the rest of your info too...I'll check it all out.