jomin 发表于 2009-9-30 08:26

Enigma主程序脱壳破解系列之一 -----DLL解捆绑[全面开放]

Enigma主程序脱壳破解系列之一 -----DLL解捆绑[全面开放]
之前发脱壳版的时候,我说过Enigma这个壳的核心是一个dll文件。所有的解码和处理过程都是在这个dll里面完成的。本片文章就来讨论一下如何把捆绑在里面dll文件提取出来。
对于所有用Enigma保护的程序来说,捆绑DLL_Loader.dll这个文件是必须的。而对于Enigma 1.65的主程序来说,这里面还另外捆绑了两个dll,这两个dll也是Enigma运行的时候必须的。

开始讨论。

PS:对于想学脱壳的初学者来说,下面的代码一定要仔细看,弄明白。因为这段代码里面几乎包含了一个壳的所有功能。如果你能完全弄懂下面这段代码。相信你的水平很上升一个新台阶的。

OD载入主程序。
x
00000: 0061A767 >55               push ebp<------停在这里
00001: 0061A768    8BEC             mov ebp,esp
00002: 0061A76A    83C4 F0          add esp,-10
00003: 0061A76D    B8 00104000      mov eax,Enigma.00401000
00004: 0061A772    E8 01000000      call Enigma.0061A778<----近call F7
00005: 0061A777    9A 83C4108B E55D call far 5DE5:8B10C483
00006: 0061A77E- E9 3D6F4400      jmp Enigma.00A616C0
00007:
00008:
00009: 0061A778    83C4 10          add esp,10
00010: 0061A77B    8BE5             mov esp,ebp
00011: 0061A77D    5D               pop ebp
00012: 0061A77E- E9 3D6F4400      jmp Enigma.00A616C0-----跳到下面去了
00013:
00014: 00A616C0    60               pushad
00015: 00A616C1    E8 00000000      call Enigma.00A616C6
00016: 00A616C6    5D               pop ebp-----------------代码自定位,在dll中才有效果
00017: 00A616C7    81ED 06000000    sub ebp,6
00018: 00A616CD    81ED C0166600    sub ebp,Enigma.006616C0-
00019: 00A616D3    E9 4C000000      jmp Enigma.00A61724
00020:
00021: 解码
00022: 00A6172D    B8 C0166600      mov eax,Enigma.006616C0
00023: 00A61732    03C5             add eax,ebp
00024: 00A61734    81C0 93000000    add eax,93
00025: 00A6173A    B9 0C060000      mov ecx,60C
00026: 00A6173F    BA F24D8F45      mov edx,458F4DF2
00027: 00A61744    3010             xor byte ptr ds:,dl
00028: 00A61746    40               inc eax
00029: 00A61747    49               dec ecx
00030: 00A61748^ 0F85 F6FFFFFF    jnz Enigma.00A61744
00031: 00A6174E    E9 04000000      jmp Enigma.00A61757
00032:
00033: 00A61757    6A 40            push 40
00034: 00A61759    68 00100000      push 1000
00035: 00A6175E    68 00EE0B00      push 0BEE00
00036: 00A61763    81F0 4DE6FA2A    xor eax,2AFAE64D
00037: 00A61769    81F0 4DE6FA2A    xor eax,2AFAE64D
00038: 00A6176F    33C0             xor eax,eax
00039: 00A61771    50               push eax
00040: 00A61772    FF95 80015F00    call dword ptr ss:          ; 申请一段内存,用来解压dll的代码
00041: 00A61778    50               push eax
00042: 00A61779    8BCD             mov ecx,ebp
00043: 00A6177B    8B89 3C000000    mov ecx,dword ptr ds:
00044: 00A61781    81C1 F8000000    add ecx,0F8
00045: 00A61787    03CD             add ecx,ebp
00046: 00A61789    B8 0A000000      mov eax,0A
00047: 00A6178E    BA 28000000      mov edx,28
00048: 00A61793    F7E2             mul edx
00049: 00A61795    03C8             add ecx,eax
00050: 00A61797    8B81 0C000000    mov eax,dword ptr ds:
00051: 00A6179D    03C5             add eax,ebp
00052: 00A6179F    50               push eax
00053: 00A617A0    68 01DA0400      push 4DA01
00054: 00A617A5    68 BE3C6100      push Enigma.00613CBE
00055: 00A617AA    012C24         add dword ptr ss:,ebp
00056: 00A617AD    68 00000000      push 0
00057: 00A617B2    E8 05000000      call Enigma.00A617BC                  ; 异或解密压缩后的dll数据
00058: 00A617B7    E9 28000000      jmp Enigma.00A617E4
00059: 00A617BC    55               push ebp
00060: 00A617BD    8BEC             mov ebp,esp
00061: 00A617BF    8B85 08000000    mov eax,dword ptr ss:
00062: 00A617C5    8B95 0C000000    mov edx,dword ptr ss:
00063: 00A617CB    8B8D 10000000    mov ecx,dword ptr ss:
00064: 00A617D1    C1E9 02          shr ecx,2
00065: 00A617D4    3102             xor dword ptr ds:,eax
00066: 00A617D6    83C2 04          add edx,4
00067: 00A617D9    49               dec ecx
00068: 00A617DA^ 0F85 F4FFFFFF    jnz Enigma.00A617D4
00069: 00A617E0    5D               pop ebp
00070: 00A617E1    C2 0C00          retn 0C
00071: 00A617E4    8B8C24 04000000mov ecx,dword ptr ss:
00072: 00A617EB    68 01DA0400      push 4DA01
00073: 00A617F0    68 BE3C6100      push Enigma.00613CBE
00074: 00A617F5    012C24         add dword ptr ss:,ebp
00075: 00A617F8    51               push ecx
00076: 00A617F9    E8 05000000      call Enigma.00A61803
00077: 00A617FE    E9 27020000      jmp Enigma.00A61A2A
00078: 00A61803    55               push ebp
00079: 00A61804    54               push esp
00080: 00A61805    5D               pop ebp
00081: 00A61806    FF75 0C          push dword ptr ss:
00082: 00A61809    FF75 08          push dword ptr ss:
00083: 00A6180C    E8 66000000      call Enigma.00A61877                  ; 调用APlib的解压函数解码dll代码,压缩后的数据放在A13CBE里,解压的代码放在申请的内存中-----1
00084: 00A61811    8BBD 08000000    mov edi,dword ptr ss:            ; 这里是用来修正由于磁盘文件和内存镜像之前的差异.
00085: 00A61817    33C9             xor ecx,ecx
00086: 00A61819    33D2             xor edx,edx
00087: 00A6181B    83E8 05          sub eax,5
00088: 00A6181E    48               dec eax
00089: 00A6181F    0F84 4E000000    je Enigma.00A61873
00090: 00A61825    0F88 48000000    js Enigma.00A61873
00091: 00A6182B    66:8B1C39      mov bx,word ptr ds:
00092: 00A6182F    80FB E8          cmp bl,0E8
00093: 00A61832    0F84 1A000000    je Enigma.00A61852
00094: 00A61838    80FB E9          cmp bl,0E9
00095: 00A6183B    0F84 11000000    je Enigma.00A61852
00096: 00A61841    66:81FB FF25   cmp bx,25FF
00097: 00A61846    0F84 15000000    je Enigma.00A61861
00098: 00A6184C    41               inc ecx
00099: 00A6184D^ E9 CCFFFFFF      jmp Enigma.00A6181E
00100: 00A61852    294C39 01      sub dword ptr ds:,ecx
00101: 00A61856    83C1 05          add ecx,5
00102: 00A61859    83E8 04          sub eax,4
00103: 00A6185C^ E9 BDFFFFFF      jmp Enigma.00A6181E
00104: 00A61861    295439 02      sub dword ptr ds:,edx
00105: 00A61865    83C1 06          add ecx,6
00106: 00A61868    83EA 04          sub edx,4
00107: 00A6186B    83E8 05          sub eax,5
00108: 00A6186E^ E9 ABFFFFFF      jmp Enigma.00A6181E
00109: 00A61873    5D               pop ebp
00110: 00A61874    C2 0C00          retn 0C
00111:
00112:
00113: 00A61A2A    5F               pop edi
00114: 00A61A2B    5E               pop esi
00115: 00A61A2C    E9 04000000      jmp Enigma.00A61A35
00116: 00A61A31    0D 60169AB8      or eax,B89A1660
00117: 00A61A36    C016 66          rcl byte ptr ds:,66
00118: 00A61A39    0003             add byte ptr ds:,al
00119: 00A61A3B    C581 C09B0300    lds eax,fword ptr ds:
00120: 00A61A41    00B9 04030000    add byte ptr ds:,bh
00121: 00A61A47    BA 6315C010      mov edx,10C01563
00122: 00A61A4C    3010             xor byte ptr ds:,dl                ; 继续异或解码
00123: 00A61A4E    40               inc eax
00124: 00A61A4F    49               dec ecx
00125: 00A61A50^ 0F85 F6FFFFFF    jnz Enigma.00A61A4C
00126: 00A61A56    E9 04000000      jmp Enigma.00A61A5F
00127: 00A61A5B    46               inc esi
00128: 00A61A5C    1867 FC          sbb byte ptr ds:,ah
00129: 00A61A5F    56               push esi
00130: 00A61A60    57               push edi
00131: 00A61A61    8B8E 54010000    mov ecx,dword ptr ds:
00132: 00A61A67    C1E9 02          shr ecx,2
00133: 00A61A6A    F2:A5            repne movs dword ptr es:,dword ptr>; 复制DLL的PE头到A630000,就是加壳文件的最后一个区段
00134: 00A61A6C    5F               pop edi
00135: 00A61A6D    5E               pop esi
00136: 00A61A6E    8B9E 3C000000    mov ebx,dword ptr ds:
00137: 00A61A74    53               push ebx
00138: 00A61A75    0FBF5C33 06      movsx ebx,word ptr ds:
00139: 00A61A7A    5A               pop edx
00140: 00A61A7B    81C2 F8000000    add edx,0F8
00141: 00A61A81    03D6             add edx,esi
00142: 00A61A83    81FB 00000000    cmp ebx,0                               ; 比较是否复制完
00143: 00A61A89    0F84 1B000000    je Enigma.00A61AAA
00144: 00A61A8F    56               push esi
00145: 00A61A90    57               push edi
00146: 00A61A91    8B4A 10          mov ecx,dword ptr ds:
00147: 00A61A94    037A 0C          add edi,dword ptr ds:
00148: 00A61A97    0372 14          add esi,dword ptr ds:
00149: 00A61A9A    F2:A4            repne movs byte ptr es:,byte ptr d>; 按区段复制DLL的到A63000去----------------2
00150: 00A61A9C    5F               pop edi
00151: 00A61A9D    5E               pop esi
00152: 00A61A9E    81C2 28000000    add edx,28
00153: 00A61AA4    4B               dec ebx
00154: 00A61AA5^ E9 D9FFFFFF      jmp Enigma.00A61A83
00155: 00A61AAA    68 00400000      push 4000
00156: 00A61AAF    68 00EE0B00      push 0BEE00
00157: 00A61AB4    56               push esi
00158: 00A61AB5    FF95 84015F00    call dword ptr ss:          ; 释放申请的内存
00159: 00A61ABB    87FE             xchg esi,edi
00160: 00A61ABD    87F7             xchg edi,esi
00161: 00A61ABF    8B77 3C          mov esi,dword ptr ds:
00162: 00A61AC2    87F7             xchg edi,esi
00163: 00A61AC4    8BBC37 A0000000mov edi,dword ptr ds:       ; 获取重定位表的位置
00164: 00A61ACB    03FE             add edi,esi
00165: 00A61ACD    56               push esi
00166: 00A61ACE    5B               pop ebx
00167: 00A61ACF    81EB 00004000    sub ebx,Enigma.00400000               ; 下面的代码用来把dll代码重定位到A63000
00168: 00A61AD5    87FA             xchg edx,edi
00169: 00A61AD7    8B7A 00          mov edi,dword ptr ds:
00170: 00A61ADA    87FA             xchg edx,edi
00171: 00A61ADC    87F9             xchg ecx,edi
00172: 00A61ADE    8B79 04          mov edi,dword ptr ds:
00173: 00A61AE1    87F9             xchg ecx,edi
00174: 00A61AE3    81FA 00000000    cmp edx,0
00175: 00A61AE9    0F84 46000000    je Enigma.00A61B35
00176: 00A61AEF    03D6             add edx,esi
00177: 00A61AF1    81C7 08000000    add edi,8
00178: 00A61AF7    81E9 08000000    sub ecx,8
00179: 00A61AFD    81F9 00000000    cmp ecx,0
00180: 00A61B03^ 0F84 CCFFFFFF    je Enigma.00A61AD5
00181: 00A61B09    66:8B07          mov ax,word ptr ds:
00182: 00A61B0C    C1E8 0C          shr eax,0C
00183: 00A61B0F    83E0 0F          and eax,0F
00184: 00A61B12    81F8 03000000    cmp eax,3
00185: 00A61B18    0F85 0D000000    jnz Enigma.00A61B2B
00186: 00A61B1E    66:8B07          mov ax,word ptr ds:
00187: 00A61B21    81E0 FF0F0000    and eax,0FFF
00188: 00A61B27    03C2             add eax,edx
00189: 00A61B29    0118             add dword ptr ds:,ebx            ; 修改指令,重定位-------------------3
00190: 00A61B2B    49               dec ecx
00191: 00A61B2C    49               dec ecx
00192: 00A61B2D    83C7 02          add edi,2
00193: 00A61B30^ E9 C8FFFFFF      jmp Enigma.00A61AFD
00194: 00A61B35    E9 04000000      jmp Enigma.00A61B3E
00195: 00A61B3A    DAC9             fcmove st,st(1)
00196: 00A61B3C    51               push ecx
00197: 00A61B3D    AD               lods dword ptr ds:
00198: 00A61B3E    B8 C0166600      mov eax,Enigma.006616C0
00199: 00A61B43    03C5             add eax,ebp
00200: 00A61B45    81C0 A4040000    add eax,4A4
00201: 00A61B4B    B9 FB010000      mov ecx,1FB
00202: 00A61B50    BA 6872F6BB      mov edx,BBF67268
00203: 00A61B55    3010             xor byte ptr ds:,dl                ; 继续向下解码
00204: 00A61B57    40               inc eax
00205: 00A61B58    49               dec ecx
00206: 00A61B59^ 0F85 F6FFFFFF    jnz Enigma.00A61B55
00207: 00A61B5F    E9 04000000      jmp Enigma.00A61B68
00208: 00A61B64    47               inc edi
00209: 00A61B65    DD85 B58B7E3C    fld qword ptr ss:
00210: 00A61B6B    8BBC37 80000000mov edi,dword ptr ds:       ; 获取输入表位置
00211: 00A61B72    03FE             add edi,esi
00212: 00A61B74    837F 0C 00       cmp dword ptr ds:,0
00213: 00A61B78    0F84 9A000000    je Enigma.00A61C18
00214: 00A61B7E    97               xchg eax,edi                            ; 这里开始填充IAT-----------------4
00215: 00A61B7F    8B78 0C          mov edi,dword ptr ds:
00216: 00A61B82    97               xchg eax,edi
00217: 00A61B83    03C6             add eax,esi
00218: 00A61B85    50               push eax
00219: 00A61B86    FF95 88015F00    call dword ptr ss:          ; 调用GetModuleHandleA,载入需要的dll文件的基址
00220: 00A61B8C    81F8 00000000    cmp eax,0
00221: 00A61B92    0F85 0C000000    jnz Enigma.00A61BA4                     ; 没有载入的话就用下面的函数载入
00222: 00A61B98    8B47 0C          mov eax,dword ptr ds:
00223: 00A61B9B    03C6             add eax,esi
00224: 00A61B9D    50               push eax
00225: 00A61B9E    FF95 94015F00    call dword ptr ss:          ; 调用LoadLibraryA,载入需要的dll文件
00226: 00A61BA4    837F 0C 00       cmp dword ptr ds:,0
00227: 00A61BA8    0F84 6A000000    je Enigma.00A61C18
00228: 00A61BAE    837F 00 00       cmp dword ptr ds:,0
00229: 00A61BB2    0F85 0A000000    jnz Enigma.00A61BC2
00230: 00A61BB8    837F 10 00       cmp dword ptr ds:,0
00231: 00A61BBC    0F84 4A000000    je Enigma.00A61C0C
00232: 00A61BC2    55               push ebp
00233: 00A61BC3    8D55 00          lea edx,dword ptr ss:
00234: 00A61BC6    87FD             xchg ebp,edi
00235: 00A61BC8    8B7D 10          mov edi,dword ptr ss:
00236: 00A61BCB    87FD             xchg ebp,edi
00237: 00A61BCD    03EE             add ebp,esi
00238: 00A61BCF    837D 00 00       cmp dword ptr ss:,0
00239: 00A61BD3    0F84 33000000    je Enigma.00A61C0C
00240: 00A61BD9    8B4D 00          mov ecx,dword ptr ss:
00241: 00A61BDC    50               push eax
00242: 00A61BDD    52               push edx
00243: 00A61BDE    0BC9             or ecx,ecx
00244: 00A61BE0    0F89 06000000    jns Enigma.00A61BEC
00245: 00A61BE6    51               push ecx
00246: 00A61BE7    E9 09000000      jmp Enigma.00A61BF5
00247: 00A61BEC    03CE             add ecx,esi
00248: 00A61BEE    81C1 02000000    add ecx,2
00249: 00A61BF4    51               push ecx
00250: 00A61BF5    50               push eax
00251: 00A61BF6    FF92 8C015F00    call dword ptr ds:          ; 调用GetProAddress获取API地址
00252: 00A61BFC    5A               pop edx
00253: 00A61BFD    8945 00          mov dword ptr ss:,eax
00254: 00A61C00    58               pop eax
00255: 00A61C01    81C5 04000000    add ebp,4
00256: 00A61C07^ E9 C3FFFFFF      jmp Enigma.00A61BCF
00257: 00A61C0C    5D               pop ebp
00258: 00A61C0D    81C7 14000000    add edi,14
00259: 00A61C13^ E9 5CFFFFFF      jmp Enigma.00A61B74
00260: 00A61C18    54               push esp                              ; 到此dll载入过程已基本完成.
00261: 00A61C19    64:FF35 00000000 push dword ptr fs:                   ; 还差一步,就是为DLL的初始化提供适当的环境,这步骤由dll自己完成
00262: 00A61C20    68 601D6600      push Enigma.00661D60
00263: 00A61C25    56               push esi
00264: 00A61C26    55               push ebp
00265: 00A61C27    8B46 3C          mov eax,dword ptr ds:
00266: 00A61C2A    8B8430 78000000mov eax,dword ptr ds:
00267: 00A61C31    03C6             add eax,esi
00268: 00A61C33    81C0 28000000    add eax,28
00269: 00A61C39    60               pushad
00270: 00A61C3A    8B40 04          mov eax,dword ptr ds:
00271: 00A61C3D    56               push esi
00272: 00A61C3E    03C6             add eax,esi
00273: 00A61C40    FFD0             call eax                              ; 调用dll自身的initial函数 为自己提供初始化环境
00274: 00A61C42    61               popad
00275: 00A61C43    90               nop
00276: 00A61C44    8B40 00          mov eax,dword ptr ds:
00277: 00A61C47    90               nop
00278: 00A61C48    03C6             add eax,esi
00279: 00A61C4A    56               push esi
00280: 00A61C4B    6A 00            push 0
00281: 00A61C4D    6A 01            push 1
00282: 00A61C4F    55               push ebp
00283: 00A61C50    50               push eax---------------------------------这里有玄机,留在下篇再讲。
00284: 00A61C51    8B46 3C          mov eax,dword ptr ds:
00285: 00A61C54    8B8430 28000000mov eax,dword ptr ds:
00286: 00A61C5B    03C6             add eax,esi
00287: 00A61C5D    50               push eax                              ; 这里就会去dll的入口点了
00288: 00A61C5E    C3               retn

