flat assembler
Message board for the users of flat assembler.

Index > Windows > Picnic Playground

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
Picnic



Joined: 05 May 2007
Posts: 1288
Location: Paradise Falls
Picnic
Chat is a very simple console application to provide a direct communication between two computers in the same peer to peer environment.
It uses UDP sockets, the winsock api and C library calls and is tested on Windows XP on my home network as my work also.
I had it unfinished on my hard disk for quite some time.

Command line parameters syntax like this: listen_port destination_machine destination_port

Example using hostnames.
on my laptop: chat 1024 desktop 1025
on my pc: chat 1025 laptop 1024

Example using IP address.
on my laptop: chat 1024 192.168.1.102 1025
on my pc: chat 1025 192.168.1.101 1024

Code:
;-------------------------------------------------------------------------
;   CHAT.ASM
;   Win32 Console Application
;-------------------------------------------------------------------------
;   Application uses the User Datagram Protocol (UDP)
;   to provide a direct communication between 2
;   computers in a peer to peer like environment.
;-------------------------------------------------------------------------
;   Fasm v1.69.20
;   20 Sep 2010, Picnic
;-------------------------------------------------------------------------

    format pe console
    entry main

    include "include\win32ax.inc"

section ".idata" import data readable writeable

    library\
    kernel32,"kernel32.dll",\
    user32,"user32.dll",\
    ws2_32,"ws2_32.dll",\
    msvcrt,"msvcrt.dll"

    include "include\api\kernel32.inc"
    include "include\api\user32.inc"

    import ws2_32,\
    gethostbyname,"gethostbyname",\
    gethostbyaddr,"gethostbyaddr",\
    WSAGetLastError,"WSAGetLastError",\
    WSAStartup,"WSAStartup",\
    WSACleanup,"WSACleanup",\
    closesocket,"closesocket",\
    inet_ntoa,"inet_ntoa",\
    inet_addr,"inet_addr",\
    recvfrom,"recvfrom",\
    sendto,"sendto",\
    socket,"socket",\
    listen,"listen",\
    bind,"bind",\
    htonl,"htonl",\
    htons,"htons",\
    ntohs,"ntohs"

    import msvcrt,\
    __getmainargs,"__getmainargs",\
    _beginthreadex,"_beginthreadex",\
    memset,"memset",\
    strcpy,"strcpy",\
    strlen,"strlen",\
    printf,"printf",\
    fgets,"fgets",\
    fflush,"fflush",\
    atoi,"atoi",\
    _iob,"_iob"

;-------------------------------------------------------------------------
;
section ".data" data readable writeable
;
;-------------------------------------------------------------------------

    MAX_SIZE = 2048
    INVALID_SOCKET = 0xFFFFFFFF
    crlf equ 0x0D,0x0A

    argc dd ?
    argv dd ?
    env dd ?
    listen_socket dd ?
    listen_port dd ?
    dest_port dd ?
    dest_name rb 256
    buffer rb MAX_SIZE

    align 4
    saddr sockaddr_in
    WSAData WSADATA

