為Asp-Loader增加命令列功能,高手莫笑 (7千字)

看雪資料發表於2002-10-15

一、問題的提出:
為了SendTo的客觀需要。

二、分析原檔案:
004017A6  |. C685 B0FBFFFF 00        MOV BYTE PTR SS:[EBP-450],0
004017AD  |. C785 ECFAFFFF AC104000  MOV DWORD PTR SS:[EBP-514],LOADER.004010AC        ;  ASCII "exe file"
004017B7  |. C785 10FBFFFF CC104000  MOV DWORD PTR SS:[EBP-4F0],LOADER.004010CC        ;  ASCII "Choose a exe..."
004017C1  |. 8D8D B0FBFFFF            LEA ECX,DWORD PTR SS:[EBP-450]
004017C7  |. 898D FCFAFFFF            MOV DWORD PTR SS:[EBP-504],ECX
004017CD  |. C785 00FBFFFF 04010000  MOV DWORD PTR SS:[EBP-500],104
004017D7  |. C785 14FBFFFF 00180000  MOV DWORD PTR SS:[EBP-4EC],1800
004017E1  |. C785 F8FAFFFF 01000000  MOV DWORD PTR SS:[EBP-508],1
004017EB  |. C785 1CFBFFFF DC104000  MOV DWORD PTR SS:[EBP-4E4],LOADER.004010DC        ;  ASCII "exe"
004017F5  |. C785 0CFBFFFF E0104000  MOV DWORD PTR SS:[EBP-4F4],LOADER.004010E0
004017FF  |. C785 E0FAFFFF 4C000000  MOV DWORD PTR SS:[EBP-520],4C
00401809  |. 8D95 E0FAFFFF            LEA EDX,DWORD PTR SS:[EBP-520]
0040180F  |. 52                      PUSH EDX                                          ; /pOpenFileName
00401810  |. FF15 70104000            CALL DWORD PTR DS:[<&comdlg32.GetOpenFileNameA>]  ; \GetOpenFileNameA      ;如果在GetOpenFileNameA之前先判斷一下引數,如果有引數則直接Load引數所代表的EXE,否則再開啟這個對話方塊。
00401816  . 85C0                    TEST EAX,EAX
00401818  . 75 05                    JNZ SHORT LOADER.0040181F
0040181A  . E9 8F0B0000              JMP LOADER.004023AE
0040181F  > 6A 00                    PUSH 0                                            ; /hTemplateFile =  NULL    ;如果帶有引數,直接跳到這裡。
00401821  . 6A 01                    PUSH 1                                            ; |Attributes = READONLY
00401823  . 6A 03                    PUSH 3                                            ; |Mode = OPEN_EXISTING
00401825  . 6A 00                    PUSH 0                                            ; |pSecurity = NULL
00401827  . 6A 01                    PUSH 1                                            ; |ShareMode = FILE_SHARE_READ
00401829  . 68 00000080              PUSH 80000000                                    ; |Access = GENERIC_READ
0040182E  . 8D85 B0FBFFFF            LEA EAX,DWORD PTR SS:[EBP-450]                    ; |
00401834  . 50                      PUSH EAX                                          ; |FileName
00401835  . FF15 40104000            CALL DWORD PTR DS:[<&KERNEL32.CreateFileA>]      ; \CreateFileA


三、解決方案
1、準備工作
要想取得引數,得用到GetCommandLineA。原想用LordPE加入這個函式到引入表。可是LordPE顯示沒有足夠的空間!!!!!開啟目標程式一看,“乖乖,真的有效”,老大可真是惜字如金,怪不得功能這麼強大的東東才只有8K!!!

Offset      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

000001C0  2E 74 65 78 74 00 00 00  00 1D 00 00 00 10 00 00  .text...........
000001D0  00 1D 00 00 00 02 00 00  00 00 00 00 00 00 00 00  ................
000001E0  00 00 00 00 20 00 00 E0  00 00 00 00 00 00 00 00  .... ..?.......
000001F0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

程式只用到了一個SECTION,裡面包括所有的資料和程式碼,想再把檔案頭擴大200位元組,有些麻煩,而且原檔案增大不少,最重要的是有可能出現未知錯誤(反正我沒有嘗試)。手動增加引入函式吧。什麼?沒有空間?想辦法呀:P

2、身體力行之手動增加引入函式
不管三七二十一,先在程式末尾加入GetCommandLineA的描述字串:
Offset      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

00001DE0              00 00 47 65  74 43 6F 6D 6D 61 6E 64      ..GetCommand
00001DF0  4C 69 6E 65 41 00 4B 65  72 6E 65 6C 33 32 2E 64  LineA.Kernel32.d
00001E00  6C 6C 00 E4 2B 00 00                              ll.?..
                    ^^^^^^^^^^^=1DE4+100-4200

