1

So I'm exploring mhook 2.3 and have build a sample executable specifically for this purpose. I have an injector that injects a dll containing mhook into the target process.

This all works correctly and I can verify that my code is being called by the target process by checking my log file.

However, when I go to hook my target function mhook simply returns and says that it failed to hook the function. I've used OllyDBG and IDA to verify that the address for the target function that I'm passing in to mhook is correct and the function signature for the trampoline is exactly the same as the target function but it still fails.

I'm at my wits end. Can someone please tell me what I'm doing wrong here?

Here is the target program that I've built. It's a simple Windows console application that prints out a random message every second.

// reverse me.cpp : This is the program that I will be attempting to hook into.
//

#include "stdafx.h"

#include <stdlib.h>
#include <Windows.h>
#include <Psapi.h>
#include <string>

class blargClass1
{
public:
    blargClass1();
    void WINAPI blargFunction1(void);
};

__declspec(noinline) blargClass1::blargClass1()
{
    printf("blargClass1::blargClass1\n");
};

__declspec(noinline) void  WINAPI blargClass1::blargFunction1( void )
{
    switch( rand() % 10 + 1 )
    {
    case 1:
        printf("blargFunction1 - case 1\n");
        break;
    case 2:
        printf("blargFunction1 - case 2\n");
        break;
    case 3:
        printf("blargFunction1 - case 3\n");
        break;
    case 4:
        printf("blargFunction1 - case 4\n");
        break;
    case 5:
        printf("blargFunction1 - case 5\n");
        break;
    default:
        printf("blargFunction1 - default\n");
    }
};

#pragma comment( lib, "psapi.lib")

DWORD GetCurrentModuleBase( LPWSTR targetModule )
{ 
    HMODULE hMods[1024];
    HANDLE hProcess;
    DWORD cbNeeded;
    DWORD baseAddress = -1;
    unsigned int i;

    // Get the current process id.
    DWORD processID = GetCurrentProcessId();
    printf( "GetCurrentProcessId = %u\n", processID );

    // Get a handle to the process.
    hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID );

    // Sanity checking on process handle.
    if( hProcess == NULL )
    {
        printf( "hProcess is NULL.\n" );
        return 1;
    }

   // Get a list of all the modules in this process.
    if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
    {
        // Iterate through each module
        for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
        {
            WCHAR szModName[MAX_PATH];

            // Get the full path to the module's file.
            if ( GetModuleFileNameEx( hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR)))
            {
                // Print the module name and handle value.
                //wprintf( L"\t%s (0x%08X)\n", szModName, hMods[i] );

                // Is this the module that we're looking for?
                std::wstring moduleName = szModName;
                if( moduleName.find( targetModule ) != std::wstring::npos )
                {
                    baseAddress = (DWORD)hMods[i];
                }
            }

        }
    }

    // Release the handle to the process.
    CloseHandle( hProcess );

    return baseAddress;
}


int _tmain(int argc, _TCHAR* argv[])
{
    blargClass1 blarg_class_1;

    printf( "GetCurrentModuleBase = 0x%08X\n", GetCurrentModuleBase( L"reverse me.exe" ) );

    while( true )
    {

        // Call the target function
        blarg_class_1.blargFunction1();

        Sleep(1000);
    }

    return 0;
};

And here is the DLL containing the mhook code that I inject into that process. All I'm trying to do is hook blargFunction1 so that it prints out an additional line when it's called.

//SimpleDLL.cpp
#include "Stdafx.h"
#include "SimpleDLL.h"
#include "mhook-lib/mhook.h"
#include <Psapi.h>
#include <string>
#include <wchar.h>

// Open the log file.
FILE *file;

//=========================================================================
// Define the target functions so we can dynamically bind to the function
//
typedef void (WINAPI *_blargFunction1)( void );


//=========================================================================
// Get the current (original) address to the functions to be hooked
//
_blargFunction1 TrueBlargFunction1 = (_blargFunction1)(0x1770);

//=========================================================================
// This is the function that will replace the target function once the hook 
// is in place
//
void WINAPI blargFunction1(void)
{
    fprintf( file, "***** Call to blargFunction1 from mhook sample.\n");
    return TrueBlargFunction1();
}

#pragma comment(lib, "psapi.lib")

DWORD GetCurrentModuleBase( LPWSTR targetModule )
{ 
    HMODULE hMods[1024];
    HANDLE hProcess;
    DWORD cbNeeded;
    DWORD baseAddress = -1;
    unsigned int i;

    // Get the current process id.
    DWORD processID = GetCurrentProcessId();
    fprintf( file, "Process ID: %u\n", processID );

    // Get a handle to the process.
    hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID );

    // Sanity checking on process handle.
    if( hProcess == NULL )
    {
        fprintf( file, "hProcess is NULL.\n" );
        return 1;
    }

   // Get a list of all the modules in this process.
    if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
    {
        // Iterate through each module
        for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
        {
            WCHAR szModName[MAX_PATH];

            // Get the full path to the module's file.
            if ( GetModuleFileNameEx( hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR)))
            {
                // Print the module name and handle value.
                //fwprintf( file, L"\t%s (0x%08X)\n", szModName, hMods[i] );

                // Is this the module that we're looking for?
                std::wstring moduleName = szModName;
                if( moduleName.find( targetModule ) != std::wstring::npos )
                {
                    //fprintf( file, "Found it.\n");

                    baseAddress = (DWORD)hMods[i];
                }
            }

        }
    }

    // Release the handle to the process.
    CloseHandle( hProcess );

    return baseAddress;
}


extern "C" int WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) {

    time_t now = time(NULL);
    struct tm nowTM;
    char datetime[32];
    DWORD baseAddress = 0;

    localtime_s( &nowTM, &now );

    // Generate a date/time string.
    strftime(datetime, 32, "%Y%m%d %H:%M:%S", &nowTM);

    fopen_s( &file, "simpledll.log", "a+");

    // Perform different actions based on why this function is being called.
    switch( fdwReason )
    {
        case DLL_PROCESS_ATTACH:

            fprintf(file, "----------------------------------\n");
            fprintf(file, "%s SimpleDll - DLL_PROCESS_ATTACH.\n",  datetime);

            // Determine the base address of this process.
            baseAddress = GetCurrentModuleBase( L"reverse me.exe" );
            strftime(datetime, 32, "%Y%m%d %H:%M:%S", &nowTM);
            fprintf( file, "%s SimpleDll - GetCurrentModuleBase = 0x%08X\n", datetime, baseAddress );

            // Determine the memory address of the target function.
            TrueBlargFunction1 = (_blargFunction1)( (DWORD)TrueBlargFunction1 + baseAddress);
            strftime( datetime, 32, "%Y%m%d %H:%M:%S", &nowTM );
            fprintf( file, "%s SimpleDll - TrueBlargFunction1 = 0x%08X.\n",  datetime, TrueBlargFunction1 );

            //strftime(datetime, 32, "%Y%m%d %H:%M:%S", &nowTM);
            //fprintf(file, "%s SimpleDll - Before Mhook_SetHook.\n",  datetime);

            // Set the hook
            if( Mhook_SetHook( (PVOID*)&TrueBlargFunction1, blargFunction1) ) 
            {
                strftime(datetime, 32, "%Y%m%d %H:%M:%S", &nowTM);
                fprintf(file, "%s SimpleDll - Successfully set hook.\n",  datetime);

                // Remove the hook
                //Mhook_Unhook((PVOID*)&TrueBlargFunction1);

                //strftime(datetime, 32, "%Y%m%d %H:%M:%S", &nowTM);
                //fprintf(file, "%s SimpleDll - Unset hook.\n",  datetime);

            }
            else
            {
                strftime(datetime, 32, "%Y%m%d %H:%M:%S", &nowTM);
                fprintf(file, "%s SimpleDll - Failed to set hook.\n",  datetime);
            }

            strftime(datetime, 32, "%Y%m%d %H:%M:%S", &nowTM);
            fprintf(file, "%s SimpleDll - After Mhook_SetHook.\n",  datetime);

            break;

        case DLL_PROCESS_DETACH:
            strftime(datetime, 32, "%Y%m%d %H:%M:%S", &nowTM);
            fprintf(file, "%s SimpleDll - DLL_PROCESS_DETACH.\n",  datetime);
            break;
        case DLL_THREAD_ATTACH:
            strftime(datetime, 32, "%Y%m%d %H:%M:%S", &nowTM);
            fprintf(file, "%s SimpleDll - DLL_THREAD_ATTACH.\n",  datetime);
            break;
        case DLL_THREAD_DETACH:
            strftime(datetime, 32, "%Y%m%d %H:%M:%S", &nowTM);
            fprintf(file, "%s SimpleDll - DLL_THREAD_DETACH.\n",  datetime);
            break;
    }

    fclose( file );

    return TRUE;
};

