PDA

View Full Version : Patch works in memory but not in executable file!


yyzyyz
June 20th, 2008, 16:20
Greetings!

I’m trying to reverse engineer a program to remove a nag window… So I load it up in OllyDbg and after spending half a day, finally zero in on the JNZ instruction where the decision to show the nag window is made. I change the byte from ‘75’ to ‘74’ and hit F9. Presto! The program window shows up with no nags! I note down the surrounding bytes and load up the executable binary in hex editor, locate these bytes, change ‘75’ to ‘74’ and run the patched executable. However, all I see is a message that the the file may be corrupt! Can someone please explain this? The same patch works from within OllyDbg but not when applied to the executable file…

It appears that the program is checking the its executable file for potential modifications. Any ideas how to defeat this? Of course, I could repeat the procedure to locate where this switch is made, but I am looking for something easier than this…

Other details…
I’m positive that I patched the executable in the right location as there was only one instance found.
OllyDbg reports “Module ‘XXX’ has entry point outside the code (as specified in the PE header). Maybe this file is self-extracting or self-modifying”

Thanks!

Nacho_dj
June 20th, 2008, 17:11
Quote:
[Originally Posted by yyzyyz;75306]
It appears that the program is checking the its executable file for potential modifications.

I think so. Some kind of CRC checking.

Quote:
[Originally Posted by yyzyyz;75306]
Any ideas how to defeat this?

Well, a way could be searching for the condition that enables displaying the messagebox telling you "your file is corrupt".

Best regards

Nacho_dj

naides
June 20th, 2008, 17:27
Hi yy.
Several things may be at work in here:
Quote:
OllyDbg reports “Module ‘XXX’ has entry point outside the code (as specified in the PE header). Maybe this file is self-extracting or self-modifying”

If that is true, and is very likely to be true, the program is packed and/or crypted, which makes simple patching of the program in disk unlikely to work. Take a very good look at the bytes you see in disk and in memory and make triple sure that you are not patching a decoy. Better yet, download one or several of the packer identification and protection identification utilities from the CRCETL, for instance PEID, run you executable through them and figure out if and how your program is packed/encrypted.

Also, it is not unusual for programs to check the integrity of their code early in the program execution, in order to detect patching. Finding how and when it is done is not necessarily a simple exercise. The program may open its executable image from disk, obtain a CRC or an MD5 check of the file or a segment of the file, compare it to a stored value; if different, someone messed with the code and the alarms go off. How is it done? Sometimes a .dll does it when it gets loaded, some times there is code hidden in aThread Local storage callback and other tricks of that nature.

Your challenge would be to unpack the program, if packed, and/or implement a loader that patches the program in memory before the program normal execution (just as you do with Olly manually).
Both approaches have been widely discussed in tutorials and in this board
Good luck.

dELTA
June 20th, 2008, 18:51
How many bytes around the patch point did you search for? Try using 10-20 bytes and see if you still get a match, to make sure it wasn't just a false positive match...

TBone
June 24th, 2008, 15:49
If it is some kind of integrity check, here's another approach that you might use:

Load up the original program in one instance of OllyDbg and the modified version in another. Use trace over (Ctrl+F12) in both sessions. Compare the trace log to see where the execution diverges. The last common instruction will probably be a call from which the modified version never returns (because ExitProcess is called from somewhere within). Set a breakpoint on this call in both instances and then restart them. Run both of them to the break point, step into it, then start your trace over at this level.

Keep drilling deeper like this until you find where the check is made. Sooner or later you should find some conditional jump that branches differently in the modified version. Alternately, you might find something like "CALL EAX" where EAX is a different value in the modified version than in the unmodified verson. Either way, you are probably close to the integrity check. Step through the code just before this (or review the run trace if you have it) and see if you can figure it out.

Arcane
June 24th, 2008, 23:58
even easier...at OEP place a Hardware Breakpoint on Access BYTE on the jmp ..and run ...once it then tries to CRC and READS the byte...you should catch it

yyzyyz
June 25th, 2008, 12:41
Hi all

Thanks a lot for all the ideas... I really appreciate the enthusiasm in this forum.

Here are some updates:

I had already made sure (even before my first post) that I'm patching the right location by loading the patched executable in ollydbg and verifying the address.

Next step was to find out the exact place where checksum is verifed - which I did and patched again, only to run into a different error. It looks like there are multiple integrity checks and catching the subsequent ones was getting increasingly challenging.

So I tried patching the memory, which was easy enough, with so many tools available specifically for this purpose and worked out pretty well. It makes me wonder though: why would the developers not go that extra mile and do an integrity check on process memory too? Is it something that's not feasible technically?

Well, this was my first attempt at RCE based on a tutorial that I read some 10 years ago (in 1998!) and that too on one very well protected program. I'm pretty satisfied with what I have achieved (at least, for the time being) thanks to all the help I got from this forum! I'll try out some of the other suggestions offered here and hopefully be able to patch it completely in disk file.

Cheers!
YYZ

dELTA
June 26th, 2008, 06:51
The reason that many protections only check the executable file on disk, and not the code in memory, is most likely that the in-memory check requires much more low-level knowledge, which most developers don't have. It is also "harder" or "more tedious" to implement in general.

Oh, and about the execution path comparison method, there's a very good Olly plugin for that:

http://www.woodmann.com/collaborative/tools/index.php/Conditional_Branch_Logger