看程式的引入表塊指標:
Offset      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

00000140                            18 29 00 00                      .)..

從2918h-1000h+200h=1b18h處向前看,這不是有很多0嗎?這不就是空間?可是,呵呵,這是資料區,可不是那麼便宜就給你用的。如果沒用,憑老大這麼吝嗇的人,會給你留著?:P
Offset      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

00001AE0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00001AF0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00001B00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00001B10  00 00 00 00 00 00 00 00  84 29 00 00 00 00 00 00  ........?......
00001B20  00 00 00 00 70 2B 00 00  08 10 00 00 E0 29 00 00  ....p+......?..

沒辦法,暫時借用一下,等你用時再還給你,反正我只用一次,而且是在你用之前(我是瞎猜的,但運氣好得很,在我用這塊資料區之前,程式暫時沒用到它),我把它還原成“00”不就得了嘛。在這裡面增加引入表的結構塊:
Offset      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

00001B00              03 2C 00 00  00 00 00 00 00 00 00 00      .,..........
00001B10  F6 2B 00 00 03 2C 00 00                            ?...,..

修改OPTIONAL HEADER裡面的引入表偏移,
從原來的002918改為002918-14=002904:
Offset      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

00000140                            04 29 00 00                      .)..

3、身體力行之補丁檔案:
然後呢,就是在GetOpenFileName之前判斷是否帶有命令列引數,如果有,就不顯示開啟檔案的對話方塊,直接Load它.......

a)修改GetOpenFileName之前語句,轉向我們的判斷:
004017A6    . 68 102C400>PUSH CMDLNLOA.00402C10
004017AB    . C3        RETN                                              ;  RET used as a jump to 00402C10
004017AC      90        NOP

b)我們的判斷部分:
GetCommandLine沒有用到其他引數,返回值eax指向命令列引數的起始地址。沒得說了。

00402C10    > 60        PUSHAD
00402C11    . FF15 032C4>CALL DWORD PTR DS:[<&Kernel32.GetCommandLineA>]  ; [GetCommandLineA]
00402C17    . 8BF8      MOV EDI,EAX
00402C19    . 57        PUSH EDI          ;儲存備用,下次查詢引數的起始地址
00402C1A    . 33C0      XOR EAX,EAX        ;查詢命令列結尾,ecx存放命令列長度。
00402C1C    . 33C9      XOR ECX,ECX
00402C1E    . 49        DEC ECX
00402C1F    . F2:AE      REPNE SCAS BYTE PTR ES:[EDI]
00402C21    . F7D9      NEG ECX
00402C23    . 49        DEC ECX
00402C24    . 49        DEC ECX
00402C25    . 5F        POP EDI            ;查詢引數的起始地址,以第一個空格為標誌。
00402C26    . B0 20      MOV AL,20
00402C28    . F2:AE      REPNE SCAS BYTE PTR ES:[EDI]
00402C2A    . 51        PUSH ECX          ;ECX為引數的長度,入棧。
00402C2B    . 90        NOP
00402C2C    . 90        NOP
00402C2D    . 8BF7      MOV ESI,EDI        ;從原文的GetOpenFileName來看,EBP-450處是檔名存放的地方
00402C2F    . 8DBD B0FBF>LEA EDI,DWORD PTR SS:[EBP-450]  ;複製引數過去。
00402C35    . 41        INC ECX            ;把結尾的0也複製過去
00402C36    . F3:A4      REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
00402C38    . BF 0429400>MOV EDI,CMDLNLOA.00402904      ;還記得我們當初借用的資料空間嗎?把它還原為14H個字長的0。
00402C3D    . B9 0500000>MOV ECX,5
00402C42    . 33C0      XOR EAX,EAX
00402C44    . F3:AB      REP STOS DWORD PTR ES:[EDI]
00402C46    . 59        POP ECX            ;判斷命令列長度,如果為0,出現開啟檔案對話方塊;否則直接Load...
00402C47    . 85C9      TEST ECX,ECX
00402C49    . 74 07      JE SHORT CMDLNLOA.00402C52
00402C4B    . 61        POPAD
00402C4C    . 68 1F18400>PUSH CMDLNLOA.0040181F
00402C51    . C3        RETN                                              ;  RET used as a jump to 0040181F
00402C52    > 61        POPAD
00402C53    . 68 AD17400>PUSH CMDLNLOA.004017AD
00402C58    . C3        RETN                                              ;  RET used as a jump to 004017AD


四、完成啦。太過弱智化,高手莫笑。

wscn
02/10/15

相關文章