Addendum: I'm using a Windows 32 bit environment because ultimately I'll be trying this approach on an older legacy 32 bit application and the injector doesn't seem to work unless they're on the same platform.

  • 1
    Just curious, how come you make this weird assumption about the address of TrueBlargFunction1 and don't follow the example given on the project's website and use GetProcAddress? – 0xC0000022L Jan 27 '14 at 13:59
  • Well, all of my assumptions are probably weird but which one are you referring to? I have implemented the example from mhooks documentation and it works correctly so I know the platform is sound and my ide works. I'm sure I'm doing something else wrong but can't figure out what it is. Oh, if you mean the 0x1770 magic number. That's the offset that I found for the start of blargFunction1 in the executable. I verified it through decompiling it with both IDA and OllyDbg. I take that offset and add it to the base address of the module to determine the location in memory to insert my hook. – blargfoot Jan 27 '14 at 16:43
  • Uhm, nope ... it reads: _blargFunction1 TrueBlargFunction1 = (_blargFunction1)(0x1770); ... that address is likely not even in the address range of the module anyway. – 0xC0000022L Jan 27 '14 at 16:51
  • I agree. 0x1770 represents the offset from the base address of the module, not the address of the function in memory. I determine the base address of the module after the dll has been loaded into the target process space and add the offset to that. // Determine the memory address of the target function. TrueBlargFunction1 = (_blargFunction1)( (DWORD)TrueBlargFunction1 + baseAddress); In theory, it should give me the address of the target function in memory. Of course, something's wrong somewhere so I could be completely off base. – blargfoot Jan 27 '14 at 17:15
2

This is more a comment than an answer (but comments are to short and limited in formatting), so I'll make it community wiki:

EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define GetCurrentModuleBase() ((HMODULE)&__ImageBase)

Basically you can save the effort with your implementation completely and use the above as a replacement. Also, the era of 32bit-only-Windows is over. Using DWORD for a memory address is improper and definitely out of style by now.

  • Thank you for the useful function. That certainly helps! Unfortunately, my hands are tied with Win32. Ultimately, I'll be using this technique on a legacy Win32 application and am locked into that platform. Bearing that in mind, what would you suggest as an alternative to DWORD for my memory values? – blargfoot Jan 27 '14 at 16:50
  • @blargfoot: easy, HMODULE is the proper type in this particular case and DWORD_PTR a sensible one, as well. DWORD on the other hand isn't. – 0xC0000022L Jan 28 '14 at 19:03
  • legacy win32 or not, doesnt matter.. the __ImageBase is a linker directive, the linker does it for you, and adds the reloc information if you're making a dll, so you are not locked at all.. also, are you trying to inject into yourself? why not just loadlibrary the injectable, as for getting your own base .. GetModuleHandle(NULL) kinda works, if you're still not wanting to do the __ImageBase method.. and is the compiler actually compiling the function, or is it making it a vtable (you have defined it as a class) ?... – evlncrn8 Sep 19 '14 at 0:28

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.