日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
一種快速提取惡意軟件解密邏輯代碼的方法

前言

創(chuàng)新互聯(lián)建站技術(shù)團(tuán)隊(duì)10多年來(lái)致力于為客戶提供成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、成都外貿(mào)網(wǎng)站建設(shè)高端網(wǎng)站設(shè)計(jì)成都營(yíng)銷網(wǎng)站建設(shè)、搜索引擎SEO優(yōu)化等服務(wù)。經(jīng)過(guò)多年發(fā)展,公司擁有經(jīng)驗(yàn)豐富的技術(shù)團(tuán)隊(duì),先后服務(wù)、推廣了上1000+網(wǎng)站,包括各類中小企業(yè)、企事單位、高校等機(jī)構(gòu)單位。

在平時(shí)的惡意軟件分析和逆向工作中,我們往往需要對(duì)某些類型的加密算法或者解壓縮算法進(jìn)行逆向。而這一逆向工作,可能會(huì)需要好幾個(gè)小時(shí)、好幾天、好幾個(gè)月,甚至是好幾年才能完成。在我們分析的過(guò)程中,常常需要弄明白惡意軟件所使用的數(shù)據(jù)Blob是什么。

要回答這個(gè)問(wèn)題,本身就是一件有挑戰(zhàn)性的工作,我通常并沒(méi)有那么多的時(shí)間來(lái)對(duì)一些加密的程序做完全徹底的逆向。我一般只需要弄明白這個(gè)數(shù)據(jù)是惡意軟件用來(lái)做什么的配置文件,甚至有的時(shí)候,我根本不知道這些數(shù)據(jù)是什么。盡管很不愿意接受這樣的結(jié)果,但卻是時(shí)常發(fā)生的。

目前,有幾種方法可以解密惡意軟件,并解壓其中的數(shù)據(jù)。我們可以運(yùn)行惡意軟件并轉(zhuǎn)儲(chǔ)內(nèi)存段、在調(diào)試器中對(duì)其進(jìn)行調(diào)試、在解密/解壓縮的部分放置Hook從而dump出其返回值、進(jìn)行靜態(tài)分析等等。雖然這些方法都很不錯(cuò),但無(wú)疑要花費(fèi)大量的時(shí)間。

如果我們有幾個(gè)需要解密或解壓縮的數(shù)據(jù)Blob,那么該怎么辦呢?如果可以直接從惡意軟件的解密/解壓縮部分中得到其匯編代碼,那便可以將其放在一個(gè)編譯器中(比如Visual Studio),將其編譯成動(dòng)態(tài)鏈接庫(kù)(DLL),然后再使用我們熟悉的腳本語(yǔ)言(比如Python)對(duì)其進(jìn)行調(diào)用。

本文將重點(diǎn)講解可以實(shí)現(xiàn)這一點(diǎn)的技術(shù)方法。在分析惡意軟件Reaver的過(guò)程中,Unit 42安全小組發(fā)布了一個(gè)API調(diào)用及字符串的數(shù)據(jù)庫(kù)查找工具,地址為:

https://github.com/pan-unit42/public_tools/tree/master/Reaver_Decompression

分析過(guò)程

我們以針對(duì)Reaver惡意軟件家族的分析為例,嘗試確定其使用的壓縮算法,并確定是否可以在不運(yùn)行惡意軟件的前提下,從中逆向出其使用的算法。請(qǐng)注意,這里的前提是不運(yùn)行惡意軟件。

