masm32 ReadFile Function x86 -Windows - windows

I've been trying to read the string written inside a .txt file and print it out on the console. But it seems I'm not doing it right. Can someone review my codes and tell me what's wrong? Thanks!
include \masm32\include\masm32rt.inc
.data
txtFilter db "*.txt",0
txtFD WIN32_FIND_DATA <>
txtHandle HANDLE ?
fHandle HANDLE ?
bufferLength db ?
buffer db 5000 dup(?)
lnt db "1024",0
okay db "Okay!",0
dokay db "Dokay!",0
.code
start:
push offset txtFD
push offset txtFilter
call FindFirstFile
mov txtHandle, eax
push offset txtFD.cFileName
call StdOut
push 0
push FILE_ATTRIBUTE_NORMAL
push OPEN_EXISTING
push 0
push 0
push FILE_APPEND_DATA
push offset txtFD.cFileName
call CreateFile
.if eax == INVALID_HANDLE_VALUE
jmp _error
.else
mov fHandle, eax
.endif
push 0
push offset bufferLength
push offset lnt
push offset buffer
push fHandle
call ReadFile
jmp _next
_error:
push offset dokay
call StdOut
jmp _next
_okay:
push offset okay
call StdOut
_next:
push offset buffer
call StdOut
push fHandle
call CloseHandle
push txtHandle
call FindClose
push 0
call ExitProcess
end start
The code can't seem to read what is inside my txt file. However I can successfully search my txt file and perform the function CreateFile

Four issues:
bufferLength db ? reserves only one byte. ReadFile will store there a DWORD and overwrite three bytes of buffer. If there is a NULL, StdOut will stop the output. Change the definition to bufferLength dd ?
lnt db "1024",0 is a string. ReadFile expects a DWORD value. Change it to lnt dd 1024.
push FILE_APPEND_DATA creates a handle only for writing. Change it to push GENERIC_READ.
push offset lnt passes a pointer. However, ReadFile expects a DWORD value. Change it to push lnt.
Like that:
include \masm32\include\masm32rt.inc
.data
txtFilter db "*.txt",0
txtFD WIN32_FIND_DATA <>
txtHandle HANDLE ?
fHandle HANDLE ?
; bufferLength db ?
bufferLength dd ?
buffer db 5000 dup(?)
; lnt db "1024",0
lnt dd 1024
okay db "Okay!",0
dokay db "Dokay!",0
.code
start:
push offset txtFD
push offset txtFilter
call FindFirstFile
mov txtHandle, eax
push offset txtFD.cFileName
call StdOut
; https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
push 0 ; HANDLE hTemplateFile
push FILE_ATTRIBUTE_NORMAL ; DWORD dwFlagsAndAttributes
push OPEN_EXISTING ; DWORD dwCreationDisposition
push 0 ; LPSECURITY_ATTRIBUTES lpSecurityAttributes
push 0 ; DWORD dwShareMode
; push FILE_APPEND_DATA ; DWORD dwDesiredAccess
push GENERIC_READ ; DWORD dwDesiredAccess
push offset txtFD.cFileName ; LPCTSTR lpFileName,
call CreateFile
.if eax == INVALID_HANDLE_VALUE
jmp _error
.else
mov fHandle, eax
.endif
; https://msdn.microsoft.com/en-us/library/windows/desktop/aa365467(v=vs.85).aspx
push 0 ; LPOVERLAPPED lpOverlapped
push offset bufferLength ; LPDWORD lpNumberOfBytesRead
; push offset lnt ; DWORD nNumberOfBytesToRead
push lnt ; DWORD nNumberOfBytesToRead
push offset buffer ; LPVOID lpBuffer
push fHandle ; HANDLE hFile
call ReadFile
jmp _next
_error:
push offset dokay
call StdOut
jmp _next
_okay:
push offset okay
call StdOut
_next:
push offset buffer
call StdOut
push fHandle
call CloseHandle
push txtHandle
call FindClose
push 0
call ExitProcess
end st

Related

