En primer lugar, si solo estás entrando en este tema, te recomiendo que
Como breve resumen les dejo aquí el enlace a las publicaciones anteriores:
¿Por lo que pasaremos?
Dado que el objetivo es analizar el controlador y darle la información que necesita para aprender el resto por su cuenta. No voy a profundizar en lo que son las rutinas de notificación y devolución de llamada. Aquí tienes algunos enlaces interesantes:
fn_InitRegistrationNotifyAndCallbackRoutines (0x140003550)
Hay algunas funciones que inicializan variables, spinlocks y matrices que aún no hemos visto. Todas esas variables se usan en múltiples funciones del controlador, y lo que generalmente sucede es que descubriremos el significado de esas (si alguna vez lo hacemos) mientras revertimos otras funciones que aún no hemos visto.
Como las funciones son cada vez más grandes y complejas, evitaré explicar algunas cosas básicas sobre el desarrollo de controladores, como las inicializaciones de mutex, las asignaciones, etc.
Comencemos con esta función: puede ver la función original aquí (
Al comienzo de la función tenemos algunas inicializaciones de búfer y mutex. Todavía no sabemos para qué son esas variables, pero podemos reconocerlas debido a cómo se utilizan esas variables; por ejemplo, como parámetro para funciones relacionadas con mutex como KeInitializeMutex o códigos de operación de ensamblaje como lock xadd :
Después de eso, encontraremos la primera función interesante sub_140003C38 , que decidí llamar j_fn_ConfigWindowsVersion . Verá esta función invertida en la siguiente publicación. En pocas palabras, la función identifica la versión actual de Windows e inicializa una serie de variables de desplazamiento con información sobre algunas estructuras de kernel particulares. Si esta función no falla, la ejecución continúa:
Vamos a ignorar fn_InitWeirdVariables_ y fn_InitWeirdVariables2_ , dado que esas funciones solo inicializan algunos spinlocks y variables extrañas que el controlador usa más adelante. No estamos interesados en eso por ahora. En realidad, si sabes lo que están haciendo en estas líneas, házmelo saber, porque no sé qué tipo de hechicería están lanzando (creo que es una forma de generar un GUID para cada proceso, pero quién sabe):
Después de eso, se inicializan dos variables NTSTATUS : status_PsSetCreateProcessNotifyRoutine y status_PsSetCreateProcessNotifyRoutineEx. Vamos a ver que si falla el primer intento de registrar NotifyRoutine usando PsSetCreateProcessNotifyRoutineEx , van a usar estas variables para controlar el flujo de ejecución y hacer un segundo intento usando PsSetCreateProcessNotifyRoutineEx .
La dirección de PsSetCreateProcessNotifyRoutineEx se recupera y se almacena en una variable. Si este valor variable no es NULL, se realiza el primer intento:
Podemos ver que se llama a
Avanzando un poco más en la función, si el primer intento falla, veremos que
Nuevamente, hemos identificado otra de las rutinas de devolución de llamada: fn_CreateProcessNotifyRoutine.
fn_CreateProcessNotifyRoutine y fn_CreateProcessNotifyRoutineExImp
Si verificamos fn_CreateProcessNotifyRoutineExImp y fn_CreateProcessNotifyRoutine , notaremos que ambos son envoltorios de las rutinas reales:
Los parámetros recibidos por
fn_Analyze_CreateProcessNotifyRoutine y fn_Analyze_ExitProcessNotifyRoutine son grandes funciones que analizaremos más adelante
Volver a fn_InitRegistrationNotifyAndCallbackRoutines
Finalmente, se intenta el último registro de devolución de llamada:
Sin embargo, como puede ver, si registerCallbackFunction falló, la NotifyRoutine creada anteriormente debe eliminarse antes de salir. En ese caso, establecen _RemoveRoutine en 1 y luego vuelven a llamar a PsSetCreateProcessNotifyRoutine para eliminarlo.
fn_RegisterCallbackFunction se revertirá en las siguientes publicaciones, así como en las otras dos funciones.
Próximos pasos
Niemad
Enlace origen
Twitter
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
de
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
que te dará mucha información sobre este Anti-Cheat.Porfavor, Acceder o Registrarse para ver el contenido citado!
Como breve resumen les dejo aquí el enlace a las publicaciones anteriores:
- Parte 1: identificación del punto de entrada del conductor
- Parte 2: análisis de las funciones de inicio (fn_InitDispatchMethodArray y fn_ObtainKernelFunctions)
- Parte 3: Analizar la función de envío (fn_DriverIOCTLDispatcher)
¿Por lo que pasaremos?
- Identificar mutex y spinlocks
- Aprenda cómo se registran las rutinas de notificación utilizando la API win
- Aprenda cómo se crea
Porfavor, Acceder o Registrarse para ver el contenido de las URL!
- Aprenda cómo el controlador maneja los diferentes estados de error que pueden aparecer durante la ejecución.
Dado que el objetivo es analizar el controlador y darle la información que necesita para aprender el resto por su cuenta. No voy a profundizar en lo que son las rutinas de notificación y devolución de llamada. Aquí tienes algunos enlaces interesantes:
-
Porfavor, Acceder o Registrarse para ver el contenido de las URL!
-
Porfavor, Acceder o Registrarse para ver el contenido de las URL!
-
Porfavor, Acceder o Registrarse para ver el contenido de las URL!
fn_InitRegistrationNotifyAndCallbackRoutines (0x140003550)

Hay algunas funciones que inicializan variables, spinlocks y matrices que aún no hemos visto. Todas esas variables se usan en múltiples funciones del controlador, y lo que generalmente sucede es que descubriremos el significado de esas (si alguna vez lo hacemos) mientras revertimos otras funciones que aún no hemos visto.
Como las funciones son cada vez más grandes y complejas, evitaré explicar algunas cosas básicas sobre el desarrollo de controladores, como las inicializaciones de mutex, las asignaciones, etc.
Comencemos con esta función: puede ver la función original aquí (
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
y
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
) . Y
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
el resultado final de la inversión (trata de no consentirte). Como siempre, tómate tu tiempo para tratar de entenderlo por ti mismo.Al comienzo de la función tenemos algunas inicializaciones de búfer y mutex. Todavía no sabemos para qué son esas variables, pero podemos reconocerlas debido a cómo se utilizan esas variables; por ejemplo, como parámetro para funciones relacionadas con mutex como KeInitializeMutex o códigos de operación de ensamblaje como lock xadd :

Después de eso, encontraremos la primera función interesante sub_140003C38 , que decidí llamar j_fn_ConfigWindowsVersion . Verá esta función invertida en la siguiente publicación. En pocas palabras, la función identifica la versión actual de Windows e inicializa una serie de variables de desplazamiento con información sobre algunas estructuras de kernel particulares. Si esta función no falla, la ejecución continúa:
C++:
Porfavor,
Acceder
o
Registrarse para ver el contenido de los códigos!
Vamos a ignorar fn_InitWeirdVariables_ y fn_InitWeirdVariables2_ , dado que esas funciones solo inicializan algunos spinlocks y variables extrañas que el controlador usa más adelante. No estamos interesados en eso por ahora. En realidad, si sabes lo que están haciendo en estas líneas, házmelo saber, porque no sé qué tipo de hechicería están lanzando (creo que es una forma de generar un GUID para cada proceso, pero quién sabe):
C++:
Porfavor,
Acceder
o
Registrarse para ver el contenido de los códigos!
Después de eso, se inicializan dos variables NTSTATUS : status_PsSetCreateProcessNotifyRoutine y status_PsSetCreateProcessNotifyRoutineEx. Vamos a ver que si falla el primer intento de registrar NotifyRoutine usando PsSetCreateProcessNotifyRoutineEx , van a usar estas variables para controlar el flujo de ejecución y hacer un segundo intento usando PsSetCreateProcessNotifyRoutineEx .
C++:
Porfavor,
Acceder
o
Registrarse para ver el contenido de los códigos!
La dirección de PsSetCreateProcessNotifyRoutineEx se recupera y se almacena en una variable. Si este valor variable no es NULL, se realiza el primer intento:
C++:
Porfavor,
Acceder
o
Registrarse para ver el contenido de los códigos!
Podemos ver que se llama a
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
. En el primer parámetro, envía la rutina ( fn_CreateProcessNotifyRoutineExImp ) para que se ejecute siempre que se cree o salga un nuevo proceso; y en el segundo parámetro, establece que la Rutina de notificación debe registrarse en lugar de eliminarse. Como puede ver, la misma función se utiliza para crear y eliminar una rutina de notificación.Avanzando un poco más en la función, si el primer intento falla, veremos que
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
se llama como un segundo intento:
C++:
Porfavor,
Acceder
o
Registrarse para ver el contenido de los códigos!
Nuevamente, hemos identificado otra de las rutinas de devolución de llamada: fn_CreateProcessNotifyRoutine.
fn_CreateProcessNotifyRoutine y fn_CreateProcessNotifyRoutineExImp
Si verificamos fn_CreateProcessNotifyRoutineExImp y fn_CreateProcessNotifyRoutine , notaremos que ambos son envoltorios de las rutinas reales:
C++:
Porfavor,
Acceder
o
Registrarse para ver el contenido de los códigos!
Los parámetros recibidos por
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
se explican en la
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
. En base a eso, podemos identificar cómo esta función decide si se invoca la devolución de llamada debido a que se está creando o eliminando un proceso.fn_Analyze_CreateProcessNotifyRoutine y fn_Analyze_ExitProcessNotifyRoutine son grandes funciones que analizaremos más adelante
Volver a fn_InitRegistrationNotifyAndCallbackRoutines
Finalmente, se intenta el último registro de devolución de llamada:
C++:
Porfavor,
Acceder
o
Registrarse para ver el contenido de los códigos!
Sin embargo, como puede ver, si registerCallbackFunction falló, la NotifyRoutine creada anteriormente debe eliminarse antes de salir. En ese caso, establecen _RemoveRoutine en 1 y luego vuelven a llamar a PsSetCreateProcessNotifyRoutine para eliminarlo.
fn_RegisterCallbackFunction se revertirá en las siguientes publicaciones, así como en las otras dos funciones.
Próximos pasos
- Parte 4.2 - Administrar versiones de ventanas
- Parte 4.3 - Uso de ObRegisterCallbacks
- Parte 4.4 - Análisis de las rutinas de notificación
Niemad
Enlace origen
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!