Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>What is possible but perhaps not entirely useful in your case would be to extract the current and previous stack frame pointers (i e bp register) and, using the standard stack frame structure, determine how many 4 byte (for a 32-bit application) parameter units have been passed in the call to the current routine. You won't be able to determine which units are char, short or long and if two of them together might be a long long/__int64 parameter.</p> <hr> <p>I've thought about this some more. Consider a typical function call "func (a,b)". The calling code unless you have parameters in registers (some x86-32 compiler options and intel recommended for x86-64) the code would turn out like this</p> <pre><code> ; long *esp,*ebp; push b ; *(--esp)=b; push a ; *(--esp)=a; call func ; *(--esp)=return_address_location; return_address_location: add esp,8 ; esp+=2; // free memory allocated for passing parameters </code></pre> <p>Then you come to processing in func</p> <pre><code>func: push ebp ; *(--esp)=(long) ebp; // save current ebp &lt;=&gt; current stack frame mov ebp,esp ; ebp=esp; // create new stack frame in ebp sub esp,16 ; esp-=4; // reserve space for local variables &lt;=&gt; sizeof(long)*4 (func code ...) </code></pre> <p>Now when you're in func and you need access to parameters you address them with ebp+2 and ebp+3 (*ebp contains previous ebp, ebp+1 the return address. When you need access to local variables you address them with ebp-4 to ebp-1 (may be over-simplified if they are not all longs and you have some packing option set).</p> <p>After a while func has done its thing and you need to return:</p> <pre><code>mov esp,ebp ; esp=ebp; // unreserve space for local variables pop ebp ; ebp=*(esp++); // restore previous ebp &lt;=&gt; previous stack frame ret ; eip=*(esp++); // pop return address into instruction pointer </code></pre> <p>From the first snippet you will also see how the first stack allocation (for passing parameters) is freed right after returning.</p> <p>A few tips:</p> <ul> <li>Do the math for yourself while single-stepping (instruction by instruction) through a call/return sequence and you'll get ideas on how to solve the original problem. This is basic stack handling which looks more or less the same on all architectures and implementations so it's a good thing to know</li> <li>Imagine an incorrectly calculated memset/memcpy to a local buffer and how it will destroy the data on the stack including return addresses, previous stack frames etc</li> <li>Take note of the values in ds and ss (data and stack selectors) and if they contain the exact same value a solution of yours could use memcpy to copy the parameters from the stack to data memory for examination or whatever if that helps</li> <li>If ds=ss you can use &amp; to find the address of the passed parameters from inside func (&amp;param1, &amp;param2)</li> <li>If ds and ss or not equal (as they might be in a multi-threaded application) you will need a memcpy variant that uses "far addressing" which will handle the situation where ds and ss differ</li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload