This article comprises subsequent contents:
Binary Sample Patching Configuration in IDA Pro Binary Analysis Binary Cracking & Patching with IDA Pro Script Patching Substitute Final Note
IDA Pro appears to have managed mystical potentials in the reverse engineer’s mind by having the impression that merely opening a binary with IDA will reveal all the secrets of a target file. IDA Pro is intended to assist you in considering the behavior of a binary by offering us disassembled code. IDA Pro is in fact not designed to modify or patch the binary code to suit your needs like other tools such as OllyDbg and CFF Explorer. It is really only a static-analysis disassembler tool. It can only facilitate your attempts to locate software vulnerabilities, bugs and loopholes which are typically utilized by both white hat and black hat professionals. Ultimately, it is up to your skills and how you apply them as to whether IDA makes your search for vulnerabilities easier.
Essential
This tutorial requires thorough knowledge of Assembly Programming and Hex Code manipulation because patching binary with IDA Pro especially deals with assembly opcode instructions. Besides that, the reverse engineer is supposed to operate the IDA Pro Software IDE features perfectly. This operation lists the following tools of the trade:
The Target Binary (C /C++ code) IDA Pro Interactive Dissembler IDA-Script File (*.idc files) Assembly Language skills ASCII Converter
Binary Sample
This article exposes the demonstration of byte patching over a typical C++ binary which essentially required a user password to validate his identity and let him log into the system, and such confidential information is only provided to the registered person indeed. There is of course no direct method to breach into this application without being authenticated, except to reverse engineer or patch the critical bytes which are responsible for performing validation. The following code will make the binary executable live as binaryCrack.exe: [c] #include “stdafx.h” #include #include #include #include #define password “ajay” int _tmain(int argc, _TCHAR* argv[]) { char pwd[100]; printf(“Please enter the password::nn”); scanf(“%s”, pwd); if ( strcmp(pwd, password) == 0 ) { printf(“Congratulation!!nn”); printf(“Ready to login with: %s”,password); } else { printf(“Wrong password”); } getch(); return 0; } [/c] We can use any compiler to execute the aforementioned binary source code which makes an executable as binaryCrack.exe, and when we run that file, it will prompt to enter the password. If we enter the correct password as “ajay” then it shows the congratulations message, otherwise it will issue the wrong password message as following.
It is probable that we might not have the real password and in such circumstances we can’t proceed without this information. So the only option left is Reverse Engineering this binary and manipulating the sensitive bytes to suit our needs as we shall see in the next sections.
Patching configuration in IDA Pro
The patching or editing assembly code features are normally invisible in the IDA Pro. You can double check from the Edit menu that no Patch program options appeared. Thus, in order make this option visible, open the idagui.cfg configuration file of IDA Pro which is located at Drive: Program FilesIDA PRO Advanced Editioncfg folder and scroll down to find the DISPLAY_PATCH_SUBMENU option which is typically set to NO. So, do the following changes and save this file.
After saving this file, re-launch the IDA PRO and the moment you change the submenu option in the configuration file, you can notice that Patch program option becomes visible in the Edit menu.
Now, load the target binary into IDA Pro. It will ask to create a new database as usual, then we select the PE file option as shown in the following figure. An important point to remember: don’t forget to uncheck the Make imports segment option, because some useful data can be lost from the database if this option is enabled.
The target file will be loaded into the IDA Pro, but we could still not modify the byte sequence of the binary file even if enabling the Patch program option in the Edit menu earlier. So here, the role of special IDA script files comes into light as they are able to modify the byte like OllyDbg as well as write the changes into the executable to make the effect permanent. The IDC script files can be downloaded from this URL as http://www.openrce.org/downloads/details/57/PE_Scripts. When downloaded, extract the files in a separate folder on the file system of your machine. A few script files are provided, but mainly two script files are significant:
After loading the target binary into the IDA Pro, open the folder where the aforesaid IDA script files are located and execute the pe_sections.idc file in order to extend new functionality into IDA Pro such as binary patching and writing. You can ensure the new specification from the Segments (shift + F7) windows that certain new segments are automatically added.
After successfully completion of such aforesaid operations, we can modify as well as write the byte sequence into binary file.
Binary analysis
We have only the binary executable and it is almost impossible to know about the logic implementation without the source code. But we can disassemble the source code of any binary by employing IDA Pro, because unless we are aware of logic flow, how can we subvert any security mechanism? Hence, let’s analyze the proper logic flow path of the binary file. As we can consider the following image, IDA Pro disassembles the binary into raw assembly instruction sets. This program first prompts the user to enter the password by displaying a string message, then compares this value to a predefined value “ajay” which might be the real password. The comparison happens via string class strcmp method, and if the value is 0 then the entered value is correct; otherwise it is incorrect.
If the value of eax register is 1 then the execution is shifted towards the loc_411444 block by jnz statement, where the “wrong password” message would be echoed in the screen as follows:
And if the value of eax is 0 then jump won’t throw the execution anywhere. The program informs us that we have entered the correct password:
We can easily anticipate that the Jump instruction determines either the password is correct or incorrect. If the eax register has value 1 then execution is diverted towards the “wrong password” box flow, otherwise the “congratulations” message would be displayed. As we are implying from execution flow, everything depends on jnz instruction. So, a reverse engineer would surely be interested in this instruction because manipulation of this instruction can produce different results.
Binary cracking and patching
As we have concluded from the analysis, the outcome of this binary application is regulated by the jnz short 1oc_411444 statements. The 1oc_411444 instruction belongs to the unmatched password display block, and execution is directly jumped to this block, as you can notice by the RED arrow.
However, all we have to do is to change the corresponding jnz statement related bytes. So right click on the current location of this statement and synchronize it with Hex Editor View in order to examine this statement byte sequence:
The hex view offers a 16 bytes sequence in one line and each two bytes represent only one assembly instruction set such that the hex value 75 35 belongs to .text: 0041140D address location where assembly code jnz short 10c_411444 is implemented as following.
So we have to identify the correct bytes to the specific instructions so that we can modify them to suit our needs. The following figure showcasing the hex code refers to which instruction.
Finally, we have concluded that hex code 35 is the key value that directing the execution flow of the program. However, select the address location 0041140D into text view and go to Edit menu, choose Patch program and select Patch Bytes over there. It will show the entire 16 hex bytes sequence alike to hex view:
In order to diffuse the effect of the jnz statement where the execution is shifting towards the 1oc_411444 block, we have to change its corresponding hex value 35 to 00 which typically fills a nothing action in the memory.
The moment you change the 1oc_411444 instruction code to 00, it will also reflect in the assembly:
You can also notice the modification in the hex view:
One of the important changes to notice is that after making the value 00, no jump arrow is showing, which was pointing the execution divert to 1oc_411444 earlier.
Now open the graph view and notice that the “congratulations” block is merged into the main code rather than being separated as before editing the hex value. The BLUE arrow finally goes to end of statement block and the “wrong password” block is isolated or disconnected from the main operation. So even if we enter wrong password value , always the correct password block would be executed because jnz statement code is diffused to 00 and the 1oc_411444 block is disconnected:
Okay, we have done the byte editing, so it’s time save the effect permanently into memory, but IDA Pro is not capable of writing bytes of the binary file into memory; instead it can write altered bytes into a database. So for this purpose, IDA special script file are used here. Go to File and select Script file and choose pe_write.idc which makes the perpetual effects in the memory:
The moment you run the pe_write.idc file, you will notice that bytes have been written to segments successfully, and lastly, IDA will prompt to re-save the binary file:
Save the modified binary with the same name as binaryCrack.exe:
Now, load the binaryCrack.exe and it will prompt to enter the password, merely enter any value and BINGO!!!!!!! Congratulations message along with original password appearing. We have successfully bypassed or subverted the password mechanism by patching some related critical bytes using IDA Pro.
Patching string bytes
As we can observe in the binaryCrack.exe, couples of strings messages are showing. We can access all these strings into place via String window (shift + F12) and can directly reach to its assembly code merely by clicking the string.
It is not a good programming practice to show the sensitive strings likes serial keys or passwords directly. Such information should be hidden because after patching (reverse engineering) the password’s assembly code, the hacker can easily aware that the password is “ajay” as it is showing after the “congratulations” message. So we can hide or rename the password on the screen by patching its corresponding bytes. So, double click over the “ajay” in the String windows, and IDA will let us reach its assembly code where we can modify its visibility:
Thereafter open the Hex view and we can observe the “ajay” byte code sequence as 61 6A 61 79 00 as following:
Again open the Patch Bytes from the Patch program in the Edit menu and replace all these bytes with 00 as following:
Now once again, run the pe_write.idc to make changes perpetual in the binary file and the binaryCrack.exe. Enter any value as the password and observe that this time the real password is not showing:
Removing segments
A question comes into mind: why should we display the string message after the “Congratulations” message when we subverted the password mechanism? We cannot execute a particular assembly code by using IDA Pro. Here, we can easily figure out that the code instruction after address location 00411411 is senseless to be displayed as:
This time we are not patching the bytes, instead we are integrating new assembly code so that any string message won’t display after the “Congratulations” message. Hence, go to Patch program and choose Assemble as following:
Now place nop assembly instruction which stands for no operation and it decides that none of the code would be executed as following:
After this, you can notice that nop is placed after 0041132 locations:
Now, run pe_write.idc again and notice that none of code is executing after the message:
Script patching substitute
It is not necessary that we only patch bytes by using the IDA Script file which exports the current IDA’s database into the EXE binary executable. Rather, we can opt for another approach. First make changes in the byte or hex code just by editing them and produce a new DIF file as test.dif. Now open the test.dif file and it shows the original hex code and patched code:
Later compile the following C program by using any editor (I suggest use GCC in the linux platform). [c] #include int main(int argc, char **argv) { char line[256]; FILE *patch = stdin; FILE *input = NULL; unsigned int offset; int orig; int newval; int i; for (i = 1; i < argc; i += 2) { if (!strcmp(argv[i], “-p”)) { if ((i + 1) < argc) { FILE f = fopen(argv[i+1], “r”); if (f) { patch = f; } else { fprintf(stderr, “Failed to open patch file %sn”, argv[i+1]); exit(0); } } } else if (!strcmp(argv[i], “-i”)) { if ((i + 1) < argc) { fprintf(stderr, “Opening %sn”, argv[i+1]); input = fopen(argv[i+1], “rb+”); if (input == NULL) { fprintf(stderr, “Failed to open input file %sn”, argv[i+1]); exit(0); } } } else { fprintf(stderr, “usage:nt%s [-i ] [-p ]n”, argv[0]); fprintf(stderr, “t%s [-p ]n”, argv[0]); fprintf(stderr, “t%s [-i ] < n”, argv[0]); fprintf(stderr, “t%s < n”, argv[0]); exit(0); } } if (patch == stdin) { fprintf(stderr, “Reading patch data from stdin.n”); } fgets(line, sizeof(line), patch); / eat dif file intro line / fgets(line, sizeof(line), patch); / eat blank line / if (input == NULL) { fprintf(stderr, “Inferring input file name from patch file data.n”); fscanf(patch, “%256s”, line); input = fopen(line, “rb+”); if (input == NULL) { fprintf(stderr, “Failed to open input file %sn”, line); exit(0); } } else { / don’t need input file name, but need to skip it in dif file */ fgets(line, sizeof(line), patch); } while (fscanf(patch, “%x: %x %x”, &offset, &orig, &newval) == 3) { fseek(input, offset, SEEK_SET); if (fgetc(input) == orig) { fseek(input, offset, SEEK_SET); fputc(newval, input); } else { //original bytes don’t match expected? } } fclose(input); if (patch != stdin) { fclose(patch); } } [/c] After compiling this code successfully, execute the following command on DOS which requires the DIF file and new patched file name as: ida_patcher.exe -i PatchedApp.exe -p binaryCrackPatched.dif This approach also fulfills the same objective and produces a patched binary as defined earlier in the papers.
Conclusion
So, we have learnt one of the amazing tactics of patching the binary and producing new executable files using IDA Pro, for which crackers used to struggle because as of the IDA limitation, it can only disassemble the binary code to analyze the vulnerabilities or bugs in the code. We can temporary divert the instruction code by modifying the ZF register during debugging just by placing the breakpoint, but can’t patch or modify the bytes sequence into the memory directly to produce new binary executable, because IDA Pro makes change in the database, not in the binary executable. This paper taught us how to make visible the hidden features of the Patch program in IDA Pro IDE. We have also come across with string patching and new way to modify bytes by producing DIF file, which later passed as an argument to a custom C patch code.