Foreword:

Hello everyone, this is Jay Chou

Here I have integrated some notes and unpacking from my previous study of software manual unpacking, hoping to give some help to children's shoes who are new to learning software reverse engineering and unpacking.

1 some concepts

1.1 Packing

Packing should be the full name of executable program resource compression, which is a common method of protecting files. The packed program can be run directly, but the source code cannot be viewed. The source code can be viewed only after shelling.

Packing is to use special algorithms to compress and encrypt resources in EXE and DLL files. The effect is similar to WINZIP, except that the compressed file can be run independently, and the decompression process is completely hidden and all completed in memory. After they are attached to the original program and loaded into the memory through the Windows loader, they are executed before the original program to obtain the control right. The original program is decrypted and restored during the execution. After the restoration is completed, the control right is returned to the original program and the original program is executed. Code part. After adding the shell, the original program code generally exists in the encrypted form in the disk file, and it is only restored in the memory during execution, so that it can effectively prevent the cracker from illegally modifying the program file. Prevent the program from being statically decompiled.

The types of shells are usually divided into two types: compressed shells and encrypted shells. The feature of the compressed shell is to reduce the size of the software, and encryption protection is not the focus. There are many types of encryption shells, and different shells have different focuses. Some shells simply protect the program, while others provide additional functions, such as providing registration mechanisms, usage times, and time limits.

1.2 OEP

OEP: (Original Entry Point), the entry point of the program. Software packing generally hides the real OEP of the program (or uses a fake OEP). We need to find the real OEP of the program to complete the unpacking.

Generally, the packer program will stop at the preprocessing block of the shell when using dynamic debugging tools such as Ollydbg. That is, before decompressing or decrypting the original code block of the program, after running the program self-unpacking module, it will stay at the OEP position before the program is packed. This is the best time to dump the program. When shelling, place an int3 breakpoint at the real OEP, and you can capture the state where the program code segment is completely restored. Therefore, finding the correct OEP of the packer program has become the first priority when manually unpacking.

1.3 IAT

IAT: (Import Address Table), import the address table. Since imported functions are functions that are called by the program but whose execution code is not in the program, the codes of these functions are located in one or more DLLs. When the PE file is loaded into the memory, the Windows loader loads the DLL and associates the instruction that calls the imported function with the actual address of the function (dynamic link). This operation requires the import table to be completed. The imported address table indicates the actual address of the function. Most packer software will rebuild the import address table when it is running, so obtaining the correct import address table of the packer program is also a key issue in the manual unpacking operation.

2 Some unpacking methods

2.1 Single-step tracking method

The principle of the single-step tracking method is to use Ollydbg's single-step (F8), single-step entry (F7) and run to (F4) functions to completely walk through the self-unpacking process of the program, skip some loop recovery code fragments, and use Step into it to ensure that the program will not skip OEP. In this way, after the software automatic unpacking module runs, it will reach the OEP and dump the program.

2.2 ESP Law

The ESP law is a sharp weapon for shelling and one of the most frequently used shelling methods.

The principle of ESP law lies in the rational use of stack balance in the program. Because in the process of program self-decryption or self-decompression, many shells will first push the current register content, such as using pushad, after the decompression is completed, the previous register value will be popped out of the stack, such as using popad. Therefore, when the register is popped from the stack, the program code is usually restored automatically, and the hardware breakpoint is triggered at this time. Then at the current position of the program, it is easy to reach the correct OEP position with only a little single-step tracking.

2.3 Memory mirroring method (secondary breakpoint method)

The memory mirroring method is to enter the virtual memory section of the program through the ALT+M shortcut key of OD when the packer program is loaded. Then by adding two memory one-time breakpoints, the correct OEP position of the program is reached.

The principle of the memory mirroring method is that for the program resource segment and the breakpoint of the code segment, when the program is self-decompressing or self-decrypting, it will first access the resource segment to obtain the required resources, and then switch back to the program code segment after the automatic unpacking is completed. At this time, a one-time memory breakpoint is placed, and the program will stop at OEP.

2.4 Reach OEP in one step

The so-called unpacking method to reach OEP in one step is to find the closest assembly instruction to OEP according to the characteristics of unpacking, and then set the int3 breakpoint, and dump the program when the program reaches OEP. For example, some compressed shells often popad instructions are very close to OEP or Magic Jump. Therefore, using the search function of Ollydbg, you can search for the characteristic assembly code of the shell to achieve the effect of one-step breakpoint to OEP.

2.5 The last exception method

