Re: ref parameter

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



On Fri, 06 Jun 2008 10:09:32 -0700, parez <psawant@xxxxxxxxx> wrote:

[...]
When you did it the wrong way, you passed it the address of the byte
on the stack. Now, I'm going to *guess* that the stack looked
something like:

[value of TagType]
[value of SerialNo]
[address of param]

(because param is passed in by reference)

The DLL then merrily writes over SerialNo *and then part of 'address
of param'*. Not a problem so far, but...

Why would the dll overwrite the address of param? Just curious..

Let's make sure we understand what is meant by "param" first. :) Technically, "param" is the local argument to the method. The "address" of that is simply an offset relative to the current stack frame. But I don't think that's what's meant in the text quoted.

Rather, in that context, "param" refers to the original parameter, which is passed as an address stored in a location that is referenced as an offset relative to the current stack frame. Here, the phrase "address of param" refers not to the actual address of the local argument relative to the current stack frame, but rather to the value stored in that location, the address of the original parameter..

Confused yet? :)

What happens is that when the DLL is called, the OP incorrectly passed the address of a single byte of storage, rather than an array of bytes of storage. Furthermore, that single byte was stored on the stack as a local variable, rather than in the heap. So, when the called function went to write data to what it thought was an array of bytes, it was actually writing to that local variable.

But the address of the original parameter passed as "param" was stored in the stack just past that local variable. Since the local variable didn't use enough of the stack to accomodate all of the data that the called function tried to write to it, the address of "param" winds up getting overwritten as well.

Ironically, the code could have failed in much more spectacular ways. The OP is fortunate to have had such a clearly incorrect result, but one which was still testable. :)

Pete

(Bonus reading: of course, the "single byte" variable actually takes up more room on the stack than just the one byte. I haven't checked, but probably it's consuming a full 4 bytes, due to alignment requirements. But that's still not enough for the called function, which apparently was expecting 7 bytes [why 7? I don't know...that's a weird size for a buffer]. So three more bytes get written into the "address of param" storage...just one byte would have been enough to cause the later assignment to fail, and so it does).
.



Relevant Pages

  • Re: ref parameter
    ... of an array of bytes. ... I'm going to *guess* that the stack looked ... [value of SerialNo] ... (because param is passed in by reference) ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: ref parameter
    ... of an array of bytes. ... I'm going to *guess* that the stack looked ... [value of SerialNo] ... (because param is passed in by reference) ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: ref parameter
    ... I'm going to *guess* that the stack looked ... of param'*. ... of that is simply an offset relative to the current stack frame. ... But the address of the original parameter passed as "param" was stored in ...
    (microsoft.public.dotnet.languages.csharp)
  • Strange hang with Dns.GetHostEntry
    ... is tough to debug. ... The stack looks correct. ... The param is only ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: [Clax86list] Noob Question
    ... The trick is that the C calling conventions have changed. ... ; rcx; 4th param for C call ... Are they put on the stack? ...
    (comp.lang.asm.x86)