;-------------------------------------------------------------------------
;
section ".text" code readable executable
main:
;
;-------------------------------------------------------------------------

    cinvoke __getmainargs, addr argc, addr argv, addr env, 0
    .if ( dword [argc] = 4 )
        mov ebx, [argv]
        cinvoke atoi, dword [ebx+04h]
        mov dword [listen_port], eax
        push eax
        cinvoke atoi, dword [ebx+0Ch]
        mov dword [dest_port], eax
        pop ecx
    .endif

    ; Make sure data passed on command line is correct
    .if ( dword [argc] <> 4 | ~eax | ~ecx | eax > 65535 | ecx > 65535 | eax = ecx )
        cinvoke printf, <"Usage: chat [listen port] [destination machine] [destination port]",crlf>
        mov eax, 1
        ret
    .endif

    ; Save the destination machine's address/name
    cinvoke strcpy, addr dest_name, dword [ebx+08h]

    cinvoke printf, <"Initializing...",crlf>

    ; Starts the Winsock service
    invoke WSAStartup, 0202h, addr WSAData
    .if ( eax <> 0 )
        cinvoke printf, <"WSAStartup failed",crlf>
        mov eax, 1
        ret
    .endif

    ; Try to listen to requested port
    stdcall TryListen, dword [listen_port]
    .if ( ~eax )
        cinvoke printf, <"Error listening to port %d",crlf>, dword [listen_port]
        mov ebx, 1
    .else
        cinvoke printf, <"chat ready: <Ctrl-C> to exit",crlf>
        cinvoke fgets, addr buffer, MAX_SIZE, dword [_iob]

        .while ( eax <> 0 )
            ; Forward the sendbuf to destination machine
            ; Continue to grab input from stdin
            cinvoke strlen, addr buffer
            stdcall SendMsg, addr buffer, eax, addr dest_name, dword [dest_port]
            cinvoke fgets, addr buffer, MAX_SIZE, dword [_iob]
        .endw

        xor ebx, ebx
    .endif

    .if ( dword [listen_socket] <> INVALID_SOCKET )
        invoke closesocket, dword [listen_socket]
    .endif

    invoke WSACleanup
    invoke ExitProcess, ebx
    ret

;-------------------------------------------------------------------------
;
;   SendMsg()
;
;-------------------------------------------------------------------------

align 4
proc SendMsg uses ecx ebx edx,\
sendbuf:dword, sendlen:dword, host:dword, port:dword

    local ipaddr dd ?
    local to sockaddr_in

    ; Is the host passed a name?
    cinvoke atoi, dword [host]
    .if ( ~eax )
        invoke gethostbyname, [host]
    .else
        ; Otherwise, assume it's IP format
        cinvoke inet_addr, dword [host]
        mov dword [ipaddr], eax
        invoke gethostbyaddr, addr ipaddr, 4, AF_INET
    .endif

    .if ( ~eax )
        invoke WSAGetLastError
        cinvoke printf, <"Error getting host address - code: %ld",crlf>, eax
        xor eax, eax
        ret
    .endif

    virtual at eax
        .hostdata hostent
    end virtual
    mov eax, [.hostdata.h_addr_list]
    mov eax, [eax]
    mov eax, [eax]

    ; Endpoint address of the destination computer
    mov dword [to.sin_addr], eax
    mov dword [to.sin_family], AF_INET
    invoke htons, dword [port]
    mov word [to.sin_port], ax

    cinvoke printf, <"Message being sent to host %s port %d",crlf>, dword [host], dword [port]

    invoke sendto, dword [listen_socket], dword [sendbuf], dword [sendlen], 0, addr to, sizeof.sockaddr_in

    .if ( eax > dword [sendlen] | eax = INVALID_SOCKET )
        cinvoke printf, <"Error sending UDP packet from listen socket",crlf>
        xor eax, eax
        ret
    .endif

    mov eax, 1
    ret
endp

;-------------------------------------------------------------------------
;
;   TryListen()
;
;-------------------------------------------------------------------------

align 4
proc TryListen uses ecx ebx edx, port:dword

    local thread dd ?

    mov dword [listen_socket], INVALID_SOCKET

    ; This socket uses the User Datagram Protocol (UDP)
    invoke socket, AF_INET, SOCK_DGRAM, 17
    .if ( eax = INVALID_SOCKET )
        cinvoke printf, <"Error: listen socket creation failed",crlf>
        xor eax, eax
        ret
    .endif

    mov dword [listen_socket], eax

    mov dword [saddr.sin_family], AF_INET
    invoke htonl, 0 ; any address
    mov dword [saddr.sin_addr], eax
    invoke htons, dword [port]
    mov word [saddr.sin_port], ax

    invoke bind, dword [listen_socket], addr saddr, sizeof.sockaddr_in
    .if ( eax <> 0 )
        cinvoke printf, <"Error: bind on listen socket failed",crlf>
        invoke closesocket, dword [listen_socket]
        xor eax, eax
        ret
    .endif

    cinvoke _beginthreadex, 0, 0, addr ListenThread, dword [listen_socket], 0, addr thread
    .if ( ~eax )
        cinvoke printf, <"Error creating listen thread",crlf>
        xor eax, eax
        ret
    .endif

    invoke CloseHandle, eax

    mov eax, 1
    ret
