Patch an EXE
April 7, 2007 11:44 PM   Subscribe

How can I patch an EXE not to call a certain function ? I have an EXE which displays a certain message as a result of certain function call. I need to find out which function it is calling and then patch it so as not to call it. Is it possible ?
posted by inquisitive to Computers & Internet (21 answers total) 7 users marked this as a favorite
Response by poster: Can somebody guide me step by step how to do this, which tools to use and how ?

I need a step by step guide, if somebody can please handhold me for this.
posted by inquisitive at 11:46 PM on April 7, 2007

There are several types of EXE files. You're talking about Windows EXE most likely? A DOS EXE is the easiest type to patch, but presumably you are not still using a DOS application.

Anyway, people have patched and do patch EXE files, so it is certainly possible, but it is not for the fainthearted or ill-trained. At a minimum you should know enough 80x86 assembly language to understand the binary code you are attempting to patch. Do you know any assembly language? If not, patching EXE binary code is probably not a process you should attempt, even for a small patch like this (although as a special case, disabling the function itself might not require knowledge of assembly language as a single byte change might suffice).

Further to the parenthetical, patches to not call an internal function instead often involve patching the called function not to do anything. This approach is frequently easier than attempting to locate and modify all the control paths to the function you want to inhibit. Obviously whether this is a better approach depends on the program, the function, and other variables.

So buried in the above are questions asking for your follow-up input: the EXE type, your level of programming knowledge, whether the function is internal to the EXE (if known), and whether the offending function needs to ever execute normally after patching.
posted by mdevore at 12:06 AM on April 8, 2007

Search the EXE and find the message, then change the first letter of the message to a zero (as in 00 hex, not the digit '0'), thus making it an empty string. The message will still technically print, but it will consist of nothing.

