2

別のプロセス内で関数を呼び出し、createremotethread を介して複数の引数を送信したいと考えています。

さて、インラインasmを送信することでそれを行うことができましたが、そのようにするための十分なアセンブリがわかりません。また、リモート プロセスのソース コードにアクセスすることもできません。

私は使用することを考えていました:

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

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

}

しかし、私が理解していることから、リモートプロセスはそれを処理する方法を知っている必要があります.

アセンブリを含まないリモート プロセスに複数の引数を送信する簡単な方法はありますか?

編集:

これが現在解決しようとしている方法ですが、メモリ不足の例外が発生し、何が間違っているのか本当にわかりません。

リモート プロセスの 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);
}  
4

2 に答える 2

1

簡単な方法はありません。最も簡単な方法はLoadLibrary、アンマネージ コードを使用してこれを行うことです。32 ビット dll と 64 ビット dll の 2 つのバージョンが必要です。ターゲット プロセスの「ビット数」に基づいて、どちらを挿入するかを選択します。

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

C# CreateRemoteThread LoadLibraryをグーグルで検索すると、インターネットで参照が見つかります。

その後、カスタム 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を参照してください。

于 2014-10-09T21:27:48.877 に答える