News:

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

Using th str$() macro

Started by allynm, July 25, 2009, 06:54:53 PM

Previous topic - Next topic

allynm

hi Dedndave -

I think I figured out that GetStdHandle puts the handle in eax....

Fine.  But, I can't get your proc (the original version) to produce any output.  Things I don't understand in your code:  (old and new version):

1.  why do you opush eax two lines before WriteFile
2.  why do you put esp into ecx?  The way WriteFile is described in my documentation (admittedly not good) is that ecx should have the address of a variable that contains the number
of bytes written....

Please forgive my obtuseness.

Mark Allyn

allynm

Dedndave and Michael W -

Further on this business...I had thought too that eax should have the handle, but when I looked at the address initially it was in low memory....I thought it should be in high(er) memory.  The value shown after the call is 00000007.  I reckon that is the handle.  Anyway, ollydbg indicates that it is indeed a fhandle.

In fact everything works hunky-dory in Dedndave's procedure until I hit the WriteFile call.  The parameters seem to be OK -- at any rate olly likes them.  Then the wheels come off when I call the WriteFile function.

Just to add a llittle clarification, when the WriteFile call bombs ollyreports an error message as follows:  ERROR_INVALID_ACCESS (0000000C).

Thanks again,
Mark A.

dedndave

ok Mark - let me play with it a little bit
the idea of pushing eax (could be any dword) was just to make an empty spot on the stack to receive the NumberOfBytesWritten
(sub esp,4 would accomplish the same thing)
then, i moved esp (which points to that spot on the stack) into ecx for the call
when the function call is done, we pop that into eax for the return value
i must have made a mistake someplace - lol

dedndave

i assembled it and it ran the first time, Mark
see the attached file
it prints out "AA" because it is called twice

[attachment deleted by admin]

allynm

Hi Dedndave -

Your explanation on push eax; mov ecx, esp was crystal clear.  I would have done a beginner's thing and it wouldn't have been as efficient.

I looked at the code you sent and the thing that jumped out at me was the addition of the pop eax instruction at the end of the proc.  This wasn't there before.  I haven't tried the code yet, but I bet that is the reason for the failure.

Now here's another question (no good deed goes unpunished!) :  if you popped eax to clean up the stack why do you add 4 bytes more in the ret instruction?  Maybe I don't understand ret...

Thanks.  I have to muck a couple of horse stalls and then I'll give your code a try.

Mark A.


dedndave

yes - i changed that but you'll also notice i used LEAVE on the first version

push ebp
mov ebp,esp
.
.
.
leave
ret        nn

the push ebp/mov ebp,esp is the normal way to set up a stack frame
leave is the same as mov esp,ebp/pop ebp
if you use leave, you do not have to balance the stack because esp gets set to the value saved in ebp
in the second version, i decided to get rid of the stack frame because we only need to reference it one time
that means that push ebp/mov ebp,esp/leave are unneccessary overhead

when you use ret nn, it pops the variables that were passed to the procedure off the stack after returning
those variables are on the stack, above the return address
stack frame variables are below the return address

allynm

Hi dedndave -

I read over your most recent commentary and I understand what you are saying. 

I downloaded and assembled your proc.  It works perfectly on my machine.  I will clone it to do the ReadFile complement. 

This has been a very satisfying learning experience for me, for what it's worth. 

Mysteries remain, however.  One of them is this:  If you'll forgive me for mentioning some C code, when I use the __p__iob call to get a handle (stdin or stdout) to use the _fgets function the call returns a very different result.  Not same as the call to GetStdHandle.  _Fgets and _Fputs both work fine, and _Fputs will do what your code does.  The puzzling thing to a novice like me is why __p__iob returns a different result than GetStdHandle does.  How in heck many Stdins and Stdouts are there.  (lol?)

Many, many thanks for your generosity.

Mark Allyn

dedndave

well - i am not familiar with that C function
however, windows sometimes assigns an "alias" to a handle
it is kind of like a translator ("this" actually means "that")
i am not really sure why windows does this, but it likely has something to do with some internal flaw in their mechanism
they overcome the flaw by assigning a different value and map it to the original
it provides a way for different processes and threads to access the same object with different handles

MichaelW

The __p__iob call returns the address of an array of FILE structures that the CRT uses to manage Stream I/O.

Some relevant definitions from stdio.h:

#ifndef _FILE_DEFINED
struct _iobuf {
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
        };
typedef struct _iobuf FILE;
#define _FILE_DEFINED
#endif

/* Declare _iob[] array */

#ifndef _STDIO_DEFINED
_CRTIMP extern FILE _iob[];
#endif  /* _STDIO_DEFINED */

#define stdin  (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])


Vortex covered the topic here:

http://www.masm32.com/board/index.php?topic=7523.0

eschew obfuscation

dedndave

that looks suspiciously like C, Michael - lol