0

hey I have been using masm for 2 weeks now and I am trying to read from a text file line by line that has paths of files in them

example of text file
C:\a.rar
C:\a.txt
C:\a.png

then I want to read in the whole contents of the file path and get the md5 check sum of the file path

the below code works perfectly for the first time(the first message box is the file path,the second is the contents of the file and the third is the md5 check sum)

but then after the first loop it reads the second files path but can not read the contents of the second file and then crashes because it has nothing to md5 check sum.

it must be a easy mistake of not resetting something or not closing something but I have spent like 20 hours on this and can not get it to work

for example the below code is in a button and when you press the button this is what it is supposed to do

message box C:\a.rar
message box "contents of file"
message box 44644af7515bc4870d44fa688684798
message box C:\a.txt
message box "contents of file"
message box 6057f13c496ecf7fd777ceb9e79ae285
message box C:\a.png
message box "contents of file"
message box 01654ab48d84f484z446ba48453cb48

but this is what happens

message box C:\a.rar
message box "contents of file"
message box 44644af7515bc4870d44fa688684798
message box C:\a.txt
blank contents cant read the contents of the file on loop (this is the problem)
message box blank because it cant md5 no contents

crash

can someone please help

LOCAL Buffer3  :DWORD

invoke CreateFile, ADDR filestoscan, GENERIC_READ, 0, 0,OPEN_EXISTING, 0, 0
mov hFile, eax

invoke GetFileSize,hFile,NULL
mov Byteforstreamreader,eax
streamreader2:
.if Byteforstreamreader != 0
invoke ReadFile, hFile, ADDR Buffer2,1, ADDR BytesWritten, 0
.if Buffer2 == 13







invoke CreateFile, ADDR StringBuffer, GENERIC_READ, 0, 0,OPEN_EXISTING, 0, 0
mov hFile2, eax

invoke GetFileSize,hFile2,NULL
mov Bytes,eax

invoke ReadFile, hFile2, ADDR FileBuffer,Bytes, ADDR BytesWritten, 0
invoke CloseHandle,hFile2






invoke MessageBoxA, NULL, addr StringBuffer, offset BoxCaption, NULL
invoke MessageBoxA, NULL, addr FileBuffer, offset BoxCaption, NULL







invoke MD5_Startup
invoke MD5_Init, offset ctxt
invoke MD5_Read, offset ctxt, offset FileBuffer, Bytes
invoke MD5_Digest, offset ctxt, offset filehash
invoke MD52String, offset filehash, offset strn, 1


invoke MessageBoxA, NULL, addr strn, offset BoxCaption, NULL








mov FileBuffer,0
mov StringBuffer,0
dec Byteforstreamreader
jmp streamreader2
.endif
mov eax,offset Buffer2
mov Buffer3,eax



invoke lstrcat,ADDR StringBuffer,addr Buffer2

dec Byteforstreamreader
jmp streamreader2
.endif
.if Byteforstreamreader == 0
invoke CloseHandle,hFile
.endif

.data
filestoscan      db "myfiles.txt",0
FileBuffer        DB 50000 DUP(?)
Bytes dd ?
Bytes2 dd ?
BytesWritten dd ?
BytesWritten3 dd ?
hFile dd ?
hFile2 dd ?

.data ?
hFile dd ?
Byteforstreamreader dd ?  
BytesWritten2 dd ?
StringBuffer DB 100 DUP(?)
Buffer2  db 500 dup (?)
ctxt db 1000 dup (?)
filehash db 1000 dup (?)
strn db 33 dup(?) ; use dw for unicode

also as a side question if someone could please answer it does not seem right to me to have to reserve 50000 bytes on filebuffer so I can open a 50000 bytes or smaller file. how can I open any file size without reserving all that memory because some of these files may be 100 mb or more

