Para responder a su pregunta, debo cubrir la descripción completa de cómo se creó un nuevo proceso.
Hay una gran descripción de esto en el Capítulo 5 de 6ª edición de Windows Internals Parte 1 ( 5 es disponible en línea gratuitamente en línea el sitio web de Microsoft) que explica exactamente cómo funciona todo esto.
Parafrasearé un resumen de lo que se dice en el libro, ya que copiarlo literalmente probablemente tenga algunos problemas de derechos de autor.
El cargador de PE está expuesto por un conjunto de API de usuario en kernel32.dll
, bajo la familia CreateProcess
. Hay diferentes API para hacer cosas diferentes, por ejemplo, ejecutar un proceso en un contexto de seguridad alternativo.
Así es como funciona:
- La API de modo de usuario valida los parámetros de entrada y los convierte en sus homólogos de sistema (nativos).
- Luego abre el archivo ejecutable y lo carga en la memoria.
- Crea el objeto de proceso ejecutivo en el kernel. Esto implica llenar la estructura
EPROCESS
y registrar el proceso en varias listas.
- Crea el hilo principal del proceso (pila, contexto de ejecución, objeto de hilo)
- Realiza la inicialización específica del subsistema, por ejemplo, CLR init para aplicaciones .NET.
- Iniciar el hilo principal (a menos que se haya creado con el conjunto de indicadores suspendido)
- Cargue los DLL apropiados en el contexto del proceso.
La mayoría de esto se realiza a nivel del kernel, utilizando las funciones nativas prefijadas Ps
-prefixed. El conjunto completo de pasos involucrados es bastante complejo (de hecho, ocupa 15 páginas completas en el libro) e involucra muchas acciones diferentes dependiendo del sistema de susbs utilizado.
La parte difícil con tu pregunta es que el "cargador" no es realmente algo que obtiene el flujo de control. En el instante en que llama a CreateProcess
, técnicamente está ejecutando el cargador. Sin embargo, la parte del kernel del cargador comienza cuando ntdll!NtCreateUserProcess
hace la transición al modo kernel. Si somos realmente estrictos al respecto, podríamos decir que la primera parte del cargador es PspAllocateProcess
, ya que eso es lo que asigna las estructuras iniciales.