IDA Patcher is a plugin for Hex-Ray's IDA Pro disassembler designed to enhance IDA's ability to patch binary files and memory. The plugin is useful for tasks related to malware analysis, exploit development as well as bug patching. IDA Patcher blends into the standard IDA user interface through the addition of a subview and several menu items.
Folks, as this is the first public release (and my first IDA plugin), I would be infinitely grateful for any bug reports, feature requests or criticism of anything that just doesn't work right. Thanks =
Table of Contents
InstallationSimply copy idapatcher.py into IDA's plugins folder. The plugin will be automatically loaded the next time you start IDA Pro. CompatibilityThe plugin uses pure IDA Python API, so it should be compatible with all versions of IDA on different platforms. However, it was only extensively tested on IDA Pro 6.5 for Windows with x86, x86-64 and ARM binaries. User guideThis guide will walk you through various features of the plugin by examining and patching a simple program below: .text:00401000 ; int __cdecl main(int argc, char **argv).text:00401000 _main proc near .text:00401000.text:00401000 argc = dword ptr 8.text:00401000 argv = dword ptr 0Ch.text:00401000.text:00401000 push ebp.text:00401001 mov ebp, esp.text:00401003 cmp [ebp+argc], 0.text:00401007 jz short $LN6.text:00401009 push offset Format ; "Terminating...\n".text:0040100E call ds:__imp__printf.text:00401014 add esp, 4.text:00401017 push 1 ; Code.text:00401019 call ds:__imp__exit.text:0040101F ; -------------------------------------------------------------------.text:0040101F.text:0040101F $LN6: ; CODE XREF: _main+7j.text:0040101F push offset aYouHavePatched ; "patched...".text:00401024 call ds:__imp__printf.text:0040102A add esp, 4.text:0040102D xor eax, eax.text:0040102F pop ebp.text:00401030 retn.text:00401030 _main endp.text:00401030As you can see, the program will always follow the "Terminating..." branch since the conditional jump at 00401007 will never be true (argc is normally greater than 0). Let's patch the application to reverse the logic and change jz to jnz. The traditional way to do this in IDA is to open the Hex subview and change the appropriate byte corresponding to jz (0x74) to jnz(0x75) as follows: At this point it is impossible to revert the patched byte to its original form or manage all of the patched bytes in the database without developing several one off IDA scripts. IDA Patcher addresses this and many other use cases to make binary patching in IDA easy and convenient. Patches subviewIn order to quickly navigate and manage all of the applied patches, the plugin includes a new subview simply called Patches. To open the subview select View->Open subviews->Patches. It is the very last item after the Problems subview. NOTE: You may need to select Refresh from the Edit submenu or press Ctrl-U to see the latest changes. In the view above you can see the patch we have just made to the database together with the exact address, name of the function and segment, size, modified and original bytes as well as any comments at that location. TIP: To quickly jump to the location of the patch in the IDA subview simply double-click on one of the entries in the Patches subview. Fill selectionLet's make another modification to the database by filling a range of addresses with NOPs. To do this select a range of instructions or hex bytes from IDA or Hex subviews respectively. Next, open the Fill selection dialog from Edit->Patch program and populate the value field with 0x90: The start and end addresses of the selection are automatically populated; however, you can adjust them from the dialog. Press the Fill button to apply changes in the database and switch back to thePatches subview: Notice that single byte patches were combined into larger consecutive buffers to make it easier to manage. The reason why there are two separate entries with NOPs instead of a single large one is due to the presence of the 0x90 byte somewhere in the original binary blob. As a result, IDA Patcher produced two separate entries since one byte in the middle was not actually updated. Here is the source of the issue: .text:00401009 68 00 21 40 00 push offset Format .text:0040100E FF 15 90 20 40 00 call ds:__imp__printf.text:00401014 83 C4 04 add esp, 4.text:00401017 6A 01 push 1 ; Code.text:00401019 FF 15 8C 20 40 00 call ds:__imp__exitFilling a range of bytes with the same value is useful when you need to quickly NOP-out a series of instructions or simply fill a memory area with a known value in the debugger (e.g. 0xCC to break execution when landing in that memory area). Restore original byte(s)At this point you may decide to restore original byte values since it wasn't really necessary to overwrite that many bytes. To accomplish this select one or more entries from the Patches subview and click onRestore original byte(s)... menu entry by right clicking anywhere within the subview: For each of the items in the selection, you will get a popup similar to the one below confirming the change: NOTE: You will not be able to edit bytes when restoring them. If you want to edit patched bytes, use one of the methods described below Press Restore to apply changes to the database. Edit patch byte(s)There are several ways to edit bytes in IDA Patcher depending on whether you are editing an existing patch or applying a new one. The edit dialog to alter already patched bytes can be triggered by selecting Edit from the right-click context menu in the Patches subview: Notice the variety of valid hex input representations that can be mixed together. You can safely input fewer or greater number of bytes than the original patch buffer. In the case of fewer bytes, the original bytes at the end will be restored. Inputting more than the original length will simply continue overwriting the database as expected. You can also bring up a similar edit dialog by selecting a range of addresses from IDA or Hex views and clicking on the Edit->Patch Program->Edit Selection... menu item. All of the bytes in the selected range will be already populated in the dialog edit box; however, you are free to edit more or less than the selected buffer just like in the previous example. While similar to the previous method, this dialog allows you to create new patches instead of editing existing ones. Import dataA powerful way of importing binary blobs into the database involves the use of Import data dialog. It can be opened from the Edit menu while IDA or Hex subviews are active. By selecting a range of memory addresses (or at least a starting point), you can paste large blobs of binary data from external files or pasted as hex bytes or string literals. The example below illustrates how to quickly inject shellcode into the stack memory area to aid in exploit development: You can switch between different import types to change where the data is coming from and how to interpret it. For example, string literal type will interpret pasted buffer as raw bytes without trying to decode it as a hex values. The trim to selection checkbox will ensure that imported data does not exceed specified address ranges by trimming whatever extra bytes at the end. Applying PatchesWith all of the modifications done to the IDA database you may want to apply them to the original input file. You have two identical ways of accomplishing this: using IDA's own Edit->Apply patches to input file... or the plugin's replica dialog which can be called from the right-click menu in the Patchessubview: It is important to note that not all binary modifications in the database can be applied to the input file. For example, modifications done in the debugger example above can't be applied to the input file because stack memory area is dynamically generated and not linked to any particular segment in the original file. The screenshot above illustrates different icons associated with each patch entry: a little save disk icon for the patches that can be applied and a little red cross for the ones that can't be applied. Just like in the original Apply patches to input file dialog, you have an option to create a backup file or simply restore the previously patched file to its original form. Once you click OK, all of the patches which can be applied will be stored in the specified input file. Known bugs- 64-bit version of IDA Pro 6.5 for Windows does not correctly report selected address ranges (most significant 4 bytes appear to be zeroed out).
Special NoteThank you Ilfak Guilfanov and Hex-Rays development team for the excellent product and quick support. The plugin would not be possible if not for Chris Eagle's excellent IDA Pro book from which I have learned about the world of IDA and reverse engineering, thank you sir! References
http://thesprawl.org/projects/ida-patcher/
|