endp

;-------------------------------------------------------------------------
;
;   ListenThread()
;
;-------------------------------------------------------------------------

align 4
proc ListenThread uses ecx ebx edx, s:dword

    local from_len dd ?
    local from sockaddr_in
    local recvbuf rb MAX_SIZE+100

    .while ( 1 )    ; loop forever

        mov [from_len], sizeof.sockaddr_in
        cinvoke memset, addr recvbuf, 0, MAX_SIZE
        invoke recvfrom, dword [s], addr recvbuf, MAX_SIZE-1, 0, addr from, addr from_len

        .if ( signed eax > 0 )

            lea ebx, dword [recvbuf]
            mov byte [ebx+eax], 0

            invoke inet_ntoa, dword [from.sin_addr]
            push eax
            movzx eax, word [from.sin_port]
            invoke ntohs, eax
            pop ecx

            cinvoke printf, <"Message received from host %s port %d",crlf>, ecx, eax
            cinvoke printf, ">> %s", addr recvbuf

        .endif

    .endw

    ret
endp
    


Image


Last edited by Picnic on 21 Mar 2020, 10:44; edited 6 times in total
Post 20 Sep 2010, 20:29
View user's profile Send private message Reply with quote
Overflowz



Joined: 03 Sep 2010
Posts: 1046
Overflowz
Oh, so nice ! BTW can you write more simple code without command line args and without proc-s ? just like when conencted to wait for recive or send and client/server same like that. thank you! Smile
Post 21 Sep 2010, 11:20
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4242
Location: 2018
edfed
and for IRC?
Post 21 Sep 2010, 11:35
View user's profile Send private message Visit poster's website Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: Paradise Falls
Picnic
Hi,

Overflowz, __getmainargs function provides a simple way to get the command line parameters.
As better alternatives see Windows API functions GetCommandLine or CommandLineToArgvW
Search fasm board for examples or even more simple winsock samples.

edfed i don't know much about IRC, never used it.
Post 22 Sep 2010, 11:26
View user's profile Send private message Reply with quote
Overflowz



Joined: 03 Sep 2010
Posts: 1046
Overflowz
Okay thanks. Smile I'm just stuck how to receive buffer and I know only send >.<
Post 22 Sep 2010, 12:55
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: Paradise Falls
Picnic
A simple Winsock Multi-User Console Chat Server.
Made for Windows XP, tested with telnet.exe, putty client will also work.
It can handle backspace, users can change their names, it prints a user-list. Program is inspired from a C++ sample.
The listening port can be passed as a command line argument, the default port is 23. Esc stops the server.
Despite my lame code which is written in three days, it works well.

[code removed]

Image


Last edited by Picnic on 21 Mar 2020, 11:26; edited 5 times in total
Post 22 Jul 2012, 21:51
View user's profile Send private message Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 9132
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
looks great!!
Post 23 Jul 2012, 00:40
View user's profile Send private message Reply with quote
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek
Yeah, wonderful!
Post 23 Jul 2012, 05:48
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: Paradise Falls
Picnic
thank you both, appreciate the comments.
Post 24 Jul 2012, 05:06
View user's profile Send private message Reply with quote
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek
Where did the last version go?
Post 26 Aug 2012, 07:32
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: Paradise Falls
Picnic
A login system with a username and password as well as a server log were added to server.

[code removed]

Image