从上面的分析可以看出,我们有四处可以提取代码的地方:
1,在壳代码刚刚调用完Aplib的解压函数的时候,这个时候的dll文件直接提取出来就可以用,不用做任何修正.因为这个时候的代码对齐值是0x200,即正常磁盘中PE文件的对齐值.

2,在把代码复制到A63000中以后.这个过程其实是壳模仿PE加载器把文件按照0x1000的对齐值映射到内存中的过程.这个时候提取文件的话,需要修正文件对齐值为0x1000,并修正PE头中的RAW=RVA。

3,在处理完重定位以后.这个是壳代码仿照加载器重定位dll的代码和数据到A63000.如果在重定位以后提取文件的话,除了修正上面提到的数据外.还要修正代码基址.

4,填充IAT以后.这个时候IAT表已经被填充完毕.抓取文件后 需要修正的部分没有增加.

来评价一下四处抓取文件的优劣.

1,这个时候的代码是最原始的.也就是说这个时候的代码跟原始文件是一模一样的,是最完美的.但是用于内存对齐值跟文件对齐值不相同,RAW和RVA存在一个换算的问题.所以有的时候比较麻烦.个人不推荐

2,这个时候的文件就相当于磁盘文件刚刚被映射到内存中一样,RVA=RAW.其他的数据都没有被动过.算比较完美的了.个人比较推荐在这时提取.