ReadConsoleInputA throws an Access Violation

I am trying to learn how to use the windows api (instead of just using C calls, irvine32 or masm32) And are running into issues with ReadConsoleInputA (WriteConsoleA works fine).
Also, I don't get why in the PROC prototype for the function, most examples append either an A or a W at the end of ReadConsoleInput/WriteConsole, can you explain why?
.data
consoleOutHandle dd ?
consoleInHandle dd ?
bufferlen dd ?
buffer db ?
bufferSize DWORD ?
message db "Enter a number:", 0
lmessage equ $-message
.code
main PROC
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov consoleOutHandle, eax
invoke ReadConsoleInputA, consoleOutHandle, offset buffer, 128, bufferSize
main endp
end main
It throws: Access violation writing location 0x00000004.
Following the advice from Michael Petch, I have this code now:
.data
consoleOutHandle dd ?
consoleInHandle dd ?
byteswritten dd ?
bufferlen dd ?
buffer db 128 DUP(?)
bufferSize dd ?
message db "Enter a number:", 0
lmessage equ $-message
.code
main PROC
invoke GetStdHandle, STD_INPUT_HANDLE
mov consoleInHandle, eax
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov consoleOutHandle, eax
mov eax, lmessage
invoke WriteConsoleA, consoleOutHandle, offset message, eax, bytesWritten, 0
invoke ReadConsoleInputA, consoleInHandle, offset buffer, 128, offset bufferSize
main endp
end main
And now it throws "triggered a breakpoint".
Disassembly:
invoke ReadConsoleInputA, consoleInHandle, offset buffer, 128, offset bufferSize
00E71066 push offset bufferSize (0E74090h)
00E7106B push 80h
00E71070 push offset buffer (0E74010h)
00E71075 push dword ptr [consoleInHandle (0E74004h)]
00E7107B call _ReadConsoleInputA#16 (0E7100Ah)
--- No source file -------------------------------------------------------------
00E71080 int 3 **---> Breakpoint here**
00E71081 int 3
You asked what the A and W suffix on the end of the WinAPI functions are for. Functions ending with A denote Ansi, and functions ending with W are Wide. Microsoft documents them this way:
Unicode and ANSI Functions
When Microsoft introduced Unicode support to Windows, it eased the transition by providing two parallel sets of APIs, one for ANSI strings and the other for Unicode strings. For example, there are two functions to set the text of a window's title bar:
SetWindowTextA takes an ANSI string.
SetWindowTextW takes a Unicode string.
In the first version of the code
You don't allocate space necessary for buffer. You had:
buffer db ?
That allocated a single byte to the buffer. It should have been:
buffer db 128 DUP(?)
You used STD_OUTPUT_HANDLE instead of STD_INPUT_HANDLE
The last parameter to ReadConsoleInputA is a pointer to a DWORD that will return the number of events read. Changing the variable name bufferSize might make the code more readable. From the ReadConsoleInputA documentation:
BOOL WINAPI ReadConsoleInput(
_In_ HANDLE hConsoleInput,
_Out_ PINPUT_RECORD lpBuffer,
_In_ DWORD nLength,
_Out_ LPDWORD lpNumberOfEventsRead
);
If you are reading just the keyboard you should be using ReadConsoleA as ReadConsoleInputA will process keyboard and mouse events and may prematurely return before your string is read. ReadConsoleA takes one extra parameter and you can set it to NULL:
BOOL WINAPI ReadConsole(
_In_ HANDLE hConsoleInput,
_Out_ LPVOID lpBuffer,
_In_ DWORD nNumberOfCharsToRead,
_Out_ LPDWORD lpNumberOfCharsRead,
_In_opt_ LPVOID pInputControl
);
To exit the program you need to invoke ExitProcess .
In the second version of the code
Your code does:
invoke WriteConsoleA, consoleOutHandle, offset message, eax, bytesWritten, 0
bytesWritten needs to be a pointer because that is an output parameter. From WriteConsoleA documentation:
BOOL WINAPI WriteConsole(
_In_ HANDLE hConsoleOutput,
_In_ const VOID *lpBuffer,
_In_ DWORD nNumberOfCharsToWrite,
_Out_ LPDWORD lpNumberOfCharsWritten,
_Reserved_ LPVOID lpReserved
);
A version of the code that uses ReadConsoleA instead of ReadConsoleInputA based on your second code example could look like:
.data
consoleOutHandle dd ?
consoleInHandle dd ?
bytesWritten dd ?
bufferlen dd ?
buffer db 128 DUP(?)
numEvents dd ?
message db "Enter a number:", 0
lmessage equ $-message
.code
main PROC
invoke GetStdHandle, STD_INPUT_HANDLE
mov consoleInHandle, eax
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov consoleOutHandle, eax
mov eax, lmessage
invoke WriteConsoleA, consoleOutHandle, offset message, eax, offset bytesWritten, 0
invoke ReadConsoleA, consoleInHandle, offset buffer, 128, offset numEvents, 0
invoke ExitProcess, 0
main endp
end main
This code can be cleaned up a bit by using MASM's sizeof operator. The code could be written as:
.data
consoleOutHandle dd ?
consoleInHandle dd ?
buffer db 128 DUP(?)
bytesWritten dd ?
numEvents dd ?
message db "Enter a number:", 0
.code
main PROC
invoke GetStdHandle, STD_INPUT_HANDLE
mov consoleInHandle, eax
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov consoleOutHandle, eax
invoke WriteConsoleA, consoleOutHandle, offset message, sizeof message, offset bytesWritten, 0
invoke ReadConsoleA, consoleInHandle, offset buffer, sizeof buffer, offset numEvents, 0
invoke ExitProcess, 0
main endp
end main

