читать источник веб-страницы в fasm или nasm

У меня есть этот код С++ для чтения источника веб-страницы.

#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, но это не сработало. может ли кто-нибудь помочь мне преобразовать его в сборку? спасибо (обратите внимание, что я никогда раньше не работал с сокетами на ассемблере, поэтому я не уверен, близок ли этот код или нет, я думаю, что он подключается, но выдает пустое окно сообщения вместо исходного кода веб-страницы)

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'

person Darrin Woolit    schedule 24.05.2014    source источник
comment
Может ли кто-нибудь помочь мне преобразовать его в сборку? — не очень хороший вопрос для StackOverflow. Можете ли вы указать на конкретную часть кода, с которой у вас возникли проблемы? (включите объяснение того, что вы ожидаете от этого фрагмента кода и что он на самом деле делает)   -  person Michael    schedule 24.05.2014
comment
похоже, что он подключается к lastfm через порт 80, но я не думаю, что он отправляет правильное сообщение GET.   -  person Darrin Woolit    schedule 25.05.2014
comment
У меня нет большого опыта в этом, но я могу сказать вам, что формат сообщения GET очень разборчив. Интересно, правильно ли экранируется /n/r. Я бы попробовал заменить их явными 13, 10, если вы не уверены, что получаете именно это.   -  person Frank Kotler    schedule 25.05.2014


Ответы (2)


Это моя инет-функция, может вам поможет.

push cookie
push post
push url
push buffer 
call connectHTTP

Результат помещается в буфер. Функция не оптимизирована, но работает стабильно.

; ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~
;
;  inet.asm
;
;  HFT -> inet functions
;
;  Copyright (C) 2013 Ilya M. Chirkunov ([email protected])
;
; - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ -

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)
person cheebeez    schedule 17.11.2014

Я настоятельно рекомендую вам не заморачиваться с сокетами и просто использовать функции из WinInet, так как вы работаете в Windows. Этот WinAPI довольно легко использовать в fASM.

person Mints97    schedule 28.07.2014