【问题标题】:Call function inside another process which is not written in .NET在另一个未用 .NET 编写的进程内调用函数
【发布时间】:2014-10-08 19:29:39
【问题描述】:

我想在另一个进程中调用一个函数并通过 createremotethread 发送多个参数。

现在,我可以通过发送内联 asm 来做到这一点,但我不知道足够的汇编来做到这一点。此外,我无权访问远程进程源代码。

我正在考虑使用:

[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct RemoteThreadParams
{
    [MarshalAs(UnmanagedType.I4)]
    public int Param1;

    [MarshalAs(UnmanagedType.I4)]
    public int Param2;

}

但据我了解,远程进程必须知道如何处理。

有没有一种简单的方法可以向不包含任何程序集的远程进程发送超过 1 个参数?

编辑:

这就是我目前正在尝试解决的方法,但是我内存不足异常,我真的不明白我做错了什么。

我们在远程进程中的 0x64D480 处有函数 ptr,这是从 IDA pro 获取的程序集。

// FUNCTION PTR IS 0x64D480
.text:0064D480 sub_64D480      proc near               ; CODE XREF: sub_4DA7F0+3Ap
.text:0064D480                                         ; sub_64D550+Bp ...
.text:0064D480
.text:0064D480 var_C           = dword ptr -0Ch // arg1
.text:0064D480 arg_0           = dword ptr  4 // arg2
.text:0064D480
.text:0064D480                 push    esi
.text:0064D481                 push    edi
.text:0064D482                 mov     edi, [esp+8+arg_0]
.text:0064D486                 push    edi
.text:0064D487                 mov     esi, ecx
.text:0064D489                 call    sub_64D330
.text:0064D48E                 test    al, al
.text:0064D490                 jnz     short loc_64D497
.text:0064D492                 pop     edi
.text:0064D493                 pop     esi
.text:0064D494                 retn    4  

不应该这样调用函数吗:

[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct RemoteThreadParams
{
    [MarshalAs(UnmanagedType.I4)]
    public int Param1;

    [MarshalAs(UnmanagedType.I4)]
    public int Param2;

}  

void CallFunction(IntPtr _functionPtr, RemoteThreadParams _parameters)
{
    // Allocate some native heap memory in your process big enough to store the parameter data
    IntPtr iptrtoparams = Marshal.AllocHGlobal(Marshal.SizeOf(_parameters));

    // Copies the data in your structure into the native heap memory just allocated
    Marshal.StructureToPtr(_parameters, iptrtoparams, false);
    // Use to alloc "committed" memory that is addressable by other process
    IntPtr iptrremoteallocatedmemory = VirtualAllocEx(this.handle, IntPtr.Zero, (uint)Marshal.SizeOf(_parameters), AllocationType.Commit, MemoryProtection.ExecuteReadWrite);
    UIntPtr bytesWritten = UIntPtr.Zero;
    // Copy from local process memory to the memory of the remote process
    WriteProcessMemory(this.handle, iptrremoteallocatedmemory, iptrtoparams, (uint)Marshal.SizeOf(_parameters), out bytesWritten);
    //Free up memory
    Marshal.FreeHGlobal(iptrtoparams);

    //thread id and return value in case we need it for later
    uint iThreadId;
    uint returnValue = 0;

    IntPtr hThread = CreateRemoteThread(this.handle, IntPtr.Zero, 0, _functionPtr, iptrtoparams, 0, out iThreadId);

    WaitForSingleObject(hThread, 0xFFFFFFFF);
    GetExitCodeThread(hThread, out returnValue);

    CloseHandle(hThread);
    CloseHandle(this.handle);
}  

【问题讨论】:

  • 这只是常规注射。我无法理解有什么特别之处。选择一种注射技术并继续前进。
  • 好吧,例如,我在远程进程中有一个函数指针:0x64D480,它接受两个参数:.text:0064D480 var_C = dword ptr -0Ch .text:0064D480 arg_0 = dword ptr 4并且进程正在运行非托管代码,我如何调用该函数并从我的 C# 应用程序发送这两个参数?
  • 介意给我发一个链接到那些无数例子中的一个吗? :)
  • 感谢您的帮助。
  • 想看看更新后的帖子吗?我不想让你浪费你的时间:) 提前谢谢

标签: c# pinvoke .net-assembly createremotethread


【解决方案1】:

没有简单的方法。最简单的方法是使用LoadLibrary 和非托管代码来执行此操作。您需要两个版本:32位dll和64位dll,您根据目标进程“位数”选择注入哪一个。

CreateRemoteThread(....., Address of LoadLibrary,   "location of your unmanaged dll");

当您使用 Google 搜索 C# CreateRemoteThread LoadLibrary 时,您会在 Internet 上找到参考资料。

之后,您希望自定义 dll 进行函数调用:

#include "stdafx.h"

typedef void (__stdcall *MyCustomFunc)(int param1, int param2);

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        {
            // this code is executed arbitrarily. 
            // this is just a test,
            // you're better off writing a separate function in a DLL
            // and export it, so you can later call it from C#, once DLL is injected.
            MyCustomFunc test = 0x64D480;
            test(2, 4);
        }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

ps,如果需要,您还需要FreeLibrary。正确使用调用约定也很重要。我在这里很犹豫,说它看起来像 __stdcall,但它可能是 __cdecl 或 __fastcall 或其他。请参阅:http://www.codeproject.com/Articles/1388/Calling-Conventions-Demystified 了解更多信息。

【讨论】:

    【解决方案2】:

    我不认为这会有所帮助,但是:

    您实际上可以使用例如调用本机方法(您可能已经知道)

    public static extern Foo (Bar argument);
    public void Main()
    {
        Foo(new Bar());
    }
    

    此外,您实际上可以做的是读取和操作应用程序存储在 RAM 中的数据 这是大多数“游戏培训师”所做的,这可能会对您有所帮助:http://forum.cheatengine.org/viewtopic.php?t=530207

    【讨论】:

    • 但是使用本地方法需要从进程中导入 DLL 不是吗?
    • No Afaik 你不能导入 not-.net-dlls(.dll 文件是本机等并且不包含托管 .net 程序集)编辑:等等,你的意思是 [DllImport] 是它需要您以编程方式导入 dll,但不将它们设置为对您的项目的引用,这就是我上面的意思。另见msdn.microsoft.com/en-us/library/e59b22c5.aspx
    猜你喜欢
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 2011-03-23
    • 2015-04-20
    • 2017-09-22
    • 2016-11-13
    • 2017-05-08
    • 1970-01-01
    相关资源
    最近更新 更多