用MASM32编程获取网站首页文件名并读取首页代码

用MASM32编程读取网站首页代码

记得在某个汇编论坛上有网友讨论如何获取一个网站的首页文件名,是index.htm,index.html,index.asp,还是……
于是动手写了这个程序读取网站的返回信息来做测试,发现有些网站的返回信息中的Content-Location值包含了首页文件名,如www.hcny.gov.cn
/---
HTTP/1.1 200 OK
Content-Length: 34432
Content-Type: text/html
Content-Location: http://www.hcny.gov.cn/index.htm
Last-Modified: Wed, 05 Dec 2007 02:59:18 GMT
Accept-Ranges: bytes
ETag: "244d2d3ea36c81:80a"
Server: Microsoft-IIS/6.0
Date: Wed, 05 Dec 2007 15:05:19 GMT
---/


有些网站则没有,如www.163.com
/---
HTTP/1.0 200 OK
Date: Wed, 05 Dec 2007 15:01:13 GMT
Server: Apache/2.0.59 (Unix)
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Length: 127476
Content-Type: text/html; charset=GB2312
Age: 265
X-Cache: HIT from www.163.com
Connection: keep-alive
---/

另外 IE 从 SP2 开始不支持 view-source 了,为了使用 view-source 而装一个 FireFox 似乎有点麻烦,于是加了读取网页代码的功能。目前是读取网站的首页的代码。
其中的一些代码参考了MASM32官方论坛的贴子:
http://www.masm32.com/board/index.php?topic=8197.0

增加了SearchStr()来搜索网页代码结束位置后,程序运行时间要多久一些,改进的方法是参考网站的返回信息中的Content-Length的值,在最后一次从Sock读取数据时进行进行搜索……

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;  FileName: WebHome.asm
;    Author: Purple Endurer
; Functiion: Read a web homepage content
;    DevEnv: Win XP SP2 + MASM32 v8

; log
; ------------------------------
; 2007-12-05 Added SearchStr() to search the webpage code end mark string 
; 2007-12-04 Can read web homepage content
; 2007-12-03 Created!
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.386
.model  flatstdcall
option  casemap: none

include /masm32/ include/windows.inc

include /masm32/ include/kernel32.inc
includelib /masm32/ lib/kernel32.lib

include /masm32/ include/user32.inc
includelib /masm32/ lib/user32.lib

include /masm32/ include/shell32.inc
includelib /masm32/ lib/shell32.lib

include /masm32/ include/wsock32.inc
includelib /masm32/ lib/wsock32.lib


WinMain  PROTO : DWORD, : DWORD, : DWORD, : DWORD
btnShow_Click  PROTO
fInitInternet  proto : dword
fConnect  proto lpszHostName: dword,nPortNumber: dword
SendHttpHead  proto :LPSTR, :LPSTR
ReadSockData  proto :LPSTR, : dword
ResizeConctrol  proto : DWORD
SearchStr  proto :LPSTR, :LPSTR


m_GotoEnd  MACRO
     invoke SendMessage, g_hEditVerInfo, EM_SETSEL, 0 , -1
     invoke SendMessage, g_hEditVerInfo, EM_SETSEL, -1 , 0
ENDM

m_InsStr  MACRO lpszStr: REQ
     invoke SendMessage, g_hEditVerInfo, EM_REPLACESEL,  FALSE, lpszStr
ENDM

m_GoNextLine  MACRO
    m_InsStr  addr g_szCR
ENDM

m_InsCrStr  MACRO lpszStr: REQ
    m_GoNextLine
    m_InsStr  lpszStr
ENDM


WM_FSOCKET       equ WM_USER + 0fh
IDC_BtnRead      equ 103
IDC_EdtURL       equ 105
IDC_EdtHTML      equ 107

c_BufLen         equ 5000h
c_Resize         equ 1
d_TestData       equ 1

c_EditURLLeft    equ 2
c_EditURLTop     equ 5
c_EditURLWidth   equ 500
c_EditURLHeight  equ 20

c_BtnReadTop     equ c_EditURLTop
c_BtnReadLeft    equ (c_EditURLLeft+c_EditURLWidth+10)
c_BtnReadWidth   equ 70
c_BtnReadHeight  equ c_EditURLHeight

c_EdtHTMLLeft    equ 2
c_EdtHTMLTop     equ 30
c_EdtHTMLWidth   equ c_BtnReadLeft+c_BtnReadWidth+2
c_EdtHTMLHeight  equ 300

c_WinWidth       equ c_EdtHTMLLeft+c_EdtHTMLWidth+10
c_WinHeight      equ c_EdtHTMLTop+c_EdtHTMLHeight+30

c_RichEditStyle  equ WS_CHILD  or WS_VISIBLE  or ES_MULTILINE  or WS_VSCROLL  or ES_AUTOVSCROLL  or WS_HSCROLL  or ES_NOHIDESEL  or ES_SAVESEL  or ES_SELECTIONBAR

MAX_STRING_LEN   equ 8192 ; 2000h
SYSINFO_RET_OK   equ 1
SYSINFO_RET_FAIL  equ 2

;sssssssssss
.data
;sssssssssss
g_szClsName label  byte
g_szAppName  db  "HttpDemo", 0
if d_TestData eq 1
    g_szTestURL  db  "www.hcny.gov.cn", 0
endif    ;d_TestData
g_szFailIni  db  "Fail initialize internet connection!", 0
g_szFailGetHostName  db  "Fail to get host name!", 0
g_szConnect  db  "Fail to connect!", 0
g_szFailWSAStartup  db  "Fail to WSAStartup", 0
g_szEnterURL  db  "请先输入URL!", 0

g_szEditCls  db  "EDIT", 0
g_szBtnCls  db  "button", 0

g_szNoRichEdit     db  "无法载入"
g_szRichEditDLL    db  "RICHED20.DLL", 0
g_szRichEditClass  db  "RichEdit20A", 0

g_szBtnReadText  db  "&R 读取", 0
g_szFmt1  db  "GET /%s HTTP/1.1", 0dh, 0ah
     db  "Host:%s", 0dh, 0ah
     db  "Accept: */*", 0dh, 0ah
     db  "User-Agent: Mozilla/4.0"
     db  "(compatible; MSIE 6.00; Windows 2000)", 0dh, 0ah
     db  "Connection:Keep-Alive", 0dh, 0ah
     db 0dh, 0ah
g_szCR  db 0dh, 0ah, 0

g_szHTTP400  db  "HTTP/1.1 400 Bad Request", 0
g_szFmt2  db  "WSACleanup failed with error %d", 0

;sssssssssss
.data?
;sssssssssss
g_hInstance HINSTANCE ?
g_hWndMain HANDLE ?
g_hEditURL HANDLE ?
g_hBtnRead HANDLE ?
g_hEditVerInfo HANDLE ?
g_hRichEditDLL HANDLE ?

wsadata WSADATA <>
sin sockaddr_in <> 
sock  dd ?
error_code  dd ?
g_szURL  db 256 dup(?)
g_buf  byte c_BufLen dup (?)


;sssssssssss
.code
;sssssssssss
start:
invoke GetModuleHandle, NULL
mov    g_hInstance,  eax
invoke LoadLibrary,  OFFSET g_szRichEditDLL
.if  eax != 0
     mov g_hRichEditDLL,  eax
     invoke WinMain, g_hInstance, NULL, NULL, SW_SHOWDEFAULT
     invoke FreeLibrary, g_hRichEditDLL
.else
     invoke MessageBox, 0,  OFFSET g_szNoRichEdit,/
         OFFSET g_szAppName, MB_OK  or MB_ICONERROR
.endif

invoke ExitProcess,  eax