3,这个时候的文件相比上一处的文件,就差了一个重定位,这时文件的基址被重定位到了A63000.就多了一个修复代码基址的步骤.不过实践证明,这个时候提取的文件,如果把代码基址修正为00A63000的话会出现无法载入的问题,大概是因为这个基址被保留了吧。这时候可以用LordPE重建一下镜像基址就可以了。同样不推荐在这里。

4,这个时候是最不好的.输入表的中的整个IAT都被修改了。个人不喜欢(偶是完美主义者)。

看完上面的分析,相信你应该能按自己喜好提取出Dll_Loader.dll文件了。

OK。下面开始提取下面剩下的两个文件。
刚才说了DLL_Loader.dll是整个壳保护的核心。所有的解码 代码处理都在这个dll里面进行。当然剩下两个dll的解码也是这里完成的。
说句预先得到的结论,这个版本的Enigma会把剩下两个释放在DLL_Loader.dll后面紧接着它的内存中。---------怎么获得这个结论的呢?让程序运行,然后dump进程,用exeinfoPE提取其中的PE文件。
复制内容到剪贴板代码:

00663000 4D5A MZ 00000100 ( PE )
发现 Exe PE 在偏移 :       00663000
保存文件为 :   G:\破解工具箱\加壳工具\Enigma\The Enigma Protector 1.65_20090406_cn\dumped1~Rip.exe
006F650D 4D5A MZ 0000F88B ( ? )
006FABE0 4D5A MZ 0000D88B ( ? )
0071310C 4D5A MZ 00005AFB ( ?)
007177B1 4D5A MZ 00005537 ( 舿 )
0074B000 4D5A MZ 00000100 ( PE )
发现 Exe PE 在偏移 :       0074B000
保存文件为 :   G:\破解工具箱\加壳工具\Enigma\The Enigma Protector 1.65_20090406_cn\dumped2~Rip.exe
0076DDAA 4D5A MZ 000048C0 ( ? )
0076DF6A 4D5A MZ 0000F8E0 ( ?? )
0076E15E 4D5A MZ 0000F300 ( ?? )
0076E1DE 4D5A MZ 0000F8D0 ( ?? )
0076E312 4D5A MZ 000000B7 ( 亄 )
00788000 4D5A MZ 000000D8 ( PE )
发现 Exe PE 在偏移 :       00788000
保存文件为 :   G:\破解工具箱\加壳工具\Enigma\The Enigma Protector 1.65_20090406_cn\dumped3~Rip.exe
007906B7 4D5A MZ 0000D233 ( ?? )
--- 文件末尾 ---   
发现 :    3
发现最后一个区段中有三个PE文件,第一个就是DLL_Loader.dll。剩下那两个就是我们的目标。
再说一句,1.55版本不会这样,而是把剩下的两个文件释放在申请的内存中。但是没关系,我们后面说的提起方法对这种方式同样有效。
闲话不多说了。开始!
既然知道了壳会把剩下的两个dll释放的位置,就先在00B4B000处下个硬件访问断点或内存访问断点。我们知道这里会写入一个'M'。然后运行程序。(一般来说硬件断点很难断下来,内存断点也有的时候也断不下来,这时考虑使用双断点法,即在某些频繁调用的系统API代码中间下Int3断点。这样中断几次就可以在目标位置断下来了。)
x
00000: 00A658E8    56               push esi
00001: 00A658E9    57               push edi
00002: 00A658EA    89C6             mov esi,eax
00003: 00A658EC    89D7             mov edi,edx
00004: 00A658EE    89C8             mov eax,ecx
00005: 00A658F0    39F7             cmp edi,esi
00006: 00A658F2    77 13            ja short Enigma.00A65907
00007: 00A658F4    74 2F            je short Enigma.00A65925
00008: 00A658F6    C1F9 02          sar ecx,2
00009: 00A658F9    78 2A            js short Enigma.00A65925
00010: 00A658FB    F3:A5            rep movs dword ptr es:,dword ptr d>---断在这里。
00011: 00A658FD    89C1             mov ecx,eax
00012: 00A658FF    83E1 03          and ecx,3
00013: 00A65902    F3:A4            rep movs byte ptr es:,byte ptr ds:>
00014: 00A65904    5F               pop edi
00015: 00A65905    5E               pop esi
00016: 00A65906    C3               retn
这是DLL_Loader.dll中比较频繁调用的写代码的地方。不特征 我们返回到上一层去。