在我對(duì)該惡意軟件的分析過(guò)程中,發(fā)現(xiàn)它似乎使用了一個(gè)修改過(guò)的Lempel-Ziv-Welch(LZW)壓縮算法。我們所分析的Reaver惡意軟件樣本中,解壓縮算法位于地址0x100010B2,其匯編代碼大約有200行。解壓縮例程如下所示:

 
 
 
 
  1. ; void __thiscall decompress(_DWORD *this, int nstream, int output, int zero, int zero2, int zero3) 
  2. decompress      proc near               ; CODE XREF: decompressingData+5A↓p 
  3. nstream         = dword ptr  8 
  4. output          = dword ptr  0Ch 
  5. zero            = dword ptr  10h 
  6. zero2           = dword ptr  14h 
  7. zero3           = dword ptr  18h 
  8.                  push    ebp 
  9.                  mov     ebp, esp 
  10.                  push    ebx 
  11.                  push    esi 
  12.                  push    edi 
  13.                  mov     esi, ecx 
  14.                  push    16512           ; unsigned int 
  15.                  call    Malloc 
  16.                  pop     ecx 
  17.                  mov     edi, eax 
  18.                  mov     ecx, 1020h 
  19.                  xor     eax, eax 
  20.                  mov     [esi], edi 
  21.                  xor     ebx, ebx 
  22.                  rep stosd 

為了簡(jiǎn)潔起見(jiàn),我們沒(méi)有展示該函數(shù)的全部代碼。需要注意的地方是:

該函數(shù)調(diào)用約定(Calling Convention)是__thiscall(說(shuō)明是C++);

該函數(shù)使用了5個(gè)參數(shù);

該函數(shù)從惡意軟件中調(diào)用一次(通過(guò)在IDA Pro中標(biāo)識(shí)的交叉引用數(shù)量來(lái)看到的)。

下面是該函數(shù)調(diào)用部分的代碼:

 
 
 
 
  1. xor     eax, eax 
  2. mov     ecx, [ebp+v6] 
  3. push    eax 
  4. push    eax 
  5. push    eax 
  6. movzx   eax, word ptr [ebx+24] 
  7. push    dword ptr [edx] ; output 
  8. lea     eax, [eax+ebx+26] 
  9. push    eax 
  10. call    decompress 

對(duì)調(diào)用解壓縮函數(shù)的分析如下:

會(huì)清除EAX寄存器,因此EAX為0;

指向?qū)ο蟮闹羔槾鎯?chǔ)在ECX(Thiscall)中;

EAX的三次push說(shuō)明了解壓縮例程的第3、4、5個(gè)參數(shù)始終為0;

第2個(gè)參數(shù)是指向目標(biāo)緩沖區(qū)的指針;

第1個(gè)參數(shù)是指向壓縮數(shù)據(jù)的指針。

