Download: http://www.bkjia.com/uploadfile/2013/0606/20130606103852815.rar
"I don't regret it when I get more and more out of my clothes." ------ Mr. Wang Guowei, Liu Yong's butterfly and love flowers, once used this as a metaphor for the second stage of study. I want to share this with the kings who are still struggling in the KSSD big classroom! However, the shelling of a higher version is usually based on a lower version. If you know something about a lower version, you can ignore it here. http://bbs.pediy.com/showthread.php?t=172921 Or move to KSSD to go to the topic! Run the F9 command first. After the program ends, pull the stack up to find (figure 1): There is a return to 00401510, go to the Disassembly window to see: Code: 0040147E 8AD4 mov dl, AH00401480 8915 F4844000 mov dword ptr ds: [4084F4], 4158bc8 mov ecx, EAX00401488 81E1 FF000000 and ecx, 415890d F0844000 mov dword ptr ds: [4084F0], ECX00401494 C1E1 08 shl ecx, 800401497 03CA ADD ECX, EDX00401499 890D EC844000 mov dword ptr ds: [4084EC], ECX0040149F C1E8 10 shr eax, 10004014A2 A3 E8844000 mov dword ptr ds: [4084E8], EAX004014A7 6A 00 PUSH 0004014A9 E8 A80A0000 CALL sayhello.00401F56004014AE 59 POP ECX004014AF 85C0 test eax, EAX004014B1 75 08 jnz short rj6a 1C PUSH 1C004014B5 E8 9A000000 CALL sayhello.00401554004014BA 59 POP ECX004014BB 8365 FC 00 and dword ptr ss: [EBP-4], 0004014BF E8 72070000 CALL limit E8 A0FA2E02 CALL limit 90 NOP004014CA A3 F8894000 mov dword ptr ds: [4089F8], EAX004014CF E8 30060000 CALL limit A3 D0844000 mov dword ptr ds: [4084D0] EAX004014D9 E8 D9030000 CALL 450e8 1B030000 CALL 0000e8 90000000 CALL 0000a1 04854000 mov eax, dword ptr ds: [408504] 004014ED A3 08854000 mov dword ptr ds: [408508], pushed 50 PUSH EAX004014F3 FF35 FC844000 push dword ptr ds: [4084FC] 004014F9 FF35 F8844000 push dword ptr ds: [4084F8] 004014FF E8 fcfaffff call limit 83C4 0C add esp, 0C00401507 8945 E4 mov dword ptr ss: [EBP-1C], EAX0040150A 50 PUSH EAX0040150B E8 95000000 CALL 4508b45 ec mov eax, dword ptr ss: [EBP-14] 00401513 8B08 mov ecx, dword ptr ds: [EAX] 00401515 8B09 mov ecx, dword ptr ds: [ECX] 00401517 894D E0 mov dword ptr ss: [EBP-20], ECX0040151A 50 PUSH EAX0040151B 51 PUSH ECX0040151C E8 59010000 CALL sayhello.0040167A00401521 59 POP ECX00401522 59 POP ECX00401523 C3 RETN this is a pseudo OEP of VC program, the header is stolen some bytes into CALL sayhello.00401000 (figure 2)
Like earlier versions, call is processed. Observe the data window, we can judge that 00405000 is the beginning of the Iat segment (Figure 3): Well, load the OD again, and write the breakpoint in the memory of 00405000: Code: 004127a0 8F02 pop dword ptr ds: [EDX]; disconnected at 004425a0 (VM code here) (Figure 4) view the stack return (Figure 5). The CALL code is: Code: 004C26F9 FF95 7A278906 call dword ptr ss: [EBP + 689277A] Remember that when the earlier version is used, it needs a table and obtains the original API address, IAT address and CALLAPI address based on the data in the table. Is the same here, let's take a look at the next breakpoint here. After F9, we checked [esi] and found a very familiar table (figure 6): We found it here. We know that it needs data to obtain various addresses. It can be tracked after the breakpoint is accessed in the memory or directly from the c26f9 breakpoint, because its processing process must be a loop process. So let's track it directly. First, f8. skip this CALL. If you don't care about the VM for the moment, first figure out the process. Obviously, after this CALL, IAT is filled with the address after processing (figure 7), and our [esi] Table is also changed (figure 8 ): it can be seen that at least the callapi acquisition step is completed in the VM. The next step is approaching the processing of the next API. Yes, right after this "dddddddddd. The single-step process is not detailed in detail, which is almost the same as the earlier version, but some junk code is added. The Code: 004BF68C C785 running 0> mov dword ptr ss: [EBP + 6821D2D], 0004BF696 C785 311B8206 0> mov dword ptr ss: [EBP + 6821B31], 0004BF6A0 83BD 00B48C06 0> cmp dword ptr ss: [EBP + 68CB400], the starting point of the cycle that 0 is very familiar with. Like the earlier version, the following Verification Section also needs to be modified: code: 004BF6E3 83BD 21158206 6> cmp dword ptr ss: [EBP + 6821521], 64004BF6EA 0F82 09010000 JB sayhello.004BF7F9; modify it to jmp to skip the following section to judge whether the [esi] Table is processed: code: 004BF893 3D eeeeeeee cmp eax, eeeeeeeeee004bf898 0F85 AB 000000 JNZ running F5 running 813E dddddddd cmp dword ptr ds: [ESI], 1270f85 9E000000 JNZ running F8 CLC004BF8AC F8 limit 50 PUSH pushed into B8 00000000 mov eax, 0004BF8B3 8906 mov dword ptr ds: [ESI], EAX004BF8B5 8B0424 mov eax, dword ptr ss: [ESP] 004BF8B8 83C4 04 add esp, 4004BF8BB E9 08000000 JMP limit 53 PUSH EBX004BF8C1 F4 HLT; privileged command 004BF8C2 running D 7ADF2136 and dword ptr ds: [3621DF7A], EDI004BF8C8 52 PUSH Pull BA 04000000 mov edx, 4004BF8CE 81C6 5C04AE28 add esi, 201701d6 add esi, EDX004BF8D6 81EE 5C04AE28 sub esi, 1275a POP EDX004BF8DD E9 0F000000 JMP sayhello.004BF8F1 get the value of the [esi] Table: Code: 004BF85C AD LODS DWORD PTR DS: [ESI] continues to track a loop: Code: 004BFC57 3B02 cmp eax, dword ptr ds: [EDX] 004BFC59 0F84 6F000000 JE found; find the KEY bounce cycle 004BFC5F 0F89 1E000000 JNS 000060 PUSHAD004BFC66 E8 14000000 CALL history AB STOS DWORD PTR ES: [EDI] 004BFC6C F2: PREFIX REPNE :; extra prefix 004BFC6D 93 xchg eax, EBX004BFC6E 6B30 A8 imul esi, dword ptr ds: [EAX],-58004BFC71 B6 fd mov dh, 127d19e 2B586176 rcr dword ptr ds: [ESI + 7661582B], 1004BFC79 B7 07 mov bh, 7004BFC7B 05 CCF02A5A add eax, 201760 PUSHAD004BFC81 61 POPAD004BFC82 61 POPAD004BFC83 57 PUSH EDI004BFC84 893424 mov dword ptr ss: [ESP], must BE 04000000 mov esi, 4004BFC8C 01F2 add edx, listen 5E POP listen FC listen 52 PUSH Pull BA 01000000 mov edx, 1004BFC96 01D1 add ecx, listen 5A POP listen F9 STC004BFC9A 3B8D B8BF8B06 cmp ecx, dword ptr ss: [EBP + 68BBFB8] 004BF CA0 ^ 0F85 B1FFFFFF JNZ sayhello.004BFC57 according to the low version flow, here is to get an offset value, each API corresponds to a different offset, this offset table can be viewed as storing the decryption KEY of the corresponding API maintained by TMD, which has little to do with shelling. We can skip the cyclic code by executing the breakpoint in the hardware of bfcce: 004 BFCCE 898D E11C8206 mov dword ptr ss: [EBP + 6821CE1] After this line of code, ECX displays the original api address: Code: 004BFED7 01C8 add eax, ECX004BFED9 2D running f5568 SUB EAX, the APIs of some modules in 68550F19 are only a string here. The Code: 004C026C 61 POPAD 004C026D FFD3 call ebx will continue one step. After this CALL, the original api address 004C026F 60 PUSHAD will be obtained; at this time, eax is the API location After an API address is obtained, it processes the API and stores it in the VM. However, if some functions are not processed, the address will have a judgment, we will continue to look for this judgment in a single step (a TMD reconstructs the API at the address it applied for in a single step, which is the same as the idea of a lower version, which will not be detailed here ). After a long one-step process, you can go to the following code (of course, you will find it soon after you start to return the result, and of course the sequence is helpful for us to understand the process: 004C26DF 83BD E9B48C06 0> cmp dword ptr ss: [EBP + 68CB4E9], 0004C26E6 0F85 91000000 JNZ sayhello.004C277D we haven't found the IAT address yet, it can be seen that it is also processed in the VM. The process from the VM is clear. First, let's take a look at the unencrypted state, where the breakpoint is located at 004C26DF. Let's start with the single step: Code: 004C279A 0385 ad1_206 add eax, dword ptr ss: [EBP + 68210AD]; eax is the IAT address 004C27A0 F5 CMC and then processes the CALLAPI address. Like in earlier versions, it processes the "90" filling, we can ignore this because we will refill the CALLAPI: 004C291C 0385 ad0000206 add eax, dword ptr ss: [EBP + 68210AD]; here [EAX] callapi address 004C2922 F9 STC004C2923 83BD F9148206 0> cmp dword ptr ss: [EBP + 68214F9], 1004C292A 0F84 F1040000 JE limit 6 1 POPAD; here [EAX] Is CALLAPI address 004C293F 813E aaaaaaaa cmp dword ptr ds: [ESI], AAAAAAAA; compare whether to fill the FF25---------------------------------------------------------------------------------------------------------------------------------004C293F is also a breakpoint code we need: 004C2DF4 AB STOS DWORD PTR ES: [EDI]; after CALLAPI processing is completed, you can re-write it back to 004C2DF5 60 PUSHAD. After the above steps are completed, we will understand the entire process, let's take a look at the VM. The so-called vm I understand is that it makes a new convention for the original instructions, and executes the transformed code according to the new convention to replace or "equivalent" to complete the original instruction set, each of its new agreed commands has a sequence of commands. The following two important code codes are available: 00442221 ac lods byte ptr ds: [ESI]; a vm byte is obtained here, which is calculated, get the jump of the command sequence 00442222 30D8 xor al, BL code: 00447B00/FF2487 jmp dword ptr ds: [EDI + EAX * 4]; jump to the command sequence 00447B03 | 61 POPAD00447B04 | C3 RETN followed by [edi] To find a command sequence table (figure 9): Of course, you can record the comparison between the above two breakpoints if you want to analyze it carefully. Of course we will not analyze it now. We mainly want to shell it out. Tracking shows that several key data are written through 004108a0 8F02 pop dword ptr ds: [EDX]; analysis by printing script 004366a0, recording [esp] and edx (because they will produce key data, during this tracking process, we can find that TMD is similar to this. Of course, different VM engines can be set differently. For details, see KSSD-> Protection-> Virtual Machine) Tracking script: code: var vedxvar vespvar x bphwcbphws 004108a0, "x" bphws 004c0169, "x" mov x, 0 estoloop: cmp eip, 004109a0jne exitmov vedx, edxmov vesp, [esp] inc xlog vedxlog vespcmp x, 15je exitestojmp loopexit: ret obtains the following data through observation records: the iat RV is calculated 016th times by the API address after the 0a occurrence of confusion A calculates the VA of the iat for 017th times and fills the iat at 0x1f times to calculate the callapi address for 0x25 times and fills the callpi offset, the code for filling e8 e9 is not here. You must also look for the next element that compares esi at 0x26 to see if it is ffffffff, if not, it indicates that there are still callapis to be filled. If it is ffffffff, it will enter the next loop after 0x28. If it is not ffffffff, the next callapi address will be calculated at 0x2b for the same 6 times. after the disconnection, fill the callapi address at 0x31. The following code analyzes and calculates the iat and then downloads the breakpoint after 0x16: code: 00444DB0 311C24 xor dword ptr ss: [ESP], 2017331c24 xor ebx, dword ptr ss: [ESP] 00444DB6 8B2424 mov esp, dword ptr ss: [ESP] 00444DB9 010424 ADD Dword ptr ss: [ESP], EAX; sayhello.00400000 the iat address is calculated by code at 00444DB9, at this time, the iat address is stored in [esp], and the analysis of callapi offset is continued after the 0 x 1E, And the breakpoint tracking is performed: it is found that the address for writing callapi is also in the 00444DB9 where you can find this pattern in the Virtual Machine segment (though you don't have to trust it too much. Different versions may slightly differ, but the method is the same) next, we will continue to analyze and compare the analysis results of ffffffff after the 0x26 breakpoint. Here: Compare ecx and eax. If they are equal, the elements end with the inequality and the callapi code is: 0044D099 8B2424 mov esp, dword ptr ss: [ESP] 0044D09C 3BC8 cmp ecx, EAX breakpoint 00444DB9 plus hardware breakpoint 004C026F test found that 00444DB9 here the IAT or CALLAP is obtained only when the condition eax = 00400000 is determined. I address, and it is the IAT address for the first time (in fact, this breakpoint can already process the IAT address of the VM, the first is IAT, followed by the callapi address) 0044D09C also requires the condition eax = ffffffff eax! = Ffffffff indicates that there are still unprocessed callapis. If they are equal, it indicates that the current API element has been processed. With the above conditions, we can write scripts to complete shelling. The main breakpoint is as follows: 004C026F ---------- obtain the original API address Case1: 004C26F9 --------- enter the VM here. The IAT and CALLAPI acquisition filling of some functions are implemented here Case2: 004C27A0 -------- here, the IAT of the API does not need to be encrypted. The value -------- in eax is used to add an auxiliary breakpoint to take IAT after judgment, and find the 004c27ce Case_VM in a few lines of code in a single step: 00444DB9 --------- determine whether the obtained IAT or callapi is correct by judging eax = 00400000, and adding a digital ID: 004C293F --------------------- obtain the callapi value 004C2DF5 -------------- here the filling is complete and re-write the code back: var apivar I Atvar callapivar nbcbphwcbphws 004c026f, "x"; get the original API address estobp 004BF8DD; after processing is complete, you can adjust it to OEP. Of course, you can skip this breakpoint, because OEP can find bp 004C26F9 through the exit method, and enter VMbp 00444DB9; get IAT and CALLAPI address bp 004C27A0 in VM; unencrypted IATbp scheme; unencrypted CALLAPIbp 004C2DF5; after the CALLAPI is filled, write back bp 004c27ce. Because 004C27A0 is used as the Redirect condition for encryption, add a breakpoint below to retrieve unencrypted IATmov [004bf6ea], # e90a0000090 #; change the verification field to JMP and skip loop: cmp eip, 004c026fjne swtichmov api, eaxmov n, 0; Judge IAT and CALLA in VM PIestojmp loopswtich:; The cmp eip addresses Encrypted and unencrypted, respectively, notnotvmcmp eip, vmjmp exitnotvm: cmp eip, ipvjne filliatmov iat, and notvmfilliat: cmp eip, 004C27CEjne callapimov [iat], api; get IAT. Some encryption APIS also process javasnotvmcallapi: cmp eip, javasfillcallapimov callapi, eax; obtain the CALLAPI address estojmp notvmfillcallapi: cmp eip, 004C2DF5jne loopfind callapi, # E9 #, 2; compare whether to fill FF25cmp $ RESULT, 0jne fil LFF25Amov [callapi], # ff15 # add callapi, 2mov [callapi], iat estojmp notvmfillFF25A: mov [callapi], # ff25 # add callapi, 2mov [callapi], iatestojmp notvmvm: estocmp eip, 00444DB9 jne loopcmp eax, 00400000; When condition eax = 00400000, it may be ITA or CALLAPIjne vminc ncmp n, 1; n to determine whether to process IAT or CALLAPIjne callapifunmov iat, [esp] add iat, 00400000; get the IAT or CALLAPI vabc00420.a0; add a breakpoint, the code here will fill in IATestoestoestoestomov [iat], api; IAT after four F9 times Fill out BC 004425a0jmp vmcallapifun: mov callapi, [esp] add callapi, 00400000bp 0040000a0; add breakpoint, the code here will be filled in; after 10 F9 times, CALLAPI fill out find callapi, # E9 #, 2; compare whether to fill FF25cmp $ RESULT, 0bc 004425a0jne fillFF25bmov [callapi], # ff15 # add callapi, 2mov [callapi], iat jmp vmfillFF25b: mov [callapi], # ff25 # add callapi, 2mov [callapi], iatjmp vm exit: bcbphwcbprm 00401000,4000; after processing, the memory access breakpoint is reached, After OEPestoret is disconnected, restore the OEP according to the conventional method, just like the earlier version. The TMD version will be different, and the shelling method will be slightly different, but the overall process is like this. According to this analysis, there is no problem with Shell removal! June 5, 2013