miércoles, 20 de junio de 2012

Simple Anti-Inyector de Dlls

En estas últimas semanas estuve leyendo algunas de las protecciones que realizan algunos sistemas anticheats y me decidí probar algunas de dichas protecciones, en este caso evitar la inyección de cheats en Half-Life y sus mods derivados...

Ahora, bien sabemos que la mayoría de los cheats utilizan inyecciones que se realizan por hilo remoto. Los pasos para crear un hilo remoto son los siguientes:

  1. Encontrar y abrir el proceso (abrir el proceso con permisos)
  2. Almacenar memoria en el proceso para la dirección de la dll o código a ejecutar
  3. Escribir la dirección de la dll o rutina a ejecutar
  4. Crear un hilo remoto para que fuerze al programa ejecutar el código del hack
Como pensé que bloquear cada paso posible no sería muy complicado, cosa que tengo que admitir que me equivoqué (la razón fue porque varias cosas del sistema fallaban y en algunas ocasiones tuve resultados muy azules), decidí directamente bloquear directamente el último y más importante paso que es el que habilita el inicio de los cheats...

Entonces teniendo en cuenta lo leído acá:
http://foro.inexinferis.com/index.php?topic=6559.0

Lo que haremos será crear un driver que "hookée" la rutina NtCreateThread y detenga cualquier intento de crear un hilo desde otro programa hacia el juego:

(c):
NTSTATUS NTAPI HOOK_ZwCreateThread(OUT PHANDLE ThreadHandle,IN ACCESS_MASK DesiredAccess,   IN POBJECT_ATTRIBUTES ObjectAttributes,   IN HANDLE ProcessHandle,OUT PCLIENT_ID ClientId,   IN PCONTEXT ThreadContext,IN PUSER_STACK UserStack,   IN BOOLEAN CreateSuspended) { NTSTATUS lStatus; CHAR CurFileName[MAX_PATH]={0},ProcFileName[MAX_PATH]={0}; HANDLE CurrentPID=PsGetCurrentProcessId(); HANDLE ProcessHandleId=(HANDLE)GetProcessIdByHandle(ProcessHandle); PEPROCESS EProc;   lStatus=PsLookupProcessByProcessId(CurrentPID,&EProc); if(lStatus==STATUS_SUCCESS) { ImageFileName(EProc,CurFileName); ObDereferenceObject(EProc); } lStatus=PsLookupProcessByProcessId(ProcessHandleId,&EProc); if(lStatus==STATUS_SUCCESS) { ImageFileName(EProc,ProcFileName); ObDereferenceObject(EProc); }   if(!strcmp(_strlwr(ProcFileName),"hl.exe")) { if(CurrentPID==ProcessHandleId || !strcmp(_strlwr(CurFileName),"explorer.exe")) return pZwCreateThread(ThreadHandle,DesiredAccess,ObjectAttributes, ProcessHandle,ClientId,ThreadContext,UserStack, CreateSuspended); else { DbgPrint("%s tried to create a remote thread in the game... ACCESS DENIED!!!\n",CurFileName); return STATUS_UNSUCCESSFUL; } } return pZwCreateThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle, ClientId,ThreadContext,UserStack,CreateSuspended); }

Este es un código muy simple, estoy seguro que se pueden bloquear mejor y de muchas otras formas las inyecciones...

El proyecto tanto el código fuente completo y los binarios de prueba se puede encontrar en el siguiente link:
DESCARGA

El código fue liberado bajo la GPL v3


B#

2 comentarios:

  1. se podría inyectar una dll en el explorer que inyecte la dll... (ups, dije algo que el sxe no controla)

    ResponderEliminar
    Respuestas
    1. si esa fue una dificultad que tuve al hacer este driver de ejemplo, hay que poner el explorer como excepción y controlar que ningún programa externo te lo toque tambien... (sería lo ideal)

      PD: si no me equivoco a los turcos se les escaparon ese detalle tmb en su foro cuando hablaban de uno de sus cheats xD


      B#

      Eliminar