hooking exe function

Nov 28, 2012 at 6:29 AM

how can i hook exe functions?

Nov 28, 2012 at 4:59 PM

Use LocalHook.Create and pass the address of the function

Nov 29, 2012 at 12:42 AM

I get that I was just asking for a working snippet

Nov 29, 2012 at 9:18 AM

It's not any different than hooking exported functions. You just need to find the address, signature, and calling convention of the function you want to hook, declare a delegate, slap on a UnmanagedFunctionPointerAttribute, and pass the address of the function to LocalHook.Create

Here's a link to similar discussion on EasyHook forums: https://easyhook.codeplex.com/discussions/283317

Nov 29, 2012 at 10:34 AM

Still can't understand , a example could really help me out and in C# please

Nov 29, 2012 at 10:54 AM

I guess somebody here might be able to help if you post the disassembly of the function you want to hook :/

Nov 29, 2012 at 2:34 PM
Edited Nov 29, 2012 at 3:45 PM

I have a simple console application that I created using MSVC 11:

#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <thread>

int counter;

// http://stackoverflow.com/questions/4862222/locally-disable-function-inlining
template <class F> F NOINLINE( F f ) {
    return f;
}

int IncreaseAndGet() {
    counter++;
    return counter;
}

int _tmain(int argc, _TCHAR* argv[]) {
    counter = 0;
    std::chrono::milliseconds duration(1000);
    while(true) {
        std::cout << "hai : " << NOINLINE(IncreaseAndGet)() << std::endl;
        std::this_thread::sleep_for(duration);
    }

    return 0;
}

I built it in release config, and found the address of IncreaseAndGet() function using IDA free 5.0, and then created a hook in C# using EasyHook, and tada:

namespace Hook
{
    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;

    using EasyHook;

    public class Main : IEntryPoint
    {
        private LocalHook IncreaseAndGetHook;

        private DIncreaseAndGet IncreaseAndGet_Original;

        public Main(RemoteHooking.IContext InContext, string InChannelName)
        {
        }

        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        private delegate int DIncreaseAndGet();

        public void Run(RemoteHooking.IContext InContext, string InChannelName)
        {
            // install hook...
            try
            {
                // 0x000016B0: the address of IncreaseAndGet func in target.exe (Release)
                var funcAddr = new IntPtr(
                                   0x000016B0 + 
                                   (int)Process.GetCurrentProcess().MainModule.BaseAddress);

                this.IncreaseAndGet_Original = (DIncreaseAndGet)Marshal.GetDelegateForFunctionPointer(
                                                   funcAddr,
                                                   typeof(DIncreaseAndGet));

                this.IncreaseAndGetHook = LocalHook.Create(
                                              funcAddr,
                                              new DIncreaseAndGet(this.IncreaseAndGet_Hooked),
                                              this);

                this.IncreaseAndGetHook.ThreadACL.SetExclusiveACL(new[] { 0 });
            }
            catch (Exception ExtInfo)
            {
                return;
            }

            while (true)
            {
            }
        }

        private int IncreaseAndGet_Hooked()
        {
            var originalResult = this.IncreaseAndGet_Original();
            Console.WriteLine("lol : " + originalResult);
            return 1337;
        }
    }
}

It would be a bit trickier to figure out the hook delegate if the signature of the hooked function was unknown, and it was using complex types, or if it was an instance method of a class.

Nov 29, 2012 at 2:44 PM
Edited Nov 29, 2012 at 2:48 PM

Just what I needed! Thanks 

Also how to call an original function from, the exe?

Nov 29, 2012 at 3:04 PM

it's already in the code :P

var funcAddr = new IntPtr(0x000016B0 + (int)Process.GetCurrentProcess().MainModule.BaseAddress);
this.IncreaseAndGet_Original = (DIncreaseAndGet)Marshal.GetDelegateForFunctionPointer(funcAddr, typeof(DIncreaseAndGet));
var originalValue = this.IncreaseAndGet_Original();