0

I am having a few issues with my code. I am trying to read both of the PE headers inside of an executable file. However, when I invoke ReadFile, it sets [hFile] to 5A, which is not the handle I put inside from CreateFile. From what I understand, ReadFile should not change this in any way. However, when I store the handle inside another variable and use it to set the file pointer, the next ReadFile instruction still gives me the MZ header instead of the PE header, which is located at offset 3C from the MZ header.

Summary: ReadFile changes my handle, SetFilePointer sees the change as an invalid handle, SetFilePointer does not change the pointer for the next read when given a valid handle.

format PE console 4.0
entry start

include 'win32ax.inc'

section '.data' data readable writeable

thisFile db "thisfile.exe",0
read db ?
hFile dd ?

section '.text' data readable executable

start:
;========Open File================
invoke CreateFile,thisFile,GENERIC_READ,FILE_SHARE_READ,0,\
                  OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
mov [hFile],eax

;========MZ HEADER================
invoke ReadFile,[hFile],read,2,NULL,0 ; = MZ, , however, changes [hFile]
                                      ;to 5A? Why does it change it?
invoke printf,read

;========PE HEADER================
invoke SetFilePointer,[hFile],03Ch,0,FILE_CURRENT ; = 0, beginning of file ATM
                                                  ;Should make next read = PE
invoke ReadFile,[hFile],read,3,NULL,0 ; = PE

invoke printf,read

invoke getchar
invoke ExitProcess,0 
Chris Altig
  • 680
  • 3
  • 8
  • 22

1 Answers1

2

Here you're reading 2 bytes into read:

invoke ReadFile,[hFile],read,2,NULL,0

But look at how you've declared read:

read db ?

That's a single byte. So the second byte you're reading with ReadFile will get written into whatever follows read in memory, which happens to be hFile. Thus, you're overwriting the least significant byte of hFile.

There's another place in your code where you're trying to read 3 bytes into read, but I guess that will fail since by then your hFile will be invalid.

What you need to do is to reserve more space for read, as much as you ever plan on storing in it. Let's say that you want 4 bytes, you could get that with:

read db 4 dup(0)

or

read: times 4 db 0

or

read rb 4

or

read dd ?

Since you're passing read to printf as a string, keep in mind that strings are expected to be NUL-terminated.

Michael
  • 57,169
  • 9
  • 80
  • 125
  • So for the past few weeks, I have been getting lucky in the fact none of my data was overwritten. Thank you for clearing up one of my misconceptions. I always assumed that `abc DB ?` meant that it was going to make space for what I put into it. – Chris Altig Aug 05 '14 at 19:16
  • A smaller sub-question, however. In assembly, how would I handle data that I won't know how big it is. Like a filename. Because if I did `filename DB 256 dup (0)` for every variable of unknown length, it wold cause my program to bloat. Is `GlobalAlloc` my answer? – Chris Altig Aug 05 '14 at 19:19
  • 1
    Yes, at some point you'll probably need some sort of heap allocation routine. There are several of them in Windows (`LocalAlloc`, `GlobalAlloc`, `HeapAlloc`, ...). You can probably find out on MSDN which of them that would be best to use for your purposes. – Michael Aug 05 '14 at 19:29