最近的W32dsm v8.93漏洞:
"The program uses the wsprintf() function to copy the name of the
imported/exported functions of the analyzed file into a buffer of only
256 bytes, with the possibility for an attacker to execute malicious
code."

验证了一下,W32dsm处理导入函数时确实存在栈溢出漏洞,但是很长导入函数会造成PE文件无效,所以用作Anti-W32dsm可能性不大。仔细
看看漏洞说明"imported/exported functions...",如果导出函数也有同样漏洞那就...嘻嘻...因为很长的导出函数不会导致PE文件无效,
而且一般不会去看一个.exe文件的导出表,所以有利用价值。

废话少说,先分析一下W32dsm对导入/导出函数的处理。

W32dsm对导入函数处理的分析:

0045D805   |> \6A 00             ||push 0                                    ; /Origin = FILE_BEGIN
0045D807   |.  6A 00             ||push 0                                    ; |pOffsetHi = NULL
0045D809   |.  8B45 E0           ||mov eax,dword ptr ss:[ebp-20]             ; |
0045D80C   |.  8B55 EC           ||mov edx,dword ptr ss:[ebp-14]             ; |
0045D80F   |.  03C2              ||add eax,edx                               ; |
0045D811   |.  8B4D FC           ||mov ecx,dword ptr ss:[ebp-4]              ; |
0045D814   |.  2BC1              ||sub eax,ecx                               ; |
0045D816   |.  50                ||push eax                                  ; |OffsetLo
0045D817   |.  FFB3 12596000     ||push dword ptr ds:[ebx+605912]            ; |hFile
0045D81D   |.  E8 1E130500       ||call W32dsm8_.004AEB40                    ; \SetFilePointer
0045D822   |.  6A 00             ||push 0                                    ; /pOverlapped = NULL
0045D824   |.  8D45 F4           ||lea eax,dword ptr ss:[ebp-C]              ; |
0045D827   |.  50                ||push eax                                  ; |pBytesRead
0045D828   |.  6A 02             ||push 2                                    ; |BytesToRead = 2
0045D82A   |.  69D6 CEEA0200     ||imul edx,esi,2EACE                        ; |
0045D830   |.  03D3              ||add edx,ebx                               ; |
0045D832   |.  6BCF 5B           ||imul ecx,edi,5B                           ; |
0045D835   |.  03D1              ||add edx,ecx                               ; |
0045D837   |.  81C2 F26A1700     ||add edx,176AF2                            ; |
0045D83D   |.  52                ||push edx                                  ; |Buffer
0045D83E   |.  FFB3 12596000     ||push dword ptr ds:[ebx+605912]            ; |hFile
0045D844   |.  E8 CD120500       ||call W32dsm8_.004AEB16                    ; \ReadFile 【1】:读入导入函数字符串的偏移
0045D849   |.  6A 00             ||push 0                                    ; /Origin = FILE_BEGIN
0045D84B   |.  6A 00             ||push 0                                    ; |pOffsetHi = NULL
0045D84D   |.  8B45 E0           ||mov eax,dword ptr ss:[ebp-20]             ; |
0045D850   |.  8B55 EC           ||mov edx,dword ptr ss:[ebp-14]             ; |
0045D853   |.  03C2              ||add eax,edx                               ; |
0045D855   |.  8B4D FC           ||mov ecx,dword ptr ss:[ebp-4]              ; |
0045D858   |.  2BC1              ||sub eax,ecx                               ; |
0045D85A   |.  83C0 02           ||add eax,2                                 ; |
0045D85D   |.  50                ||push eax                                  ; |OffsetLo
0045D85E   |.  FFB3 12596000     ||push dword ptr ds:[ebx+605912]            ; |hFile
0045D864   |.  E8 D7120500       ||call W32dsm8_.004AEB40                    ; \SetFilePointer
0045D869   |.  6A 00             ||push 0                                    ; /pOverlapped = NULL
0045D86B   |.  8D45 F4           ||lea eax,dword ptr ss:[ebp-C]              ; |
0045D86E   |.  50                ||push eax                                  ; |pBytesRead
0045D86F   |.  68 2C010000       ||push 12C                                  ; |BytesToRead = 12C (300.)
0045D874   |.  FFB3 A5726000     ||push dword ptr ds:[ebx+6072A5]            ; |Buffer
0045D87A   |.  FFB3 12596000     ||push dword ptr ds:[ebx+605912]            ; |hFile
0045D880   |.  E8 91120500       ||call W32dsm8_.004AEB16                    ; \ReadFile 【2】:从【1】得到的偏移开始,读入12C字节。注意是12c字节!
0045D885   |.  FFB3 A5726000     ||push dword ptr ds:[ebx+6072A5]            ; /String2
0045D88B   |.  8D93 2B0A6400     ||lea edx,dword ptr ds:[ebx+640A2B]         ; |
0045D891   |.  52                ||push edx                                  ; |String1
0045D892   |.  E8 C3130500       ||call W32dsm8_.004AEC5A                    ; \lstrcpyA
...
0045D8C8   |>  8D83 2B0A6400     ||lea eax,dword ptr ds:[ebx+640A2B]
0045D8CE   |.  50                ||push eax                                  ; /<%s>
0045D8CF   |.  68 18384C00       ||push W32dsm8_.004C3818                    ; |Format = "%s"
0045D8D4   |.  8D95 04FFFFFF     ||lea edx,dword ptr ss:[ebp-FC]             ; |
0045D8DA   |.  52                ||push edx                                  ; |s
0045D8DB   |.  E8 A0170500       ||call W32dsm8_.004AF080                    ; \wsprintfA    ★