The principle of the last exception method is that the program may trigger numerous exceptions during the process of self-decompression or self-decryption. If the position of the last program abnormality can be located, it may be very close to the position where the automatic shelling is completed. Now you can use Ollydbg's exception counter plug-in for the last exception method unpacking, first record the number of exceptions, then reload, and automatically stop at the last exception.

2.6 Simulation tracking method

The principle of the simulation tracking method is to use the conditional breakpoint under Ollydbg. SFX is equivalent to a self-extracting segment. At the end of the self-extracting segment (when the value of eip is transferred to the code segment), it is already very close to the OEP, but this tracking method will It is time-consuming.

2.7 "SFX" method

The "SFX" method uses the OEP search function that comes with Ollydbg. You can choose to stop the program directly at the OEP found by OD. At this time, the self-extracting has been completed and you can directly dump the program.

3 some shelling practices

The following is an example of how to use the above methods, try to manually unpack these several commonly used shelling notes.

3.1UPX shelling notes

First detect the shell:

在这里插入图片描述

First throw the program into OllyIce and you can see:

在这里插入图片描述

Then try to use the ESP theorem: that is, when the ESP is changed for the first time, set a hardware word access breakpoint to the ESP address, so that after the code is restored by the UPX algorithm, it jumps to the normal entry of the program.

在这里插入图片描述

Then F5 runs, and does not directly jump to the big jump position at the entrance of the program, but you can see the big jump of UPX right in front of you:

在这里插入图片描述

Therefore, the entry point of the restored program is 0x00445151 (by stepping down, F4 skips the loop statement of going back, you can also see the position of the big jump.) Next, go to the big jump position and jump to normal Entrance of the program:

在这里插入图片描述

Then remove the hardware breakpoints and use the dump function of LoadPE to dump the target program:

在这里插入图片描述

Correct the image size first, and then select complete unpacking, so that you can get the dump program in the first step, and then use ImportREC to repair the OEP of the dump program. The OEP information can be queried through the dump function that comes with OD or directly fill in 45151:

在这里插入图片描述

Fill in the correct entry address into ImportREC, and then automatically search for IAT information:

在这里插入图片描述

Then click Get Input Table to get the program function input table after IAT is corrected, and then click Show invalid function, and happily find that there is no invalid function, then you can directly repair the dump file.

在这里插入图片描述

Select the dump file that was dumped in the first step just now to repair it. After the repair is completed, the shelling is complete:

在这里插入图片描述

Here for the compressed shell UPX, the ESP law is directly used, and it is easy to find the OEP and dump the program.

4.2 tElock shelling notes

Here is a tElock shell:

在这里插入图片描述

1. Use the simplest last exception method first: first throw the program into OllyIce and set the exception option in the OD debugging option.

在这里插入图片描述

Only keep the memory illegal access exceptions, and then use the exception counter plug-in, clear the breakpoint settings before using:

在这里插入图片描述

After the program runs normally, reload the program, and then select the second step, stopping before the last exception:

在这里插入图片描述

Then use Alt+M to go to the memory window, and execute SHIFT+F9 on the memory breakpoint in the main program code segment:

在这里插入图片描述

In this way, the program is interrupted at the correct OEP, and you can choose to delete the analysis from the module to display the normally analyzed assembly code. Then use the LoadPE dump program and correct the program image size. But when using ImportREC v1.6F Fix, input the correct OEP and get the function input table information, invalid pointers will be found. After using method one to repair, use method three to completely repair

在这里插入图片描述

Click Fix dump again, you can repair the program that was dumped before, and the shelling is complete:

在这里插入图片描述

2. Use the secondary memory breakpoint method: first load the program, ignore all exception types, then set the memory breakpoint in the idata section, then SHIFT+F9:

在这里插入图片描述

After stopping, set a memory breakpoint in the code section again, execute SHIFT+F9 again, and you can directly reach the correct OEP:

在这里插入图片描述

Then LoadPE dump, and then repair IAT. The repair method is the same as method 1.

3. Find the magic jump and the dump program after repairing the function table: add memory breakpoints (idata, code) in the first two steps, and then locate the correct OEP of the program

在这里插入图片描述

Then if you use LoadPE dump to fix it at this time, it will be the same as the previous two. Here we first use ImportREC to get the pointer address of the first position of the function input table.

在这里插入图片描述

Then get the offset address of the function pointer at 0x005512C, and add the base address to 0x045512C. At this time, the hardware accesses the double word breakpoint at this position. After restarting SHIFT+F9 to ignore the abnormal execution, the CRC check error of tElock will be triggered due to the breakpoint:

在这里插入图片描述

