[vox-tech] late night musings: stripping

Jeff Newmiller vox-tech@lists.lugod.org
Thu, 26 Feb 2004 13:51:13 -0800 (PST)


On Thu, 26 Feb 2004, Mitch Patenaude wrote:

> On Thursday, Feb 26, 2004, at 09:22 US/Pacific, Peter Jay Salzman wrote:

[...]

> > what would be useful would be something like GDB which can follow a
> > process and collect information about:
> >
> > 1. control flow (what functions call what).
> > 2. get the parameters and return values of the function calls.
> >
> >
> > the only way i know how to get #1 is to sit there, using stepi (and
> > possibly nexti over uninteresting libc functions) with a pencil and
> > paper in hand.

Much easier to do this with code that is not abused like license
management code would be.

> > as for #2, seems like the only way to do that would be to disassemble
> > the code.  i don't know a lick of x86 assembly, but i did notice that
> > %eax appears to be the register for returning integers.

Again, not knowing x86 assembly would be a severe handicap with license
management code... they don't want to make it easy to do what you are
proposing.

> gdb has a pretty extensive scripting language, and I imaging that you 
> could do that by looking at when the next instruction is a "CALL", 
> though you also need to trap "INT 0x80" because that's the system call 
> interrupt.
> 
> > i rewrote myfunction to return an int of 1.
> 
> For those unfamiliar with the C call stack I'll add some comments
> 
> >    0x8048380 <myfunction>: push   %ebp
> Pushes the base pointer onto the stack, to save the stack frame of the 
> calling function
> 
> >    0x8048381 <myfunction+1>:       mov    %esp,%ebp
> Moves the current stack pointer into the base pointer to make a new 
> "frame"

These first two instructions are almost universal in C functions for
"receiving the ball" from the calling function.  All accesses to local
variables and function arguments are relative to the ebp register (or one
like it on other processors)... that is, the first auto integer variable
might be at this address minus 4, while the first calling argument might
be at this address plus 8 or 12 (depending on whether the function return
value was being returned on the stack or not).  The return address is at
ebp+4, and of course the old stack pointer is now at ebp.  Since the
calling function put the parameters on the stack, the called function
doesn't really know for sure how many there are, except as whatever the
function declaration proposed, which could include "..." and be
open-ended.  Those arguments would all be at positive offsets from ebp.

> >    0x8048383 <myfunction+3>:       sub    $0x8,%esp
> Make room on the stack for 8 bytes of automatic variables and arguments.

If this function had automatic variables, this would be the kind of
command used to "allocate" them at this point.

However, in this case, myfunction has no auto variables... this
instruction seems to be allocating room for the arguments to printf on the
stack.  Since only one (four byte) argument is being passed, I am guessing
it is allocating 8 bytes has something to do with the fact that the printf
function signature has an indeterminate number of arguments??

This mucking with the stack pointer prevents any interrupts that come
along from pushing values on the stack at unexpected times and munging
this memory.  Remember, anything below the stackpointer is fair game to be
destroyed by interrupt service routines at any time.

> >    0x8048386 <myfunction+6>:       movl   $0x80484b4,(%esp,1)
> "Push" the address of the format string "Hello World" onto the stack 
> (notice that it doesn't use push.. and so leaves the stack pointer 
> untouched.. I don't know why that is.)

Optimization, I would guess.

> >    0x804838d <myfunction+13>:      call   0x8048288 <printf>
> call printf

By the time the printf function starts, the stack looks like:

        | ... 
        +-----------+
esp+22  | ...       |
        +-----------+
esp+20  | esp+yy    | frame pointer used by startup code
        +-----------+
esp+16  | main rtn  | program counter to return to in main
        +-----------+
esp+12  | esp+20    | frame pointer used by main  <-ebp
        +-----------+
esp+08  | ???       | extra?
        +-----------+
esp+04  | 0x80484b4 | pointer to "Hello World"
        +-----------+
esp+00  | 0x8048392 | program counter to return to when printf is done
        +-----------+

> >    0x8048392 <myfunction+18>:      mov    $0x1,%eax
> Move the return value into eax
> 
> >    0x8048397 <myfunction+23>:      leave
> I don't remember leave.. maybe it's an post 386 extension to 
> automatically clean up the stack

yes, equivalent to
   movl  %ebp, %esp  # ignore any stack allocations below frame
   popl  %ebp        # restore old frame

[,,,]

---------------------------------------------------------------------------
Jeff Newmiller                        The     .....       .....  Go Live...
DCN:<jdnewmil@dcn.davis.ca.us>        Basics: ##.#.       ##.#.  Live Go...
                                      Live:   OO#.. Dead: OO#..  Playing
Research Engineer (Solar/Batteries            O.O#.       #.O#.  with
/Software/Embedded Controllers)               .OO#.       .OO#.  rocks...2k
---------------------------------------------------------------------------