You're a bit light on details, so it's hard to know whether this will work, (i.e., if the message is appearing in a dialog box, you'll still get the dialog box with the string in it. And, if you want the message to appear in some cases but not others, this might not work.)

I'm actually curious what you are using this for, if you don't mind elaborating.
posted by blenderfish at 12:19 AM on April 8, 2007

Unpack the exe of course. If it is a function that does not return something the program will use, you can try just replacing the name in the bss section with a another function that is harmless.

But if it is to return a ptr, or structure to use, it is harder.
posted by lundman at 12:21 AM on April 8, 2007

Cracking code - Part 1. He has several more in the series on his weblog.

I really hope you're not trying to circumvent license protection or a nagware screen, because that would be a pretty fucked up thing to do.
posted by cmonkey at 12:44 AM on April 8, 2007

cmonkey: What else would s/he be doing? That was the very first thing I thought when I read the question.
posted by pjern at 5:32 AM on April 8, 2007

If you are trying to circumvent or crack a program, then some nefarious parties would suggest you go search for an existing crack. There are lots of really smart people who do this sort of thing for a hobby and there are a couple of nice sites that provide searches for these sorts of things (not that I've ever visited any, but someone on the bus mentioned one called 'astalavista' once I think).
posted by wackybrit at 6:49 AM on April 8, 2007

Grab yourself a disassembler. Preferably a smart one, with interactive debugging systems. I like IDA Pro.

Then, find the function that's being called, and patch it with a return immediately upon invocation. Of course, you need to handle the stack frame properly. This is assuming that the function doesn't return anything. If it does, you need to do something more than render null the function.
posted by Netzapper at 7:14 AM on April 8, 2007

Also, if you find where the function is called from and its a fairly simple call (i.e., there aren't a ton of paths its called from, & the compiler hasn't inlined/optimized it to hell), you can just replace all the instructions to call the function with no-ops. If its inlined (which it may be if its a simple function), just jump over all of it. Basicially you have to do some digging first, to even begin to know what to do.
posted by devilsbrigade at 2:08 PM on April 8, 2007

Oh, and if you don't want to shell out money for a debugger, OllyDBG is surprisingly well made.
posted by devilsbrigade at 2:09 PM on April 8, 2007

Response by poster: I liked mdevore's suggestion of "patching the called function not to do anything"

The EXE is a Windows EXE. My OS is Windows 2000 SP4.(if that makes a difference)

I used to know Assembly language 6-7 years ago, but now I have forgotten. But I can recapture the essential Assembly langauge instructions.

Anyway, I want to attempt patching this EXE, even if I fail, I wont lose anything. Coz I will first make a backup of the EXE.

I dont know whether the function is internal to the EXE or located in some DLL.

I think the function returns some value, based on which the message is displayed.

I want to change the value the function returns, so that the caller function takes the other path instead of displaying the message.

First thing is: how do I find the function as a result of which the message is getting displayed ?

I have OllyDBG and EXEScope and Spy++.

But please guide me step by step how to do this, especially how to find the function which I want to patch ?

Many thanks for your help.
posted by inquisitive at 3:23 AM on April 9, 2007

Does the function have a distinct purpose? If so, you might check the public names of symbolics and external references inside the EXE file list and see if there are any candidates. This could greatly speed up locating the function you want since you can quickly look up the corresponding code location or DLL that goes with it.

If you don't have any clues about the function name orn whether it is publicly declared (it may well not be), then you can fall back on tried-and-true, if more tedious, methods. I'll give you one basic approach that will work to locate a lot of patchable code, though it won't work in all situations.

Run the EXE under the debugger and step through each line, not tracing into the individual calls/functions. Eventually the function you want to patch will pop up to display its message during the single-stepping. At that point, you know which untraced call triggered the function -- assuming the function is in linear code and is not based on time, keystroke, or another callback-style event.

Restart the debugger, breakpointing on that last untraced call. Execute the program and when the breakpoint triggers, trace into that call. Single-step through the called code as before, not tracing into other call/functions, until the message function pops up again. Again restart the debugger, breakpointing on that line containing the untraced call. As before, trace into it. then normally step through the code. Continue in this fashion until you location the line of code which calls the function you're interested in. This is a divide-and-conquer approach where you incrementally nest down call levels closer and closer to the exact call which makes the message function execute. Once you have located that, you are in good shape because you can then determine whether you need to patch the function call, or whether you can patch the function itself (internally or externally in another file).

Assuming you want to patch pure binary code, look at the surrounding binary code values which aren't subject to address or loader fixups. Try to find a close-by pattern which isn't often repeated. For example, avoid an opcode pattern which loads the EAX register with a 0 or 1, since that instruction will likely be in the program extremely often. Locate the same pattern in the EXE file, ensuring it is the right spot by additional byte checks. Modify the bytes in the EXE to match the desired patched instruction using a binary file editor. For example, if you are eliminating the call to the function, change the call opcodes in the file to a series of one-byte NOP opcodes.

Obviously I've glossed over the process a huge amount to fit this answer into a reasonable length. There are a lot of side issues that can come up, and there are other approaches which can be used along with or instead of this method. This method is just one of the simplest to describe which has a decent chance of success.

Incidentally, if you would tell us exactly what software you are trying to patch and how it is currently not working for you, that could be a big help in giving advice. If it is a crack of commercial software, you do stand an excellent chance of losing any further support here -- as well you should -- but if not, then we are in a much better position to give details on how to do what you want to do. It also might clear up the raging MetaTalk topic posted elsewhere concerning your question, although probably not given how far-ranging and silly it has become. But it would be nice to know if you are innocently patching a misbehaving program or trying hack past a nag screen. Nice to know, even if your answer doesn't change anyone else's idea of what is appropriate to initially (perhaps wildly) assume about file-patching questions posted here.
posted by mdevore at 12:38 AM on April 10, 2007 [1 favorite]

Response by poster: Well, I am doing this for one of my clients who got a software developed from somebody who is no longer available. My client does not have source code of the software.

There was some business logic which was valid earlier, but not valid now. As a result, the software which is validating as per the old business logic is displaying a dialog box.

From that dialog box, I want to backtrace and disable call to that business logic function, or change the business logic function to return a true value.
posted by inquisitive at 11:16 AM on April 10, 2007

Response by poster: Now I am able to load this software in OllyDbg, but when I do Animate Over, or even when I Run it under the debugger, I get this:

E0002 -- Error loading program.

And the debugged program terminates.

What could be the reason ?

I am howver able to run this software independently, and then attach the debugger to the already running software. But this way, I am not able to Step through the code, when I select a particular menu option from the software.
posted by inquisitive at 11:20 AM on April 10, 2007

Response by poster: BTW, where is the "raging MetaTalk topic posted elsewhere concerning your question" ??
posted by inquisitive at 11:21 AM on April 10, 2007

MeTa. Incidentally, this is a great thread, my concern about the links to cracking resources notwithstanding. (I wasn't disputing that your question was on-the-level, or at least phrased in a sufficiently neutral way.) I enjoy watching people talk shop at the low level, even though my assembler skills are long-since-rusted.
posted by spiderwire at 11:47 AM on April 10, 2007

E0002 -- Error loading program

Uh-oh, that's not good. First check that you are calling the EXE through the debugger the same way as you are calling it normally. Do you directly call the EXE or is it through another program? Do you have any parameters passed the program that you need to pass when using the debugger call? Debugger invocation should exactly match normal program invocation.

Also try using a few different debuggers, just to run the program under without testing anything else. You can use any debugger you find which runs under Windows since you're only trying to establish whether the program can run under a debugger environment at all. You can come back to a favorite debugger later if things work. Try this because the software vendor may have anti-debugger traps in the program. Does this software have versioning or copy protection built-in? If so, patching an protected EXE is probably too advanced a topic to address here in two or three paragraphs.

An alternate method to find out what you want is to run the program under a virtual environment such as QEMU or Bochs which have debugging capability built into the emulator. It's more difficult (but not impossible) for a program to detect whether it's running under emulation or virtualized. Emulation can therefore be easier for debugging processes when a program puts barriers in the way of a native host debugger. Be aware that there will be a learning curve associated with using those programs.

The MetaTalk thread I mentioned is here. As fair warning, it was started by an individual who was just sure you wanted information to illegally crack commercial software protection. That interpretation was quickly countered by a crazy old coot who held you hadn't implicated yourself in anything bad, and from there the topic quickly went off in various and sundry directions, including sarcastic analogies, one's right to crack software, one's lack of a right to crack software but right to bypass nag screens, educational benefits of [h|cr]acking, the legal liabilities of posting links to cracking instructions, plus miscellaneous scatalogical references hurled by members at the opposition. In other words, pretty typical MetaTalk fare.
posted by mdevore at 3:58 PM on April 10, 2007

Response by poster: The EXE does not take any parameters on startup.
Debugger invocation is exactly the same as normal program invocation.

Instead of running it under different debugger or under virtual enironment, can you tell me how to proceed after I start the EXE independently and then attach the OllyDbg debugger to the running EXE.

After I attach, how do I step through the code when I select a particular menu option from the EXE or I click a button ?

In fact, even when the EXE is waiting for some user action like menu selection or some input, if I try to Animate into the code from the debugger, it steps into the code which befuddles me, coz how can the debugger step through the code when the EXE is actually waiting for some user action !!
posted by inquisitive at 9:44 PM on April 10, 2007

You may be more invested in the idea of using OllyDbf than is best for your situation. Ultimately your aim is to patch the EXE. Attaching a debugger after the program runs is less helpful than invoking it at startup because an application memory image may no longer be in the same state as an startup executable; things may have moved around or been changed to the point that they can no longer be easily matched up with the EXE file image. There is also the task of orienting yourself within the already executing program. In addition, the fact that the program does not work from command line under OllyDbg could indicate anti-debugger efforts in the application which may foil patching attempts. All results are data to be interpreted.

There is little reason to be loyal to one debugger for initial testing. You need not abandon OllyDbg, but put it aside briefly while you test other debuggers to see if they work better for you. OllyDbg may have the most powerful and best feature set, but frankly, for a small patch like this, you do not need the best debugger available. There are probably dozens of debuggers for Windows, and most of them are up to the task of examining data, disassembling code, and stepping over or tracing into calls. I suggest trying one or two other debuggers that sound promising and easy to use. Your time is too valuable to spend fighting a debugger during the preliminary patch efforts.

If you are committed to OllyDbg, I have never seriously used it and unfortunately cannot offer much help with debugger-specific problems. Hopefully someone else who has experience with it is still reading and can offer help. Perhaps your debugger problem has a simple solution and you can quickly continue. Otherwise, consider my advice about trying other debuggers. You may uncover useful information that you can carry back to OllyDbg for full testing.

I offer one other bit of advice that may be relevant. If you find that you can only modify the program after it begins execution, another technique which may resolve your situation is dynamic patching. One form of dynamic patching is to run a small program which loads the main application, applies any patches needed, and then terminates, leaving the patched application running normally. This technique avoids having to mess about with patching application disk files when they are encrypted, copy-protected, or otherwise resistent to modification. On the downside, it can be more difficult to set up than a static patch of a disk file. I've not done dynamic patching for many years and am not a good information resource on that particular topic.
posted by mdevore at 4:56 AM on April 11, 2007

Response by poster: OK. I will try out some other debugger. You yourself suggest which one I should try out; preferably the one you are familiar with.

I have tried W32DASM ver 8.7. But as soon as I load the EXE, the W32DASM crashes with this error:

URSoft W32Dasm Program Disassembler/Debugger (Demo Version 8.7): W32dsm87.exe - Application Error
The instruction at "0x77e334d6" referenced memory at "0x00000078". The memory could not be "read".

Click on OK to terminate the program
Click on CANCEL to debug the program
OK Cancel

So please suggest some other debugger.
posted by inquisitive at 9:53 AM on April 11, 2007

Any good file downloads aggregation site should have a several debuggers to choose from. I don't have a free debugger preference myself. When I did a lot of native debugging, I typically used Microsoft's Visual Studio debugging. Check around Microsoft's site to see what they have available for download, a lot of their tools can be had for free nowadays. Later, I used QEMU (with GDB) or Bochs, but you've indicated you'd prefer not to mess about with emulators.

As a sample of what I know about or have used at some point: You could try a Windows-compatible version of GDB. It's certainly powerful enough, though not exactly the most user-friendly debugger out there. The Open Watcom open source project has a nice debugger in WD, I used it quite a bit in the past. Or try the free evaluation version of
IDA Pro. It should work well enough within the test drive restrictions. Oh, and the PEBrowse Windows debugger looks interesting too.

If you have problems running the program with more than one of the above, you're almost certainly looking at an application or environment issue rather than a debugger fault.
posted by mdevore at 2:47 PM on April 11, 2007

« Older Non random randomness.   |   The goggles..., they do nothing... Newer »
This thread is closed to new comments.