Сведения о вопросе

ЧОВИД

10:22, 4th August, 2020

Теги

c#   code-injection    

Инъекция Кода С C#

Просмотров: 454   Ответов: 4

Можете ли вы использовать windows крючки или другие методы, чтобы сделать инъекцию кода с c#? я видел много вещей о инъекции кода, но все они сделаны в C/C++. я не знаю ни одного из этих языков и очень трудно переводить. У кого-нибудь есть идеи, как это сделать?



  Сведения об ответе

DINO

01:55, 26th August, 2020

Кевин, это вполне возможно. Вы можете создать библиотеку с помощью window hook proc, используя управляемый C++. Все, что вам нужно сделать, это ввести этот крюк в какое-то приложение, используя стандартный WinAPI (SetWindowsHookEx и т. д.). Внутри этого крючка вы можете вызвать метод System::AppDomain::CurrentDomain - >Load, чтобы загрузить ваш assembly в AppDomain целевого приложения. Затем вы можете вызвать методы, определенные в вашем assembly, используя отражение. Например, Snoop использует этот метод.


  Сведения об ответе

ITSME

14:50, 29th August, 2020

У Майка Столла есть этот образец, который использует CreateRemoteThread. Он имеет то преимущество, что не требует никакого C++.


  Сведения об ответе

qwerty101

04:32, 26th August, 2020

- Похоже , я неверно истолковал этот вопрос .... У меня сложилось впечатление, что речь идет о внедрении кода в текущий процесс.


Я вступаю в партию довольно поздно, но я только что использовал именно это несколько недель назад:

Делегат содержит закрытые поля IntPtr _methodPtr и IntPtr _methodPtrAux , которые представляют адрес памяти тела. Установив в поле (через отражение) определенные значения, можно изменить адрес памяти, на который будет указывать EIP.
Используя эту информацию, можно сделать следующее:

  1. Создайте массив с assembly байтами, которые должны быть выполнены
  2. Переместите указатель метода делегата на соответствующие байты
  3. Вызов делегата
  4. Прибыль ???

(Конечно, вы можете изменить значение _methodPtr на любой адрес памяти - даже в пространстве kernel, но для этого могут потребоваться соответствующие привилегии выполнения).


У меня есть рабочий пример кода здесь, Если вы хотите:

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

Конечно, он также мог бы написать следующий метод:

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 .


  Сведения об ответе

ЯЯ__4

12:41, 20th August, 2020

Вы можете проверить CInject для инъекции кода в сборки .NET на сайте CodePlex http://codeinject.codeplex.com/ . Вам не нужно иметь никаких знаний об инъекции кода, чтобы ввести любой код, когда вы используете CInject.


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться