0

我有这个 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.1\r\nHost: www.last.fm\r\nConnection: close\r\n\r\n", strlen("GET /music/taylor+swift/+albums?order=reach&page=1 HTTP/1.1\r\nHost: www.cplusplus.com\r\nConnection: close\r\n\r\n"), 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 '\Fasm\INCLUDE\win32ax.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.1\r\nHost: www.last.fm\r\nConnection: close\r\n\r\n',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'
4

2 回答 2

2

这是我的 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)
于 2014-11-17T16:53:37.680 回答
1

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

于 2014-07-28T14:56:24.190 回答