而壓縮的數(shù)據(jù)如下:

 
 
 
 
  1. 08 00 A5 04 01 12 03 06  8C 18 36 7A 04 21 62 25   ..¥.....?.6z.!b% 
  2. 08 94 24 33 64 B8 20 C3  86 4D 03 05 02 09 1A 8C   .”$3d? ??M.....? 
  3. 71 A3 C7 91 32 74 AA CC  29 23 C7 49 98 36 65 82   q£?‘2taì)#?I?6e? 
  4. 5C CC 58 F0 20 8E 1E 52  CA 9C 19 C2 E6 CD C8 25   ìXe ?.Rê?.??íè% 
  5. 65 F2 AC 1C D8 32 46 0E  98 32 9F C0 29 E3 06 67   eò?.?2F.?2?à)?.g 
  6. 9E 22 78 54 62 E4 69 50  06 0C A0 33 E5 94 09 43   ?"xTb?iP.. 3?”.C 
  7. A7 8C 51 A4 4A 59 36 8D  01 75 0A 48 2B 61 D8 D4   §?Q¤JY6..u.H+a?? 
  8. 29 83 75 A7 46 18 32 64  40 25 52 86 0D C8 32 60   )?u§F.2d@%R?.è2` 
  9. C5 A6 34 DB 52 C6 0C 85  64 D4 D4 99 43 87 CA 9B   ?|4?R?.…d???C?ê? 
  10. 35 44 A1 C8 49 63 27 8D  DB 33 65 E6 D0 6D 4A A3   5D?èIc'.?3e?DmJ£ 
  11. 07 93 37 7F EB C0 11 4C  D8 B0 4C B8 61 C7 66 65   .“7.?à.L?°L?a?fe 
  12. 8A B6 46 0F A1 81 E5 BC  19 93 78 8E 5F C0 6E 16   ??F.?.??.“x?_àn. 
  13. A3 4D 38 85 4E 18 39 74  BC CA 29 4C 7A F3 59 19   £M8…N.9t?ê)LzóY. 

為了簡(jiǎn)潔起見(jiàn),在這里也不展示壓縮數(shù)據(jù)的全部?jī)?nèi)容,其完整大小是45115字節(jié)。

第1-7字節(jié)(08 00 A5 04 01 12 03)是壓縮例程的一個(gè)“魔法值”,我們?cè)谒蠷eaver變種中都發(fā)現(xiàn)了這個(gè)頭部。

在掌握了上述這些之后,我們就可以將注意力集中在解壓縮例程的工作機(jī)制上。

請(qǐng)大家注意:在這里,我們可以監(jiān)視調(diào)用或轉(zhuǎn)儲(chǔ)目標(biāo)緩沖區(qū)內(nèi)容后所得到的返回結(jié)果,其中會(huì)包含解壓縮的數(shù)據(jù),但是如果選擇這種方法,就需要我們?cè)谡{(diào)試器中運(yùn)行代碼。而我們的前提是不運(yùn)行惡意軟件樣本。

創(chuàng)建DLL

在掌握了一定信息后,我們開始創(chuàng)建一個(gè)DLL。我們可以使用Visual Studio,或者任何能處理編譯程序集(NASM/MASM)的編譯器。創(chuàng)建一個(gè)新的空DLL項(xiàng)目,并添加一個(gè)新的頭文件。

舉例來(lái)說(shuō),我創(chuàng)建了一個(gè)頭文件,如下所示:

 
 
 
 
  1. #pragma once 
  2. #ifndef _DEFINE_LZWDecompress_DLL 
  3. #define _DEFINE_LZWDecompress_DLL 
  4.   
  5. #ifdef __cplusplus   
  6. extern "C" { 
  7. #endif   
  8. __declspec(dllexport) BOOL  Decompress(char *src, char *dst); 
  9. #ifdef __cplusplus   
  10. #endif  
  11. BOOL Decompress(char *src, char *dst); 
  12. #endif 

上述代碼會(huì)創(chuàng)建一個(gè)名為“Decompress”的文件,并且能接收兩個(gè)參數(shù)。我們?cè)谶@里之所以僅使用了兩個(gè)參數(shù),原因在于其他三個(gè)參數(shù)始終為0,所以無(wú)需定義他們。該函數(shù)的返回類型為布爾型。

針對(duì)源文件(.cpp或.c),需要從IDA Pro或其他調(diào)試器中獲得匯編代碼,再將其添加到源文件中。以下是我修復(fù)后的源文件代碼:

 
 
 
 
  1. #include  
  2. #include  
  3. #include "TestDLL.h" 
  4. BOOL Decompress(char *src, char *dst) 
  5.     //Use calloc vs malloc.  Temp buffer is for the dictionary  
  6.     void *pTmpbuff; 
  7.     pTmpbuff = (int*) calloc(0x4080u, sizeof(unsigned int)); 
  8.     if (src && dst) 
  9.     { 
  10.         __asm 
  11.         { 
  12.             xor ebx, ebx;  //Need to clear ebx register  
  13.             SUB ESP, 0x40; //Need to subtract stack, so we don’t overwrite some Ctypes return data 
  14.             MOV ESI, ESP; 
  15.             PUSH EAX; 
  16.             POP EDI;        //Our Temp Buffer 
  17.             PUSH[EBP + 8];      //Source Buffer 
  18.             POP EAX; 
  19.             PUSH[EBP + 0xC];  //Destination Buffer 
  20.             POP EDX; 
  21.             LEA ECX, DWORD PTR DS : [EAX + 1]; //Where we start.  Get the 1st DWORD of the compressed data appears to be magic value 
  22.             MOV DWORD PTR DS : [ESI], EDI;//Temp buffer address 
  23.             MOV DWORD PTR DS : [ESI + 0x1C], EDX;//Destination address 
  24.             MOV DWORD PTR DS : [ESI + 0x18], ECX;//Compressed Data 
  25.             MOV BYTE PTR DS : [ESI + 0x20], BL;//0 
  26.             MOV CL, BYTE PTR DS : [EAX];//08 
  27.             PUSH 1; 
  28.             POP EAX; 
  29.             MOV BYTE PTR DS : [ESI + 0x22], CL; 
  30.             SHL EAX, CL; 
  31.             MOV DWORD PTR DS : [ESI + 0x30], EBX; 
  32.             MOV WORD PTR DS : [ESI + 8], AX; 
  33.             INC EAX; 
  34.             MOV WORD PTR DS : [ESI + 0xA], AX; 
  35.             MOV EAX, DWORD PTR SS : [EBP + 0x10]; 
  36.             MOV DWORD PTR DS : [ESI + 0x2C], EAX; 
  37.             LEA EAX, DWORD PTR DS : [EAX * 8 + 0x1F]; 
  38.             SHR EAX, 5; 
  39.             SHL EAX, 2; 
  40.             CMP BYTE PTR SS : [EBP + 0x18], BL; 
  41.             MOV DWORD PTR DS : [ESI + 0x38], EAX; 
  42.             SETE AL; 
  43.             DEC EAX; 
  44.             AND AL, 1; 
  45.             ADD EAX, 0x0FF; 
  46.             CMP AL, BL; 
  47.             MOV BYTE PTR DS : [ESI + 0xC], AL; 
  48.             JNZ SHORT check3; 
  49.             MOV EAX, DWORD PTR SS : [EBP + 0x14]; 
  50.             MOV DWORD PTR DS : [ESI + 0x14], EDX; 
  51.             MOV DWORD PTR DS : [ESI + 0x28], EAX; 
  52.             MOV DWORD PTR DS : [ESI + 0x34], EBX; 
  53. check3: 
  54.             MOV ECX, ESI; 
  55.             CALL check4; 
  56. check26: 
  57.             MOV ECX, ESI; 
  58.             CALL check10; 
  59.             MOV EDI, EAX; 
  60.             CMP DI, WORD PTR DS : [ESI + 0xA]; 
  61.             JE Finished; 
  62.             CMP DI, WORD PTR DS : [ESI + 8]; 
  63.             JNZ SHORT check22; 
  64.             MOV ECX, ESI; 
  65.             CALL check4; 
  66. check24: 
  67.             MOV ECX, ESI; 
  68.             CALL check10; 
  69.             MOV EDI, EAX 
  70.             CMP DI, WORD PTR DS : [ESI + 8] 
  71.             JNZ SHORT check23; 
  72.             JMP SHORT check24; 
  73. check22: 
  74.             CMP DI, WORD PTR DS : [ESI + 0X24] 
  75.             JNB SHORT check25; 
  76.             PUSH EDI 
  77.             JMP SHORT check27; 
  78. check25: 
  79.             PUSH EBX; 
  80. check27: 
  81.             MOV ECX, ESI; 
  82.             CALL check28; 
  83.             MOVZX AX, AL; 
  84.             PUSH EAX; 
  85.             PUSH EBX; 
  86.             MOV ECX, ESI; 
  87.             CALL check31; 
  88.             PUSH EDI; 
  89.             MOV ECX, ESI; 
  90.             CALL check35; 
  91.             MOV EBX, EDI; 
  92.             JMP SHORT check26; 
  93. check10: 
  94.             MOVZX EAX, BYTE PTR DS : [ECX + 0x20]; 
  95.             PUSH EBX; 
  96.             PUSH ESI; 
  97.             PUSH EDI; 
  98.             MOVZX EDI, BYTE PTR DS : [ECX + 0x23]; 
  99.             ADD EAX, EDI; 
  100.             CMP EAX, 8; 
  101.             JA SHORT Check6; 
  102.             MOV EDX, DWORD PTR DS : [ECX + 0x18]; 
  103.             MOVZX ESI, BYTE PTR DS : [EDX]; 
  104.             JMP SHORT Check8; 
  105.         Check6: 
  106.             MOV EDX, DWORD PTR DS : [ECX + 0x18]; 
  107.             CMP EAX, 0x10; 
  108.             JA SHORT Check7; 
  109.             MOVZX ESI, WORD PTR DS : [EDX]; 
  110.             JMP SHORT Check8; 
  111.         Check7: 
  112.             MOVZX ESI, BYTE PTR DS : [EDX + 2]; 
  113.             MOVZX EBX, WORD PTR DS : [EDX]; 
  114.             SHL ESI, 0X10; 
  115.             OR ESI, EBX; 
  116.         Check8: 
  117.             MOV EBX, EAX; 
  118.             PUSH 0x20; 
  119.             SHR EBX, 3; 
  120.             ADD EBX, EDX; 
  121.             MOV DL, AL; 
  122.             AND DL, 7; 
  123.             MOV DWORD PTR DS : [ECX + 0X18], EBX; 
  124.             MOV BYTE PTR DS : [ECX + 0X20], DL; 
  125.             POP ECX; 
  126.             SUB ECX, EAX; 
  127.             MOV EAX, ESI; 
  128.             PUSH 0x20; 
  129.             SHL EAX, CL; 
  130.             POP ECX; 
  131.             SUB ECX, EDI; 
  132.             POP EDI; 
  133.             POP ESI; 
  134.             POP EBX; 
  135.             SHR EAX, CL; 
  136.             RETN; 
  137.         check28: 
  138.             MOV EAX, DWORD PTR DS : [ECX]; 
  139.             MOV EDX, DWORD PTR SS : [ESP + 4]; 
  140.         check30: 
  141.             MOVZX ECX, DX; 
  142.             MOV CX, WORD PTR DS : [EAX + ECX * 4]; 
  143.             CMP CX, 0x0FFFF; 
  144.             JE SHORT check29; 
  145.             MOV EDX, ECX; 
  146.             JMP SHORT check30; 
  147.         check29: 
  148.             MOVZX ECX, DX; 
  149.             MOV AL, BYTE PTR DS : [EAX + ECX * 4 + 2]; 
  150.             RETN 4; 
  151.         check31: 
  152.             MOVZX EDX, WORD PTR DS : [ECX + 0x24]; 
  153.             LEA EAX, DWORD PTR DS : [ECX + 0x24]; 
  154.             PUSH ESI; 
  155.             MOV ESI, DWORD PTR DS : [ECX]; 
  156.             PUSH EDI; 
  157.             MOV DI, WORD PTR SS : [ESP + 0xC]; 
  158.             MOV WORD PTR DS : [ESI + EDX * 4], DI; 
  159.             MOV ESI, DWORD PTR DS : [ECX]; 
  160.             MOVZX EDX, WORD PTR DS : [EAX]; 
  161.             MOV DI, WORD PTR SS : [ESP + 0x10]; 
  162.             MOV WORD PTR DS : [ESI + EDX * 4 + 2], DI; 
  163.             INC WORD PTR DS : [EAX]; 
  164.             MOV AX, WORD PTR DS : [EAX]; 
  165.             POP EDI; 
  166.             CMP AX, 8; 
  167.             POP ESI; 
  168.             JE SHORT check32; 
  169.             CMP AX, 0x10; 
  170.             JE SHORT check32; 
  171.             CMP AX, 0x20; 
  172.             JE SHORT check32; 
  173.             CMP AX, 0x40; 
  174.             JE SHORT check32; 
  175.             CMP AX, 0x80; 
  176.             JE SHORT check32; 
  177.             CMP AX, 0x100; 
  178.             JE SHORT check32; 
  179.             CMP AX, 0x200; 
  180.             JE SHORT check32; 
  181.             CMP AX, 0x400; 
  182.             JE SHORT check32; 
  183.             CMP AX, 0x800; 
  184.             JNZ SHORT check33; 
  185.         check32: 
  186.             INC BYTE PTR DS : [ECX + 0x23]; 
  187.         check33: 
  188.             RETN 8; 
  189.         check4: 
  190.             MOV EDX, ECX; 
  191.             PUSH EDI; 
  192.             MOV ECX, 0x1000; 
  193.             OR EAX, 0xFFFFFFFF; 
  194.             MOV EDI, DWORD PTR DS : [EDX] 
  195.             REP STOS DWORD PTR ES : [EDI]; 
  196.             XOR EAX, EAX; 
  197.             POP EDI; 
  198.             CMP WORD PTR DS : [EDX + 8], AX; 
  199.             JBE SHORT check1; 
  200.             PUSH ESI; 
  201.             MOV ESI, DWORD PTR DS : [EDX]; 
  202.         check2: 
  203.             MOVZX ECX, AX; 
  204.             MOV WORD PTR DS : [ESI + ECX * 4 + 2], AX; 
  205.             INC EAX; 
  206.             CMP AX, WORD PTR DS : [EDX + 8]; 
  207.             JB SHORT check2; 
  208.             POP ESI; 
  209.         check1: 
  210.             MOV AX, WORD PTR DS : [EDX + 0xA]; 
  211.             INC AX; 
  212.             MOV WORD PTR DS : [EDX + 0x24], AX; 
  213.             MOV AL, BYTE PTR DS : [EDX + 0x22]; 
  214.             INC AL; 
  215.             MOV BYTE PTR DS : [EDX + 0x23], AL; 
  216.             RETN; 
  217.         check23: 
  218.             PUSH EDI; 
  219.             MOV ECX, ESI; 
  220.             CALL check35; 
  221.             MOV EBX, EDI; 
  222.             JMP SHORT check26; 
  223.         check35: 
  224.             PUSH EBP; 
  225.             MOV EBP, ESP; 
  226.             PUSH ESI; 
  227.             PUSH EDI; 
  228.             MOV ESI, ECX; 
  229.             NOP; 
  230.             MOV AX, WORD PTR SS : [EBP + 8]; 
  231.             CMP AX, WORD PTR DS : [ESI + 8]; 
  232.             JNB SHORT check36; 
  233.             NOP; 
  234.             MOV ECX, DWORD PTR DS : [ESI]; 
  235.             MOV EDX, DWORD PTR DS : [ESI + 0x1C]; 
  236.             MOV EDI, DWORD PTR DS : [ESI + 0x30]; 
  237.             MOVZX EAX, AX; 
  238.             MOV AL, BYTE PTR DS : [ECX + EAX * 4 + 2]; 
  239.             MOV BYTE PTR DS : [EDX + EDI], AL; 
  240.             INC DWORD PTR DS : [ESI + 0x30]; 
  241.             NOP; 
  242.             MOV EAX, DWORD PTR DS : [ESI + 0x30]; 
  243.             CMP EAX, DWORD PTR DS : [ESI + 0x2C]; 
  244.             JNZ SHORT FuncRetn; 
  245.             MOV ECX, ESI; 
  246.             CALL check37; 
  247.             NOP; 
  248.             JMP SHORT FuncRetn; 
  249. check36: 
  250.             MOVZX EDI, AX; 
  251.             MOV EAX, DWORD PTR DS : [ESI]; 
  252.             MOV ECX, ESI; 
  253.             SHL EDI, 2; 
  254.             MOV AX, WORD PTR DS : [EDI + EAX]; 
  255.             PUSH EAX; 
  256.             CALL check35; 
  257.             NOP; 
  258.             MOV EAX, DWORD PTR DS : [ESI]; 
  259.             MOV ECX, ESI; 
  260.             MOV AX, WORD PTR DS : [EDI + EAX + 2]; 
  261.             PUSH EAX; 
  262.             CALL check35; 
  263.             NOP; 
  264.             NOP; 
  265.             POP EDI; 
  266.             POP ESI; 
  267.             POP EBP; 
  268.             RETN 4; 
  269.         check38: 
  270.             MOVZX EDX, AL; 
  271.             MOVZX EDX, BYTE PTR DS : [EDX + ECX + 0xD]; 
  272.             ADD DWORD PTR DS : [ECX + 0x34], EDX; 
  273.             MOV EDX, DWORD PTR DS : [ECX + 0x34]; 
  274.             CMP EDX, DWORD PTR DS : [ECX + 0x28]; 
  275.             JB SHORT FuncRetrn2; 
  276.             INC AL; 
  277.             CMP AL, 4; 
  278.             MOV BYTE PTR DS : [ECX + 0xC], AL; 
  279.             JNB SHORT Frtn; 
  280.             MOVZX EAX, AL; 
  281.             MOVZX EAX, BYTE PTR DS : [EAX + ECX + 0xD]; 
  282.             SHR EAX, 1; 
  283.             MOV DWORD PTR DS : [ECX + 0x34], EAX; 
  284.             FuncRetrn2: 
  285.             MOV EAX, DWORD PTR DS : [ECX + 0x38]; 
  286.             MOV EDX, DWORD PTR DS : [ECX + 0x14]; 
  287.             IMUL EAX, DWORD PTR DS : [ECX + 0x34]; 
  288.             SUB EDX, EAX; 
  289.             MOV DWORD PTR DS : [ECX + 0x1C], EDX; 
  290.             Frtn: 
  291.             RETN; 
  292. FuncRetn: 
  293.             NOP; 
  294.             POP EDI; 
  295.             POP ESI; 
  296.             POP EBP; 
  297.             RETN 4; 
  298.         check37: 
  299.             MOV AL, BYTE PTR DS : [ECX + 0xC]; 
  300.             AND DWORD PTR DS : [ECX + 0x30], 0; 
  301.             CMP AL, 0x0FF; 
  302.             JNZ SHORT check38; 
  303.             MOV EAX, DWORD PTR DS : [ECX + 0x38]; 
  304.             SUB DWORD PTR DS : [ECX + 0x1C], EAX; 
  305.             RETN; 
  306.         Finished: 
  307.             MOV ESP,EBP; 
  308.             POP EBP; 
  309.             //Debug VS Release build have different stack sizes.  The following is needed for the return parameters and CTYPES 
  310. #ifdef _DEBUG 
  311.             ADD ESI, 0x120; 
  312. #else 
  313.             ADD ESI, 0x58; //Need for Pythnon CTypes return parameters! 
  314. #endif 
  315.             RETN; 
  316.         } 
  317.     } 
  318.     return TRUE; 

通過(guò)IDA Pro或者例如Immunity Debugger這樣的反匯編程序來(lái)獲取匯編代碼并不難,但是在獲得之后,還需要我們進(jìn)行一些處理。特別需要注意的一個(gè)地方就是在代碼塊中進(jìn)行的函數(shù)調(diào)用。在匯編中,每一次調(diào)用過(guò)程都需要一個(gè)名稱(標(biāo)簽),并且所有的代碼需要按照調(diào)用順序正確地排列,否則將產(chǎn)生意外的結(jié)果,或者是直接崩潰。因此,我們?cè)趶?fù)制每個(gè)函數(shù)的匯編代碼時(shí)都需要非常謹(jǐn)慎。在剛剛的例子中,為了方便快速,我直接使用了“check”來(lái)表示函數(shù)名稱或者跳轉(zhuǎn)的位置。

由于LZW使用索引將數(shù)據(jù)編碼到字典中,解壓例程所做的第一件事,就是分配內(nèi)存中的16512字節(jié)(0x4080)的緩沖區(qū)來(lái)創(chuàng)建字典。在匯編中,它使用C++ API malloc分配緩沖區(qū),并將緩沖區(qū)設(shè)置為NULL(這是malloc的工作方式)。有一種更簡(jiǎn)單有效的方法,是使用calloc函數(shù),在減少指令數(shù)量的前提下實(shí)現(xiàn)緩沖區(qū)的分配。

我們首先在C++中進(jìn)行編碼,然后再Visual Studio中使用__asm關(guān)鍵字內(nèi)嵌匯編語(yǔ)言。在__asm內(nèi)的代碼塊就是我們放置匯編指令并進(jìn)行必要調(diào)整的位置:

將EBX設(shè)置為0;

從棧中減去64字節(jié)(0x40),以防止我們覆蓋任何棧的數(shù)據(jù);

將棧指針保存到ESI中;

EDI指向我們通過(guò)calloc創(chuàng)建的字典緩沖區(qū);

EAX指向我們的源數(shù)據(jù);

EDX指向我們的目標(biāo)緩沖區(qū)。

為了滿足解壓縮算法的要求,我們手工添加了下面的9行代碼,其余代碼直接從Immunity Debugger中復(fù)制即可:

 
 
 
 
  1. xor ebx, ebx;          //Need to clear ebx register  
  2. SUB ESP, 0x40;    //Need to subtract stack, so we don’t overwrite some Ctypes return data 
  3. MOV ESI, ESP; 
  4. PUSH EAX; 
  5. POP EDI;    //Our Temp Buffer 
  6. PUSH[EBP + 8];  //Source Buffer 
  7. POP EAX; 
  8. PUSH[EBP + 0xC];  //Destination Buffer 
  9. POP EDX; 

此時(shí),我們需要做的就是更新匯編調(diào)用,跳轉(zhuǎn)到有意義的名稱,并按正確的順序來(lái)排列它們?,F(xiàn)在代碼應(yīng)該可以編譯并運(yùn)行了。但當(dāng)例程結(jié)束后,我們必須手動(dòng)恢復(fù)棧,從而讓Python ctypes返回到正確的調(diào)用方。我們添加了以下代碼:

 
 
 
 
  1. Finished: 
  2. MOV ESP,EBP; 
  3. POP EBP; 
  4. //Debug VS Release build have different stack sizes.  The following is needed for the return parameters and CTYPES 
  5. #ifdef _DEBUG 
  6. ADD ESI, 0x120; 
  7. #else 
  8. ADD ESI, 0x58; //Need for CTypes return parameters!!!! 
  9. #endif 
  10. RETN; 

在這里,我們嘗試恢復(fù)堆棧指針寄存器(SP)和基址指針寄存器(BP),并將0x120或0x58添加到ESI,具體要取決于VS的版本是測(cè)試版還是正式版。

調(diào)用DLL

至此,我們就有了一個(gè)DLL,可以開始調(diào)用它,并通過(guò)Python和ctypes來(lái)傳遞它的數(shù)據(jù)。下面這個(gè)Python腳本的作用就是利用這個(gè)DLL,來(lái)解密Reaver的數(shù)據(jù):

 
 
 
 
  1. #------------------------------------------------------------------------------- 
  2. # Name:        LzwDecompression 
  3. # Purpose: 
  4. # Author:      Mike Harbison Unit 42 
  5. # Created:     11/11/2017 
  6. #------------------------------------------------------------------------------- 網(wǎng)站名稱:一種快速提取惡意軟件解密邏輯代碼的方法
    標(biāo)題路徑:http://m.5511xx.com/article/coeecoe.html