News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

reading bytes (as chars) from memory

Started by zork, April 15, 2005, 03:39:54 PM

Previous topic - Next topic

zork

I'm one of those "used to program in assembly way back when" kinda guys. I'm making an attempt at getting
back into it and have run into some snags.
I am re-writting programs I've written in the past using masm32. One that I am working on now is a simple file-encryptor (xor)
I know that there are examples out there I could download, but I'm trying to write it myself to learn it better.
So far, I parse the command line, open the file, get the file size, alloc memory and then read the file into memory.
but now I am having problems figuring out how to read characters from the memory location.
Here's what I have so far ( snippet)
..
invoke   CreateFile, [argv+04h], GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0
   mov   [hFile], eax
   invoke   GetFileSize, eax, 0
   mov   [dwInFileSize], eax
   invoke   GlobalAlloc, GMEM_MOVEABLE, [dwInFileSize]
   mov   [hMemoryIn], eax
   invoke   GlobalLock, eax
   mov   [dwFileIn], eax
   invoke   ReadFile, [hFile], eax, [dwInFileSize], esp, 0
   invoke   CloseHandle, [hFile]

Ok, this part works fine. I can then invoke something like Messagebox and pass it dwFileIn
and it will give me a dialog with the contents of the file (yes, the file is small and I'm just doing that
for testing). OK, what I would like to do now, is start at the point in memory where dwFileIn
resides and begin reading characters. I've tried everything I can think of all to no avail.
In this little example, it would be something like (pseudocode)
read char from memlocation + ptr
xor char with key
either save result to buffer, or back to same location in ram
increment ptr.
loop
write results out to file
but like I said, everything I've tried has failed. I tried loading my exe in ollydebug and stepping
through, I can see it grab chars here & there, but it's not like it's reading the chars that are the
actual letters in the file.

thanks!

hitchhikr

Never use esp as argument.
Paste the code you used to read that buffer.

zork

uh.uhm.. duh.. I .. uhm...
the line
invoke   ReadFile, [hFile], eax, [dwFileSize], esp, 0
I got from a sample code on the web (dont remember exactly where)
Now that I go back and re-read the source, I dont set esp anywhere.
excepting the command line parsing, and the data and includes, what I posted
above is the code to do all the work in the prog.
I guess that's the problem with snagging code from elsewhere.
I'll have to re-read the spec for readfile to see what I'm supposed to pass there.
but that said, the code does read the file contents and put it in ram without any problems (that I can
see)
My main issue after that is reading a character at a time from memory.
thanks!

all of the books I have on assembly are old ( <= 1990) and after going thru them
I still haven't found much.

hitchhikr

#3
Quote
I'll have to re-read the spec for readfile to see what I'm supposed to pass there.

You're supposed to pass the address of a variable that will receive the real amount of bytes read.

Something like:


invoke   ReadFile, [hFile], eax, [dwInFileSize], addr my_variable, 0


It should be a problem here but since arguments are passed from right to left, the last 0 is translated as a "push 0", that instruction modifies esp (esp-=4) so beware if you plan to use the stack pointer inside an argument list, it's value might be different from what you think it may be.

If you have troubles reading the memory content itself post the code you're using to actually read that memory content.

zork

I don't know where I got esp on that line.. oh well, fixed now, I even had a variable defined
for bytesread. just call me a dumbass for now, I guess... or we'll call it a typo.
for reading chars, I've tried so many different bits of code and they all failed, so I didn't keep
any of them, but
I was starting along the lines of
               
   mov   ecx, [dwInFileSize]
loop1:
               mov       al, [dwFileIn]
               lodsb   buffer[counter],al
              inc  counter
             jnz   loop1

now that I type that out, I have another idea on what to try.. we'll see what happens

zork

OK. I tried something else today. It still does not run ( I get a msg from winders that says  program.exe has encountered
a problem and must be closed).

from the READFILE line down, here's what I have..

invoke   ReadFile, [hFile], eax, [dwFileSize], ADDR bytesRead, 0
      mov   edx,eax
      mov   ecx,bytesRead
      mov   ah, 3
   loop1:   mov   al, [edx+ecx]
      mov   bytearray1[counter], al
      dec   ecx
                                inc            counter
      jnz   loop1
      
