samedi 11 juillet 2015

Loading/Injecting .Net Assembly into existing .net process?

In my situation i want to load a custom .net assembly into a running .net process's domain, for example Windows Explorer, What i have tried already is just injecting the assembly to explorer.exe but that doesn't seem to work for no obvious reason.

Injector Code:

public class CodeInjector
{
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr OpenProcess(uint dwDesiredAccess, int bInheritHandle, uint dwProcessId);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern int CloseHandle(IntPtr hObject);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr GetModuleHandle(string lpModuleName);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, IntPtr dwSize, uint flAllocationType, uint flProtect);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern int WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, uint size, int lpNumberOfBytesWritten);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttribute, IntPtr dwStackSize, IntPtr lpStartAddress,
        IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);

    private static CodeInjector _instance;

    public static CodeInjector GetInstance
    {
        get { return _instance ?? (_instance = new CodeInjector()); }
    }

    public InjectionResult Inject(string sProcName, string sDllPath)
    {
        if (!File.Exists(sDllPath))
        {
            return InjectionResult.DllNotFound;
        }

        var procs = Process.GetProcesses();
        var procId = (from t in procs where t.ProcessName == sProcName select (uint)t.Id).FirstOrDefault();

        if (procId == 0)
        {
            return InjectionResult.ProcessNotFound;
        }

        if (!Inject(procId, sDllPath))
        {
            return InjectionResult.InjectionFailed;
        }

        return InjectionResult.InjectionSucceed;
    }

    private static bool Inject(uint pToBeInjected, string sDllPath)
    {
        var hndProc = OpenProcess((0x2 | 0x8 | 0x10 | 0x20 | 0x400), 1, pToBeInjected);

        if (hndProc == IntPtr.Zero)
        {
            return false;
        }

        var lpLlAddress = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");

        if (lpLlAddress == IntPtr.Zero)
        {
            return false;
        }

        var lpAddress = VirtualAllocEx(hndProc, (IntPtr)null, (IntPtr)sDllPath.Length, (0x1000 | 0x2000), 0X40);

        if (lpAddress == IntPtr.Zero)
        {
            return false;
        }

        var bytes = Encoding.ASCII.GetBytes(sDllPath);

        if (WriteProcessMemory(hndProc, lpAddress, bytes, (uint)bytes.Length, 0) == 0)
        {
            return false;
        }

        if (CreateRemoteThread(hndProc, (IntPtr)null, IntPtr.Zero, lpLlAddress, lpAddress, 0, (IntPtr)null) == IntPtr.Zero)
        {
            return false;
        }

        CloseHandle(hndProc);

        return true;
    }
}





Aucun commentaire:

Enregistrer un commentaire