I am using /Gh and /GH compiler option of visual studio to profile a bunch of code. Two methods used are _penter and _pexit which are called when a function is entered or exited in the code being profiled. Since I need specific functions being profiled/debugged, I use an already defined array FuncTable which contains the addresses of the functions I need to instrument with their names as string. So when a function is entered, the pStack[0], which basically contains the register contents, contains the address to current line of the code being executed. Similarly when a function is exited, pStack[0] contains the address of last line of the code.
THE ISSUE: When a function is entered (_penter is called), I get the address of first line of the function in pStack[0] and hence I can get the function's address by subtracting a constant(-5) and save that to my list to be retrieved later in the _pexit function. But since in _pexit I am getting address to the last line of the function, I need to find the size of the function in order to subtract that size from the address in pStack[0] to reach the starting address of the function and then compare that address to the ones saved in my list. Pasted below is the code.
void _stdcall EnterFunc0(unsigned * pStack)
{
void * pCaller;
pCaller = (void *)(pStack[0] - 5); // pStack[0] is first line, -5 for function address
Signature * funct = FuncTable;
while (funct->function)
{
const BYTE * func = (const BYTE *)funct->function;
if ((func == (const BYTE *)pCaller) || ((*func == 0xE9) && ((func + *(DWORD *)(func + 1) + 5) == (const BYTE *)pCaller)))
{
Stack_Push(funct->name, funct->returnType, true, pCaller);
}
funct++;
}
}
extern "C" __declspec(naked) void __cdecl _penter()
{
_asm
{
pushad // save all general purpose registers
mov eax, esp // current stack pointer
add eax, 32 // stack pointer before pushad
push eax // push pointer to return address as parameter to EnterFunc0
call EnterFunc0
popad // restore general purpose registers
ret // start executing original function
}
}
void _stdcall ExitFunc0(unsigned * pStack)
{
if (startRecording)
{
StackEntry * start = top;
while (start != NULL)
{
//**HERE I NEED TO COMPARE THE ADDRESS OF THE FUNCTION WITH THE ONE ALREADY IN MY STACK**
if ((void *)(pStack[0] - sizeOfTheFunction) == start->Address)
{
OutputDebugString("Function Found\n");
}
start = start->next;
}
}
}
extern "C" __declspec(naked) void __cdecl _pexit()
{
_asm
{
pushad // save all general purpose registers
mov eax, esp // current stack pointer
add eax, 32 // stack pointer before pushad
push eax // push pointer to return address as parameter to EnterFunc0
call ExitFunc0
popad // restore general purpose registers
ret // start executing original function
}
}