Publicación rápida para analizar una función particular donde el controlador XC3 administra las diferentes versiones de Windows y brinda soporte a cada una de ellas.
Introducción
Como ya sabrá, en Windows, los desplazamientos dentro de la estructura del kernel diferente pueden cambiar de una versión a la siguiente.
Las estructuras críticas del núcleo como EPROCESS, KTHREAD, etc., tienen mucha información sobre sus atributos. Los Anti-Cheats generalmente acceden a esa información para verificar manualmente la información sobre procesos, sistema y memoria por su cuenta, sin la necesidad de usar la API de Windows.
Si este controlador está siendo utilizado por cientos de miles de usuarios, deben determinar correctamente las compensaciones correctas de cada atributo al que desean acceder para cada versión. Y esta función inicializa algunas variables, que luego son utilizadas por el resto de las funciones.
Publicaciones anteriores
j_fn_ConfigWindowsVersion (0x 140003C38)
Vale la pena mencionar que solo proporcionaré algunos ejemplos de las compensaciones que están administrando. Identificar cada uno de ellos lleva mucho tiempo y te dejo esa parte como tarea. 😉 Los que he identificado, se han utilizado en otras funciones que invertí manualmente antes.
Esta función es básicamente un salto a la implementación real:
Si echamos un vistazo a sub_14000646C, notaremos que la función básicamente está obteniendo la versión actual del sistema operativo. Luego, basándose en la versión mayor y menor, y el número de compilación, inicializan un grupo de variables globales.
Según la documentación,
Se están inicializando una serie de 8 variables globales con punteros de función que recuperan algún desplazamiento particular de diferentes estructuras.
Centrémonos en un caso: qword_14000CDF0 se está inicializando con off_140009BA0 , que contiene una referencia a otra función:
Podemos ver cómo la función toma el valor de rcx (primer parámetro) y agrega 0x418 :
Aquí es donde las cosas se ponen más difíciles. Para identificar qué estructura es la que se envía a través de RCX, necesitamos encontrar un caso en el que se esté usando qword_14000CDF0 :
Para resumir y evitar que las cosas sean aún más complejas, vamos a terminar con el siguiente caso (por supuesto, después de cambiar el nombre y algunos análisis):
fn_GetObjectTable es nuestra función qword_14000CDF0 , y esta será la pista que nos dirá que la función EPROCESS es la que se envía como parámetro. Tenga en cuenta que
El desplazamiento 0x418 pertenece al atributo ObjectTable , un puntero a la estructura _HANDLE_TABLE dentro del núcleo.
Nota al margen
ObjectTable se usa mucho para enumerar y analizar manualmente los MANEJOS de un proceso. Los AC usualmente toman esta tabla y acceden a cada identificador existente para determinar si otros procesos tienen un MANGO para el proceso del juego; o si el MANGO del proceso como lsass.exe o csrss.exe ha sido manipulado.
Próximos pasos
Niemand
Enlace origen
Twitter
Introducción
Como ya sabrá, en Windows, los desplazamientos dentro de la estructura del kernel diferente pueden cambiar de una versión a la siguiente.
Las estructuras críticas del núcleo como EPROCESS, KTHREAD, etc., tienen mucha información sobre sus atributos. Los Anti-Cheats generalmente acceden a esa información para verificar manualmente la información sobre procesos, sistema y memoria por su cuenta, sin la necesidad de usar la API de Windows.
Si este controlador está siendo utilizado por cientos de miles de usuarios, deben determinar correctamente las compensaciones correctas de cada atributo al que desean acceder para cada versión. Y esta función inicializa algunas variables, que luego son utilizadas por el resto de las funciones.
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)
- Parte 4.1 - Registro de rutinas de notificación y devolución de llamada
- Cómo los controladores de este tipo admiten versiones múltiples de Windows
- Cómo se mantienen las compensaciones codificadas utilizadas para acceder a las estructuras del núcleo.
- Identificar las estructuras del núcleo que se utilizan.

j_fn_ConfigWindowsVersion (0x 140003C38)
Vale la pena mencionar que solo proporcionaré algunos ejemplos de las compensaciones que están administrando. Identificar cada uno de ellos lleva mucho tiempo y te dejo esa parte como tarea. 😉 Los que he identificado, se han utilizado en otras funciones que invertí manualmente antes.
Esta función es básicamente un salto a la implementación real:
C++:
Porfavor,
Acceder
o
Registrarse para ver el contenido de los códigos!
Si echamos un vistazo a sub_14000646C, notaremos que la función básicamente está obteniendo la versión actual del sistema operativo. Luego, basándose en la versión mayor y menor, y el número de compilación, inicializan un grupo de variables globales.
C++:
Porfavor,
Acceder
o
Registrarse para ver el contenido de los códigos!
Según la documentación,
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
devuelve las
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
Major, minor y build en el primer, segundo y tercer parámetro, respectivamente. Lo que sucede más adelante es una serie de "si y más", donde determinan la versión exacta y el número de compilación:
C++:
Porfavor,
Acceder
o
Registrarse para ver el contenido de los códigos!
Se están inicializando una serie de 8 variables globales con punteros de función que recuperan algún desplazamiento particular de diferentes estructuras.
Centrémonos en un caso: qword_14000CDF0 se está inicializando con off_140009BA0 , que contiene una referencia a otra función:
C++:
Porfavor,
Acceder
o
Registrarse para ver el contenido de los códigos!
Podemos ver cómo la función toma el valor de rcx (primer parámetro) y agrega 0x418 :
C++:
Porfavor,
Acceder
o
Registrarse para ver el contenido de los códigos!
Aquí es donde las cosas se ponen más difíciles. Para identificar qué estructura es la que se envía a través de RCX, necesitamos encontrar un caso en el que se esté usando qword_14000CDF0 :

Para resumir y evitar que las cosas sean aún más complejas, vamos a terminar con el siguiente caso (por supuesto, después de cambiar el nombre y algunos análisis):
C++:
Porfavor,
Acceder
o
Registrarse para ver el contenido de los códigos!
fn_GetObjectTable es nuestra función qword_14000CDF0 , y esta será la pista que nos dirá que la función EPROCESS es la que se envía como parámetro. Tenga en cuenta que
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
se llama antes y el segundo parámetro se usa para almacenar la estructura EPROCESS , como explica la documentación.El desplazamiento 0x418 pertenece al atributo ObjectTable , un puntero a la estructura _HANDLE_TABLE dentro del núcleo.
Nota al margen
ObjectTable se usa mucho para enumerar y analizar manualmente los MANEJOS de un proceso. Los AC usualmente toman esta tabla y acceden a cada identificador existente para determinar si otros procesos tienen un MANGO para el proceso del juego; o si el MANGO del proceso como lsass.exe o csrss.exe ha sido manipulado.
Próximos pasos
- Parte 4.3 - Uso de ObRegisterCallbacks
- Parte 4.4 - Análisis de las rutinas de notificación
Niemand
Enlace origen
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!
Porfavor,
Acceder
o
Registrarse
para ver el contenido de las URL!