thank you

  • 1
    If the code isn't that long then paste it in, select it all and press Ctrl+K to turn it into a code block. – Neil Mar 31 '13 at 17:16
  • ok i got the code on their now – patchariadog Mar 31 '13 at 17:20
  • 1
    As far as your side question about how to handle large files without having a huge static buffer - think about how you might do that in C. Generally you don't read the whole file into a single buffer, instead you have a loop that reads blocks of the file into a smaller buffer and processes the file a block at a time. – Michael Burr Mar 31 '13 at 17:21
  • I've never seen an assembly construct like `mov hFile2, fopen(addr StringBuffer)` - does MASM support somehow calling a function to get the source data for the move instruction? I would have thought that you'd need to explicitly call the `fopen()` function (maybe using the `invoke` directive) followed by a `mov hfile2, eax` instruction. I must say, I'm not a big fan of the 'extended' MASM directives for flow control and function calling. – Michael Burr Mar 31 '13 at 17:50
  • yeah i like to use the lower assembly that is why the ; lines are in place of the high level fopen. the only reason I tried to use fopen is to see if it worked any better with the crashing problem – patchariadog Mar 31 '13 at 18:13
  • I took the high level fopen stuff out so it does not confuse people – patchariadog Mar 31 '13 at 18:16
  • @patchariadog: actually, I'm interested in any docs you can point me to about those high level constructs. I may not be a fan, but I'd still like to know a bit more about them. Also, don't go by my opinion on whether or not to use them. – Michael Burr Mar 31 '13 at 18:27
  • this code invoke CreateFile, ADDR filestoscan, GENERIC_READ, 0, 0,OPEN_EXISTING, 0, 0 mov hFile, eax invoke GetFileSize,hFile,NULL mov Byteforstreamreader,eax streamreader2: .if Byteforstreamreader != 0 invoke ReadFile, hFile, ADDR Buffer2,1, ADDR BytesWritten, 0 is the same as mov hFile2, fopen(addr StringBuffer) mov flen, fsize(hFile2) mov BytesWritten3, fread(hFile2,addr FileBuffer,flen) fclose hFile2 the only difference is one uses flen to store the length and one uses Bytes to store the length i got it from hlhelp in the help folder of masm. do you know why the code is crashing – patchariadog Mar 31 '13 at 18:49
  • I see - the `fopen()`, `fread()` constructs are macros from the "MASM32" project, which I am unfamiliar with: http://www.masm32.com – Michael Burr Mar 31 '13 at 19:36

1 Answers1

0

Here's a somewhat annotated version of your streamreader2 loop:

streamreader2:
.if Byteforstreamreader != 0
    invoke ReadFile, hFile, ADDR Buffer2,1, ADDR BytesWritten, 0

    ; check for end-of-line (CR)
    .if Buffer2 == 13

        ; open the file named in Buffer2 and 
        ; do a bunch of stuff to it to get the MD5
        ;
        ; ...

        mov FileBuffer,0
        mov StringBuffer,0
        dec Byteforstreamreader
        jmp streamreader2
    .endif

    ; I don't know what the purpose of these two lines are
    mov eax,offset Buffer2
    mov Buffer3,eax

    ; append the character just read from hFile to StringBuffer
    invoke lstrcat,ADDR StringBuffer,addr Buffer2

    dec Byteforstreamreader
    jmp streamreader2
.endif

So no characters read from hFile are handled specially except for 13 (CR). However, I think there's a good chance that the line endings in that file are CRLF so when the next file is opened the name will have a LF control character at the start of it. So the CreateFile or fopen call will fail to open the file.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • thank you so much Michael Burr that works! i added another invoke ReadFile, hFile, ADDR Buffer2,1, ADDR BytesWritten, 0 under the .if Buffer2 == 13 part of my code to get it to work. one more quick question is if i have a file that is 20mb big how do I read that into FileBuffer because you cant reserve 20971520 bytes(20mb) of it, and if i split it into chunks how would I join them into one chunk to md5 it. maybe if Michael Burr or anyone has a good way to do this they could post it. thanks! – patchariadog Mar 31 '13 at 19:55
  • @patchariadog: I don't know the details of the MD5 library you're using, but usually there's a function that calculates intermediate MD5 values that you can pass buffer after buffer to. It looks like the `MD5_Read()` function in your library might be like that; if so, just pass the contents (and length) of each buffer you read from the file to `MD5_Read()`, then when `MD5_Digest()` is called it will finalize the MD5. Keep in mind I'm just guessing about the behavior of your MD5 library. But given that you have `MD5_Init()`/`MD5_Digest()` 'bookends', I think it's a reasonable guess. – Michael Burr Mar 31 '13 at 20:09