Call to RemoteHooking.Inject doesn't work unless I Sleep

Nov 19, 2010 at 3:58 PM

Hi,

this is quite an awesome API and I have my code working except for one very annoying problem. My code is virtually identical to FileMon and FileMonInject; I use this on the host:

 

// Create the process suspended so that we can hook stuff before it starts

PROCESS_INFORMATION pinfo = new PROCESS_INFORMATION();
STARTUPINFO sinfo = new STARTUPINFO();

SECURITY_ATTRIBUTES sap = new SECURITY_ATTRIBUTES();
SECURITY_ATTRIBUTES sat = new SECURITY_ATTRIBUTES();
sap.nLength = Marshal.SizeOf(sap);
sat.nLength = Marshal.SizeOf(sat);

bool result = CreateProcess(
    cached_exe,
    options,
    ref sap,
    ref sat,
    false,
    (uint)CreateProcessCreationFlags.CREATE_SUSPENDED,
    IntPtr.Zero,
    null,
    ref sinfo,
    out pinfo);

// TODO: Do temporarily or just once?
Config.Register("Blah", "DistributeAgent.exe", "DistributeShared.dll", "VirtualisationInject.dll");

// Create the host and inject the virtualisation DLL
string channel_name = null;
RemoteHooking.IpcCreateServer<AgentVirtualisationInterface>(ref channel_name, WellKnownObjectMode.SingleCall);
RemoteHooking.Inject(pinfo.dwProcessId, "VirtualisationInject.dll", "VirtualisationInject.dll", channel_name);

// Kick-off the process and wait for it to complete
ResumeThread(pinfo.hThread);
WaitForSingleObject(pinfo.hProcess, INFINITE);

 

The injection DLL contains, simply:

 

public Main(RemoteHooking.IContext context, string channel_name)
{
    // Connect to the host
    try
    {
        m_AgentInterface = RemoteHooking.IpcConnectClient<DistributeShared.AgentVirtualisationInterface>(channel_name);
    }
    catch (Exception)
    {
        return;
    }
    m_AgentInterface.Connected();
}

public void Run(RemoteHooking.IContext context, string channel_name)
{
    try
    {
        // Install the hook
        IntPtr CreateFileW = LocalHook.GetProcAddress("kernel32.dll", "CreateFileW");
        m_CreateWFileHook = LocalHook.Create(CreateFileW, new CreateFileWDelegate(Hook_CreateFileW), this);
        m_CreateWFileHook.ThreadACL.SetExclusiveACL(new int[] { 0 });
    }
    catch (Exception exception)
    {
        m_AgentInterface.ReportException(exception);
        return;
    }

    m_AgentInterface.HookInstalled(RemoteHooking.GetCurrentProcessId());

    while (true)
    {
        System.Threading.Thread.Sleep(500);
        m_AgentInterface.Ping();
    }
}

 

(note I don't call WakeUpProcess because I'm not using CreateAndInject - although my problem still exists if I try that route).

When running normally I only get my call to Connected. If I slowly step-debug the host then I get my call to HookInstalled and it's entirely random whether my hooks get called or not.

However, if I put a Sleep(10) directly after the call to RemoteHooking.Inject I get all my init code called and every single hook triggers correctly. Putting the sleep before the Inject call doesn't work and putting it after the ResumeThread doesn't work, either; I'm presuming Inject is kicking off some background process which is not completing quickly enough and I have no way to wait for completion. This is a managed C# project calling a version of the Tiny C compiler (tcc.exe).

I'm off to parse the source code in the hope I can figure out what's going on but hopefully somebody here can point me in the right direction. Any ideas what's going on?

 

Cheers,

- Don