Print hexa value in masm

I do a MapViewOfFile to get a pointer on the begin of my file, after that I want to print the value of it in hexa.
When I print it as string I get "MZ" which is the good value (the magic number) but I want it in hexa (5A4D).
I tried to format with %x in wsprintf but it doesn't work, I got 230000 as value..
EDIT the tried for %x:
.data
header_format db "The header is: %x",0
buffer db 256 dup(?) ; File data
.data?
pMemory DWORD ? ; Pointer to the data in the source file
getData:
;pMemory is the ptr which is correctly printed with %s
invoke wsprintf, ADDR buffer, ADDR header_format, [pMemory] ;
invoke MessageBox, NULL, Addr buffer, Addr header_test, MB_OK
Have you any suggestions ?
Thanks.
It finally works by using this solution :
push STD_OUTPUT_HANDLE
call GetStdHandle
mov eax, pMemory
push eax
print right$(uhex$(eax),2),13,10
pop eax
mov eax, pMemory
push eax
print right$(uhex$([eax]),2),13,10
pop eax

GetModuleFileName in NASM x86 assembly

Here's the code...
extern GetStdHandle
extern GetModuleFileNameW
extern WriteFile
extern ExitProcess
import GetStdHandle kernel32.dll
import GetModuleFileNameW kernel32.dll
import WriteFile kernel32.dll
import ExitProcess kernel32.dll
global ..start
segment .code USE32
..start:
push dword -11
call [GetStdHandle]
mov dword [hStdOut], eax
;Getting the filepath of exe on disk...
push dword 256 ;MAX_PATH
push dword [filepath] ;Pointer to the buffer
push dword 0 ;NULL
call [GetModuleFileNameW]
;Trying to output the filepath...
push dword 0
push dword nBytes
push dword 256 ;MAX_PATH
push dword filepath
push dword [hStdOut]
call [WriteFile]
xor eax, eax
push eax
call [ExitProcess]
segment .data
segment .bss
hStdOut resd 1
nBytes resd 1
filepath resd 32
I've played around with it a bit, and all I get is a blank output. I've also gotten a bunch of gibberish when I play around with it a bit. Still no file path, and still no joy. I have a hunch that I'm doing something wrong with GetModuleFileNameW, but I can't be sure. I followed the documentation on the Microsoft website, and I put the arguments in in the opposite order like you're supposed to in assembly language. What am I doing wrong?
;Getting the filepath of exe on disk...
push dword 256 ;MAX_PATH
push dword [filepath] ;Pointer to the buffer
push dword 0 ;NULL
call [GetModuleFileNameW]
... must be changed to...
;Getting the filepath of exe on disk...
push dword 256 ;MAX_PATH
push dword filepath ;Pointer to the buffer
push dword 0 ;NULL
call [GetModuleFileNameW]

