This article contains personal observations related to how EXECryptor manages to catch breakpoints, if set in OllyDbg (the most common debugger out there).
Was playing today with my favorite program ever - Uninstall Tool - attempting to get to the spot where, if patched, file CRC would be bypassed. Everyone (well, reversers) knows that in this protector's case, a quick breakpoint on _lopen API, combined with a little tracing, would lead you to a memory spot where a comparison is made. If open file's handle is valid, EC starts to check for modifications. How, it compares active memory with raw code from file. But what if handle is invalid? If that happens, we bypassed CRC checking of file.
To show an example, this is the spot where patching Uninstall Tool (latest, 2.3.1) can be achieved.

If you look at 552C79, you will notice that [EBP-1C] holds the file's handle and it's compared to -1 (invalid handle).
Simply changing that code to:
CMP EAX,EAX
NOP
NOP
You will notice that EC will not whine if file CRC has been changed.
---
Back to our discussion, was trying to get to that location, by simple bp _lopen. Well, to my surprise, author enabled API-checks. And this is especially performed on all critical APIs that may be used to exploit the target. If, say, by any chance, you break on an API, and EC crashes, then you know for sure that API is used for something trivial. All that remains is for you to dig deeper and see what's it used for ;)
Moving on, I wanted to know how the fucker catches me. Normal F2 breakpoints (0xCC) and hardware breakpoints (on execute) didn't lead me anywhere. EC crashed leaving me pissed. But then I started thinking - what if I use memory breakpoints to see what accesses this API? And so I did..
That is _lopen API on XP SP2:

a. Olly > Ctrl+G > _lopen > Enter.
b. Right-click, Breakpoint > Memory, on access.
c. Then Shift+F9.
I got this:


Now, based on the two pictures above, especially the 2nd one, EC reads the APIs, copies the first DWORD it finds there, and performs SHR operations on bytes, to check if there's any 0xCC or 0xCD2E (INT 2E breakpoint). So, let's catch the fucker :) I restarted application, went to those two addresses: 591B1A and 5A2E80, and set two conditional breakpoints:
Shift+F2 > eax == 7C85EA30 (that's our condition, break if _lopen API is read)
Set a regular break on _lopen (F2) and then I ran the target. Surprise..

So, one way to defeat the son of a gun is to either patch that CMP or the JNZ you see below it. If we are to trace the code further, by following that JMP at 5A2E8E, we'll find this:

INT 2E, anyone? =))
Anyway, this is how I chose to patch it (see below). Since that JNZ is always taken, when EAX != 0x66, let's force it to always jump there, by changing the CMP ;)

So, there you have it folks, a way to defeat the freaking breakpoint checks EXECryptor comes bundled with. Good luck and happy trails :)
February 14th, 2008 at 9:51 pm
[...] I check the patches I've made, disable some breakpoint-checks in EC (discussed in another article here) and before you know it I find [...]