x
00000: 00AF74BE    6A 40            push 40
00001: 00AF74C0    68 00100000      push 1000
00002: 00AF74C5    8B45 F4          mov eax,dword ptr ss:
00003: 00AF74C8    8B40 50          mov eax,dword ptr ds:
00004: 00AF74CB    50               push eax
00005: 00AF74CC    6A 00            push 0
00006: 00AF74CE    E8 4923F7FF      call Enigma.00A6981C---------------这里修改内存属性
00007: 00AF74D3    8945 F0          mov dword ptr ss:,eax
00008: 00AF74D6    EB 03            jmp short Enigma.00AF74DB
00009: 00AF74D8    894D F0          mov dword ptr ss:,ecx
00010: 00AF74DB    8B45 F4          mov eax,dword ptr ss:
00011: 00AF74DE    8B40 50          mov eax,dword ptr ds:
00012: 00AF74E1    8903             mov dword ptr ds:,eax
00013: 00AF74E3    8B45 F4          mov eax,dword ptr ss:
00014: 00AF74E6    8B48 54          mov ecx,dword ptr ds:
00015: 00AF74E9    8B55 FC          mov edx,dword ptr ss:
00016: 00AF74EC    8B45 F0          mov eax,dword ptr ss:
00017: 00AF74EF    E8 E42AF7FF      call Enigma.00A69FD8------------------写代码的地方
00018: 00AF74F4    8B45 F4          mov eax,dword ptr ss:
00019: 00AF74F7    0FB770 06      movzx esi,word ptr ds:
00020: 00AF74FB    4E               dec esi
00021: 00AF74FC    85F6             test esi,esi
00022: 00AF74FE    7C 35            jl short Enigma.00AF7535-----------这个循环是用来复制PE头的
00023: 00AF7500    46               inc esi
00024: 00AF7501    33DB             xor ebx,ebx
00025: 00AF7503    8D049B         lea eax,dword ptr ds:
00026: 00AF7506    8B55 F4          mov edx,dword ptr ss:
00027: 00AF7509    8B8CC2 08010000mov ecx,dword ptr ds:
00028: 00AF7510    8B55 F4          mov edx,dword ptr ss:
00029: 00AF7513    8B94C2 0C010000mov edx,dword ptr ds:
00030: 00AF751A    0355 FC          add edx,dword ptr ss:
00031: 00AF751D    52               push edx
00032: 00AF751E    8B55 F4          mov edx,dword ptr ss:
00033: 00AF7521    8B84C2 04010000mov eax,dword ptr ds:
00034: 00AF7528    0345 F0          add eax,dword ptr ss:
00035: 00AF752B    5A               pop edx
00036: 00AF752C    E8 A72AF7FF      call Enigma.00A69FD8
00037: 00AF7531    43               inc ebx
00038: 00AF7532    4E               dec esi--------------------------esi表示的区段数
00039: 00AF7533^ 75 CE            jnz short Enigma.00AF7503--------------这个循环是用来按0x1000对齐复制代码的。
00040: 00AF7535    8B45 F4          mov eax,dword ptr ss:----------执行到这里就可以提取文件了
00041: 00AF7538    8B80 A0000000    mov eax,dword ptr ds:
00042: 00AF753E    85C0             test eax,eax

