Mejor manera de importar API Win32 desde shellcode inyectado

9

Estoy inyectando código x86 nativo en una aplicación .NET, a través de una devolución de llamada TLS en la imagen binaria. Desafortunadamente, los ejecutables .NET solo importan mscorlib.dll dentro del PE y tienen kernel32.dll asignado automáticamente en el espacio de memoria en tiempo de ejecución. No quiero inyectar ninguna importación. Esto hace que la búsqueda de las direcciones de LoadLibrary y GetProcAddress sea torpe.

Mi primer pensamiento para una solución fue encontrar el PEB a través de mov eax, dword ptr [fs:030h] , luego cargar PEB->Ldr y PEB->Ldr.InMemoryOrderModuleList.Flink desde allí, y usarlos para encontrar el módulo en la memoria. Desde allí, podría tomar la dirección base de kernel32.dll en la memoria, y desplazarme al encabezado PE y al directorio RVA de exportación. Desde allí, puedo escanear las entradas de importación para la exportación por nombre y encontrar la dirección.

Esto tiene los siguientes problemas:

  • Un montón de código para algo tan trivial como una llamada a la API.
  • La cadena ASCII que representa el nombre de la API debería estar incrustada en el código.
  • El almacenamiento en caché de las direcciones encontradas en un largo tiempo de ejecución / múltiples subprocesos es incómodo.

¿Hay una forma más limpia de hacerlo que resuelva estos problemas, sin recurrir a la importación de inyección? Tenga en cuenta que no puedo cambiar el EP de la imagen, porque CLR se basa en que el EP es un salto al IL administrado.

    
pregunta Polynomial 27.11.2012 - 10:52
fuente

1 respuesta

3

Hay una buena manera de resolver los problemas (2) y (3) en el proceso de enlace manual descrito, pero me resisto a publicar un tutorial público bueno y elaborado sobre el diseño de código de shell aquí en StackExchange. ^ _ ^ Por lo tanto, hay una sugerencia para usted de usar crcs para (2) y llamadas indirectas para (3): parece estar lo suficientemente familiarizado con el proceso de enlace manual para deducir la forma exacta de aplicar estos dos conceptos.

Respecto a (1), no es un problema sino un supuesto incorrecto: vincular las exportaciones a las importaciones y proporcionar una capacidad de programador para llamar a la API del sistema es no trivial por cualquier medio. La pregunta es quién hará todo el trabajo sucio. Tan pronto como rechace el servicio de Windows Linker por su dependencia de los nombres de texto sin formato, estará solo para implementar los detalles sucios a su manera.

La inyección de importación parece ser la forma más limpia al modificar el binario de todos modos, pero agrega nombres de API de texto sin formato, por lo que supongo que debido a eso está fuera de tu consideración.

    
respondido por el Van Jone 20.12.2012 - 23:50
fuente

Lea otras preguntas en las etiquetas