首页
社区
课程
招聘
Armadillo 4.0x Manually Unpacking+IAT Rebuilding Tutorial by KaGra
发表于: 2005-3-4 11:26 9782

Armadillo 4.0x Manually Unpacking+IAT Rebuilding Tutorial by KaGra

fly 活跃值
85
2005-3-4 11:26
9782
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&          Armadillo 4.0x Manually Unpacking+IAT Rebuilding Tutorial by KaGra        &&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

        Hallo to all ppl out there.Well,since my last Armadillo tutorial,I had many requests
        to make a tutor with full IAT rebuilding.I proudly present you Armadillo 4.0x MUP tutor.
        The target is a crackme,and I packed it with Armadillo v4.05,download it from their site
        directly.I used the professional version of it and in Protection->Edit Project->Protection
        Options I checked Standard Protection only,Enable Import Table Elimination,Enable strategic Codes
        splicing and enable memory-patching protections.I also created a default certificate.

        The tools I used are Olly debugger v1.10,Olly Dump Plugin,ImpRec v1.6f and HideOlly Plugin,PEid v0.93,LordPE

        Open PEid v0.93,and you see that identifies the target as packed with Armadillo 1.xx - 2.xx ->
        Silicon Realms Toolworks [Overlay].Well,cannot detect the right version packed (I packed it using
        Armadillo v4.05) because it is a new version.Actually,last version at that time I am
        writing this tutorial.

        HideOlly Plugin will protect you against IsDebuggerPresent API that the protector calls during
        unpacking,and if a debugger is present sets EAX=1.If you do not have the Plug,DO NOT set
        any kind of breakpoint,because Armadillo will find it.Just get the plug to be sure,and do not worry
        any more about it.

        Now,load the packed.exe that is in zip in Olly.In Options->Debugging Options->check all exceptions
        and at the Ignore also following custom exceptions,add as a range all the exceptions that Olly
        provides in a list.Also,disable ALL breakpoint (hardware,software etc) you may have,the protector
        can detect them all.

        So,you loaded the exe,you are at Entry Point paused,here:

004307C3 >/$ 55             PUSH EBP
004307C4  |. 8BEC           MOV EBP,ESP
004307C6  |. 6A FF          PUSH -1
004307C8  |. 68 20AB4500    PUSH evdcm2.0045AB20
004307CD  |. 68 00054300    PUSH evdcm2.00430500                     ;  SE handler installation
004307D2  |. 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
004307D8  |. 50             PUSH EAX
004307D9  |. 64:8925 000000>MOV DWORD PTR FS:[0],ESP
004307E0  |. 83EC 58        SUB ESP,58

        Before proceed,we have to patch a call to OutputDebugStringA API,because the protector uses that
        API to detect Olly,using a bug that she has (the debugger).To see what I mean,if U proceed pressing
        Shift+F9,Olly will crash.This is an anti-debugging trick.So,Armadillo uses a buffer overflow that
        exists in Olly,when using OutputDebugStringA to send a string in the debugger.To patch it,we just
        have to see where OutputDebugStringA starts,and as a first opcode to put a ret there,so the API will
        not be triggered,so no overflow will occur,so Olly will not crush.You are at Entry Point,right click
        on code section window and Search for->Name in all modules.Start writing OutputDebugStringA and when
        you see it,double click on it.You see this:

77E949B7 > 68 2C020000      PUSH 22C
77E949BC   68 8853E977      PUSH kernel32.77E95388
77E949C1   E8 1259FEFF      CALL kernel32.77E7A2D8
77E949C6   8365 FC 00       AND DWORD PTR SS:[EBP-4],0
77E949CA   8B4D 08          MOV ECX,DWORD PTR SS:[EBP+8]
77E949CD   8BC1             MOV EAX,ECX
77E949CF   8D70 01          LEA ESI,DWORD PTR DS:[EAX+1]
77E949D2   8A10             MOV DL,BYTE PTR DS:[EAX]
77E949D4   40               INC EAX
77E949D5   84D2             TEST DL,DL
77E949D7  ^75 F9            JNZ SHORT kernel32.77E949D2
77E949D9   2BC6             SUB EAX,ESI
77E949DB   40               INC EAX
77E949DC   8945 E0          MOV DWORD PTR SS:[EBP-20],EAX
77E949DF   894D E4          MOV DWORD PTR SS:[EBP-1C],ECX
77E949E2   8D45 E0          LEA EAX,DWORD PTR SS:[EBP-20]
77E949E5   50               PUSH EAX
77E949E6   6A 02            PUSH 2
77E949E8   6A 00            PUSH 0
77E949EA   68 06000140      PUSH 40010006
77E949EF   E8 43EEFDFF      CALL kernel32.RaiseException
77E949F4   834D FC FF       OR DWORD PTR SS:[EBP-4],FFFFFFFF
77E949F8   E8 A259FEFF      CALL kernel32.77E7A39F
77E949FD   C2 0400          RETN 4

        So,the OutputDebugStringA APi code ends with a RETN 4.So at 77E949B7 replace the PUSH 22C with
        a RETN 4 opcode.

        Now,go at Entry Point again in code section window in Olly,and press Shift+F9 to start the
        execution of the packed exe.Wait some seconds till it pauses.It actually pauses in the Messagebox,that
        says that protector is not licenced.Now,press the "M" button and you can see the Image of memory.In
        code section (CODE) right click on it and set a break-on-access breakpoint.Now press the OK in the
        previous messagebox.Olly pauses at the breakpoint we just set,here:

00428542  |. 8A11           |MOV DL,BYTE PTR DS:[ECX]
00428544  |. 8B45 08        |MOV EAX,DWORD PTR SS:[EBP+8]
00428547  |. 33C2           |XOR EAX,EDX
00428549  |. 25 FF000000    |AND EAX,0FF
0042854E  |. 8B4D 08        |MOV ECX,DWORD PTR SS:[EBP+8]
00428551  |. C1E9 08        |SHR ECX,8

        Well,ECX=00401000 and we have bytes movements and processing,unpacking started.Good.Now uncheck ALL
        exceptions and press Shift+F9 one time.We have an access violation (00000000).Now set again a
        break-on-access breakpoint at code section (CODE),and press Shift+F9 one more time.You land at
        the OEP,here:

00401099   EB 27            JMP SHORT evdcm2.004010C2
0040109B   33C0             XOR EAX,EAX
0040109D   A3 F7204000      MOV DWORD PTR DS:[4020F7],EAX
004010A2   6A 29            PUSH 29
004010A4   68 0E204000      PUSH evdcm2.0040200E
004010A9   6A 65            PUSH 65
004010AB   FF75 08          PUSH DWORD PTR SS:[EBP+8]
004010AE   E8 D9010000      CALL evdcm2.0040128C                     ; JMP to USER32.GetDlgItemTextA

        If it is for another packed application,bigger,the same method to find OEP is used,but you
        may have to press more times Shift+F9 from the time you will uncheck all exceptions,till you
        set the last memory break-on-access breakpoint.So,just count them,and next time minus one,and
        set the last memory break-on-access breakpoint.

        Ok,time to dump.Well,before we dump,there is the PE header to be fixed.Why?Open Imprec and try to
        choose out process from the process list.A messagebox appearz telling us that we have an invalid
        PE header.So,open a second Olly and load the packed exe.Now press the "M" button and double click
        on the PE header section (PE header).Now right click->Hex->16 bytes.Select all header bytes from
        00400000 till 00400390->Binary copy.Now,close this Olly,and goto the PE header section of the
        Olly from where we will dump,and paste the PE header.Now,using OllyDump Plugin dump the process,
        having unchecked the IAT rebuilding options,and as OEP=1099.

        Now time for IAT rebuilding.Open Imprec and select the process and set OEP=1099.Now IAT
        autosearch,Get imports and Show invalid.We have five Invalid.

        Goto Olly.We are at OEP,scroll down to see tha JMP [XXXXXXXX] opcodes,that jamp to IAT API
        addresses.We see this:

00401274  -FF25 70304000    JMP DWORD PTR DS:[403070]                ; USER32.TranslateMessage
0040127A  -FF25 74304000    JMP DWORD PTR DS:[403074]                ; USER32.DefWindowProcA
00401280  -FF25 78304000    JMP DWORD PTR DS:[403078]
00401286  -FF25 7C304000    JMP DWORD PTR DS:[40307C]                ; USER32.DispatchMessageA
0040128C  -FF25 80304000    JMP DWORD PTR DS:[403080]                ; USER32.GetDlgItemTextA
00401292  -FF25 84304000    JMP DWORD PTR DS:[403084]                ; USER32.GetMessageA
00401298  -FF25 88304000    JMP DWORD PTR DS:[403088]
0040129E  -FF25 8C304000    JMP DWORD PTR DS:[40308C]                ; USER32.SendDlgItemMessageA
004012A4  -FF25 90304000    JMP DWORD PTR DS:[403090]                ; USER32.SetDlgItemTextA
004012AA  -FF25 98304000    JMP DWORD PTR DS:[403098]
004012B0  -FF25 9C304000    JMP DWORD PTR DS:[40309C]

        So,as we can see here,we have four invalid and are actually the same with those you see
        in ImpRec.The fifth invalid we saw in Imprec is not here,will be cut as thunk later,it
        is useless.How are we going to identify which API calls we have?

        Well,we follow that method:

       
        Let's identify the JMP at 00401280.So,click in 00401280 JMP opcode,right click on it and
        set new origin (EIP=00401280).Press one time F7 to execute the JMP and we land here:

00AC9C31   55               PUSH EBP
00AC9C32   8BEC             MOV EBP,ESP
00AC9C34   FF75 18          PUSH DWORD PTR SS:[EBP+18]
00AC9C37   FF75 14          PUSH DWORD PTR SS:[EBP+14]
00AC9C3A   FF75 10          PUSH DWORD PTR SS:[EBP+10]
00AC9C3D   FF75 0C          PUSH DWORD PTR SS:[EBP+C]
00AC9C40   FF75 08          PUSH DWORD PTR SS:[EBP+8]
00AC9C43   FF15 4024AE00    CALL DWORD PTR DS:[AE2440]               ; USER32.DialogBoxParamA
00AC9C49   5D               POP EBP
00AC9C4A   C2 1400          RETN 14

        So,between 00AC9C31 and 00AC9C4A where exits,no other jmps or calls.So the API is DialogBoxParamA
        and what Armadillo has done here is emulating the first instructions of the API and then jamping
        into it.So in ImpRec,goto invalid thunk 00AC9C31 and double click on it,and choose user32.dll and
        enter as name API the name DialogBoxParamA.

        Second to identify is the jamp at 00401298.So,set new origin at 00401298 and press F7 and you
        are here:

00AC8EE3   55               PUSH EBP
00AC8EE4   8BEC             MOV EBP,ESP
00AC8EE6   51               PUSH ECX
00AC8EE7   53               PUSH EBX
00AC8EE8   56               PUSH ESI
00AC8EE9   57               PUSH EDI
00AC8EEA   60               PUSHAD
00AC8EEB   8B15 484BAF00    MOV EDX,DWORD PTR DS:[AF4B48]            ; kernel32.77E7A237
00AC8EF1   83C2 64          ADD EDX,64
00AC8EF4   FFD2             CALL EDX
00AC8EF6   8B15 044BAF00    MOV EDX,DWORD PTR DS:[AF4B04]            ; USER32.77D66412
00AC8EFC   83C2 64          ADD EDX,64
00AC8EFF   B9 05000000      MOV ECX,5
00AC8F04   803A CC          CMP BYTE PTR DS:[EDX],0CC
00AC8F07   74 10            JE SHORT 00AC8F19

        You see at 00AC8F04 a check that is being done if there is a software breakpoint at [EDX].And
        guess what,[EDX] has the address of the API that is invalid.So trace with F9 till 00AC8F04 and
        look at the registers window at EDX.EDX points at MessageBoxA.So this is the invalid.Have in
        mind also at 00AC8EF4 the CALL EDX.This is a call at GetTickCount and after that out software
        breakpoint check.So,to fix also the third invalid JMP in 004012AA,put a hardware breakpoint
        at the RET (last) instruction of the code of GetTickCount and when you exit,a few opcodes
        later you find the magic comparison.Do not place a software breakpoint,because Armadillo
        detects it,because before fixing all the IAT,there is still some Armadillo code that runs in the
        dumped exe.So,the 004012AA JMP goes at GetModuleHandleA.

        One left,tha JMP at 004012B0.Well,common sense says that should be an exit proccess kind of
        API,since no other API is for exiting the application.So,we are at new origin of 004012B0 and
        press F7 and we land here:

00AC687C   55               PUSH EBP
00AC687D   8BEC             MOV EBP,ESP
00AC687F   6A FF            PUSH -1
00AC6881   68 1827AE00      PUSH 0AE2718
00AC6886   68 101AAE00      PUSH 0AE1A10                             ; JMP to msvcrt._except_handler3
00AC688B   64:A1 00000000   MOV EAX,DWORD PTR FS:[0]

        Tracing with F8 some lines more we land here:

00AC68D3   8B15 184BAF00    MOV EDX,DWORD PTR DS:[AF4B18]            ; kernel32.77E79899
00AC68D9   83C2 64          ADD EDX,64
00AC68DC   FF75 08          PUSH DWORD PTR SS:[EBP+8]
00AC68DF   FFD2             CALL EDX                                 ; kernel32.ExitProcess

       
        So,this invalid is ExitProcess.Having fixed four thunks,and since in Olly we cannot see
        any other invalid we cut the one invalid thunk in ImpRec.My tree is that:

Target: C:\Documents and Settings\asd\Desktop\evdcm2.exe
OEP: 00001099        IATRVA: 0000306C        IATSize: 00000034

FThunk: 00003070        NbFunc: 00000009
1        00003070        user32.dll        02AB        TranslateMessage
1        00003074        user32.dll        008F        DefWindowProcA
1        00003078        user32.dll        009F        DialogBoxParamA
1        0000307C        user32.dll        00A2        DispatchMessageA
1        00003080        user32.dll        0114        GetDlgItemTextA
1        00003084        user32.dll        013B        GetMessageA
1        00003088        user32.dll        01DD        MessageBoxA
1        0000308C        user32.dll        0237        SendDlgItemMessageA
1        00003090        user32.dll        0254        SetDlgItemTextA

FThunk: 00003098        NbFunc: 00000002
1        00003098        kernel32.dll        016F        GetModuleHandleA
1        0000309C        kernel32.dll        00B0        ExitProcess

        Now fix the dump.Run the exe.Damn Lord,it runz!!!

        Well,because the dump using Olly gave us a big size of the exe,we can reduce its size using
        LordPE.Well,if you see in Olly and LordPE the sections of the fixed exe,are these:

Memory map
Address    Size       Owner      Section    Contains      Type   Access    Initial   Mapped as
00400000   00001000   unpacked              PE header     Imag   R         RWE
00401000   00001000   unpacked   CODE                     Imag   R         RWE
00402000   00001000   unpacked   DATA                     Imag   R         RWE
00403000   00001000   unpacked   .idata                   Imag   R         RWE
00404000   00001000   unpacked   .reloc                   Imag   R         RWE
00405000   00040000   unpacked   .text      code          Imag   R         RWE
00445000   00010000   unpacked   .adata                   Imag   R         RWE
00455000   00010000   unpacked   .data      data          Imag   R         RWE
00465000   00010000   unpacked   .reloc1    relocations   Imag   R         RWE
00475000   00030000   unpacked   .pdata                   Imag   R         RWE
004A5000   00007000   unpacked   .rsrc      resources     Imag   R         RWE
004AC000   00001000   unpacked   .mackt     imports       Imag   R         RWE

       
        We only need PE header,CODE (code section),DATA (text data),rsrc (resources),idata (where the
        API addresses taken from IAT will be stored) and mackt section which is the IAT added by ImpRec.
        So,wipe all other sections and rebuild the exe using LordPE.Now,we have a 27K exe,and before we
        had a 692K exe.
       
        All the sections wiped contain code of the packer,which was dumped with the good,original exe code,
        and before the API fixation,was executed before the API's and its purpose was to obfuscate the
        reverser,to detect software breakpoints and general to make reversing harder.
       

        Well that's it.Let mE now RocK the WorLd by ReleaZing It...

附件:armadillo40xmup.zip

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (4)
雪    币: 303
活跃值: (476)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
Options I checked Standard Protection only标准保护,单进程
2005-3-4 11:52
0
雪    币: 301
活跃值: (300)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
3
谢谢,辛苦了
2005-3-4 12:53
0
雪    币: 61
活跃值: (160)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
4
谢谢,辛苦了,good
2005-3-9 19:56
0
雪    币: 270
活跃值: (176)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
5
大概翻译了一下,
http://bbs.pediy.com/showthread.php?s=&threadid=11919
2005-3-10 18:40
0
游客
登录 | 注册 方可回帖
返回
//