Therefore, the CRC check must be bypassed here to successfully execute to the hardware breakpoint position, so first pause the program, and then use Alt+F9 to return to the user code. After clicking the OK button, the program pauses at the position where ExitProcess is called:

在这里插入图片描述

Now look up to find a jump that can skip this exit (CRC judgment jump), and then modify and skip:

在这里插入图片描述

The location that should be modified is found, but it will be restored if it is rerun after modification, so first write down the jump address, 0x00469622. After re-run, set memory breakpoints in idata, stop with SHIFT+F9, and then Ctrl+G to find the modification point and modify it. After the modification, set the previous hardware breakpoint, so that the CRC check error will not be triggered.

After countless SHIFT+F9, the pointer can be seen in the register window and can be displayed normally:

在这里插入图片描述

Then at this time F8 single step, look for magic jump... Looking at Xiaosheng's big video screen, the position of magic jump is obtained by analyzing the suspected CRC jump:

在这里插入图片描述

Note here that the address of the magic jump is 0x0046973B, then clear the udd file, delete the hardware breakpoint, re-run the program, and then stop at the memory breakpoint under idata, then Ctrl+G to find the magic jump location, modify the jump:

在这里插入图片描述

Then memory breakpoints under the code segment:

在这里插入图片描述

Then SHIFT+F9 is executed, and it stops to the position of OEP:

在这里插入图片描述

At this time, dump the program again, the IAT table has been repaired, and you can directly get the unpacked version of the program:

在这里插入图片描述

Here I tried to use two other unpacking methods, and by looking for OEP in advance, after repairing the CRC check, dump directly to the program where the IAT was repaired.

3.3 PEncrypt shelling notes

在这里插入图片描述

Throw the program into OllyIce first, and then the program stops here, which looks weird:

在这里插入图片描述

Well, reload the program, try to use the last exception method without ignoring all exceptions, and then use the exception counter plug-in, the program stops at the last exception:

在这里插入图片描述

If F8 is single-stepped at this time, the program will trigger exception handling, and then it will not reach OEP again. At this time, you need to look at the stack data situation:

在这里插入图片描述

At this time, you need to set a breakpoint at F2 at 0040CCD7, and then execute SHIFT+F9, you can skip this pit:

在这里插入图片描述

Then the next step is the operation of F8+F4, all the way to OEP:

在这里插入图片描述

After unpacking with LoadPE and then repairing with ImportREC, although there is no invalid pointer, it still cannot run:

在这里插入图片描述

At this time, use LoadPE's rebuild PE function:

在这里插入图片描述

在这里插入图片描述

Then it can run normally:

在这里插入图片描述

This shell uses the unpacking method of single-step tracking, skipping the program "trap" all the way, and finally reaching the OEP. And used LoadPE's rebuild PE function to rebuild the program, and finally completed the whole process of unpacking the encrypted shell.

3.4 FSG deformed shell shelling notes

First detect the shell:

在这里插入图片描述

Using ESP law, first throw the program into OllyIce, step F8, observe the ESP change, when the ESP changes for the first time, set the memory hardware access WORD breakpoint at the address corresponding to the ESP, and then SHIFT+F9 runs, After the program stops, cancel the hardware breakpoint and perform F8 single step:

在这里插入图片描述

Use F4 to skip the backward jump (loop), and then continue to look down until here:

在这里插入图片描述

F4 under this jmp, the program will run away. It means that the program code has been released in this loop, so look up to see if there is a conditional jump in this loop. It is easy to find the position of the magic jump, and then we Enter or Ctrl+G to the position of 00402666, and found that it is OEP, re-analyze, and then breakpoint F2 to let the program go to OEP:

在这里插入图片描述

If it is FSG1.33, directly use LoadPE dump file, and then use ImportREC to repair it, and it can be shelled normally. But here when using ImportREC to repair, an invalid pointer will appear:

在这里插入图片描述

Here directly cut (or delete) this pointer, and then repair the dump file, and found that it cannot be opened normally:

![Insert picture description here]( https://img-blog.csdnimg.cn/6b2cb9beb0804eb4a47bcb665cebf62f.png?x-oss-
process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5Luj56CB54as5aSc5pWy,size_12,color_FFFFFF,t_70,g_se,x_16)

Then put the repaired program into OllyIce and run F9 directly:

在这里插入图片描述

Here is a hidden pile added by the deformed shell, which will cause the program to exit abnormally. Here, directly drop the nop or change the previous jle (verification) to jmp, and then save the modification and save the file. Then you can run

在这里插入图片描述


代码熬夜敲
210 声望354 粉丝

李志宽、前百创作者、渗透测试专家、闷骚男一位、有自己的摇滚乐队