0

I have found 2 source code example to hook a function.

Example1:

#include "detours.h"
#include "sigscan.h"

// this is the function that the program
// will jump to when sum() is called in the original program (testprogram.exe)

DWORD AddressOfSum = 0;
// template for the original function
typedef int(*sum)(int x, int y); 

int HookSum(int x, int y)
{
    // manipulate the arguments
    x += 500;
    y += 500;

    // we manipulate the arguments here and then
    // redirect the program to the original function

    std::cout << "your program has been hacked! " << std::endl;
    sum originalSum = (sum)AddressOfSum;
    return originalSum(x, y);
}

BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
    // store the address of sum() in testprogram.exe here.

    if (dwReason == DLL_PROCESS_ATTACH)
    {
        // We will use signature scanning to find the function that we want to hook
        // we will find the function in IDA pro and create a signature from it:

        SigScan Scanner;

        // testprogram.exe is the name of the main module in our target process
        AddressOfSum = Scanner.FindPattern("testprogram.exe", "\x55\x8B\xEC\x8B\x45\x08\x03\x45\x0C", "xxxxxxxxx");

        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());

        // this will hook the function
        DetourAttach(&(LPVOID&)AddressOfSum, &HookSum);

        DetourTransactionCommit();
    }
    else if (dwReason == DLL_PROCESS_DETACH)
    {
        // unhook
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());

        // this will hook the function
        DetourDetach(&(LPVOID&)AddressOfSum, &HookSum);

        DetourTransactionCommit();
    }
    return TRUE;
}

Example2:

#include <windows.h>
#include <detours.h>
#include <iostream>
 
#define ADDRESS 0x40133C    //This is the address where our targeted function begins
double (__cdecl* originalFunction)(double); //Pointer to the function we are going to hook, must be declared same as original(returns double and takes double as argument)
 
 
 
/*Our modified function code that is going to be executed
before continuing to the code of original function*/
double hookedFunction(double a)  
{                                 
std::cout << "original function: argument = "<< a << std::endl; //we can access arguments passed to original function
a=50.1337;                                                        //Modify arguments
return originalFunction(a);                                        //before returning to normal execution of function
}
 
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
originalFunction = (double(__cdecl*)(double))DetourFunction((PBYTE)ADDRESS, (PBYTE)hookedFunction); //Magic
break;
}
return TRUE;
}

And I ask what is best easy and flexible approach to hook functions.

My consideration:

  1. Example 1: is tested and worked.
  2. Example 1: is a filename dependent "testprogram.exe". So if I change the exe file name I need to change the source code.
  3. Example 1: "\x55\x8B\xEC\x8B\x45\x08\x03\x45\x0C" this is the address point format and it is not easy to decode like example 2: "0x40133C" (more easy)
  4. Example 2: don't work because "detourFunction" is deprecated. Now there is "detourAttach" but I don't known how migrate to it in this case.
  5. Example 2: is more easy but old. I don't known if will work in the future (32 or 64 bit)...

Can you help me please to take a decision or suggest me a better/easier solution ?

1

The first one is much better in my opinion:

  • It doesn't use deprecated function, that is probably kept only in the Detours library for backward compatibility

  • It uses pattern scanning, this is much better then embedding raw address, because lets say you are going to inject the .dll to a game, even if it's old singleplayer game it may have a lot of revisions, so the raw address may point to another function, while the pattern will mostly likely find a match anyway (providing the revisions don't differ too much)

The argument with hardcoded "testprogram.exe" doesn't really matter, beacuse there are a lot of ways to get name of the executable, for example you may use the winapi function GetModuleFileName

Not sure if I understand correctly the question about migration, however if you wan't to use DetourAttach in the second example there is no problem with that, just call the DetourAttach like in first example, but with ADDRESS instead of AddressOfSum as parameter.

| improve this answer | |
  • Thank you, The address that the function to hook start is: ".text:00401670" I have not undestand how is converted it this to "\x55\x8B\xEC\x8B\x45\x08\x03\x45\x0C". I ask if exist a conversion tool. – user3449922 Jul 14 at 15:45
  • This is pattern. Look at the bytes at 401670 in your executable, the opcodes are translated into assembler instructions by your disassembler, eg /x55/x8B/xEC is translated to "push ebp, mov ebp, esp", so this is standard function prolog. – morsisko Jul 14 at 15:48
  • you have right, probably it is my fault but the numbers are not exact the some: file code: 55 8B EC 6A 0A 8B 45 08 8B 55 08 03 51 04 address: 55 8B EC 8B 45 08 03 45 it is normal ? – user3449922 Jul 14 at 16:06
  • Are you sure this is correct address? In the question you have posted 0x40133C, not 0x401670 – morsisko Jul 14 at 16:10
  • 0x40133C is the old project. 0x401670 is the address that IDA show me at the start of the function hook. In this case is "main". Now I update my question with other screenshots. – user3449922 Jul 14 at 16:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.