Jump to content
Welcome, welcome! Come in and register, and have some developer coffee. 👨‍💻 ×

Open file and Read file


Recommended Posts

format PE console
entry start

include 'win32a.inc'

section '.data' readable writable

_message1 db 'INVALID_HANDLE_VALUE',13,10,0
_msglen1  = $ - _message1
_message2 db 'ReadFile FALSE',13,10,0
_msglen2  = $ - _message2
_dummy    dw ?
_filename db 'C:\FASM\MSGBOX.ASM',0

section '.code' code readable writable executable

_buffer  rb 256
_len     dw ?

start:
        invoke  CreateFile, _filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0
        cmp     eax, INVALID_HANDLE_VALUE
        je      .error1
        invoke  ReadFile, eax, _buffer, 256, _len, 0
        test    eax, eax
        jz      .error2
        mov     ecx, dword [_len]
        ;mov     byte [_buffer+ecx], 0
        jmp     .show

.error1:
        lea     edx, [_message1]      ; CreateFile ERROR
        mov     ecx, _msglen1
        jmp     .error

.error2:
        lea     edx, [_message2]      ; ReadFile ERROR
        mov     ecx, _msglen2

.error:
        mov     esi, edx
        lea     edx, [_buffer]
        mov     edi, edx
        mov     dword [_len], ecx
        rep     movsb

.show:
        invoke  GetStdHandle, -11
        invoke  WriteConsole, eax, _buffer, dword [_len], _dummy, 0
        invoke  ExitProcess,0

section '.idata' import readable writable

 library kernel32,'KERNEL32.DLL'

 import kernel32,\
        GetStdHandle, 'GetStdHandle', \
        ReadConsole, 'ReadConsoleA', \
        WriteConsole, 'WriteConsoleA', \
        CreateFile, 'CreateFileA', \
        ReadFile, 'ReadFile', \
        ExitProcess,'ExitProcess'            

Change the _filename to a valid path in your PC. It reads the first 256 bytes of the file only.

Can you try to improve this Assembly code, so that it can accept command-line argument as filename? Or read the entire file and display them on screen?

Link to post
Share on other sites
  • 2 weeks later...

Below is an enhancement to the original code above, which accept command-line argument as input filename.

; Open File and Read File
;
; READFILE.ASM
; Copyright (C) 2021 Boo Khan Ming
;
; MIT license apply
;
format PE console
entry start

include 'win32a.inc'

section '.data' readable writable

_message1 db 'INVALID_HANDLE_VALUE',13,10,0
_msglen1  = $ - _message1
_message2 db 'ReadFile FALSE',13,10,0
_msglen2  = $ - _message2
_dummy    dw ?
;_filename db 'C:\FASM\MSGBOX.ASM',0

section '.code' code readable writable executable

_filename rb MAX_PATH
_fnlen    dw ?
_buffer   rb 256
_len      dw ?

start:
        invoke  GetCommandLine
        push    eax
        mov     edi, eax
        or      ecx, -1
        xor     eax, eax
        repnz   scasb           ; Calculate total length of command line arguments
        not     ecx
        pop     eax
        mov     dword [_fnlen], ecx
        push    eax
        mov     edi, eax
        or      ecx, -1
        mov     eax, 32
        repnz   scasb           ; Calculate length of first command line argument (APPNAME)
        not     ecx
        pop     eax
        inc     ecx
        sub     dword [_fnlen], ecx     ; Compute the length of second command line argument (_FILENAME)
        add     eax, ecx
        mov     ecx, dword [_fnlen]
        mov     esi, eax
        lea     edx, [_filename]
        mov     edi, edx
        rep     movsb
        ;invoke  GetStdHandle, -11
        ;invoke  WriteConsole, eax, _filename, dword [_fnlen], _dummy, 0

        invoke  CreateFile, _filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0
        cmp     eax, INVALID_HANDLE_VALUE
        je      .error1
        invoke  ReadFile, eax, _buffer, 256, _len, 0    ; Read the first 256 bytes only
        test    eax, eax
        jz      .error2
        mov     ecx, dword [_len]
        ;mov     byte [_buffer+ecx], 0
        jmp     .show

.error1:
        lea     edx, [_message1]      ; CreateFile ERROR
        mov     ecx, _msglen1
        jmp     .error

.error2:
        lea     edx, [_message2]      ; ReadFile ERROR
        mov     ecx, _msglen2

.error:
        mov     esi, edx
        lea     edx, [_buffer]
        mov     edi, edx
        mov     dword [_len], ecx
        rep     movsb

.show:
        invoke  GetStdHandle, -11
        invoke  WriteConsole, eax, _buffer, dword [_len], _dummy, 0
        invoke  ExitProcess,0