access violation socket accept() on masm32

I'm trying to make a "socket" with masm32, but something is wrong with accept(), ollydbg show me an Access Violation when the code try to execute accept() and I don't know what is wrong, Can somebody tell me how can I fix it, please?
.686
.model flat, stdcall
option casemap:none
extrn ExitProcess#4:PROC
extrn WSAStartup#8:PROC
extrn socket#12:PROC
extrn bind#12:PROC
extrn listen#8:PROC
extrn accept#12:PROC
WSADATA STRUCT 8
wVersion WORD ?
wHighVersion WORD ?
iMaxSocket WORD ?
iMaxUdpDg WORD ?
lpVendorInfo DWORD ?
szDescription SBYTE 257 dup (?)
szSystemStatus SBYTE 129 dup (?)
WSADATA ENDS
sockaddr STRUCT
sa_family WORD ?
sa_port WORD ?
sa_addr DWORD ?
BYTE 8 dup (?)
sockaddr ENDS
.const
address sockaddr<2, 0B922h, 00000000h>
sbuff BYTE 50 dup (0)
.data?
wsadata WSADATA <>
Socket DWORD ?
.code
Start proc
push ebp
mov ebp, esp
lea edx, wsadata
push edx
push 2h
call WSAStartup#8
push 0h
push 1h
push 2h
call socket#12
mov Socket, eax
push 16h
lea ecx, address
push ecx
push Socket
call bind#12
push 1h
push Socket
call listen#8
push 16h
lea ecx, address
push ecx
push Socket
call accept#12
mov eax, 0
call ExitProcess#4
mov esp, ebp
pop ebp
Start endp
END
regards
The third argument of access is a pointer to the length, not the length itself.
By the way: The structure is 16 (decimal), not 16h bytes long.
Therefore your code should look like this:
.data?
wsadata WSADATA <>
Socket DWORD ?
addrlen DWORD 10h <- This one is new!
.code
...
push 10h <- Instead of 16h
...
call bind#12
...
lea ecx, addrlen
push ecx
lea ecx, address
push ecx
push Socket
call accept#12

x86 assembly - GetStdHandle & WriteConsole

In response to my question about Windows API's, I have successfully gotten it to work. My question is in regards to this code:
push STD_OUTPUT_HANDLE
call GetStdHandle
push NULL
push offset other
push mlen
push offset msg
push eax
call WriteConsole
push 0
call ExitProcess
This code is supposed to print the value of msg. Why does one need to do:
a)
push STD_OUTPUT_HANDLE
call GetStdHandle
push NULL
And:
b)
push offset other
push mlen
push offset msg
push eax
I am just wondering what the need is for getting a StdHandle and pushing offsets.
Thanks in advance,
Progrmr
Look at the definition of WriteConsole. The NULL is the last argument of the function, the lpReserved argument. Arguments are pushed in right-to-left order. The first function argument is the console handle, the one you got from GetStdHandle and you pass by pushing eax.
So properly commenting the assembly code:
push STD_OUTPUT_HANDLE ; GetStdHandle nStdHandle argument
call GetStdHandle ; eax = Console handle
push NULL ; lpReserved = null
push offset other ; lpNumberOfCharsWritten = pointer to "other"
push mlen ; nNumberOfCharsToWrite = length of "msg"
push offset msg ; lpBuffer = pointer to "msg"
push eax ; hConsoleOutput = console handle from GetStdHandle
call WriteConsole ; Write string
push 0 ; exit code = 0
call ExitProcess ; terminate program

Resources