Asprotect保護的程式脫殼後的修正--DialogBoxIndirectParamA (7千字)

看雪資料發表於2001-09-09

Asprotect保護的程式脫殼後的修正--DialogBoxIndirectParamA

Liotta[BCG]
本文主要介紹Asprotect1.3保護的程式脫殼後關於加密函式DialogBoxIndirectParamA的修正問題。
僅供新手參考。

名稱        :Advanced Direct Remailer
版本        :2.12
釋出日期        :June 1, 2001
描述        :Powerful remailer with SMTP server, support for mailing lists, plugins.
作業系統        :Windows 98
目標檔案        :Adr.exe

相關工具:
    FI
    Peditor
    Softice
    icedump + iceload
    ImpREC

參考文件:
    fs0        “脫Advanced Email Extractor PRO的殼 ”
    Liotta[BCG]    “UNPack CommView v.3.0”

    Asprotect保護的程式,當我們手動脫殼後發現程式總是無法執行,要麼自動退出、要麼出現加密函式未找到
等出錯資訊。總是不能順順利利的,對於我們新手來說能夠完成手動脫殼已是不易,再出現這種問題對我們來說,
實在是一大打擊!
    如何修正這個問題呢?
    fs0在“脫Advanced Email Extractor PRO的殼 ”一文中提到:
    用Asprotect加殼的程式, 脫殼後不能執行,我知道的有:
            1. 原程式呼叫Asprotect的"Export Function", 最簡單的就是:
          push ..
          push -1
          call GetProcAddress
        看其返回值是否為0, 為0 就出錯或退出(AeePro就是這樣的)
        2. 原程式自檢加殼後的程式(已經加殼了, 真不知道他是怎麼檢的)。
        3. Asprotect 呼叫原程式的“初始化”函式, 當到達 OEP 前, 某些全域性變數已經初始化了,
        脫殼後執行就很可能出錯, 解決方法是, 修改脫殼後的程式, 先執行該“初始化”函式, 再跳
        到OEP 執行就可以了。
        4. 再有就是DialogBoxIndirectParamA等。
    現在結合 ADR脫殼後的修正來說說這個DialogBoxIndirectParamA問題,
    首先,要找到程式的 OEP並DUMP,然後重構輸入表並修改DUMP檔。如果你還不大清楚Asprotect保護脫殼請
細閱上述參考文件。
    當執行我們脫殼後的程式時,卻出現“Crypt API not found.……”錯誤資訊框,然後就退出。
    讓我們BPX MessageBoxA,按F12返回到程式空間,向上看看:

017F:00433590 6A04            PUSH    BYTE +04
017F:00433592 6AFF            PUSH    BYTE -01
017F:00433594 FF154C014400    CALL    `KERNEL32!GetProcAddress`
017F:0043359A 85C0            TEST    EAX,EAX                <--EAX=0則出錯
017F:0043359C A36C564600      MOV      [0046566C],EAX
017F:004335A1 7516            JNZ      004335B9            <--75改成EB即可修正
017F:004335A3 6A10            PUSH    BYTE +10
017F:004335A5 68E0424400      PUSH    DWORD 004442E0
017F:004335AA 68C4774400      PUSH    DWORD 004477C4
017F:004335AF 50              PUSH    EAX
017F:004335B0 FF15A4034400    CALL    `USER32!MessageBoxA`        <--出錯資訊框
017F:004335B6 33C0            XOR      EAX,EAX
017F:004335B8 C3              RET                        <--退出

    看到了吧!用 HEX編輯器修改75成EB即可修正最簡單的錯誤。
    修正後,程式能執行。但是當我們點選HELP中的Registration時卻出現嚴重錯誤!!
我們用W32DASM來反彙編該程式,發現HELP中的Registration呼叫USER32.dll!DialogBoxIndirectParamA
可以肯定是函式DialogBoxIndirectParamA在搞鬼!並發現有幾處呼叫該函式。

其中之(一)
* Reference To: USER32.DialogBoxIndirectParamA, Ord:0091h
                                  |
:00434713 FF1568034400            Call dword ptr [00440368]

地址00440368存放的就是USER32.dll!DialogBoxIndirectParamA函式呼叫地址。
讓我們先看看,脫殼是找到的USER32.dll!DialogBoxIndirectParamA函式原型:

017F:00F5C898 55              PUSH    EBP
017F:00F5C899 8BEC            MOV      EBP,ESP
017F:00F5C89B 53              PUSH    EBX
017F:00F5C89C 8B5D08          MOV      EBX,[EBP+08]
017F:00F5C89F 8B4518          MOV      EAX,[EBP+18]
017F:00F5C8A2 50              PUSH    EAX
017F:00F5C8A3 8B4514          MOV      EAX,[EBP+14]
017F:00F5C8A6 50              PUSH    EAX
017F:00F5C8A7 8B4510          MOV      EAX,[EBP+10]
017F:00F5C8AA 50              PUSH    EAX
017F:00F5C8AB 6A05            PUSH    BYTE +05
017F:00F5C8AD 8B450C          MOV      EAX,[EBP+0C]
017F:00F5C8B0 50              PUSH    EAX
017F:00F5C8B1 53              PUSH    EBX
017F:00F5C8B2 E8157BFFFF      CALL    `KERNEL32!FindResourceA`    <--注意機器碼(5位元組)
017F:00F5C8B7 50              PUSH    EAX
017F:00F5C8B8 53              PUSH    EBX
017F:00F5C8B9 E87E7BFFFF      CALL    `KERNEL32!LoadResource`    <--注意機器碼(5位元組)
017F:00F5C8BE 50              PUSH    EAX
017F:00F5C8BF E8807BFFFF      CALL    `KERNEL32!LockResource`    <--注意機器碼(5位元組)
017F:00F5C8C4 50              PUSH    EAX
017F:00F5C8C5 53              PUSH    EBX
017F:00F5C8C6 E8917BFFFF      CALL    `USER32!DialogBoxIndirectParamA`<--注意機器碼(5位元組)
017F:00F5C8CB 5B              POP      EBX
017F:00F5C8CC 5D              POP      EBP
017F:00F5C8CD C21400          RET      14

但由於我們已重構輸入表,故上述函式要稍作修改才能引用。
在用 ImpREC重構輸入表時我們看到相關的幾項

Flag    RVA        ModuleName    Ordinal    Name
1    00040138    KERNEL32.dll    0123    FindResourceA
1    0004012C    KERNEL32.dll    023E    LockResource
1    00040130    KERNEL32.dll    022E    LoadResource
1    00040368    USER32.dll    0091    DialogBoxIndirectParamA

就可知:
KERNEL32!FindResourceA函式呼叫地址存放在00040138+400000=00440138
KERNEL32!LoadResource函式呼叫地址存放在00440130
KERNEL32!LockResource函式呼叫地址存放在0044012C
USER32!DialogBoxIndirectParamA函式呼叫地址存放在00440368

所以我們作以下修改

017F:004D0F98 55              PUSH    EBP
017F:004D0F99 8BEC            MOV      EBP,ESP
017F:004D0F9B 53              PUSH    EBX
017F:004D0F9C 8B5D08          MOV      EBX,[EBP+08]
017F:004D0F9F 8B4518          MOV      EAX,[EBP+18]
017F:004D0FA2 50              PUSH    EAX
017F:004D0FA3 8B4514          MOV      EAX,[EBP+14]
017F:004D0FA6 50              PUSH    EAX
017F:004D0FA7 8B4510          MOV      EAX,[EBP+10]
017F:004D0FAA 50              PUSH    EAX
017F:004D0FAB 6A05            PUSH    BYTE +05
017F:004D0FAD 8B450C          MOV      EAX,[EBP+0C]
017F:004D0FB0 50              PUSH    EAX
017F:004D0FB1 53              PUSH    EBX
017F:004D0FB2 FF1538014400    CALL    `KERNEL32!FindResourceA`    <--注意機器碼(6位元組)
017F:004D0FB8 50              PUSH    EAX
017F:004D0FB9 53              PUSH    EBX
017F:004D0FBA FF1530014400    CALL    `KERNEL32!LoadResource`        <--注意機器碼(6位元組)
017F:004D0FC0 50              PUSH    EAX
017F:004D0FC1 FF152C014400    CALL    `KERNEL32!LockResource`        <--注意機器碼(6位元組)
017F:004D0FC7 50              PUSH    EAX
017F:004D0FC8 53              PUSH    EBX
017F:004D0FC9 FF1568034400    CALL    `USER32!DialogBoxIndirectParamA`<--注意機器碼(6位元組)
017F:004D0FCF 5B              POP      EBX
017F:004D0FD0 5D              POP      EBP
017F:004D0FD1 C21400          RET      14

然後我們來打補丁!找一塊大小合適沒有使用空間,我在用 ImpREC重構輸入表時所加的段中選了一塊

Offset      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
000D0F90  98 0F 4D 00 00 00 00 00  55 8B EC 53 8B 5D 08 8B  ?M.....US].?
000D0FA0  45 18 50 8B 45 14 50 8B  45 10 50 6A 05 8B 45 0C  E.PE.PE.Pj.E.
000D0FB0  50 53 FF 15 38 01 44 00  50 53 FF 15 30 01 44 00  PS.8.D.PS.0.D.
000D0FC0  50 FF 15 2C 01 44 00 50  53 FF 15 68 03 44 00 5B  P.,.D.PS.h.D.[
000D0FD0  5D C2 14 00 00 00 00 00  00 00 00 00 00 00 00 00  ]?.............

Offset000D0F90存放的是函式呼叫地址004D0F98,並在Offset000D0F98中寫入修正後函式的機器碼。

最後把原先找到的幾處呼叫中Call dword ptr [00440368]改為[004D0f90]

其中之(一)
* Reference To: USER32.DialogBoxIndirectParamA, Ord:0091h
                                  |
:00434713 FF1568034400            Call dword ptr [004D0f90]

終於大功告成!點選HELP中的Registration繡出Registration視窗。Asprotect保護的程式脫殼後的修正
就講到這裡。希望對大家有幫助!

相關文章