section '.idata' import readable writable

 library kernel32,'KERNEL32.DLL'

 import kernel32,\
        GetStdHandle, 'GetStdHandle', \
        ReadConsole, 'ReadConsoleA', \
        WriteConsole, 'WriteConsoleA', \
        CreateFile, 'CreateFileA', \
        ReadFile, 'ReadFile', \
        GetCommandLine, 'GetCommandLineA', \
        ExitProcess,'ExitProcess'

 

Link to post
Share on other sites
  • 2 weeks later...
On 4/12/2021 at 6:34 AM, FlierMate said:

Can you try to improve this Assembly code, so that it can accept command-line argument as filename? Or read the entire file and display them on screen?

I solved it myself, hah.

The following code can read file up to 2^32 / 2 (2GB) and dump it on screen or redirect to another file. It accepts command-line input filename.

Usage:

DUMPFILE readme.txt

DUMPFILE readme.txt > dump.txt

Full source to be compiled with FASM.  MIT license apply.

; Open File and Read File (Extended Version with Command Line File Name Support)
;
; DUMPFILE.ASM
; Copyright (C) 2021 Boo Khan Ming
;
; MIT license apply
;
format PE console
entry start

include 'win32a.inc'

section '.data' readable writable

_message1 db 'INVALID_HANDLE_VALUE',13,10,0
_msglen1  = $ - _message1
_message2 db 'ReadFile FALSE',13,10,0
_msglen2  = $ - _message2
_dummy    dw ?
;_filename db 'LARGE.BIN',0
_format   db '%d',0

section '.code' code readable writable executable

_filename rb MAX_PATH
_fnlen    dd ?
_buffer   rb 1024
_len      dd ?
_ptr      dd ?
_handle   dd ?

start:
        invoke  GetCommandLine
        push    eax
        mov     edi, eax
        or      ecx, -1
        xor     eax, eax
        repnz   scasb           ; Calculate total length of command line arguments
        not     ecx
        pop     eax
        mov     dword [_fnlen], ecx
        push    eax
        mov     edi, eax
        or      ecx, -1
        mov     eax, 32
        repnz   scasb           ; Calculate length of first command line argument (APPNAME)
        not     ecx
        pop     eax
        inc     ecx
        sub     dword [_fnlen], ecx     ; Compute the length of second command line argument (_FILENAME)
        add     eax, ecx
        mov     ecx, dword [_fnlen]
        mov     esi, eax
        lea     edx, [_filename]
        mov     edi, edx
        rep     movsb
        ;invoke  GetStdHandle, -11
        ;invoke  WriteConsole, eax, _filename, dword [_fnlen], _dummy, 0
        invoke  CreateFile, _filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0
        mov     dword [_handle], eax
        cmp     eax, INVALID_HANDLE_VALUE
        je      .error1

.repeat:
        invoke  ReadFile, dword [_handle], _buffer, 1024, _len, 0
        test    eax, eax
        jz      .error2
        mov     ecx, dword [_len]
        add     dword [_ptr], ecx
        test    ecx, ecx
        jz      .done
        invoke  GetStdHandle, -11
        invoke  WriteFile, eax, _buffer, dword [_len], _dummy, 0
        invoke  SetFilePointer, dword [_handle], dword [_ptr], 0, FILE_BEGIN
        cmp     eax, -1         ;INVALID_SET_FILE_POINTER
        je      .error3
        jmp     .repeat

.error1:
        lea     edx, [_message1]
        mov     ecx, _msglen1
        jmp     .error

.error2:
        lea     edx, [_message2]
        mov     ecx, _msglen2
        jmp     .error

.error3:
        invoke  GetLastError
        ;cmp     eax, 997        ; ERROR_IO_PENDING
        ;je      .repeat
        push    eax
        push    _format
        push    _buffer
        call    [wsprintf]
        mov     dword [_len], 5
        jmp     .show

.error:
        mov     esi, edx
        lea     edx, [_buffer]
        mov     edi, edx
        mov     dword [_len], ecx
        rep     movsb

.show:
        invoke  GetStdHandle, -11
        invoke  WriteConsole, eax, _buffer, dword [_len], _dummy, 0

.done:
        invoke  ExitProcess,0

section '.idata' import readable writable

 library kernel32, 'KERNEL32.DLL', \
         user32, 'USER32.DLL'

 import kernel32,\
        GetStdHandle, 'GetStdHandle', \
        ReadConsole, 'ReadConsoleA', \
        WriteConsole, 'WriteConsoleA', \
        CreateFile, 'CreateFileA', \
        ReadFile, 'ReadFile', \
        WriteFile, 'WriteFile', \
        GetLastError, 'GetLastError', \
        SetFilePointer, 'SetFilePointer', \
        SetFilePointerEx, 'SetFilePointerEx', \
        GetCommandLine, 'GetCommandLineA', \
        ExitProcess,'ExitProcess'

 import user32,\
        wsprintf, 'wsprintfA'

 

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...