• 标 题:实现W32dsm.exe在2000下的命令行功能,老调重弹啦 (6千字)
  • 作 者:wscn
  • 时 间:2002-10-15 21:54:07
  • 链 接:http://bbs.pediy.com

一、问题的提出:
    我在SendTo文件夹下放了很多常用的软件的快捷方式。但是其生效的基本条件是必须支持命令行参数。W32DSM的KILLER版说明支持此参数,而且在WIN98下也通过了。但在2000下用SENDTO会自动退出。

二、查找原因:
是一个STD指令惹的祸。这个我们在以前已经讲过了。
1、
:10043042 890D305A0410            mov dword ptr [10045A30], ecx
:10043048 FD                      std                        ;设置字符串处理的方向为逆向,这在NT里面的一些函数中会发生不可预料的错误
:10043049 B05C                    mov al, 5C
:1004304B F2                      repnz
:1004304C AE                      scasb
:1004304D 85C9                    test ecx, ecx
:1004304F 7417                    je 10043068
:10043051 8BD9                    mov ebx, ecx
:10043053 83C702                  add edi, 00000002
:10043056 C647FF00                mov [edi-01], 00
:1004305A 56                      push esi

* Reference To: KERNEL32.SetCurrentDirectoryA, Ord:023Eh    ;调用这个函数前要把其字符串的处理方向设置为正向
                                  |
:1004305B E8C80C0000              Call 10043D28

2、类似的还有一处(这是我们以前改过的):
:10043168 FD                      std                      ;;;;;;;;;;;;;
:10043169 B05C                    mov al, 5C
:1004316B F2                      repnz
:1004316C AE                      scasb
:1004316D 85C9                    test ecx, ecx
:1004316F 741C                    je 1004318D
:10043171 83C702                  add edi, 00000002
:10043174 C647FF00                mov [edi-01], 00
:10043178 3BFE                    cmp edi, esi
:1004317A 7411                    je 1004318D
:1004317C 56                      push esi

* Reference To: KERNEL32.SetCurrentDirectoryA, Ord:023Eh      ;;;;;;;;;;;;
                                  |
:1004317D E8A60B0000              Call 10043D28

3、修改方法如下(以前也说过):
:10043048 FD                      std
:10043049 B05C                    mov al, 5C
:1004304B F2                      repnz
:1004304C AE                      scasb
:1004304D 85C9                    test ecx, ecx
:1004304F 7417                    je 10043068
:10043051 8BD9                    mov ebx, ecx
:10043053 47                      inc edi                      ;;;;;;;;;;;
:10043054 C60700                  mov byte ptr [edi], 00      ;;;;;;;;;;;
:10043057 47                      inc edi                      ;;;;;;;;;;;
:10043058 FC                      cld                          ;这里恢复其默认设置
:10043059 90                      nop                          ;呵呵,2条指令变4条,还多了一个字节
:1004305A 56                      push esi

* Reference To: KERNEL32.SetCurrentDirectoryA, Ord:023Eh
                                  |
:1004305B E8C80C0000              Call 10043D28

三、具体解决方案:
经过跟踪分析,在KILLER的W32DSM版本中,有两个对W32PATCH.DLL的写操作。其中应该以后一个(5271XX处的最终有效)。不管这么多,都改就行了。

1、这里:
005411A4    8DB5 953B4000    LEA ESI,DWORD PTR SS:[EBP+403B95]      ;指向%system%\W32PATCH.DLL
005411AA    6A 00            PUSH 0
005411AC    68 80000000      PUSH 80
005411B1    6A 02            PUSH 2
005411B3    6A 00            PUSH 0
005411B5    6A 00            PUSH 0
005411B7    68 00000040      PUSH 40000000
005411BC    56                PUSH ESI
005411BD    FF95 39364000    CALL DWORD PTR SS:[EBP+403639]        ;实际上是CreateFileA
005411C3    83F8 FF          CMP EAX,-1
005411C6    0F84 B9000000    JE W32ASM_2.00541285
...
0054121F    E8 710B0000      CALL W32ASM_2.00541D95
00541224    8D9D 93344000    LEA EBX,DWORD PTR SS:[EBP+403493]
0054122A    6A 00            PUSH 0
0054122C    53                PUSH EBX
0054122D    FFB5 CB344000    PUSH DWORD PTR SS:[EBP+4034CB]
00541233    FFB5 C7344000    PUSH DWORD PTR SS:[EBP+4034C7]        ;指向W32PATCH.DLL的缓冲区的指针
00541239    FFB5 C3344000    PUSH DWORD PTR SS:[EBP+4034C3]
0054123F    FF95 79364000    CALL DWORD PTR SS:[EBP+403679]        ;WriteFile