注意wsprintfA函数的第一个参数,[ebp-F4],这是函数名字符串开始覆盖的地方,由于读入字符串最大是12C > FC,所以只要导入函数名
足够长就会产生栈溢出。



W32dsm对导出函数处理的分析:

0045DD72   |> /6A 00             /push 0                                     ; /Origin = FILE_BEGIN
0045DD74   |. |6A 00             |push 0                                     ; |pOffsetHi = NULL
0045DD76   |. |8B45 FC           |mov eax,dword ptr ss:[ebp-4]               ; |
0045DD79   |. |03C7              |add eax,edi                                ; |
0045DD7B   |. |50                |push eax                                   ; |OffsetLo
0045DD7C   |. |FFB3 12596000     |push dword ptr ds:[ebx+605912]             ; |hFile
0045DD82   |. |E8 B90D0500       |call W32dsm8_.004AEB40                     ; \SetFilePointer
0045DD87   |. |6A 00             |push 0                                     ; /pOverlapped = NULL
0045DD89   |. |8D55 E4           |lea edx,dword ptr ss:[ebp-1C]              ; |
0045DD8C   |. |52                |push edx                                   ; |pBytesRead
0045DD8D   |. |6A 04             |push 4                                     ; |BytesToRead = 4
0045DD8F   |. |8D4D F0           |lea ecx,dword ptr ss:[ebp-10]              ; |
0045DD92   |. |51                |push ecx                                   ; |Buffer = 006DBF1C
0045DD93   |. |FFB3 12596000     |push dword ptr ds:[ebx+605912]             ; |hFile
0045DD99   |. |E8 780D0500       |call W32dsm8_.004AEB16                     ; \ReadFile 【3】:读入导出函数字符串的偏移
0045DD9E   |. |8B45 E4           |mov eax,dword ptr ss:[ebp-1C]
0045DDA1   |. |85C0              |test eax,eax
0045DDA3   |. |75 07             |jnz short W32dsm8_.0045DDAC
0045DDA5   |. |33C0              |xor eax,eax
0045DDA7   |. |E9 BB020000       |jmp W32dsm8_.0045E067
0045DDAC   |> |83C7 04           |add edi,4
0045DDAF   |. |8B93 DC376F00     |mov edx,dword ptr ds:[ebx+6F37DC]
0045DDB5   |. |2955 F0           |sub dword ptr ss:[ebp-10],edx
0045DDB8   |. |8B8B D8376F00     |mov ecx,dword ptr ds:[ebx+6F37D8]
0045DDBE   |. |014D F0           |add dword ptr ss:[ebp-10],ecx
0045DDC1   |. |6A 00             |push 0                                     ; /Origin = FILE_BEGIN
0045DDC3   |. |6A 00             |push 0                                     ; |pOffsetHi = NULL
0045DDC5   |. |FF75 F0           |push dword ptr ss:[ebp-10]                 ; |OffsetLo
0045DDC8   |. |FFB3 12596000     |push dword ptr ds:[ebx+605912]             ; |hFile
0045DDCE   |. |E8 6D0D0500       |call W32dsm8_.004AEB40                     ; \SetFilePointer
0045DDD3   |. |6A 00             |push 0                                     ; /pOverlapped = NULL
0045DDD5   |. |8D45 E4           |lea eax,dword ptr ss:[ebp-1C]              ; |
0045DDD8   |. |50                |push eax                                   ; |pBytesRead
0045DDD9   |. |6A 4F             |push 4F                                    ; |BytesToRead = 4F (79.)
0045DDDB   |. |8D55 8C           |lea edx,dword ptr ss:[ebp-74]              ; |
0045DDDE   |. |52                |push edx                                   ; |Buffer
0045DDDF   |. |FFB3 12596000     |push dword ptr ds:[ebx+605912]             ; |hFile
0045DDE5   |. |E8 2C0D0500       |call W32dsm8_.004AEB16                     ; \ReadFile 【4】:从【3】得到的偏移开始,读入4F字节
0045DDEA   |. |8B4D E4           |mov ecx,dword ptr ss:[ebp-1C]
0045DDED   |. |85C9              |test ecx,ecx
0045DDEF   |. |75 07             |jnz short W32dsm8_.0045DDF8
0045DDF1   |. |33C0              |xor eax,eax
0045DDF3   |. |E9 6F020000       |jmp W32dsm8_.0045E067
0045DDF8   |> |C645 DB 00        |mov byte ptr ss:[ebp-25],0
0045DDFC   |. |0FBE55 8C         |movsx edx,byte ptr ss:[ebp-74]
0045DE00   |. |83FA 40           |cmp edx,40
0045DE03   |. |75 22             |jnz short W32dsm8_.0045DE27
0045DE05   |. |8B8B 74116F00     |mov ecx,dword ptr ds:[ebx+6F1174]
0045DE0B   |. |85C9              |test ecx,ecx
0045DE0D   |. |74 18             |je short W32dsm8_.0045DE27
0045DE0F   |. |6A 01             |push 1
0045DE11   |. |8D85 3CFFFFFF     |lea eax,dword ptr ss:[ebp-C4]
0045DE17   |. |50                |push eax
0045DE18   |. |8D55 8C           |lea edx,dword ptr ss:[ebp-74]
0045DE1B   |. |52                |push edx
0045DE1C   |. |53                |push ebx
0045DE1D   |. |E8 6F2C0000       |call W32dsm8_.00460A91
0045DE22   |. |83C4 10           |add esp,10
0045DE25   |. |EB 18             |jmp short W32dsm8_.0045DE3F
0045DE27   |> |8D4D 8C           |lea ecx,dword ptr ss:[ebp-74]
0045DE2A   |. |51                |push ecx                                   ; /<%s>
0045DE2B   |. |68 60384C00       |push W32dsm8_.004C3860                     ; |Format = "%s"
0045DE30   |. |8D85 3CFFFFFF     |lea eax,dword ptr ss:[ebp-C4]              ; |
0045DE36   |. |50                |push eax                                   ; |s
0045DE37   |. |E8 44120500       |call W32dsm8_.004AF080                     ; \wsprintfA    ★

注意wsprintfA函数的第一个参数,[ebp-C4],这是函数名字符串开始覆盖的地方,由于函数名最大只读入4F,无法覆盖到ebp-C4,
所以无法产生栈溢出。

结论:W32dsm只是在处理导入函数时有可能导致栈溢出,由于windows loader会对导入函数进行有效性判断,所以利用该漏洞设计
Anti-W32dsm可能不大。

水平有限,不对之处请指正。