WinMain  proc hInst:  DWORD, hPrevInst:  DWORD, CmdLine:  DWORD, CmdShow:  DWORD
     LOCAL wc: WNDCLASSEX
     LOCAL msg: MSG
     LOCAL hwnd: HWND

     mov    wc.cbSize, SIZEOF WNDCLASSEX
     mov    wc.style, CS_HREDRAW  or CS_VREDRAW
     mov    wc.lpfnWndProc,  OFFSET WndProc
     mov    wc.cbClsExtra, NULL
     mov    wc.cbWndExtra, NULL
     mov     eax, g_hInstance
     mov    wc.hInstance,  eax
     mov    wc.hbrBackground, COLOR_APPWORKSPACE
     mov    wc.lpszMenuName, NULL
     mov    wc.lpszClassName,  OFFSET g_szClsName
     invoke LoadIcon, NULL, IDI_APPLICATION
     mov    wc.hIcon,  eax
     mov    wc.hIconSm,  eax
     invoke LoadCursor, NULL, IDC_ARROW
     mov    wc.hCursor,  eax
     invoke RegisterClassEx,  addr wc
     invoke CreateWindowEx, NULL,  ADDR g_szClsName,  ADDR g_szAppName,/
            WS_OVERLAPPEDWINDOW + WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,/
            c_WinWidth, c_WinHeight, NULL, NULL, hInst, NULL
     mov    hwnd,  eax
     .while  TRUE
         invoke GetMessage,  ADDR msg, NULL, 0, 0
         .BREAK  .IF (! eax)

         ;--- process keystrokes directly in the message loop
         .if msg.message == WM_SYSKEYUP
             .if msg.wParam ==  VK_R          ; Alt + R
                 invoke PostMessage, hwnd, WM_COMMAND, IDC_BtnRead, BM_CLICK
             .endif
         .endif
         ; ------------------------------------------------
         invoke TranslateMessage,  ADDR msg
         invoke DispatchMessage,  ADDR msg
     .endw
     mov  eax, msg.wParam
     ret
WinMain  endp


WndProc  proc hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM
     LOCAL rect: RECT
     LOCAL hdc:  DWORD

     .if uMsg==WM_CREATE
         mov  eax, hWnd
         mov g_hWndMain,  eax

         ;--- Create URL editbox
         invoke CreateWindowEx, NULL,  offset g_szEditCls, NULL,
            WS_CHILD+WS_VISIBLE+ES_AUTOHSCROLL+WS_BORDER,/
            c_EditURLLeft, c_EditURLTop, c_EditURLWidth, c_EditURLHeight,/
            hWnd, IDC_EdtURL, g_hInstance, NULL
         mov g_hEditURL,  eax

         ;--- Create read button
         invoke CreateWindowEx, NULL,  offset g_szBtnCls,  offset g_szBtnReadText,/
            WS_CHILD+WS_VISIBLE, c_BtnReadLeft, c_BtnReadTop, c_BtnReadWidth, c_BtnReadHeight,/
            g_hWndMain, IDC_BtnRead, g_hInstance, NULL
         mov g_hBtnRead,  eax

         ;--- Create file ver info editbox
         ;invoke CreateWindowEx, NULL, addr g_szEditCls, NULL,/
         ;    WS_CHILD+WS_VISIBLE+ES_MULTILINE+WS_HSCROLL+WS_VSCROLL+WS_BORDER,/
         ;    c_EdtHTMLLeft, c_EdtHTMLTop, c_EdtHTMLWidth, c_EdtHTMLHeight,/
         ;    g_hWndMain, IDC_EdtHTML, g_hInstance, NULL
   invoke CreateWindowEx, WS_EX_CLIENTEDGE,  OFFSET g_szRichEditClass,/
    NULL, c_RichEditStyle, c_EdtHTMLLeft, c_EdtHTMLTop, c_EdtHTMLWidth, c_EdtHTMLHeight,/
            hWnd, IDC_EdtHTML, g_hInstance, 0
         mov g_hEditVerInfo,  eax

   ;--- Set the text limit. The default is 64K
   invoke PostMessage,g_hEditVerInfo, EM_LIMITTEXT, -1, 0

        if d_TestData eq 1
             invoke SetWindowText, g_hEditURL,  OFFSET g_szTestURL
        endif

     .elseif uMsg==WM_COMMAND
         .IF lParam
             mov  edx, wParam
             mov  eaxedx
             shr  edx, 16
             .if  dx == BN_CLICKED
                 .IF  ax == IDC_BtnRead
                     invoke GetWindowText, g_hEditURL,  addr g_szURL, sizeof g_szURL
                     test  eaxeax
                     .if ZERO?
                         invoke MessageBox, g_hWndMain,  addr g_szEnterURL,  addr g_szAppName, MB_ICONQUESTION
                     .else
                         ;invoke MessageBox, g_hWndMain, addr g_szURL, addr g_szAppName, MB_ICONQUESTION
                         invoke btnShow_Click
                     .endif
                 .endif
             .ENDIF
         .endif
     .elseif uMsg==WM_DESTROY
         invoke PostQuitMessage, NULL