Last edited by Picnic on 21 Mar 2020, 14:20; edited 7 times in total
Post 26 Aug 2012, 10:44
View user's profile Send private message Reply with quote
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek
Thank you, Picnic!
Post 26 Aug 2012, 10:47
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: Paradise Falls
Picnic
You're welcome bzdashek!


Last edited by Picnic on 03 Mar 2013, 19:55; edited 1 time in total
Post 12 Jan 2013, 16:24
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2913
Location: 0x77760000
typedef
When working on such projects consider using multi-threaded libraries with callback support (Windows has one for GUI but kind of sucks).

Example.

Make a library that can be re-used (duh)

Pseudo code
Code:

; import winsock

; Define our interface here. Just a struct

struct ISocketEvent
         onDataArrival   dd ? ; implement as proc onDataArrival, handle, lpData, dwSize
         onClientReady dd ? ; implement as proc onClientReady, handle, lpData, lpdwSize   ; return data to send and size in the last two parameters. (See below)
         onError           dd ? ; implement as proc onError, dwCode, pszDecription
         onConnect      dd ? ; implement as proc onConnect, handle, pszRemoteHost, dwPort
         onDisconnect   dd ? ; implement as proc onDisconnect, handle
ends

; Object identifiers
struct  SocketObject
          .socket   dd 0             ; socket handle
          .sai        sockaddr_in 
          .stop      dd 1             ; connection state (closed, this stops the loop)
          .ISocketEventPtr         ; the callback table pointer to user functions
endp


; impl

proc Startup
        ... winsock initialization here
endp 

/// Returns a handle (Basically a pointer to SocketObject struct)
proc Connect pszIP_or_DNS, port, iCallbackPtr

 
      handle =    memalloc SocketObject.Size

      handle.sai.port = port;
      handle.ISocketEventPtr = iCallbackPtr

      ... start connection thread
      CreateThread.. ConnectionThread, handle

      return handle
endp
proc ConnectionThread, handle
        ..winsock connection functions here


         handle.socket = socket(...);
           .. if error call  handle.ISocketEventPtr.onError, socket_error_code, "Custom or system description"

        .. if connection made
             call  handle.ISocketEventPtr.onConnect, handle, pszHostName, port
                          
             CreateThread( MonitorThread, handle )

       .. if not
             call handle.ISocketEventPtr.onError, socket_error_code, "Custom or system description"

       .. this thread exits
endp


/// Returns a handle (Basically a pointer to SocketObject struct)
proc Listen, port, iCallbackPtr
              handle = memalloc , SocketObject.Size

              handle.sai.port = port
              handle.ISocketEventPtr = iCallbackPtr

             // start listening thread
endp

proc ListenThread, handle
         while handle.stop = false
                 // you know the drill here boys
         end while
endp

proc MonitorThread, handle

      while handle.stop = false

      fd_set read_set.
      fd_set write_set.
      fd_set error_set.

      // check states here

      ..if(read_set)
         dwBytes = 0
         ioctlsocket(handle.socket, FIONREAD, dwBytes); .. available bytes to read
         
         buffer = memalloc dwBytes
         .. if not
             call handle.ISocketEventPtr.onError, custom_error_code, "Custom or system description"

         ..else
             recv(handle.socket, buffer, dwBytes)
             .. if not 
                 call handle.ISocketEventPtr.onError, socket_error_code, "Custom or system description"
             .. else
                 call handle.ISocketEventPtr.onDataAvailable, handle, buffer, dwBytes
                    if(buffer != null)    ; in case user did something stupid with the buffer
                         memfree(buffer)
                

      .. if(write_set)
          dwSize = 0
          lpBuffer= 0
          buffer = call handle.ISocketEventPtr.onClientReady, handle, buffer, dwSize

         if(buffer != null and dwSize > 0 )
            send(handle.socket, buffer, dwSize);

         .. if not
             call handle.ISocketEventPtr.onError, socket_error_code, "Custom or system description"

      if(error_set)
           get error code
            call handle.ISocketEventPtr.onError, socket_error_code, "Custom or system description"

      // check MSDN for more on how to check for a closed/disconnected socket
      if(read_set && <some other byte checks>)
           call handle.ISocketEventPtr.onDisconnected, handle
           exit here
           break;

         // pause or sleep here

      end while

        closesocket handle.socket
