Enigma6.8 unpacking + repair by The illegalhacker7

 Enigma6.8 unpacking + repair by The illegalhacker7



Repair IAT

The second simple encryption
This kind of processing of IAT is a simple operation to decrypt the function address corresponding to the new FF25 table. Each encrypted IAT has a different value of push xxxxxxxx. The processing method of EG shell is almost the same as that of the old version. It's the same without much change.




If you want to follow his decryption in detail, you can enter this CALL

005C84B8    E8 3FC0FFFF     CALL PE提取_p.005C44FC

EAX is the return address, which is the function jump corresponding to the FF25 jump table created by the shell itself. If we write a script, it will be very simple. This decryption CALL is a common decryption function. The decryption of all functions is to call this decryption CALL.





In short, let's talk about the realization of the script

1. Since this sample is compiled by VC++, all the function calls are simply called in the form of FF15 CALL. We only need to start from 00401000 and go down to find the assembly statement at the beginning of FF15.

2. When we find the FF15 assembly statement, we can take +4 whether the value in the indirect call address is less than 5FF00000 (system function addresses are all high addresses, and shell applications are all low addresses)

3. We can select memory access breakpoints in all areas where the address table is located in the FF25 address table created by the shell, and then follow the method of 2 to obtain the corresponding function address and fill in the address of 1



Enigma still has thread interference with this method, what's the matter? That is, when you use the script to run the repair IAT, he will call the sleep function from time to time to suspend the thread to interfere with the repair. According to my observation, we can find that the packaged program has two more threads than the unpackaged program. When I terminate these two threads, the program will exit, that is, simply call the ExitProcess function to exit. We ret the program directly in the function, and the program will not exit. The operation is normal, and the sleep function will not be called to interfere with our repair.



The script code is as follows:

var addr
var taddr
var addriat
var taddriat
 
bc
bpmc
bphwcall
bprm 6ccca5,f2a
 
mov addr,401000
 
start:
findop addr,#ff15????#,ffff
mov addr,$RESULT + 4
cmp $RESULT,0
je exit
mov taddr,[$RESULT + 2],4
mov taddriat,taddr
mov taddr,[taddr],4
cmp taddr,4f000000
ja start
cmp taddr,500000
jb start
mov eip,$RESULT
eob fix
run
 
fix:
mov addriat,[eip + 2],4
mov addriat,[addriat],4
mov [taddriat],addriat,4
jmp start
 
exit:
ret


The third simulation + encryption
The last type of encryption is also the most difficult to restore. I turned Enigma upside down and I still couldn't find the corresponding original function in this IAT processing. I guess Enigma will press this small part of the function when it is processed by the SDK. After the section gets rewritten into the shell, the program is saved, and there is no risk of exposure to the second function on the spot. Although Enigma's simulation is relatively strong, it also has prerequisites. It is not possible to simulate any function. In comparison, it is found that he mainly selects some functions that must be included in the compiled language for encryption. Not only that, in this part of the function. Select the whole function without a call and a function with no jump to rewrite.

There are probably these functions:

rich code:
00425148 >7C810C6D  kernel32.GetCommandLineA
00425248 >7C80CD37  kernel32.SetHandleCount
00425198 >7C80DE95  kernel32.GetCurrentProcess
00425220 >7C811752  kernel32.GetVersion
004502C0 >7C82511A  kernel32.FreeResource
004502B4 >7C8099C0  kernel32.GetCurrentProcessId
00425290  7C80B741   kernel32.GetModuleHandleA
004250F8  7C80CD37  kernel32.SetHandleCount




There are a few more special functions that are another unique rewriting technique. The return address after decryption with the public decryption call is another kind. I have summarized these few, and the language may change.


kernel32.GetModuleHandleA 
kernel32.LoadLibraryExA
ntdll.RtlGetLastWin32Error

We can use DIE64 to check the compiler of the packed program and then find the corresponding non-shelled program to fill in the function address by comparison. The number will not be too much. If we encounter an unknown function, we can look at the number of push parameters required by the call to roughly determine which function it is.



There are shellless examples and scripts in various languages nearby. Finally, I will mention that function encryption not only encrypts the IAT of the program, but also encrypts the functions in the loaded system dll. I don’t know the specific use. I will also use the script. Send it to everyone.




Post a Comment

0 Comments