Hello guys,
I have problem with reading or writing files in C++ and MASM32. The problem is when calling the ReadFile or WriteFile the program give an exception saying "Access violation at address 0000".

This is the code in MASM32:

    LOCAL   Kernel32:DWORD
    LOCAL   CreateFileA:DWORD
    LOCAL   GetFileSize:DWORD
    LOCAL   ReadFile:DWORD
    LOCAL   pBytesRead:DWORD
    LOCAL   BytesToRead:DWORD
    LOCAL   hFile:DWORD

    ;-----------------------------------------
    ;Getting Kernel Imagebase
    ;-----------------------------------------
    ;kernel32.dll = 2511EF2C
    PUSH    02511EF2Ch
    CALL    find_dll

    MOV Kernel32, EAX

    ;-----------------------------------------
    ;Find required APIs
    ;-----------------------------------------
    ;CreateFileA = 0CF2006EAh, GetFileSize = 06D61AB47h, ReadFile = 024EF6F37h, WriteFile = 0317EB0D7h

    PUSH    0CF2006EAh
    PUSH    Kernel32
    CALL    find_api

    MOV CreateFileA, EAX

    PUSH    06D61AB47h
    PUSH    Kernel32
    CALL    find_api

    MOV GetFileSize, EAX

    PUSH    024EF6F37h
    PUSH    Kernel32
    CALL    find_api

    MOV     ReadFile, EAX

    PUSH    NULL                                ; /hTemplateFile = NULL
    PUSH    FILE_ATTRIBUTE_NORMAL               ; |Attributes = FILE_ATTRIBUTE_NORMAL
    PUSH    OPEN_EXISTING                       ; |Mode = OPEN_EXISTING
    PUSH    0                                   ; |pSecurity = NULL
    PUSH    FILE_SHARE_READ + FILE_SHARE_WRITE  ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
    PUSH    GENERIC_ALL             ; |Access = GENERIC_ALL
    PUSH    FileName                ; |FileName = "*.exe"
    CALL    CreateFileA     ; \CreateFileA

    MOV hFile,EAX

    PUSH    0                       ; /pFileSizeHigh = NULL
    PUSH    hFile                   ; |hFile
    CALL    GetFileSize     ; \GetFileSize

    CMP EAX, 0h
    JZ  Exit

    MOV BytesToRead, 10h

    PUSH    0           ; /pOverlapped = NULL
        PUSH    pBytesRead      ; |pBytesRead = ?
    PUSH    BytesToRead     ; |BytesToRead
    PUSH    OFFSET Buffer       ; |Buffer
    PUSH    hFile           ; |hFile
    CALL    ReadFile        ; \ReadFile
Exit:

When debug it in Ollydbg it stops right here:

757F85EA   8907             MOV DWORD PTR DS:[EDI],EAX
EDI = 00000000
EAX = 00000055

And give me the error (described above) because EDI is 000000.

Why this error occurred and what is the solution to fix the problem?

What's the value of DS when this error happens?

I finally found the problem, the problem was me :)
The problem is when I call WriteFile or ReadFile the function will write on BytesRead or BytesWritten which means that I must give the effective address of the variable.
In MASM32:

        PUSH    0           ; /pOverlapped = NULL
        PUSH    pBytesRead      ; |pBytesRead = ? //I gave the value of pBytesRead which is NULL
    PUSH    BytesToRead     ; |BytesToRead
    PUSH    OFFSET Buffer       ; |Buffer
    PUSH    hFile           ; |hFile
    CALL    ReadFile        ; \ReadFile

The correct code is:
        PUSH    0           ; /pOverlapped = NULL
        LEA EAX, pBytesRead
        PUSH    EAX             ;|pBytesRead = ?
        PUSH    BytesToRead     ; |BytesToRead
    PUSH    OFFSET Buffer       ; |Buffer
    PUSH    hFile           ; |hFile
    CALL    ReadFile        ; \ReadFile

In C code:

HANDLE  hFile;
    LPCVOID Buffer = "Hello";
    DWORD   BytesWritten = 0;

    hFile = CreateFile("rw.txt",FILE_APPEND_DATA, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if(!WriteFile(hFile, Buffer, 5, &BytesWritten, NULL))
        MessageBox(NULL, "Can not write!", "Error", MB_OK);

    CloseHandle(hFile)

That would do it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.