C Question

How to fix a Hook in a C program (stack's restoration)

It's a kind of training task, because nowadays these methods (I guess) don't work anymore.

Win XP and MinGW compiler are used. No special compiler options are involved (just gcc with stating one source file).

First of all, saving an address to exit from the program and jumping to the some Hook function:

// Our system uses 4 bytes for addresses.
typedef unsigned long int DWORD;

// To save an address of the exit from the program.
DWORD addr_ret;

// An entry point.
int main()
{
// To make a direct access to next instructions.
DWORD m[1];

// Saving an address of the exit from the program.
addr_ret = (DWORD) m[4];

// Replacing the exit from the program with a jump to some Hook function.
m[4] = (DWORD) Hook;

// Status code of the program's execution.
return 0;
}


The goal of this code is to get an access to the system's privileges level, because when we return (should return) to the system, we just redirecting our program to some of our methods. The code of this method:

// Label's declaration to make a jump.
jmp_buf label;

void Hook()
{
printf ("Test\n");

// Trying to restore the stack using direct launch (without stack's preparation) of the function (we'll wee it later).
longjmp(label, 1);

// Just to make sure that we won't return here after jump's (from above) finish, because we are not getting stuck in the infinite loop.
while(1) {}
}


And finally I'll state a function which (in my opinion) should fix the stack pointer - ESP register:

void FixStack()
{
// A label to make a jump to here.
setjmp(label);

// A replacement of the exit from this function with an exit from the whole program.
DWORD m[1];
m[2] = addr_ret;
}


Of course we should use these includes for the stated program:

#include <stdio.h>
#include <setjmp.h>


The whole logic of the program works correctly in my system, but I can not restore my stack (ESP), so the program returns an incorrect return code.

Before the solution described above, I didn't use jumps and FixStack function. I mean that these lines were in the Hook function instead of jump and while cycle:

DWORD m[1];
m[2] = addr_ret;


But with this variant I was getting an incorrect value in ESP register before an exit from the program (it was on 8 bytes bigger then this register's value before an enter in this program). So I decided to add somehow these 8 bytes (avoiding any ASM code inside of the C program). It's the purpose of the jump into the FixStack function with an appropriate exit from it (to remove some values from stack). But, as I stated, it doesn't return a correct status of the program's execution using this command:

echo %ErrorLevel%


So my question is very wide: beginning from asking of some recommendations in a usage of debugging utilities (I was using only OllyDbg) and ending in possible solutions for the described Hook's implementation.

Answer

Ok, I could make my program work, as it was intended, finally. Now we can launch compiled (I use MinGW in Win XP) program without any errors and with correct return code.

Maybe will be helpful for someone:

#include <stdio.h>
#include <setjmp.h>

typedef unsigned long int DWORD;

DWORD addr_ret;


int FixStack()
{
    DWORD m[1];
    m[2] = addr_ret;

    // This line is very necessary for correct running!
    return 0;
}


void Hook()
{
    printf("Test\n");

    FixStack();
}


int main()
{
    DWORD m[1];

    addr_ret = (DWORD) m[4];

    m[4] = (DWORD) Hook;
}
Comments