Kod: C#

Czy Można używać hooków windows lub innych metod do wprowadzania kodu w c#? Widziałem wiele rzeczy na temat wtrysku kodu, ale wszystkie są wykonywane w C / C++. Nie znam żadnego z tych języków i ciężko mi tłumaczyć. Czy ktoś ma jakieś pomysły jak to zrobić?

Author: Greg Sansom, 2008-08-23

4 answers

Kevin, to możliwe. Możesz utworzyć bibliotekę z Window hook proc używając managed C++. Wszystko, co musisz zrobić, to wstrzyknąć ten hook do jakiejś aplikacji przy użyciu standardowego WinAPI (SetWindowsHookEx itp.). Wewnątrz tego Hooka możesz wywołać metodę System::AppDomain:: CurrentDomain - >Load, aby załadować swój zestaw do aplikacji docelowej AppDomain. Następnie możesz wywołać metody zdefiniowane w Twoim złożeniu używając reflection. Na przykład, Snoop używa tej metody.

 5
Author: aku,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-01 04:20:56

Mike Stall ma tę próbkę , która używa CreateRemoteThread. Ma tę zaletę, że nie wymaga żadnego C++.

 3
Author: Sam Saffron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-03 21:26:24

EDIT: wydaje mi się, że źle zinterpretowałem pytanie .... Miałem wrażenie, że pytanie dotyczyło wtrysku kodu do obecnego procesu.


dołączam do partii dość późno, ale właśnie użyłem dokładnie tego kilka tygodni temu:

Delegat zawiera pola prywatne IntPtr _methodPtr oraz IntPtr _methodPtrAux, które reprezentują adres pamięci ciała. Ustawiając pole (poprzez odbicie) na określone wartości, można zmienić adres pamięci, na który EIP będzie wskazywał.
Korzystając z tych informacji, można wykonać następujące czynności:

  1. tworzenie tablicy z bajtami asemblacji, które mają być wykonane
  2. Przenieś wskaźnik metody delegata do danych bajtów
  3. zadzwoń do delegata
  4. Zysk ???

(oczywiście, możesz zmienić _methodPtr-wartość na dowolny adres pamięci-nawet w przestrzeni jądra, ale może to wymagać odpowiednich uprawnień wykonawczych).


Mam przykład kodu roboczego tutaj, jeśli chcesz:
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;
}

Które mogą być użyte w następujący sposób:

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

Oczywiście on może również napisać następującą metodę:

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();
    }
}

To samo prawdopodobnie można zrobić z istniejącymi metodami (nie delegatami) poprzez refleksję:

// 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);


używaj dowolnego kodu na własne ryzyko. przykłady kodu muszą być skompilowane z /unsafe-przełącznik kompilatora .
 3
Author: Unknown6656,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-21 20:23:16

Możesz sprawdzić CInject do wtrysku kodu do zestawów. NET w miejscu CodePlex http://codeinject.codeplex.com/. nie musisz mieć żadnej wiedzy na temat wstrzykiwania kodu, aby wprowadzić dowolny kod, gdy używasz CInject.

 2
Author: Puneet Ghanshani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-13 11:44:49