最近在ARteam上看到一个unpackme 于是下下来玩了下。
下载地址:http://stashbox.org/151499/Unpackme-mfh.rar
新手第一次发技术性的帖子,希望对和我一样的新手朋友有所帮助,当中的错误也希望各位大牛不吝赐教!
——————————————————————————————————————————————————————————————————————
OD载入 入口处的代码如下:
00460400 > /EB 15 jmp short 00460417
00460402 |4D dec ebp
00460403 |6F outs dx, dword ptr es:[edi]
00460404 |64: prefix fs:
00460405 |64: prefix fs:
00460406 |65: prefix gs:
00460407 |64:46 inc esi
00460409 |6F outs dx, dword ptr es:[edi]
0046040A |67:0062 79 add byte ptr [bp+si+79], ah
0046040E |2048 4D and byte ptr [eax+4D], cl
00460411 |58 pop eax
00460412 |3031 xor byte ptr [ecx], dh
00460414 |3031 xor byte ptr [ecx], dh
00460416 |00F3 add bl, dh
F7两次后到下面的代码:
0046041D 0F31 rdtsc ;这条指令可以获取到CPU的运行周期数,和GetTickCount类似
0046041F 31C9 xor ecx, ecx
00460421 01C1 add ecx, eax
00460423 EB 02 jmp short 00460427
00460425 60 pushad
00460426 90 nop
00460427 0F31 rdtsc ;再次获取CPU的运行周期数
00460429 29C8 sub eax, ecx
0046042B 3D FF0F0000 cmp eax, 0FFF ;判断是否处于DEBUG,处于调试则下面的跳调走
00460430 0F83 CE010000 jnb 00460604 ;不能让它跳
00460436 E8 00000000 call 0046043B
0046043B 5D pop ebp
0046043C 83C5 12 add ebp, 12
0046043F 55 push ebp
00460440 C3 retn
上面的retn跳到下面代码处
0046044D 90 nop
0046044E EB 04 jmp short 00460454
00460450 0107 add dword ptr [edi], eax
00460452 0107 add dword ptr [edi], eax
00460454 BB 72044600 mov ebx, 00460472
00460459 B9 BF030000 mov ecx, 3BF
0046045E B0 41 mov al, 41
00460460 300419 xor byte ptr [ecx+ebx], al ; 解密下面的代码
00460463 8A0419 mov al, byte ptr [ecx+ebx]
00460466 ^ E2 F8 loopd short 00460460
解密后下面的代码为:
0046046F 3E:8B40 30 mov eax, dword ptr [eax+30] ; 获取PEB地址
00460473 3E:0FB640 02 movzx eax, byte ptr [eax+2] ; 获取BeingDebugged的值 可以用OD插件来将这个位置清零
00460478 83F8 01 cmp eax, 1
0046047B 0F84 74010000 je 004605F5
00460481 E8 00000000 call 00460486
00460486 5D pop ebp
00460487 83C5 12 add ebp, 12
0046048A 55 push ebp
0046048B C3 retn
0046048C 2083 B8ED2037 and byte ptr [ebx+3720EDB8], al
00460492 EF out dx, eax
00460493 C6 ??? ; 未知命令
00460494 B9 79379E90 mov ecx, 909E3779
00460499 E8 00000000 call 0046049E
0046049E 58 pop eax
0046049F EB 09 jmp short 004604AA
004604A1 90 nop
004604A2 90 nop
004604A3 90 nop
004604A4 58 pop eax
004604A5 EB 38 jmp short 004604DF
004604A7 90 nop
004604A8 90 nop
004604A9 90 nop
004604AA 31C9 xor ecx, ecx
004604AC 83C1 10 add ecx, 10
004604AF BB FFFFFF77 mov ebx, 77FFFFFF
004604B4 64:8B83 19000088 mov eax, dword ptr fs:[ebx+88000019] ; 获取TEB地址
004604BB 8B4448 10 mov eax, dword ptr [eax+ecx*2+10] ; 获取PEB地址
004604BF 0FB640 02 movzx eax, byte ptr [eax+2] ; 获取BeingDebugged的值 可以用OD插件来将这个位置清零
004604C3 F7D0 not eax
004604C5 83E0 01 and eax, 1
004604C8 89C3 mov ebx, eax
004604CA 68 F6FBC300 push 0C3FBF6
004604CF E8 00000000 call 004604D4
004604D4 832C24 33 sub dword ptr [esp], 33
004604D8 89E6 mov esi, esp
004604DA 83C6 04 add esi, 4
004604DD FFE6 jmp esi
004604DF BD 00004000 mov ebp, 00400000 ; ASCII "MZP"
004604E4 EB 04 jmp short 004604EA
004604E6 95 xchg eax, ebp
004604E7 C030 70 sal byte ptr [eax], 70
004604EA 68 FF242400 push 2424FF
004604EF E8 00000000 call 004604F4
004604F4 830424 0A add dword ptr [esp], 0A
004604F8 8D5C24 04 lea ebx, dword ptr [esp+4]
004604FC FFE3 jmp ebx
004604FE 5B pop ebx
004604FF 5B pop ebx
00460500 EB 04 jmp short 00460506
00460502 0F0F ??? ; 未知命令
00460504 0F0F ??? ; 未知命令
00460506 8B05 89084600 mov eax, dword ptr [<&kernel32.LoadLibraryA>] ; kernel32.LoadLibraryA
0046050C 85C0 test eax, eax
0046050E 0F84 E1000000 je 004605F5
00460514 E8 0D000000 call 00460526
00460519 6B65 72 6E imul esp, dword ptr [ebp+72], 6E
0046051D 65:6C ins byte ptr es:[edi], dx
0046051F 3332 xor esi, dword ptr [edx]
00460521 2E: prefix cs:
00460522 64:6C ins byte ptr es:[edi], dx
00460524 6C ins byte ptr es:[edi], dx
00460525 00FF add bh, bh
00460527 D085 C00F84C5 rol byte ptr [ebp+C5840FC0], 1
0046052D 0000 add byte ptr [eax], al
0046052F 0089 C3EB0499 add byte ptr [ecx+9904EBC3], cl
00460535 90 nop
00460536 99 cdq
00460537 90 nop
00460538 8B05 8D084600 mov eax, dword ptr [<&kernel32.GetProcAddress>] ; kernel32.GetProcAddress
0046053E 85C0 test eax, eax
00460540 0F84 AF000000 je 004605F5
00460546 89C6 mov esi, eax
00460548 31C0 xor eax, eax
0046054A 31C9 xor ecx, ecx
0046054C 31D2 xor edx, edx
0046054E 31FF xor edi, edi
00460550 803E CC cmp byte ptr [esi], 0CC ; 判断是否在GetProcAddress下断
00460553 0F84 9C000000 je 004605F5
00460559 31C9 xor ecx, ecx
0046055B 90 nop
0046055C E3 0C jecxz short 0046056A
0046055E EB 04 jmp short 00460564
00460560 0101 add dword ptr [ecx], eax
00460562 0101 add dword ptr [ecx], eax
00460564 90 nop
00460565 E9 8C000000 jmp 004605F6
0046056A E8 0D000000 call 0046057C
0046056F 56 push esi
00460570 6972 74 75616C41 imul esi, dword ptr [edx+74], 416C6175
00460577 6C ins byte ptr es:[edi], dx
00460578 6C ins byte ptr es:[edi], dx
00460579 6F outs dx, dword ptr es:[edi]
0046057A 6300 arpl word ptr [eax], ax
0046057C 53 push ebx
0046057D FFD6 call esi
0046057F 85C0 test eax, eax
00460581 74 72 je short 004605F5
00460583 8038 CC cmp byte ptr [eax], 0CC ; 判断是否在VirtualAlloc的首字节下断
00460586 74 6D je short 004605F5
00460588 6A 04 push 4
0046058A 68 00100000 push 1000
0046058F BF 00F00400 mov edi, 4F000
00460594 EB 04 jmp short 0046059A
00460596 0202 add al, byte ptr [edx]
00460598 0202 add al, byte ptr [edx]
0046059A 57 push edi
0046059B 6A 00 push 0
0046059D FFD0 call eax ; 申请一块内存空间
0046059F 85C0 test eax, eax
004605A1 74 52 je short 004605F5
004605A3 50 push eax
004605A4 8D95 00100000 lea edx, dword ptr [ebp+1000]
004605AA 50 push eax
004605AB 52 push edx
004605AC E8 D4010000 call 00460785 ; 将数据解密到新申请的内存空间
004605B1 83C4 08 add esp, 8
004605B4 8B0424 mov eax, dword ptr [esp]
004605B7 89F9 mov ecx, edi
004605B9 49 dec ecx
004605BA 89C2 mov edx, eax
004605BC 56 push esi
004605BD 8DB5 00100000 lea esi, dword ptr [ebp+1000]
004605C3 8A0411 mov al, byte ptr [ecx+edx] ; 将解密好的数据写回到原来存放加密数据的内存空间
004605C6 880431 mov byte ptr [ecx+esi], al
004605C9 ^ E2 F8 loopd short 004605C3
004605CB 5E pop esi
004605CC 58 pop eax
004605CD 68 00400000 push 4000
004605D2 57 push edi
004605D3 50 push eax
004605D4 E8 0C000000 call 004605E5
004605D9 56 push esi
004605DA 6972 74 75616C46 imul esi, dword ptr [edx+74], 466C6175
004605E1 72 65 jb short 00460648
004605E3 65:0053 FF add byte ptr gs:[ebx-1], dl
004605E7 D6 salc
004605E8 85C0 test eax, eax
004605EA 74 0A je short 004605F6
004605EC 8038 CC cmp byte ptr [eax], 0CC
004605EF 74 05 je short 004605F6
004605F1 FFD0 call eax ; 释放解密数据用的空间
004605F3 EB 01 jmp short 004605F6
004605F5 C3 retn
004605F6 90 nop
004605F7 E8 00000000 call 004605FC
004605FC 60 pushad
004605FD EB 04 jmp short 00460603
004605FF 00AA 00AABB00 add byte ptr [edx+BBAA00], ch
00460605 1045 00 adc byte ptr [ebp], al
00460608 B9 2A1F0000 mov ecx, 1F2A
0046060D B0 C7 mov al, 0C7
0046060F 300419 xor byte ptr [ecx+ebx], al ; 解密IAT函数名
00460612 ^ E2 FB loopd short 0046060F
00460614 61 popad
00460615 E8 0D000000 call 00460627
0046061A 56 push esi
0046061B 6972 74 75616C41 imul esi, dword ptr [edx+74], 416C6175
00460622 6C ins byte ptr es:[edi], dx
00460623 6C ins byte ptr es:[edi], dx
00460624 6F outs dx, dword ptr es:[edi]
00460625 6300 arpl word ptr [eax], ax
00460627 53 push ebx
00460628 FFD6 call esi
0046062A 50 push eax
0046062B E8 0D000000 call 0046063D
00460630 4C dec esp
00460631 6F outs dx, dword ptr es:[edi]
00460632 61 popad
00460633 64:4C dec esp
00460635 6962 72 61727941 imul esp, dword ptr [edx+72], 41797261
0046063C 0053 FF add byte ptr [ebx-1], dl
0046063F D6 salc
00460640 85C0 test eax, eax
00460642 ^ 74 B1 je short 004605F5
00460644 8038 CC cmp byte ptr [eax], 0CC
00460647 ^ 74 AC je short 004605F5
00460649 89C7 mov edi, eax
0046064B EB 04 jmp short 00460651
0046064D F1 int1
0046064E F1 int1
0046064F F1 int1
00460650 F1 int1
00460651 B9 00100500 mov ecx, 51000
00460656 01E9 add ecx, ebp
00460658 8379 0C 00 cmp dword ptr [ecx+C], 0
0046065C 0F84 D6000000 je 00460738
00460662 8B59 0C mov ebx, dword ptr [ecx+C]
00460665 01EB add ebx, ebp
00460667 51 push ecx
00460668 53 push ebx
00460669 FFD7 call edi
0046066B 59 pop ecx
0046066C 85C0 test eax, eax
0046066E ^ 74 85 je short 004605F5
00460670 8038 CC cmp byte ptr [eax], 0CC
00460673 ^ 74 80 je short 004605F5
00460675 89C3 mov ebx, eax
00460677 8379 10 00 cmp dword ptr [ecx+10], 0
0046067B ^ 0F84 74FFFFFF je 004605F5
00460681 8B51 10 mov edx, dword ptr [ecx+10]
00460684 01EA add edx, ebp
00460686 57 push edi
00460687 8B39 mov edi, dword ptr [ecx]
00460689 01EF add edi, ebp
0046068B 833A 00 cmp dword ptr [edx], 0
0046068E 0F84 8F000000 je 00460723
00460694 51 push ecx
00460695 52 push edx
00460696 8339 00 cmp dword ptr [ecx], 0
00460699 75 19 jnz short 004606B4
0046069B 8B02 mov eax, dword ptr [edx]
0046069D A9 00000080 test eax, 80000000
004606A2 74 08 je short 004606AC
004606A4 25 FFFF0000 and eax, 0FFFF
004606A9 50 push eax
004606AA EB 22 jmp short 004606CE
004606AC 01E8 add eax, ebp
004606AE 83C0 02 add eax, 2
004606B1 50 push eax
004606B2 EB 1A jmp short 004606CE
004606B4 8B07 mov eax, dword ptr [edi]
004606B6 83C7 04 add edi, 4
004606B9 A9 00000080 test eax, 80000000
004606BE 74 08 je short 004606C8
004606C0 25 FFFF0000 and eax, 0FFFF
004606C5 50 push eax
004606C6 EB 06 jmp short 004606CE
004606C8 01E8 add eax, ebp
004606CA 83C0 02 add eax, 2
004606CD 50 push eax
004606CE 53 push ebx
004606CF FFD6 call esi ;GetProcAddress获得函数的地址
004606D1 5A pop edx
004606D2 59 pop ecx
004606D3 85C0 test eax, eax
004606D5 ^ 0F84 1AFFFFFF je 004605F5
004606DB 8038 CC cmp byte ptr [eax], 0CC
004606DE ^ 0F84 11FFFFFF je 004605F5
004606E4 51 push ecx
004606E5 89C1 mov ecx, eax
004606E7 51 push ecx
004606E8 52 push edx
004606E9 6A 04 push 4
004606EB 68 00100000 push 1000
004606F0 6A 0E push 0E
004606F2 6A 00 push 0
004606F4 FF5424 20 call dword ptr [esp+20] ; 申请内存空间
004606F8 5A pop edx
004606F9 59 pop ecx
004606FA 81F1 37133713 xor ecx, 13371337
00460700 C600 B8 mov byte ptr [eax], 0B8
00460703 8948 01 mov dword ptr [eax+1], ecx ; IAT加密放入新申请的内存
00460706 C640 05 35 mov byte ptr [eax+5], 35 ; 进行编码
0046070A C740 06 37133713 mov dword ptr [eax+6], 13371337
00460711 C740 0A FFE0C390 mov dword ptr [eax+A], 90C3E0FF
00460718 59 pop ecx
00460719 8902 mov dword ptr [edx], eax ; 将申请的内存首地址做为加密后的IAT地址
0046071B 83C2 04 add edx, 4
0046071E ^ E9 68FFFFFF jmp 0046068B
00460723 5F pop edi
00460724 83C1 14 add ecx, 14
00460727 8379 0C 00 cmp dword ptr [ecx+C], 0
0046072B ^ 0F85 31FFFFFF jnz 00460662
00460731 90 nop
00460732 EB 04 jmp short 00460738
00460734 95 xchg eax, ebp
00460735 C065 70 68 shl byte ptr [ebp+70], 68
00460739 ^ 78 DE js short 00460719
0046073B 04 00 add al, 0
0046073D 012C24 add dword ptr [esp], ebp ; 构造OEP
00460740 C3 retn ;转到OEP
在上面retn处F7到达OEP
0044DE78 55 push ebp ; Unpackme.00400000
0044DE79 8BEC mov ebp, esp
0044DE7B 83C4 F0 add esp, -10
0044DE7E B8 98DC4400 mov eax, 0044DC98
0044DE83 E8 607DFBFF call 00405BE8
0044DE88 A1 C8EF4400 mov eax, dword ptr [44EFC8]
0044DE8D 8B00 mov eax, dword ptr [eax]
0044DE8F E8 84E6FFFF call 0044C518
0044DE94 8B0D A4F04400 mov ecx, dword ptr [44F0A4] ; Unpackme.00450BD0
0044DE9A A1 C8EF4400 mov eax, dword ptr [44EFC8]
0044DE9F 8B00 mov eax, dword ptr [eax]
0044DEA1 8B15 B8DA4400 mov edx, dword ptr [44DAB8] ; Unpackme.0044DB04
0044DEA7 E8 84E6FFFF call 0044C530
0044DEAC A1 C8EF4400 mov eax, dword ptr [44EFC8]
0044DEB1 8B00 mov eax, dword ptr [eax]
0044DEB3 E8 F8E6FFFF call 0044C5B0
0044DEB8 E8 635EFBFF call 00403D20
0044DEBD 8D40 00 lea eax, dword ptr [eax]
到了OEP就用LordPE 把它给DUMP下来
——————————————————————————————————————————————————————————————————————————
接下来IAT的处理
在第一个call回车进去,继续进第一个call,代码为:
00405B24 - FF25 E4114500 jmp dword ptr [4511E4]
jmp进去的代码为:
00C80000 B8 06A4B76F mov eax, 6FB7A406 ;这里的数值①可以通过[4511e4]作为基址找到
00C80005 35 37133713 xor eax, 13371337 ;这里的数值②也可以通过同样的方法找到
00C8000A FFE0 jmp eax
00C8000C C3 retn
在数据窗口中看004511E4的数据
从00451118 到 004516d4 都是类似的加密后的IAT数据
在OEP下去找一断空闲的区域来写代码,来将我们真正的IAT数据写进去
0044DED0 60 pushad
0044DED1 B9 18114500 mov ecx, 00451118 ;ecx指向第一个加密的IAT
0044DED6 8B11 mov edx, dword ptr [ecx]
0044DED8 83FA 00 cmp edx, 0
0044DEDB 74 12 je short 0044DEEF ;为0则解密下一个
0044DEDD 33C0 xor eax, eax
0044DEDF 8B42 01 mov eax, dword ptr [edx+1] ;[edx+1]为数值①
0044DEE2 3342 06 xor eax, dword ptr [edx+6] ;[edx+6]为数值②
0044DEE5 8901 mov dword ptr [ecx], eax ;将真正的IAT写回
0044DEE7 81FA 0000FD01 cmp edx, 1FD0000 ;是否为最后一个IAT
0044DEED 73 0B jnb short 0044DEF4
0044DEEF 83C1 04 add ecx, 4
0044DEF2 ^ EB E2 jmp short 0044DED6
0044DEF4 61 popad
0044DEF5 ^ EB 81 jmp short 0044DE78 ;跳回OEP
在popad出F4将所有的IAT解密掉,运行Import REC 填上OEP :4DE78 自动搜索IAT ->获取输入表 然后修复dump下来的文件, OK可以运行了!
谢谢i++的提醒
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课