Disable TLB and get OldProc

Sep 17, 2010 at 2:41 PM

Hi,

I have disabled the TLB - are there any negative consequences (apart from possibly having recursive calls)? I think an "option" for the LocalHook would be nice like LocalHook.DisableTLB().

I also implemented LhGetOldProc in order to call the original function.

This is how it looks like from the application point of view (hijacking a COM-interface):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;

using EasyHook;

namespace testCOM
{
    class Program
    {
        static LocalHook hook1;
        static unsafe void Main(string[] args)
        {
            // have to instantiate an object :(
            AVRSIMMEMORY8BITLib.SimMemory8bitClass tst = new AVRSIMMEMORY8BITLib.SimMemory8bitClass();

            // get raw pointer to interface
            // (pointer is valid as long as COM-object is alive)
            Type interfaceType = typeof(AVRSIMMEMORY8BITLib.IAvrSimMemory);
            IntPtr interfaceIntPtr = Marshal.GetComInterfaceForObject(tst, interfaceType);
            int*** interfaceRawPtr = (int***)interfaceIntPtr.ToPointer();
            // get vtable
            int** vTable = *interfaceRawPtr;

            // get com-slot-number (vtable-index) of function X
            // get function-address from vtable
            MethodInfo mi = interfaceType.GetMethod("Evaluate");
            int mi_vto = Marshal.GetComSlotForMethodInfo(mi);
            int* faddr = vTable[mi_vto];


            Program prog = new Program();
            tst.Evaluate();
            hook1 = LocalHook.Create(new System.IntPtr(faddr), new DSimMemory8bitClass_Evaluate(prog.SimMemory8bitClass_Evaluate), null);
            hook1.ThreadACL.SetExclusiveACL(new Int32[]{});
            tst.Evaluate();
            hook1.Dispose();
            tst.Evaluate();

            // we can release the pointers and com-object
            Marshal.Release(interfaceIntPtr);
            Marshal.FinalReleaseComObject(tst);
        }

        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        delegate void DSimMemory8bitClass_Evaluate([MarshalAs(UnmanagedType.Interface)]AVRSIMMEMORY8BITLib.SimMemory8bitClass classInstance);

        int cnt = 0;
        unsafe void SimMemory8bitClass_Evaluate(AVRSIMMEMORY8BITLib.SimMemory8bitClass This)
        {
            cnt++;

            if (cnt == 1)
            {
                // recursion one level...
                This.Evaluate();
            }
            else
            {
                // call original
                DSimMemory8bitClass_Evaluate del = (DSimMemory8bitClass_Evaluate)Marshal.GetDelegateForFunctionPointer(hook1.OldProc, typeof(DSimMemory8bitClass_Evaluate));
                del(This);
            }
        }
    }
}

Insert that into LocalHook.cs:

 

        /// 
        /// The OldProc.
        /// 
        public IntPtr OldProc { get { return m_OldProc; } }

 
       public static LocalHook Create(
            IntPtr InTargetProc,
            Delegate InNewProc,
            Object InCallback)
        {
  .....
            NativeAPI.LhGetOldProc(Result.m_Handle, out Result.m_OldProc);
            Result.m_ThreadACL = new HookAccessControl(Result.m_Handle);

            return Result;
        }

and this into install.c:

 

EASYHOOK_NT_EXPORT LhGetOldProc(TRACED_HOOK_HANDLE InHandle, UCHAR** OutValue)
{
    LOCAL_HOOK_INFO*        Hook = NULL;
    NTSTATUS                NtStatus = STATUS_NOT_SUPPORTED;

    if(!IsValidPointer(OutValue, sizeof(PVOID)))
        THROW(STATUS_INVALID_PARAMETER, L"Invalid result storage specified.");

    RtlAcquireLock(&GlobalHookLock);
    {
        if((InHandle->Link != NULL) && LhIsValidHandle(InHandle, &Hook))
        {
			*OutValue = Hook->OldProc;
			NtStatus = STATUS_SUCCESS;
		}
	}
	RtlReleaseLock(&GlobalHookLock);

THROW_OUTRO:
FINALLY_OUTRO:
    return NtStatus;
}

Regards,

TLeibnitz