I haven't run it thru a debugger yet to figure out where it's failing..  see anything glaring in there?

I just ran it thru the debugger and see that [edx+ecx] is causing an access violation..  ok, ECX is the number of bytes read, so that should be pointing
out at the "end" of the memory area I've got (if I understand this correctly, which I probably don't :-(
do I need to drop back a word or something?

roticv

I think you should be using


      mov   ecx,dwFileSize

hitchhikr

ReadFile doesn't preserve eax (only ebx, esi, edi, ebp & esp).


push eax
invoke ReadFile, [hFile], eax, [dwFileSize], ADDR bytesRead, 0
pop edx
mov ecx,bytesRead
mov edi,bytearray1
loop1:
mov al, [edx+ecx-1]
stosb
dec ecx
jnz loop1


The array counting begins at 0 so edx+ecx is out of range.
Notice that this will copy the buffer byte/byte in reverse order.
Be sure that bytearray1 is large enough.

tenkey

Quote from: zork on April 15, 2005, 06:32:41 PM
mov     bytearray1[counter], al


This doesn't work. I'm assuming counter is stored in memory. If the assembler didn't flag an error, then I assume one or both of the "variables" are located on the stack (LOCAL). That leads to the actual address being one of these three possibilities:

1) bytearray1[ebp - counteroffset]
2) counter[ebp - bytearray1offset]
3) [ebp + ebp - bytearray1offset - counteroffset]

That's pretty much exception material.
A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8

Dark Schneider

How about using "File Mapping" instead? But I guess better leave it for now.
This code MAY do the job for you, it will xor ALL of the buffer in place.


     mov ecx, dwFileSize
     mov edx, dwFileIn
@@:
     xor byte ptr [edx], KEY  ; KEY = any constant BYTE value you want as a key
     dec ecx
     jnz @B


now the buffer "dwFileIn" is XORed with KEY, you can save it to file....etc.

zork

thanks. I figured out what I was doing wrong on Friday, but since the forum was having issues, obviously couldn't post.
I found out that the biggest problem I had was how I was getting a pointer to memory. Once I got that figured out, the rest
fell into place quickly.
Here's what I have (if there are obvious no-nos or places where you go "wtf is he doing" please let me know)
comments appreciated.. I am currently just putting 32h in AH, but will change it today to use the command line.

invoke    CreateFile, [argv+04h], GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0
mov      [hFile], eax
invoke    GetFileSize, eax, 0
mov      [dwFileSize], eax
invoke     GlobalAlloc, GMEM_MOVEABLE, [dwFileSize]
mov        [hMemoryIn], eax
invoke     GlobalLock, eax
mov        [dwFileIn], eax
invoke      ReadFile, [hFile], eax, [dwFileSize], ADDR bytesRead, 0
; output
invoke CreateFile, [argv+08h], GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0
mov [hFile],eax

mov edx,[dwFileIn]
mov ecx,30
xor eax,eax
xor ebx,ebx
mov ah, 32h
doxor: mov al, [edx+ebx]
xor al, ah
mov [edx+ebx], al
inc  ebx
dec ecx
cmp ecx,0
jnz doxor


    invoke SetFilePointer, [hFile], 0, 0, FILE_BEGIN
    invoke WriteFile, [hFile], [dwFileIn], [dwFileSize], OFFSET bytesRead, 0

;close the handle to the output file
invoke CloseHandle, [hFile]


and Dark:  if you are using 'xor byte ptr [edx] and then dec ecx, does xor byte ptr [edx] then automatically
point to a new section in memory based on ecx? I had something similar to this and found that it never moved.
always pointed at the same address in memory.
thanks!

thomasantony

Hi,
    Read the tutorial from Iczleion on memory mapped files. First use CreateFile, Then CreateFileMapping and MapViewOfFile. You get a pointer to memory you can directly use.

Thomas :U
There are 10 types of people in the world. Those who understand binary and those who don't.


Programmer's Directory. Submit for free