13

Windowsフックまたは他のメソッドを使用してC#でコードインジェクションを行うことはできますか?私はコードインジェクションについて多くのことを見てきましたが、それらはすべてC /C++で行われます。私はそれらの言語のどちらも知らず、翻訳するのに本当に苦労しています。誰かがこれを行う方法について何かアイデアがありますか?

4

4 に答える 4

6

ケビン、それは可能です。マネージC++を使用して、ウィンドウフックプロシージャでライブラリを作成できます。あなたがする必要があるのは、標準のWinAPI(SetWindowsHookExなど)を使用して、このフックをいくつかのアプリケーションに挿入することです。このフック内で、System :: AppDomain :: CurrentDomain-> Loadメソッドを呼び出して、アセンブリをターゲットアプリケーションのAppDomainにロードできます。次に、リフレクションを使用して、アセンブリで定義されたメソッドを呼び出すことができます。たとえば、Snoopはこのメソッドを使用します。

于 2008-08-23T14:23:52.330 に答える
4

Mike Stall には、CreateRemoteThread を使用するこのサンプルがあります。C++ を必要としないという利点があります。

于 2008-11-03T21:26:24.260 に答える
4

編集:私は質問を誤解しているようです....私は、質問が現在のプロセスへのコードインジェクションに関するものであるという印象を受けました。


私はかなり遅れてパーティーに参加していますが、数週間前にまさにこれを使用しました:

デリゲートには、本文のメモリ アドレスを表すプライベート フィールドIntPtr _methodPtrとが含まれます。IntPtr _methodPtrAux(リフレクションを介して) フィールドを特定の値に設定することで、EIP が指すメモリ アドレスを変更できます。
この情報を使用して、次のことができます。

  1. 実行されるアセンブリバイトで配列を作成します
  2. デリゲートのメソッド ポインターを問題のバイトに移動します。
  3. 代理人に電話する
  4. 利益 ???

(もちろん、_methodPtr-value を任意のメモリ アドレスに変更できます。カーネル空間でも変更できますが、これには適切な実行権限が必要になる場合があります)。


必要に応じて、ここに実際のコード例があります。

public static unsafe int? InjectAndRunX86ASM(this Func<int> del, byte[] asm)
{
    if (del != null)
        fixed (byte* ptr = &asm[0])
        {
            FieldInfo _methodPtr = typeof(Delegate).GetField("_methodPtr", BindingFlags.NonPublic | BindingFlags.Instance);
            FieldInfo _methodPtrAux = typeof(Delegate).GetField("_methodPtrAux", BindingFlags.NonPublic | BindingFlags.Instance);

            _methodPtr.SetValue(del, ptr);
            _methodPtrAux.SetValue(del, ptr);

            return del();
        }
    else
        return null;
}

次のように使用できます。

Func<int> del = () => 0;
byte[] asm_bytes = new byte[] { 0xb8, 0x15, 0x03, 0x00, 0x00, 0xbb, 0x42, 0x00, 0x00, 0x00, 0x03, 0xc3 };
// mov eax, 315h
// mov ebx, 42h
// add eax, ebx
// ret

int res = del.InjectAndRunX86ASM(asm_bytes); // should be 789 + 66 = 855

もちろん、 on は次のメソッドを書くこともできます:

public static unsafe int RunX86ASM(byte[] asm)
{
    Func<int> del = () => 0; // create a delegate variable
    Array.Resize(ref asm, asm.Length + 1);

    // add a return instruction at the end to prevent any memory leaks
    asm[asm.Length - 1] = 0xC3;

    fixed (byte* ptr = &asm[0])
    {
        FieldInfo _methodPtr = typeof(Delegate).GetField("_methodPtr", BindingFlags.NonPublic | BindingFlags.Instance);
        FieldInfo _methodPtrAux = typeof(Delegate).GetField("_methodPtrAux", BindingFlags.NonPublic | BindingFlags.Instance);

        _methodPtr.SetValue(del, ptr);
        _methodPtrAux.SetValue(del, ptr);

        return del();
    }
}

リフレクションを介して、既存のメソッド (デリゲートではない) に対して同じことがおそらく実行できます。

// UNTESTED //

Action new_method_body = () => { };
MethodInfo nfo = typeof(MyType).GetMethod( ..... );
IntPtr ptr = nfo.MethodHandle.Value; // ptr is a pointer to the method in question

InjectX86ASM(new_method_body, new byte[] { ......., 0xC3 }); // assembly bytes to be injected

int target = new_method_body.Method.MethodHandle.Value.ToInt32();

byte[] redirector = new byte[] {
    0xE8,   // CALL INSTRUCTION + TARGET ADDRESS IN LITTLE ENDIAN
    (byte)(target & 0xff),
    (byte)((target >> 8) & 0xff),
    (byte)((target >> 16) & 0xff),
    (byte)((target >> 24) & 0xff),
    0xC3,   // RETURN INSTRUCTION
};
Marshal.Copy(redirector, 0, ptr, redirector.Length);


コードは自己責任で使用してください。コード例は、/unsafe-compiler スイッチを使用してコンパイルする必要があります。

于 2016-09-21T15:27:56.617 に答える
2

CInjectをチェックして、CodePlexサイトhttp://codeinject.codeplex.com/で.NETアセンブリへのコードインジェクションを確認できます。CInjectを使用している場合、コードをインジェクションするためにコードインジェクションに関する知識は必要ありません。

于 2011-12-13T11:44:49.230 に答える