从注入的 DLL 调用函数

发布于 2024-09-30 00:37:18 字数 2842 浏览 1 评论 0原文


首先我想说,我并不是想破解一款游戏。我实际上受雇于我试图注入其流程的公司。 :)
我想知道如何从已注入的 DLL 中调用函数。
因此,我已使用 CreateRemoteThread() 成功地将 DLL 注入并加载到目标中。下面您可以看到注入的片段:

private static bool Inject(Process pToBeInjected, string sDllPath,out string sError, out IntPtr hwnd, out IntPtr hLibModule)
    { 
        IntPtr zeroPtr = (IntPtr)0;
        hLibModule = zeroPtr;

        IntPtr hProcess = NativeUtils.OpenProcess(
            (0x2 | 0x8 | 0x10 | 0x20 | 0x400), //create thread, query info, operation ,write, and read 
            1,
            (uint)pToBeInjected.Id);

        hwnd = hProcess;
        IntPtr loadLibH = NativeUtils.GetProcAddress( NativeUtils.GetModuleHandle("kernel32.dll"),"LoadLibraryA");

        IntPtr dllAddress = NativeUtils.VirtualAllocEx(
            hProcess,
            (IntPtr)null,
            (IntPtr)sDllPath.Length, //520 bytes should be enough 
            (uint)NativeUtils.AllocationType.Commit |
            (uint)NativeUtils.AllocationType.Reserve,
            (uint)NativeUtils.MemoryProtection.ExecuteReadWrite);

    byte[] bytes = CalcBytes(sDllPath);
        IntPtr ipTmp = IntPtr.Zero;

        NativeUtils.WriteProcessMemory(
            hProcess,
            dllAddress,
            bytes,
            (uint)bytes.Length,
            out ipTmp);


        IntPtr hThread = NativeUtils.CreateRemoteThread(
            hProcess,
            (IntPtr)null,
            (IntPtr)0,
            loadLibH, //handle to LoabLibrary function
            dllAddress,//Address of the dll in remote process
            0,
            (IntPtr)null);

        uint retV= NativeUtils.WaitForSingleObject(hThread, NativeUtils.INFINITE_WAIT);
        bool exitR = NativeUtils.GetExitCodeThread(hThread, out hLibModule);
        return true;
    }

注意:为了简洁起见,删除了错误检查和释放资源,但请放心,我会检查所有指针并释放我的资源。
上面的函数退出后,LoadLibrary 通过 hLibModule 返回一个非零的 DLL 模块句柄,这意味着 DLL 已正确加载。
我的 DLL 是一个 C# 类库,用于显示消息框(用于测试)。我尝试测试该功能并弹出消息框。它看起来像这样:

 public class Class1
    {
        public static void ThreadFunc(IntPtr param ) 
        {       
        IntPtr libPtr = LoadLibrary("user32.dll");

            MessageBox(IntPtr.Zero, "I'm ALIVE!!!!", "InjectedDll", 0);

        }
        [DllImport("kernel32", SetLastError = true)]
        public static extern IntPtr LoadLibrary(string lpFileName);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern int MessageBox(IntPtr hWnd, String text, String caption, int options);

} 

我从 Visual Studio 编译它,DLL 出现在 Debug 文件夹中。然后我将 DLL 的完整路径传递给注入器。
注入目标进程后,我不知道如何从注入的 DLL 中调用我的 ThreadFunc,因此它永远不会执行。
我无法使用 GetProcAddress(hLibModule,"ThreadFunc") 因为我不在进程中,所以答案必须以某种方式调用 CreateRemoteThread() 。另外,我了解到 DllMain 不再允许用于 .NET DLL,因此我也无法通过这种方式获得任何自由执行。
有谁知道如何从注入的 DLL 中调用函数吗?
先感谢您。

First off I would like to say, that I am not trying to hack a game. I am actually employed by the company whose process I am trying to inject. :)
I would like to know how to call a function from an already injected DLL.
So, I have successfully injected and loaded my DLL in the target using CreateRemoteThread(). Below you can see a snippet of the injection:

private static bool Inject(Process pToBeInjected, string sDllPath,out string sError, out IntPtr hwnd, out IntPtr hLibModule)
    { 
        IntPtr zeroPtr = (IntPtr)0;
        hLibModule = zeroPtr;

        IntPtr hProcess = NativeUtils.OpenProcess(
            (0x2 | 0x8 | 0x10 | 0x20 | 0x400), //create thread, query info, operation ,write, and read 
            1,
            (uint)pToBeInjected.Id);

        hwnd = hProcess;
        IntPtr loadLibH = NativeUtils.GetProcAddress( NativeUtils.GetModuleHandle("kernel32.dll"),"LoadLibraryA");

        IntPtr dllAddress = NativeUtils.VirtualAllocEx(
            hProcess,
            (IntPtr)null,
            (IntPtr)sDllPath.Length, //520 bytes should be enough 
            (uint)NativeUtils.AllocationType.Commit |
            (uint)NativeUtils.AllocationType.Reserve,
            (uint)NativeUtils.MemoryProtection.ExecuteReadWrite);

    byte[] bytes = CalcBytes(sDllPath);
        IntPtr ipTmp = IntPtr.Zero;

        NativeUtils.WriteProcessMemory(
            hProcess,
            dllAddress,
            bytes,
            (uint)bytes.Length,
            out ipTmp);


        IntPtr hThread = NativeUtils.CreateRemoteThread(
            hProcess,
            (IntPtr)null,
            (IntPtr)0,
            loadLibH, //handle to LoabLibrary function
            dllAddress,//Address of the dll in remote process
            0,
            (IntPtr)null);

        uint retV= NativeUtils.WaitForSingleObject(hThread, NativeUtils.INFINITE_WAIT);
        bool exitR = NativeUtils.GetExitCodeThread(hThread, out hLibModule);
        return true;
    }

Note: Error checking and freeing resources were removed for brevity, but rest assured I check all the pointers and free my resources.
After the function above exits, I have a non-zero module handle to my DLL returned by LoadLibrary through hLibModule, meaning that the DLL was loaded correctly.
My DLL is a C# class library meant to show a message box (for testing). I have tried testing the function and the message box pops up. It looks like this:

 public class Class1
    {
        public static void ThreadFunc(IntPtr param ) 
        {       
        IntPtr libPtr = LoadLibrary("user32.dll");

            MessageBox(IntPtr.Zero, "I'm ALIVE!!!!", "InjectedDll", 0);

        }
        [DllImport("kernel32", SetLastError = true)]
        public static extern IntPtr LoadLibrary(string lpFileName);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern int MessageBox(IntPtr hWnd, String text, String caption, int options);

} 

I compile it from Visual Studio and the DLL appears in the Debug folder. I then pass the full path of my DLL to the injector.
After injection into the target process, I don't know how to call my ThreadFunc from the injected DLL, so it never executes.
I cannot use GetProcAddress(hLibModule,"ThreadFunc") since I am out of process, so the answer must lie into calling CreateRemoteThread() somehow. Also, I have read that DllMain is no longer allowed for .NET DLLs, so I cannot get any free execution that way either.
Does anyone have any idea how to call a function from an injected DLL?
Thank you in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

书信已泛黄 2024-10-07 00:37:18

好吧,您已经在该进程内运行了一个线程。你让它做一些无聊的事情,它只加载一个 DLL。这完全是偶然的,LoadLibrary 只是碰巧必须更正函数签名。

它可以做更多的事情。然而,最好是非托管代码,就像 LoadLibrary() 一样,您不能指望任何托管代码正确运行。这需要大量的工作,您必须加载并初始化 CLR,并告诉它加载并执行您想要运行的程序集。不,您不能在 DllMain() 中加载 CLR。

要查找的关键字是 CorBindToRuntimeEx() 和 ICLRRuntimeHost::ExecuteInAppDomain()。这是一件很难开始的事情,但我已经看到它完成了。需要 COM 和 C++ 技能以及慷慨的运气。

Well, you already got a thread running inside that process. You make it do something boring, it only loads a DLL. This works completely by accident, LoadLibrary just happens to have to correct function signature.

It can do much more. That however better be unmanaged code, just like LoadLibrary(), you cannot count on any managed code running properly. That takes a heckofalot more work, you have to load and initialize the CLR and tell it to load and execute the assembly you want to run. And no, you cannot load the CLR in DllMain().

Keywords to look for are CorBindToRuntimeEx() and ICLRRuntimeHost::ExecuteInAppDomain(). This is gritty stuff to get going but I've seen it done. COM and C++ skills and generous helpings of luck required.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文