2008-08-23 13 views
13

¿Se pueden usar ganchos de Windows u otros métodos para hacer la inyección de código con C#? He visto muchas cosas sobre la inyección de código, pero todas se hacen en C/C++. No conozco ninguno de esos idiomas y me cuesta mucho traducirlo. ¿Alguien tiene alguna idea sobre cómo hacer esto?Inyección de código con C#

Respuesta

5

Kevin, es posible. Puede crear una biblioteca con el proceso de hook de ventana utilizando C++ administrado. Todo lo que necesita hacer es inyectar este enlace en alguna aplicación utilizando WinAPI estándar (SetWindowsHookEx, etc.). Dentro de este enlace puede llamar a System :: AppDomain :: CurrentDomain-> Cargar método para cargar su ensamblado en AppDomain de la aplicación de destino. Luego puede llamar a los métodos definidos en su conjunto mediante reflexión. Por ejemplo, Snoop utiliza este método.

+2

Enlace roto ahora –

+0

Puede ser útil para que alguien vea https://web.archive.org/web/20081228210203/http://blois.us/Snoop/ w.r.t. el enlace roto. –

9

encontré con un enlace que trata este tema en detalle, así que quería colocar de nuevo aquí: How To Inject a Managed .NET Assembly (DLL) Into Another Process

+2

El enlace parece estar roto –

+1

Aquí hay un archivo de Wayback Machine https://web.archive.org/web/20130303142450/http://www.codingthewheel.com/archives/how-to-inject-a-managed -assembly-dll –

+1

Veo por qué se rompe el enlace ... ¡El autor se vale de FOREVER para llegar al punto! –

3

Mike Stall tiene this sample, que utiliza CreateRemoteThread. Tiene la ventaja de no requerir ningún C++.

2

Puede ver CInject para la inyección de código en ensamblados .NET en el sitio CodePlex http://codeinject.codeplex.com/. No necesita tener ningún conocimiento sobre la inyección de código para inyectar ningún código cuando está utilizando CInject.

+0

O bien, puede seguir los pasos mencionados en este artículo sobre [Intercepting Method Calls using IL] (http://www.codetails.com/punitganshani/intercepting-method-calls-using-il/20121202) y crea tu propio interceptor usando Reflection.Emit clases en C#. –

2

EDIT: Parece que he malinterpretado la pregunta .... Tenía la impresión de que la cuestión era sobre la inyección de código en el proceso actual.


me uno a la fiesta un poco tarde, pero sólo he utilizado exactamente esto hace unas semanas:

Un delegado contiene los campos privados IntPtr _methodPtr and IntPtr _methodPtrAux, que representan la dirección de memoria del cuerpo. Al configurar el campo (a través de la reflexión) a valores específicos, se puede modificar la dirección de la memoria a la que apunta el EIP.
Con esta información, se puede hacer lo siguiente:

  1. crear una matriz con bytes de montaje, que han de ser ejecutados
  2. mover el puntero método del delegado a los bytes en cuestión
  3. llamar al delegado
  4. Beneficio ???

(Por supuesto, puede cambiar el valor P _methodPtr a cualquier dirección de memoria - incluso en el espacio del núcleo, pero esto puede requerir privilegios de ejecución apropiadas).


Tengo un ejemplo de código de trabajo aquí, si desea:

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

que puede ser utilizado de la siguiente manera:

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 

Por supuesto, el también podría escribir el siguiente método:

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

Lo mismo probablemente podría hacerse con métodos existentes (no con delegados) a través de la reflexión:

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


Uso cualquier código a su propio riesgo. Los ejemplos de código se deben compilar con /unsafe-compiler switch.

+0

El OP quiere inyectar código en un proceso externo. –

+0

@joshpoley: Oh, mi mal ... debe haber leído mal la pregunta: / – Unknown6656

Cuestiones relacionadas