endp

proc FreeHandle, handle
         memfree, handle
endp

proc Close, handle
        handle.stop = true // this will stop the thread
endp

; exports

Startup
Connect
Listen
Send
Close
FreeHandle
    




Using it
Code:

; setup GUI
myGui.setup;

libSocket.Statup


proc onDataArrival, handle, bytes, size
         if(handle = my_handle)  ; of course you'd know how to do this
           myGui.RichEdit.Text.Append(bytes)
endp

proc onDisconnect
         myGui.Button.Connect.Enabled = true;
endp

my_handle dd 0
proc myGui.button.Connent.Click
          host = myGui.Edit.Host.Text
          port = int( myGui.Edit.Port.Text )
           my_handle = libSOcket.Connect, host, port
endp

    


Well that's about it. Sorry if it seems like nonsense but someone one day will find it useful. I'm currently developing on android and I'm using threads quite extensively so I often use interfaces to make things flow better other than having to wait for a function/method to return.
Post 13 Jan 2013, 00:35
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: Paradise Falls
Picnic
@typedef no, it doesn't seem nonsense, suggestions and pseudocode are welcome.
I do have a multi-user chat program on which i used threads but is left unfinished.
I have little reusable code in asm, programs above are more like simple learning excercises, practicing C/C++ and asm simultaneously.
Post 15 Jan 2013, 12:40
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2913
Location: 0x77760000
typedef
Lol. No source code?

And what's up with the CryptXXX functions?
Post 05 Mar 2015, 02:07
View user's profile Send private message Reply with quote
catafest



Joined: 05 Aug 2010
Posts: 122
catafest
Windows defender see this like malware
Picnic wrote:
I thought to make it better, a login system with username and password for each account would be nice but to be honest i'm bored now. Feel free to modify source as you wish.
Ansi colors were added, exploited the fact that clients like telnet.exe are forgiving, and overlook that proper use requires an exchanging information first. Also a server log added.
Here you are, sorry for any inconvenience.


Silent Edit
I started re-writing the chat program. I upload new sources as soon as possible.

Image
Post 07 May 2017, 23:11
View user's profile Send private message Visit poster's website Yahoo Messenger Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: Paradise Falls
Picnic
Unfortunately many of my fasm console programs that using sockets are recognized as viruses. I can not resolve this.
Post 09 May 2017, 06:46
View user's profile Send private message Reply with quote
catafest



Joined: 05 Aug 2010
Posts: 122
catafest
Picnic wrote:
Unfortunately many of my fasm console programs that using sockets are recognized as viruses. I can not resolve this.

I think the problem is the format of :
Code:
pe console    

, I don't have your source code for CHAT.rar
If you make a search on this forum will see how to fix that.
Nice ideea if you will update this with useful tools under Windows OS ...
Make a brainstroming about how can be usefull your application Smile
Post 09 May 2017, 10:59
View user's profile Send private message Visit poster's website Yahoo Messenger Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: Paradise Falls
Picnic
A program that reads the source code of a website from a URL to a buffer.

Code:

    format PE CONSOLE 4.0
    entry main

    include 'include\win32wx.inc'


;--------------------------------------------------------------------------------------------------

section '.data' data readable writeable

;--------------------------------------------------------------------------------------------------

    MAX_BUFFER = 4096
    INTERNET_FLAG_KEEP_CONNECTION = 0x400000
    INTERNET_OPTION_RECEIVE_TIMEOUT = 6
    INTERNET_SERVICE_HTTP = 3

    WHITESPACE equ 0x9,0x20
    CRLF equ 0xD,0xA

    URL du 'https://flatassembler.net',0

    dwLastError dd ?


;--------------------------------------------------------------------------------------------------

section '.code' code readable executable

;--------------------------------------------------------------------------------------------------
main:

    stdcall GetHtml, URL, 0

    cinvoke wprintf, '%s', eax

    invoke ExitProcess, 0


;--------------------------------------------------------------------------------------------------
;  Get HTML source from URL
;  Returns a pointer to a buffer in EAX
;  Saves the last error code in global dwLastError
;  Tracks the total size in dwTotalBytes (without returning the value)
;  Call Examples:
;  stdcall GetHtml,URL,n  -->  get n bytes from url (max 4kb)
;  stdcall GetHtml,URL,0  -->  get full url source
;  10/5/2016 Picnic
;--------------------------------------------------------------------------------------------------
proc GetHtml uses ebx ecx edx esi edi, lpUrlPath:dword, dwBytesToRead:dword

    local lpOutBuf dd ?
    local lpDomain dd ?
    local hHeap dd ?
    local hData dd ?
    local hInternet dd ?
    local hConnection dd ?
    local dwTotalBytes dd ?
    local dwTimeout dd ?
    local lpRecvBuf dd ?
    local lpWideBuf dd ?
    local lpPath dd ?
    local dwRecvLen dd ?

    lea edi, [lpOutBuf]
    mov ecx, 11
    xor eax, eax
    cld
    rep stosd

    mov [dwLastError], 0

    invoke GetProcessHeap
    test eax, eax
    jz .continue
    mov [hHeap], eax

    invoke HeapAlloc, [hHeap], HEAP_ZERO_MEMORY, 3*MAX_BUFFER
    test eax, eax
    jz .continue
    mov [lpDomain], eax
    add eax, MAX_BUFFER
    mov [lpPath], eax

    mov esi, [lpUrlPath]
    mov edi, [lpDomain]

    cmp word [esi], 0
    je .continue

    .if ( (word [esi] = 'h' | word [esi] = 'H') \
        & (word [esi+2] = 't' | word [esi+2] = 'T') \
        & (word [esi+4] = 't' | word [esi+4] = 'T') \
        & (word [esi+6] = 'p' | word [esi+6] = 'T') )
        add esi, 8  ; HTTP
        .if (word [esi] = 's' | word [esi] = 'S')
            add esi, 2  ; HTTPS
        .endif
        add esi, 6  ; HTTPS://
    .endif

    ; write the domain
    .while (word [esi] <> 0 & word [esi] <> '/' & word [esi] <> '\')
        lodsw
        stosw
    .endw

    ; write the rest of the path
    invoke lstrcpy, [lpPath], esi

    mov word [edi], 0  ; null terminate

    invoke InternetOpen, <'InetURL/1.0'>, 0, 0, 0, 0
    test eax, eax
    jz .continue
    mov [hInternet], eax

    invoke InternetConnect, eax, [lpDomain], 80, <' '>,<' '>, INTERNET_SERVICE_HTTP, 0, 0
    test eax, eax
    jz .continue
    mov [hConnection], eax

    mov [dwTimeout], 6000
    invoke InternetSetOption, [hInternet], INTERNET_OPTION_RECEIVE_TIMEOUT, addr dwTimeout, 4
    test eax, eax
    jz .continue

    invoke HttpOpenRequest, [hConnection], <'GET'>, [lpPath], 0, 0, 0, INTERNET_FLAG_KEEP_CONNECTION, 0
    test eax, eax
    jz .continue
    mov [hData], eax

    invoke HttpSendRequest, [hData], 0, 0, 0, 0
    test eax, eax
    jz .continue

    invoke HeapAlloc, [hHeap], HEAP_ZERO_MEMORY, 32
    test eax, eax
    jz .continue
    mov [lpOutBuf], eax

    invoke HeapAlloc, [hHeap], HEAP_ZERO_MEMORY, 5*MAX_BUFFER
    test eax, eax
    jz .continue
    mov [lpRecvBuf], eax
    add eax, 2*MAX_BUFFER
    mov [lpWideBuf], eax

    mov [dwRecvLen], 1

    mov eax, [dwBytesToRead]
    .if (signed eax < 1 | signed eax > MAX_BUFFER-1)
        mov [dwBytesToRead], MAX_BUFFER-1
    .endif

    .while ([dwRecvLen] <> 0 & signed [dwBytesToRead] > 0)
        invoke RtlZeroMemory, [lpRecvBuf], 5*MAX_BUFFER
        invoke InternetReadFile, [hData], [lpRecvBuf], [dwBytesToRead], addr dwRecvLen
        .if (eax <> 0 & [dwRecvLen] <> 0)
            invoke MultiByteToWideChar, CP_UTF8, 0, [lpRecvBuf], -1, 0, 0
            invoke MultiByteToWideChar, CP_UTF8, 0, [lpRecvBuf], -1, [lpWideBuf], eax
            invoke lstrlen, [lpWideBuf]
            mov ecx, eax
            add ecx, 1
            shl ecx, 1
            push ecx
            invoke HeapSize, [hHeap], 0, [lpOutBuf]
            pop ecx
            add ecx, eax
            invoke HeapReAlloc, [hHeap], HEAP_ZERO_MEMORY, [lpOutBuf], ecx
            mov [lpOutBuf], eax
            invoke lstrcat, eax, [lpWideBuf]
            mov ecx, [dwRecvLen]
            add [dwTotalBytes], ecx
            .if [dwBytesToRead] <> MAX_BUFFER-1
                sub [dwBytesToRead], ecx
            .endif
        .endif
    .endw

    invoke StrTrim, [lpOutBuf], <WHITESPACE,CRLF>

    invoke HeapFree, [hHeap], 0, [lpRecvBuf]

    mov eax, 1  ; success

    .continue:

    .if eax = 0
        invoke GetLastError
        mov [dwLastError], eax
    .endif

    .if [lpDomain] <> 0
        invoke HeapFree, [hHeap], 0, [lpDomain]
    .endif

    .if [hData] <> 0
        invoke InternetCloseHandle, [hData]
    .endif

    .if [hConnection] <> 0
        invoke InternetCloseHandle, [hConnection]
    .endif

    .if [hInternet] <> 0
        invoke InternetCloseHandle, [hInternet]
    .endif

    mov eax, [lpOutBuf]

    ret
endp


;--------------------------------------------------------------------------------------------------

section '.idata' import data readable writeable

;--------------------------------------------------------------------------------------------------
    library\
    kernel32,'kernel32.dll',\
    shlwapi,'shlwapi.dll',\
    wininet,'wininet.dll',\
    msvcrt,'msvcrt.dll'

    import kernel32,\
    ExitProcess,'ExitProcess',\
    GetLastError,'GetLastError',\
    GetProcessHeap,'GetProcessHeap',\
    HeapAlloc,'HeapAlloc',\
    HeapReAlloc,'HeapReAlloc',\
    HeapFree,'HeapFree',\
    HeapSize,'HeapSize',\
    lstrcpy,'lstrcpyW',\
    lstrcat,'lstrcatW',\
    lstrlen,'lstrlenW',\
    MultiByteToWideChar,'MultiByteToWideChar',\
    RtlZeroMemory,'RtlZeroMemory'

    import shlwapi,\
    StrTrim,'StrTrimW'

    import wininet,\
    InternetOpen,'InternetOpenW',\
    InternetConnect,'InternetConnectW',\
    InternetSetOption,'InternetSetOptionW',\
    HttpOpenRequest,'HttpOpenRequestW',\
    HttpSendRequest,'HttpSendRequestW',\
    InternetReadFile,'InternetReadFile',\
    InternetCloseHandle,'InternetCloseHandle'

    import msvcrt,\
    wprintf,'wprintf'
    
Post 27 Apr 2020, 10:36
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.