if c_Resize eq 1
     .elseif uMsg==WM_SIZE
         invoke ResizeConctrol , lParam
         xor  eaxeax
         jz @F
endif
     .else
@@:
         invoke DefWindowProc, hWnd, uMsg, wParam, lParam  
         ret
     .endif
     xor  eaxeax
     ret
WndProc  endp


btnShow_Click  proc
  ;--- First I initialize the internet and get the socket using this code.
  invoke fInitInternet, g_hWndMain
  test    eaxeax
  .if !ZERO?
     invoke MessageBox, g_hWndMain,  eaxaddr g_szAppName, 0
  .else

   ;--- Second, I connect the socket using this code
   invoke fConnect,  addr g_szURL, 80
   test    eaxeax
   .if !ZERO?
     invoke MessageBox, g_hWndMain,  eaxaddr g_szAppName, 0
   .else   
     invoke SendHttpHead,  addr g_szURL, NULL

     ;--- Read http reponse head msg
     invoke ReadSockData,  addr g_buf, c_BufLen
     mov     eaxoffset g_buf
     mov     edieax
     add     edi, c_BufLen-1
     .while ( dword  ptr [ eax]!=0a0d0a0dh) && ( eax <  edi)
         inc  eax
     .endw


     .if   ( eax <  edi)
         add   eax, 3 ;inc  eax
         mov   byte  ptr [ eax], 0
         inc   eax
        
;push eax
;invoke MessageBox, g_hWndMain, eax, addr g_szAppName, 0
;pop  eax

     .else
         xor  eaxeax
     .endif
     push   eax
    m_InsCrStr  addr g_buf

     ;--- write http body msg following http reponse head msg
     pop   eax
     test  eaxeax    
     jz   @btnShow_ClickReadBody
    m_InsStr  eax
@btnShow_ClickReadBody:
     ;--- Read http body msg
     invoke ReadSockData,  addr g_buf, c_BufLen
     push    eax

     ;--- Search the end mark string
     invoke SearchStr,  addr g_buf,  addr g_szHTTP400
     inc     eax
     jz     @F    ;no found

     dec    eax
     mov    byte  ptr  [g_buf+ eax], 0
@@:
     ;--- write http body msg
    m_InsCrStr  addr g_buf

     pop     eax
     cmp     eax, SOCKET_ERROR
     je     @F
     test    eaxeax     ;cmp     eax, 0
     jnz    @btnShow_ClickReadBody     ;jg  @btnShow_ClickReadBody
@@:
     invoke closesocket, sock

     invoke WSACleanup
     .if ( eax == SOCKET_ERROR )
         invoke WSAGetLastError
         invoke wsprintf,  addr g_buf,  addr g_szFmt2,  eax
         ;invoke MessageBox, g_hWndMain, addr g_buf, addr g_szAppName, 0
        m_InsCrStr  addr g_buf
     .endif
   .endif
  .endif

  ret
btnShow_Click  endp


;eax==0, sucess
fInitInternet  proc hWnd: dword
  ; Mad wizard tutorial
  invoke WSAStartup, 101h,  addr wsadata
  test    eaxeax
  jz     @F
  mov     eaxoffset g_szFailWSAStartup
  jmp    @fInitInternetRet
@@:
  ;--- Create a stream socket for internet use 
  invoke socket, AF_INET,SOCK_STREAM, 0 ;AF_UNSPEC;IPPROTO_TCP
  ;sock = socket (AF_INET, SOCK_STREAM, 0);

  .if  eax != INVALID_SOCKET
   mov    sock, eax 
   ;invoke WSAAsyncSelect, sock, hWnd, WM_FSOCKET, FD_CONNECT+FD_READ+FD_CLOSE+FD_WRITE+FD_ACCEPT
     xor  eaxeax
  .else
   mov     eaxoffset g_szFailIni
  .endif

@fInitInternetRet:
  ret
fInitInternet  endp


;eax==0, sucess
fConnect  proc  uses  esi  edi lpszHostName: dword, nPortNumber: dword
  invoke gethostbyname, lpszHostName
  cmp     eax, NULL
  jne    @F
  mov     eaxoffset g_szFailGetHostName
  jmp    @fConnectRet
@@:

;push   eax
;invoke MessageBox, g_hWndMain, (hostent ptr [eax]).h_name, addr g_szAppName, MB_OK
;pop    eax

  mov  eax, (hostent  ptr [ eax]).h_list    ;mov eax, [eax+12]

  mov  eax, [ eax]     ; copy the pointer to the actual IP address into eax 
  mov  eax, [ eax]     ; copy IP address into eax 
  mov sin.sin_addr.S_un.S_addr,  eax  ;mov sin.sin_addr, eax 

  mov sin.sin_family, AF_INET 
  invoke htons, nPortNumber
  mov sin.sin_port,  ax

  invoke connect, sock,  addr sin, sizeof sin 
  .if  eax==SOCKET_ERROR
   invoke WSAGetLastError
   mov     eaxoffset g_szConnect
  .endif
@fConnectRet:
  ret
fConnect  endp


SendHttpHead  proc lpszHostName: LPSTR, lpParam: LPSTR
     invoke wsprintf,  addr g_buf,  addr g_szFmt1, lpParam, lpszHostName
    m_InsStr  addr g_buf
     ;invoke MessageBox, g_hWndMain, addr g_buf, addr g_szAppName, 0

     invoke send, sock,  addr g_buf, sizeof g_buf, 0
     ret
SendHttpHead  endp


ReadSockData  proc lpszBuffer: LPSTR, dwMax_buf_len:  dword
     invoke RtlZeroMemory, lpszBuffer, dwMax_buf_len
     mov    edi, lpszBuffer
     mov    esi, dwMax_buf_len
     dec    esi
@@:
     push    esi
     push    edi
     invoke recv, sock,  ediesi, 0
     pop     edi
     pop     esi
     add     edieax
     sub     esieax
     jz       @get_http_pageRet
;pushad
;invoke MessageBox, g_hWndMain, addr g_szAppName, addr g_szAppName, 0
;popad

     cmp    eax, 0
     jg      @B

@get_http_pageRet:
     ret
ReadSockData  endp


; if   eax=-1, no found
; else eax = sub string position
SearchStr  proc lpszOrgStr: LPSTR, lpszSubStr: LPSTR
     local dwPos:  dword

     mov   edi, lpszSubStr
     cmp   byte  ptr [ edi], 0
     je   @NoFound

     mov  esi, lpszOrgStr
     mov dwPos,  esi

@SearchStrLoop1Begin:
     mov   albyte  ptr [ esi]
     test  alal
     jz   @NoFound

     cmp  albyte  ptr [ edi]
     jne @SearchStrLoop1Next

@SearchStrLoop2Begin:
     inc  esi
     inc  edi            

     mov  ahbyte  ptr [ edi]
     test  ahah
     jz @Found

     mov  albyte  ptr [ esi]
     test  alal
     jz   @NoFound

     cmp  alah
     je  @SearchStrLoop2Begin

     mov   edi, lpszSubStr
@SearchStrLoop1Next:
     inc dwPos
     mov  esi, dwPos

     jmp @SearchStrLoop1Begin

@NoFound:
     xor  eaxeax  ;mov eax, -1
     dec  eax
     jmp @SearchStrRet
@Found:
     mov  eax, dwPos
     sub  eax, lpszOrgStr
@SearchStrRet:
     ret
SearchStr  endp


if c_Resize eq 1

ResizeConctrol  PROC wh: DWORD
     ;--- Get main window width
     mov  eax, wh
     mov  ecxeax

     movzx  eaxax    ; width
     push    eax       ;push for resizing the ver info edit

     sub  eax, 4
     shr  ecx, 16      ; height
     sub  ecx, c_EditURLHeight+10

     invoke MoveWindow, g_hEditVerInfo, 2, c_EdtHTMLTop,  eaxecxFALSE

     ;--- Resize the Get button
     pop  eax
     sub  eax, 5+c_BtnReadWidth
     push  eax
     invoke MoveWindow, g_hBtnRead,  eax, c_BtnReadTop, c_BtnReadWidth, c_BtnReadHeight,  TRUE

     ;--- Resize the file spec editbox
     pop  eax
     sub  eax, 10
     invoke MoveWindow, g_hEditURL, c_EditURLLeft, c_EditURLTop,  eax, c_EditURLHeight,  TRUE

     ret
ResizeConctrol  ENDP

endif    ; c_Resize

end start
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

紫郢剑侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值