在fasm或nasm中阅读网页的源代码

read source of a webpage in fasm or nasm

本文关键字:网页 源代码 fasm nasm      更新时间:2023-10-16

我有这个c++代码来读取一个网页的源代码。

#include "stdafx.h"
#include <winsock2.h>
#include <windows.h>
#include <iostream>
#include <fstream>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
int main(){
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        cout << "WSAStartup failed.n";
        system("pause");
        return 1;
    }
    SOCKET Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    struct hostent *host;
    host = gethostbyname("www.last.fm");
    SOCKADDR_IN SockAddr;
    SockAddr.sin_port = htons(80);
    SockAddr.sin_family = AF_INET;
    SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
    cout << "Connecting...n";
    if (connect(Socket, (SOCKADDR*)(&SockAddr), sizeof(SockAddr)) != 0){
        cout << "Could not connect";
        system("pause");
        return 1;
    }
    cout << "Connected.n";
    send(Socket, "GET /music/Taylor+swift/+albums?order=reach&page=1 HTTP/1.1rnHost: www.last.fmrnConnection: closernrn", strlen("GET /music/taylor+swift/+albums?order=reach&page=1 HTTP/1.1rnHost: www.cplusplus.comrnConnection: closernrn"), 0);
    char buffer[10000];
    int nDataLength;
    while ((nDataLength = recv(Socket, buffer, 10000, 0)) > 0){
        int i = 0;
        while (buffer[i] >= 32 || buffer[i] == 'n' || buffer[i] == 'r') {
             cout << buffer[i];         
            i += 1;
        }
    }
    closesocket(Socket);
    WSACleanup();

    system("pause");
    return 0;
}

我试图将其转换为fasm组件,但它不起作用。有人能帮我把它改装成总成吗?谢谢(请注意,我以前从未在asm中使用套接字,所以我不确定此代码是否关闭,我认为它连接,但它给出了一个空白消息框,而不是网页源代码)

format PE GUI 4.0
entry start
include 'FasmINCLUDEwin32ax.inc'
section '.data' data readable writeable
  IPPROTO_TCP  = 6

wsadata WSADATA
 _caption db 'Client application',0
 _igang db 'The client has started very well.',13,10,'It is now going to connect to your own computer',0
 _hostname db 'Wrong hostname',0
  hostname db 'www.lastfm.com',0
  hSock dd ?
  saddr sockaddr_in
  sizesaddr = $-saddr

  buffer rb 0x3000
  sender db 'GET /music/Taylor+swift/+albums?order=reach&page=1 HTTP/1.1rnHost: www.last.fmrnConnection: closernrn',13,10
         rb 0x100
section '.code' code readable executable
start:
       invoke WSAStartup,0101h,wsadata  ; initialiserer winsock-bibliotek
       invoke  ws_gethostbyname,hostname
       or     eax,eax
       jz     bad_hostname
              virtual at eax
               .host hostent
              end virtual
       mov    eax,[.host.h_addr_list]
       mov    eax,[eax]
       mov    eax,[eax]
       mov     [saddr.sin_addr],eax
       invoke MessageBox,0,_igang,_caption,0
       mov    al,00
       mov    ah,80          ; port 80
       mov     [saddr.sin_port],ax
       mov     [saddr.sin_family],AF_INET
       invoke  ws_socket, AF_INET, SOCK_STREAM, IPPROTO_TCP
       mov     [hSock], eax
       xchg    eax, esi
       invoke  ws_connect, esi, saddr, sizesaddr
       .if eax = 0
       invoke MessageBox,0, "connected", _caption,0
       .endif
       .if eax <> 0
       invoke MessageBox,0, "not connected", _caption,0
       .endif
       mov     ebx, buffer
       invoke  ws_send,esi,sender,109,0
       invoke  ws_recv, esi, ebx, 1000, 0
       invoke MessageBox,0, buffer, _caption,0
       .connectSucceeded:
       invoke ws_closesocket,esi
       invoke WSACleanup
       jmp stopp
bad_hostname:
        invoke MessageBox,0,_hostname,_caption,0
        jmp stopp
stopp:
        invoke ExitProcess,0

section '.idata' import data readable writeable
  library kernel,'KERNEL32.DLL',
          winsock,'WSOCK32.DLL',
          user,'USER32.DLL'
  import kernel,
         ExitProcess,'ExitProcess'
  import winsock,
        WSAStartup,'WSAStartup',
        ws_socket,'socket',
        ws_connect,'connect',
        ws_gethostbyname,'gethostbyname',
        ws_send,'send',
        ws_recv,'recv',
        ws_closesocket,'closesocket',
        WSACleanup,'WSACleanup'
  import user,
        MessageBox,'MessageBoxA'

这是我的inet功能,也许会对你有所帮助。

push cookie
push post
push url
push buffer 
call connectHTTP

结果放在缓冲区中。功能未优化,但运行稳定。

; ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~
;
;  inet.asm
;
;  HFT -> inet functions
;
;  Copyright (C) 2013 Ilya M. Chirkunov (cheebeez@yandex.ru)
;
; - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ -
format ELF
include 'cdecl.inc'
public connectHTTP
extrn  gethostbyname
extrn  socket
extrn  htons
extrn  connect
extrn  send
extrn  recv
extrn  close
extrn  strcpy2
extrn  strcat2
extrn  strpos
extrn  strlen2
extrn  hex2decascii
extrn  push_ad
extrn  pop_ad
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;                                       С Е К Ц И Я  К О Д А
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
section '.text' executable
; ------------------------------------- HTTP запрос
proc connectHTTP
        call    push_ad
        pop     eax                                           ; сохраняем адрес возврата
        pop     edi esi ecx edx                               ; edi - buffer, esi - url, ecx - post, edx - cookie
        push    eax                                           ; восстанавливаем адрес возврата
;       (составляем запрос)
        sub     esp,10000
        mov     ebx,esp                                       ; в ebx будем собирать запрос
        cmp     dword[esi],"http"
        jne     _not_http
        add     esi,7                                         ; убираем "http://"
    _not_http:
        push    szPOST
        push    ebx
        call    strcpy2                                       ; "POST " 
        cmp     ecx,0
        jnz     _is_post
        push    szGET
        push    ebx
        call    strcpy2                                       ; "GET " 
    _is_post:
        push    szSlash
        push    ebx
        call    strcat2                                       ; "GET /" 
        push    esi
        push    edi
        call    strcpy2                                       ; копируем url в буффер
        push    szSlash
        push    edi
        call    strpos                                        ; ищем URI
        cmp     eax,-1
        je      _only_host
        mov     byte[edi+eax],0                               ; в edi - host
        add     esi,eax                                       ; в esi - uri
        inc     esi
        push    esi
        push    ebx
        call    strcat2                                       ; "GET /full_uri HTTP/1.0"
_only_host:
        push    szHTTP10
        push    ebx
        call    strcat2                                       ; "GET / HTTP/1.0" 
        push    szDA
        push    ebx
        call    strcat2                                       ; "GET / HTTP/1.0",0xD,0xA
        push    szHost
        push    ebx
        call    strcat2                                       ; "GET / HTTP/1.0",0xD,0xA,"Host: "
        push    edi
        push    ebx
        call    strcat2                                       ; "GET / HTTP/1.0",0xD,0xA,"Host: sphost.org"
        push    szDA
        push    ebx
        call    strcat2                                       ; "GET / HTTP/1.0",0xD,0xA,"Host: sphost.org",0xD,0xA
        cmp     ecx,0
        jz      _finish_query_string
        push    szContType
        push    ebx
        call    strcat2                                       ; "POST / HTTP/1.0",0xD,0xA,"Host: sphost.org",0xD,0xA,"Content-Type: application/x-www-form-urlencoded"
        push    szDA
        push    ebx
        call    strcat2                                       ; "POST / HTTP/1.0",0xD,0xA,"Host: sphost.org",0xD,0xA,"Content-Type: application/x-www-form-urlencoded",0xD,0xA
        push    szLength
        push    ebx
        call    strcat2                                       ; "POST / HTTP/1.0",0xD,0xA,"Host: sphost.org",0xD,0xA,"Content-Length: "
        push    ecx
        call    strlen2
        push    eax
        push    szSize
        call    hex2decascii
        push    szSize
        push    ebx
        call    strcat2                                       ; "POST / HTTP/1.0",0xD,0xA,"Host: sphost.org",0xD,0xA,"Content-Length: 64"
        push    szDA
        push    ebx
        call    strcat2                                       ; "POST / HTTP/1.0",0xD,0xA,"Host: sphost.org",0xD,0xA,"Content-Length: 64",0xD,0xA
        push    szDA
        push    ebx
        call    strcat2                                       ; "POST / HTTP/1.0",0xD,0xA,"Host: sphost.org",0xD,0xA,"Content-Length: 64",0xD,0xA,0xD,0xA
        push    ecx
        push    ebx
        call    strcat2                                       ; "POST / HTTP/1.0",0xD,0xA,"Host: sphost.org",0xD,0xA,"Content-Length: 64",0xD,0xA,0xD,0xA,"post"
        push    szDA
        push    ebx
        call    strcat2                                       ; "POST / HTTP/1.0",0xD,0xA,"Host: sphost.org",0xD,0xA,"Content-Length: 64",0xD,0xA,0xD,0xA,"post",0xD,0xA
_finish_query_string:
        push    szDA
        push    ebx
        call    strcat2                                       ; "GET / HTTP/1.0",0xD,0xA,"Host: sphost.org",0xD,0xA,0xD,0xA
;       (отправляем запрос)
        ccall   gethostbyname, edi
        ;cmp     eax,0
        ;jz      _ret_conHTTP
        mov     eax,[eax+16]
        mov     eax,[eax]
        mov     eax,[eax]
        mov     dword[sin_addr],eax
        ccall   socket, 2, 1, 6                               ; AF_INET, SOCK_STREAM, IPPROTO_TCP
        ;cmp     eax, -1
        ;je      _ret_conHTTP
        mov     dword[sockfd],eax
        ccall   htons, 80
        mov     word[sin_port],ax
        mov     word[sin_family],2
        ccall   connect, dword[sockfd], sin_family, 16
        ;cmp     eax,0
        ;jnz     _ret_conHTTP
        push    ebx
        call    strlen2
        ccall   send, dword[sockfd], ebx, eax, 0
        add     esp,10000
;       (получаем ответ)
    _getURL_recv:
        ccall   recv, dword[sockfd], edi, 1024, 0
        add     edi,eax
        cmp     eax,0
        jnz     _getURL_recv
        mov     byte[edi],0
        ccall   close,dword[sockfd]
_ret_conHTTP:
        call    pop_ad
        ret
endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;                                       С Е К Ц И Я  Д А Н Н Ы Х
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
section '.data' writeable
  szGET             db "GET ", 0
  szPOST            db "POST ", 0
  szSlash           db "/",0
  szHTTP10          db " HTTP/1.0",0
  szDA              db 0xD,0xA,0
  szHost            db "Host: ", 0
  szContType        db "Content-Type: application/x-www-form-urlencoded",0
  szLength          db "Content-Length: ", 0
  szSize            db 12 dup (0)
  sockfd            dd 0
; sockaddr_in       db 16 dup (0)
  sin_family        db 2 dup (0)
  sin_port          db 2 dup (0)
  sin_addr          db 4 dup (0)
  sin_zero          db 8 dup (0)

我强烈建议你不要使用套接字,只要使用WinInet的函数,因为你是在Windows上。这个WinAPI很容易在fASM中使用