Question

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 ?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top