Recently I learned a lot of shell removal scripts, and Tortoiser also made a lot of videos about shell removal, which made me learn a lot and feel the power of the experts. I also need to work hard. Of course, sometimes I read the script and sometimes it appears like this. to be honest, I cannot know why such a feature is extracted there. you need to know that only you can find the answer through practice. I chose the Themida v1.8.2.0 shelling program. In addition to the OEP processing option, the shell setting is the default setting. now that the shell has been added, let's go to OEP and check it out! I disconnected the VirtualAllocEx function and ran the program for nineteen times by Shift + F9. OK, I will delete the breakpoint after 18 times, and then set the F2 breakpoint for access under the code segment, disconnected here. 8906 f77 8BF0 mov esi, eax 00419F79 A1 80F84400 mov eax, dword ptr ds: [0x44F880] 00419F7E mov dword ptr ds: [esi], eax 00419F80 8D56 04 leedx, dword ptr ds: [esi + 0x4] 00419F83 B8 ECD34400 mov eax, delphi7? 0044D3EC 00419F88 B9 02000000 mov ecx, 0x2 00419F8D E8 2689 FEFF call delphi7? 004028B8 00419F92 BA 2C9F4100 mov edx, delphi7? 00419F2C 00419F97 8D46 05 lea eax, dword ptr ds: [esi + 0x5] 00419F9A E8 ADFFFFFF call delphi7? 00419F4C 00419F9F 8946 06 mov dword ptr ds: [esi + 0x6], eax 00419FA2 8D5E 0A lea ebx, dword ptr ds: [esi + 0xA] 00419FA5 C603 E8 mov byte ptr ds: [ebx], 0xE8 00419FA8 8D56 04 lea edx, dword ptr ds: [esi + 0x4] 00419FAB 8BC3 mov eax, ebx 00419FAD E8 9 AFFFFFF call delphi7? 00419F4C copy the code F8 one step will come to: 0044 CAA8 A1 B8DF4400 mov eax, dword ptr ds: [0x44DFB8] 0044CA AD 8B00 mov eax, dword ptr ds: [eax] 0044 CAAF E8 9CE6FFFF call delphi7? 0044B150 0044CAB4 8B0D 94E04400 mov ecx, dword ptr ds: [0x44E094]; delphi7? 0044FBD0 0044 CABA A1 B8DF4400 mov eax, dword ptr ds: [0x44DFB8] 0044 CABF 8B00 mov eax, dword ptr ds: [eax] 0044CAC1 8B15 F0C64400 mov edx, dword ptr ds: [0x44C6F0]; delphi7? 0044C73C 0044CAC7 E8 9CE6FFFF call delphi7? 0044B168 0044 CACC A1 B8DF4400 mov eax, dword ptr ds: [0x44DFB8] 0044CAD1 8B00 mov eax, dword ptr ds: [eax] 0044CAD3 E8 10E7FFFF call delphi7? 0044B1E8 0044CAD8 E8 4372 FBFF call delphi7? 00403D20 0044 CADD 8D40 00 lea eax, dword ptr ds: [eax] copy the code and pull it up to see this generation is quite like the delphi Program 0044CA98 55 push ebp 0044CA99 8BEC mov ebp, esp 0044CA9B 83C4 F0 add esp,-0x10 0044CA9E B8 B8C84400 mov eax, delphi7? 0044C8B8 0044CAA3 E8 2091 FBFF call delphi7? 00405BC8 0044CAA8 A1 B8DF4400 mov eax, dword ptr ds: [0x44DFB8] 0044 CAAD 8B00 mov eax, dword ptr ds: [eax] 0044 CAAF E8 9CE6FFFF call delphi7? 0044B150 0044CAB4 8B0D 94E04400 mov ecx, dword ptr ds: [0x44E094]; delphi7? 0044FBD0 0044 CABA A1 B8DF4400 mov eax, dword ptr ds: [0x44DFB8] 0044 CABF 8B00 mov eax, dword ptr ds: [eax] 0044CAC1 8B15 F0C64400 mov edx, dword ptr ds: [0x44C6F0]; delphi7? 0044C73C 0044CAC7 E8 9CE6FFFF call delphi7? 0044B168 0044 CACC A1 B8DF4400 mov eax, dword ptr ds: [0x44DFB8] 0044CAD1 8B00 mov eax, dword ptr ds: [eax] 0044CAD3 E8 10E7FFFF call delphi7? 0044B1E8 0044CAD8 E8 4372 FBFF call delphi7? 00403D20 0044 CADD 8D40 00 lea eax, dword ptr ds: [copy the eax code. Let's go to the first CALL to see it, you can log on to jmp [xxxxxxxx] and process it as follows: 00405B04 90 nop 00405B05-E9 56B26D02 jmp 02AE0D60 00405B0A 8BC0 mov eax, eax running 90 nop running-E9 DEAD6D02 jmp 02AE08F0 00405B12 8BC0 mov eax, eax running 90 nop 00405B15-e9fac6d02 jmp 02AE07B9 00405B1A 8BC0 mov eax, eax 00405B1C 90 nop 00405B1D-E9 78A96D02 jmp 02AE049A copy of the Code. The heavy load OD is ready. After processing, let's proceed with the first step! After processing the code segment, you should write the code !!! Enable the memory image to access the breakpoint in the memory in the code segment without stopping Shift + F9. Pay attention to the Register window. If the API function appears, stop the EAX 001_11c delphi7? 0045011 CECX 7C9210E0 ntdll. RtlLeaveCriticalSectionEDX 5DECA5C2EBX 006BF497 delphi7? 006BF497ESP 0012FF64EBP F6E56041ESI 006B922D delphi7? 006B922DEDI 7C9210E0 ntdll. RtlLeaveCriticalSectionEIP 006BF364 delphi7? The 006BF364 program is disconnected here. 006BF364 8908 mov dword ptr ds: [eax], ecx; ntdll. rtlLeaveCriticalSection // mov dword ptr ds: [eax], ecx notes that this statement is used to compile ECX data and write it to an address. In this case, ECX stores the API address, here may be the data window address where the API is filled. Let's take a look at 00450114 00000000 00450118 00000000 00450120 00000000 00450124 00000000 00450128 00000000 00000000 00450130 00000000 00450134 00000000 00450138 00000000 13C 00. 000000 00450140 00000000 eax = 00000011c, 00000011c now the data is 0. In a single step, observe 00450114 00000000 00450118 029E0000 00000011c 7C9210E0 ntdll. rtlLeaveCriticalSection 00450120 00000000 00450124 00000000 // 006BF366 AD lods dword ptr ds: [esi] 006BF367 C746 FC 0000000> mov dword ptr ds: [esi-0x4], 0x0 006BF36E 89B5 051F7409 mov dword ptr ss: [ebp + 0x9741F05], esi 006BF374 83F8 FF cmp eax,-0x1 006BF377 0F85 20000000 jnz delphi7? 006BF39D 006BF37D 813E DDDDDDDD cmp dword ptr ds: [esi], 0 xdddddddddddd 006BF383 0F85 14000000 jnz delphi7? 006BF39D 006BF389 C706 00000000 mov dword ptr ds: [esi], 0x0 006BF38F 83C6 04 add esi, 0x4 006BF392 89B5 109mov dword ptr ss: [ebp + 0x9741F05], esi 006BF398 ^ E9 EDF6FFFF jmp delphi7? 006BEA8A copy the code to cancel the F9 running of the breakpoint. The program interface appears and then enters the data window, ctrl + G 00000011c go and check out and you will find that from 20171000000000000000002e50000000000648 02e5038300000064c 0000000000450650 02e503dc000000654 0000000000450658 770FAB10 2017770f515a 2017770f51a6 2017770faa 6BBB %770f4cfd %770f48f0 oleaut32.variantclear00%674 770F4950 OLEAUT32.VariantInit there are both API functions and some unknown values, so you can basically confirm 006BF364 8908 mov dword ptr ds: [eax] the code in ecx is processing IAT heavy load OD and the hardware is executing a breakpoint at 006BF364. The F9 operation is broken !!!!!!!!!!!!!! 006BF364 8908 mov dword ptr ds: [eax], ecx 006BF366 AD lods dword ptr ds: [esi] 006BF367 C746 FC 0000000> mov dword ptr ds: [esi-0x4], 0x0 006BF36E 89B5 051F7409 mov dword ptr ss: [ebp + 0x9741F05], esi 006BF374 83F8 FF cmp eax,-0x1 006BF377 0F85 20000000 jnz delphi7? 006BF39D copy the code F8 one step this very large back hop 006BF458 ^ E9 11 FFFFFF jmp delphi7? 006BF36E continue F8. Pay attention to this code. This Code extracts the base address of kernel32 from a specific address: 006BEC2C 8B0B mov ecx, dword ptr ds: [ebx]; export [ebx] = [02820000] = 7C800000 (kernel32.7C800000) Continue F8. Come to 006BEC9B and go to 006BEC9B FFD3 call ebx006BEC9D 83BD 71297409 0> cmp dword ptr ss: [ebp + 0x9742971], the address of the api eax 7C9210E0 ntdll is displayed in the 0x0 storage window. rtlLeaveCriticalSectionECX 7C800000 kernel32.7C800000EDX 5DECA5C2EBX 006BF497 delphi7? 006BF497ESP 0012FF64EBP F6E56041ESI 006B9229 delphi7? 006B9229EDI 0040136D delphi7? 0040136 DEIP 006BECA4 delphi7? Continue F8 at 006BECA4 and we will go to 006BF364 8908 mov dword ptr ds: [eax]. Let's summarize ecx. 1. obtain the address of the API function through a series of operations above 006BEC9D 2. determine whether the API needs to be encrypted. If encryption is required, computation is performed. If the result is filled in with IAT, the API is directly filled without encryption. let's write a simple script to test bphwcall var addrbphws 006BEC9B, "x" bphws 006BF364, "x" bphws 0044CA98, "x" loop: estocmp eip, 0044CA98je exitcmp eip, 006BF364je sssssto stomov addr, eaxestostomov [eax], addrjmp loopssss: stojmp loopexit: After the ret script is run, check whether the result is 00450118 7C93137A ntdll. rtlDeleteC Riticalsection0042511c 7C9210E0 ntdll. 1097c921000 ntdll. 1097c809f91 1097c809b84 1097c809af1 %7c8099cf %7c809a2d %7c81127a %7c8097d0% 7C80981A kernel 7C809806 kernel 7C80BA71 kernel32.virtualquery00kernel 14C 7C80A174 kernel 7C809C98 kernel 7C80BE56 kernel 7C8101B1 kernel 7C801D53 kernel 7C80A4B5 kernel 7C801EF2 kernel32.Ge Tstartupinfoa00425168 7C80AE40 %7c80b741 %7c80b56f %7c80d302 %7c812fbd %7c80ac7e %7c813879 %7c80ee77 %7c81cb12 %7c810e27 kern El32.writefile000000190 7C863FCA kernel32.unhandledexceptionfilter000000194 7C94ABC5 ntdll. rtlunwind000000198 7C812AA9 kernel32.RaiseException looks pretty OK. IAT is fixed in half. It looks pretty OK. IAT is fixed in half, and 00405B04 90 slave-E9 56B26D02 jmp rj8bc0 mov eax, eax heavy load OD, in the data window Ctrl + g to 00405B04 address to see and set to disassembly display 00405B04 AF scas dword ptr es: [edi] 00405B05 CD 06 int 0x600405B07 38DE cmp dh, bl00405B09 BC 5B1D18BE mov es P, 0xBE181D5B00405B0E D5 E5 aad 0xE500405B10 C3 retn00405B11 67: B8 A9BA344C mov eax, 0x4C34BAA9 hardware write breakpoint F9 run two times off under 00405B0D data window display 00405B03 90 running 90 running 90 running 90 nop00405B07 90 running 90 nop00405B09 90 running 8BC0 mov eax, fill 90 fill 90 nop00405B0E 90 nop00405B0F 90 nop00405B10 90 nop00405B11 90 nop00405B12 8BC0 mov eax, eax this code is responsible for filling 9090909090, this is not what I want, cancel Breakpoint 00405B0C 90 11690 11690 11690 11690 nop00405B11 90 nop00405B12 8BC0 mov eax, eax memory writing breakpoint, F9 running disconnected, 006BF44F AB stos dword ptr es: [edi] after a single F8 step, the data window shows that 00405B0D is filled ////////////////////////// //// // data window: 00405B06 90 nop00405B07 90 nop00405B08 90 nop00405B09 90 1168bc0 mov eax, eax00405B0C 90 116-e9 A3AE6D02 jmp 02AE09B500405B12 8BC0 Mov eax, eax EAX 026DAEA3ECX 02AE09B5EDX 029C03F6EBX 006B2436 delphi7? 006B2436ESP 0012FF60EBP F6E56041ESI 006B968D delphi7? 006B968DEDI 00405B12 delphi7? 00405B12EIP 006BF450 delphi7? 006BF450 /////////////////////////////////////// ////////////// 006BF450 AD lods dword ptr ds: [esi] 006BF451 C746 FC 0000000> mov dword ptr ds: [esi-0x4], 0x0006BF458 ^ E9 11 FFFFFF jmp delphi7? 006BF36E we found that 006BF44F AB stos dword ptr es: [edi] is filled with no other address to write it. therefore, we need to deal with 00405B0C 90 nop00405B0D-E9 A3AE6D02 jmp 02AE09B5 single step to 006BF458 address the best position to extract the signature code AB AD C7 46 FC 00 00 00 00 next we should fill 00405b 00405B03 90 nop00405B04 90 nop00405B05 90 nop00405B06 90 nop00405B07 90 nop00405B08 90 nop00405B09 90 nop00405B0A 8BC0 mov eax, eax we load the shelled delphi program into the first CALL00405B03 90 nop00405B04 $-FF25 E4014500 jmp dword ptr Ds: [<& kernel32.GetModuleHa>; ipv8bc0 mov eax, eax00405B0C $-FF25 E0014500 jmp dword ptr ds: [<& kernel32.LocalAlloc>; ipv8bc0 mov eax, eax00405B14 $-FF25 DC014500 jmp dword ptr ds: [<& gt; 4158bc0 mov eax, eax00405B1C $-FF25 D8014500 jmp dword ptr ds: [<& gt>; kernel32.TlsSetValue can be seen as shown in If the address code is not processed, it should be written back to 00405B03 90 nop00405B04 $-FF25 E4014500 jmp dword ptr ds: [<& kernel32.GetModuleHa>; kernel32.GetModuleHandleA: Okay, I don't know. One step of F8 is always at 006BEC9B FFD3 call ebx006BEC9D 83BD 71297409 0> cmp dword ptr ss: [ebp + 0x9742971], 0x0 extract the signature. Check the register EAX 7C80B741 kernel32.GetModuleHandleAECX 7C800000 kernel32.7C800000EDX 5DECA5C2EBX 006BF497 delphi7? 006BF497ESP 0012FF64EBP F6E56041ESI 006B9699 delphi7? 006B9699EDI 00405B12 delphi7? 00405B12EIP 006BEC9D delphi7? 006BEC9D found that the data in EAX is the address of GetModuleHandleA OK. This is not the function to write back the address 00405B04 !!!! But one step further goes to 006BF44F AB stos dword ptr es: [edi] 006BF450 AD lods dword ptr ds: [esi] 006BF451 C746 FC 0000000> mov dword ptr ds: [esi-0x4], 0x0 was found to have been processed into 00405B04 90 nop00405B05-E9 56B26D02 jmp 02AE0D60. I followed this code step by step to get the following information: 1. the API function address in the register after 006BEC9B FFD3 call ebx is exactly the function processed by 006BF44F AB stos dword ptr es: [edi. 2. so I only need 006BF44F AB stos dword ptr es: [edi] After execution, write the function address obtained from 006BEC9B FFD3 call ebx back to OK .3. because IAT has been fixed before, I can compare the API function address obtained in 006BEC9B FFD3 call ebx with the IAT table and find the corresponding API storage address (xxxxxxxx) in IAT ). 4. find the API storage address (xxxxxxxx ). you can fix jmp 02AE0D60 to jmp [xxxxxxxx].