2、再到这里:
005271A4    8DB5 953B4000    LEA ESI,DWORD PTR SS:[EBP+403B95]      ;指向%system%\W32PATCH.DLL
005271AA    6A 00            PUSH 0
005271AC    68 80000000      PUSH 80
005271B1    6A 02            PUSH 2
005271B3    6A 00            PUSH 0
005271B5    6A 00            PUSH 0
005271B7    68 00000040      PUSH 40000000
005271BC    56                PUSH ESI
005271BD    FF95 39364000    CALL DWORD PTR SS:[EBP+403639]        ;实际上是CreateFileA
005271C3    83F8 FF          CMP EAX,-1
005271C6    0F84 B9000000    JE W32ASM_2.00527285
...
00527224    8D9D 93344000    LEA EBX,DWORD PTR SS:[EBP+403493]
0052722A    6A 00            PUSH 0
0052722C    53                PUSH EBX
0052722D    FFB5 CB344000    PUSH DWORD PTR SS:[EBP+4034CB]
00527233    FFB5 C7344000    PUSH DWORD PTR SS:[EBP+4034C7]
00527239    FFB5 C3344000    PUSH DWORD PTR SS:[EBP+4034C3]        ;指向W32PATCH.DLL的缓冲区的指针
0052723F    FF95 79364000    CALL DWORD PTR SS:[EBP+403679]        ;WriteFile

3、补丁方案:
这两处补丁方法都一样,所以写一个标准的补丁代码段,用CALL调用它:)
(1)通用补丁的代码:
004AF811    . 8B85 C7344000    MOV EAX,DWORD PTR SS:[EBP+4034C7]
004AF817    . 8BD8            MOV EBX,EAX
004AF819    . 05 71310000      ADD EAX,3171
004AF81E    . 81C3 53300000    ADD EBX,3053
004AF824    . 68 47C60700      PUSH 7C647
004AF829    . 8F00            POP DWORD PTR DS:[EAX]
004AF82B    . FF30            PUSH DWORD PTR DS:[EAX]
004AF82D    . 8F03            POP DWORD PTR DS:[EBX]
004AF82F    . 68 0047FC90      PUSH 90FC4700            ;其中00字节是重复PUSH和POP的,为了避免影响后续的字节
004AF834    . 8F40 03          POP DWORD PTR DS:[EAX+3]
004AF837    . FF70 03          PUSH DWORD PTR DS:[EAX+3]
004AF83A    . 8F43 03          POP DWORD PTR DS:[EBX+3]
004AF83D    . 8D9D 93344000    LEA EBX,DWORD PTR SS:[EBP+403493]
004AF843    . C3              RETN

(2)需要修改的跳转:
a)
00541224    E8 E8E5F6FF        CALL W32ASM_2.004AF811        ;这里
00541229    90                NOP
0054122A    6A 00              PUSH 0
0054122C    53                PUSH EBX
0054122D    FFB5 CB344000      PUSH DWORD PTR SS:[EBP+4034CB]
00541233    FFB5 C7344000      PUSH DWORD PTR SS:[EBP+4034C7]
00527239    FFB5 C3344000      PUSH DWORD PTR SS:[EBP+4034C3]        ;指向W32PATCH.DLL的缓冲区的指针
0052723F    FF95 79364000      CALL DWORD PTR SS:[EBP+403679]        ;WriteFile
b)
00527224    E8 E885F8FF        CALL W32ASM_2.004AF811
00527229    90                NOP
0052722A    6A 00              PUSH 0
0052722C    53                PUSH EBX
0052722D    FFB5 CB344000      PUSH DWORD PTR SS:[EBP+4034CB]
00527233    FFB5 C7344000      PUSH DWORD PTR SS:[EBP+4034C7]
00527239    FFB5 C3344000      PUSH DWORD PTR SS:[EBP+4034C3]        ;指向W32PATCH.DLL的缓冲区的指针
0052723F    FF95 79364000      CALL DWORD PTR SS:[EBP+403679]        ;WriteFile

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


wscn
02/10/15