这段代码就是写入dll代码的特征代码。从1.5x-1.6x都没有什么变化。走出这个循环,就表示代码已经完全复制完了。文件对齐是0x1000。提取文件,然后修正OK了!
还有一个文件。这回选择一个快捷的方法。直接在这里“00AF74BE    6A 40            push 40”下硬件执行断点。然后运行。再断下来的时候就是写入下一个dll的地方了。
好了。这样所有的dll就提取完了。

结束语:在实际应用中,如果发现有捆绑的其他dll的话,可以在进入dll入口点以后 在上面的代码中找几条比较特征的,搜索一下就很容易找到这个地方了。
不知道有没有人注意到,后面两个dll的解码方式也是从一个地方按0x1000对齐复制过来的。其实捆绑的dll也跟DLL_Loader.dll一样 是用APlib的算法压缩的。DLL_Loader.dll里面有对这个函数的调用。而且很频繁。下一讲将讲一下如何从这里入手解码dll,以及APlib算法与脱壳的关系。
下一讲:Enigma主程序脱壳破解系列之二 -----主程序脱壳,敬请期待。
附件是修改的DLL_Loader.dll 解决脱壳后文件退出时的问题。

To Be Continued...
HyperChem
17/04/09

my1229 发表于 2009-9-30 09:48

jomin 楼主的好文章,分析得详细,学习和支持!

wuqing1501 发表于 2009-9-30 13:18

还是膜拜吧 先看看

egowssc 发表于 2009-10-11 23:04

文章真的不错。顶起来。学习

nevsayno 发表于 2010-3-13 12:33

好文章!!!

bhcjl 发表于 2010-3-13 14:21

高手就是高手,学习了,收藏研究

zst1314 发表于 2010-9-21 04:31

kankan!

ps520 发表于 2010-9-21 13:44

注意署名,转的HC的
页: [1]
查看完整版本: Enigma主程序脱壳破解系列之一 -----DLL解捆绑[全面开放]