Interceptar con Detours el Opengl Nativo por TEB

Link Original:
http://foro.elhacker.net/programacion_cc/interceptar_con_detours_el_opengl_nativo_por_teb-t387622.0.html

Primero que nada quiero decir que voy a postear el código fuente público de un hack de karman, llamado Inexinferis FX de finales del 2010.
Es un código ya publicado sólo que no se observa demasiado por internet XD

Lo posteo porque es parte de los métodos que se estaban comentando en el foro últimamente, y se trata de utilizar ‘detours’ pero a un nivel más profundo que el que ofrece Openg32.dll, siendo Opengl32.dll el nivel más alto y el driver de la tarjeta gráfica lo más bajo.Intermediamente se tiene otra DLL de relacionada con Opengl32 pero perteneciente a la firma de la tarjeta gráfica, pero el tema es que hay muchas marcas de tarjetas gráficas y por lo tanto muchos drivers. Por lo que cada uno sabe lo que tiene XD

Esta es la información que se necesita manejar para poder entender como se determinan las direcciones de bajo nivel para Opengl por medio de lo que se llama TEB (Thread Environment Block), también conocido como TIB (Thread Information Block) por algunos, aunque otros insisten en que el TIB es miembro del TEB (Ver link de undocumented.ntinternals.net).
http://es.wikipedia.org/wiki/Win32_Thread_Information_Block
http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Thread/TEB.html

Otros links
http://www.snoxd.net/index.php/topic/377-finding-the-thread-id-from-the-executable-name/
http://www.alex-ionescu.com/part1.pdf
http://www.ciphermonk.net/teb.php
http://nasutechtips.blogspot.com.ar/2011/01/thread-information-block-tib-and-fs.html
http://skypher.com/wiki/index.php/Hacking/Windows_internals/Process/Memory/TEB
http://stackoverflow.com/questions/9964236/tib-access-in-win32
http://software.intel.com/sites/products/documentation/doclib/stdxe/2013composerxe/compiler/cpp-win/GUID-F90BD123-AE25-4DC2-ADFB-B59067E77728.htm

Otros links que se pueden tomar en cuenta
http://www.nynaeve.net/?p=180
http://msdn.microsoft.com/es-ar/library/6yh4a9k1.aspx
http://msdn.microsoft.com/en-us/library/6yh4a9k1.aspx
http://msdn.microsoft.com/es-ar/library/y6h8hye8.aspx
http://msdn.microsoft.com/es-ar/library/2s9wt68x.aspx

En Opengl32.DLL básicamente se encuentran funciones que sólo hacen saltos hacia el nivel más bajo de Opengl, y para obtener las direcciones correctas del driver, se hace con este método del TEB.

Este es el ejemplo de glBegin

Pos: FS:[0x18]      Len: 4   Ver: Win9x y NT   -> Dirección lineal del TIB

con esos parámetros se consigue hacer un salto hacia el nivel bajo del que hablábamos (nvoglnt.dll en mi caso que tengo una tarjeta NVIDIA)

Luego hace otro salto hacia la función en sí.
Con OllyDBG se puede observar el estado de los registros para tener una mejor idea de como se obtienen las direcciones.
Mejor aún, para aquellos que prefieren leer una buena explicación les dejo este manual al respecto:
http://www.mediafire.com/?kmru385gmmcik46

//

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma comment(lib,"OpenGL32.lib")
#pragma comment(lib, "Version.lib")
#define _WIN32_WINNT 0x0500
#undef UNICODE
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <shlwapi.h>
#include <stdio.h>

#include "nt.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

HANDLE hThread=NULL;
PBYTE dwFSBase,dwFSBase2;

HWND hdHalfLife;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

typedef void (APIENTRY* glBlendFunc_t)(GLenum,GLenum);
typedef void (APIENTRY* glClear_t)(GLbitfield);
typedef void (APIENTRY* glVertex2f_t)(GLfloat,GLfloat);
typedef void (APIENTRY* glVertex3f_t)(GLfloat,GLfloat,GLfloat);
typedef void (APIENTRY* glVertex3fv_t)(const GLfloat*);
typedef void (APIENTRY* glBegin_t)(GLenum);
glBlendFunc_t pglBlendFunc=0;
glClear_t pglClear=0;
glVertex2f_t pglVertex2f=0;
glVertex3f_t pglVertex3f=0;
glVertex3fv_t pglVertex3fv=0;
glBegin_t pglBegin=0;

BOOL bFlash=FALSE;
BOOL bSky=FALSE;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void APIENTRY New_glBegin(GLenum mode){

if(mode==GL_TRIANGLE_STRIP||mode==GL_TRIANGLE_FAN)
glDisable(GL_DEPTH_TEST);
else if(mode!=GL_QUADS&&mode!=GL_LINES)
glEnable(GL_DEPTH_TEST);

if(mode==GL_QUADS){
float col[4];
glGetFloatv(GL_CURRENT_COLOR, col);
bFlash=(col[0]==1.0&&col[1]==1.0&&col[2]==1.0&&col[3]>0.2);
bSky=TRUE;
}
else
bSky=FALSE;
pglBegin(mode);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void APIENTRY New_glClear(GLbitfield mask){

if(mask==GL_DEPTH_BUFFER_BIT){
mask+=GL_COLOR_BUFFER_BIT;
glClearColor(0.0f,0.0f,0.0f,0.0f);
}
pglClear(mask);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void APIENTRY New_glVertex3fv(const GLfloat* v){

if(bSky) return;
pglVertex3fv(v);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void APIENTRY New_glVertex2f(GLfloat x, GLfloat y){

if(bFlash&&x==0.0&&y==0.0) glColor4f(1.0f,1.0f,1.0f,0.2f);
pglVertex2f(x,y);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void APIENTRY New_glVertex3f(GLfloat x, GLfloat y, GLfloat z){

glColor3f(1.0f,1.0f,1.0f);
pglVertex3f(x,y,z);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

BOOL GetDllVersion(HMODULE hLibModule, DLLVERSIONINFO* aVersion){

CHAR fileName[MAX_PATH];
UINT len=0;
VS_FIXEDFILEINFO* vsfi=NULL;
DWORD handle=0;
DWORD size=GetModuleFileName(hLibModule,fileName,MAX_PATH);
fileName[size]=0;
size=GetFileVersionInfoSize(fileName, &handle);
BYTE* versionInfo=new BYTE[size];
if(!GetFileVersionInfo(fileName,handle,size,versionInfo)){
delete[] versionInfo;
return FALSE;
}
VerQueryValue(versionInfo,"\\",(PVOID*)&vsfi,&len);
aVersion->dwMajorVersion=HIWORD(vsfi->dwFileVersionMS);
aVersion->dwMinorVersion=LOWORD(vsfi->dwFileVersionMS);
aVersion->dwBuildNumber=HIWORD(vsfi->dwFileVersionLS);
aVersion->dwPlatformID=LOWORD(vsfi->dwFileVersionLS);
delete[] versionInfo;
return TRUE;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void* Detour1(BYTE* src, const BYTE* dst, const int len){
BYTE* jmp = (BYTE*)malloc(len+5);
DWORD dwback;
while(!VirtualProtect(src, len, PAGE_READWRITE, &dwback));
memcpy(jmp, src, len);jmp+=len;
jmp[0] = 0xE9;
*(DWORD*)(jmp+1)=(DWORD)(src+len-jmp)-5;
src[0] = 0xE9;
*(DWORD*)(src+1)=(DWORD)(dst-src)-5;
while(!VirtualProtect(src, len, dwback, &dwback));
return (jmp-len);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*
DWORD GetProcessThreadId(unsigned long ProcessId)
{
HANDLE hSnapThread = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, ProcessId);
if(hSnapThread == INVALID_HANDLE_VALUE) return NULL;
THREADENTRY32 te;
te.dwSize = sizeof(THREADENTRY32);
if(Thread32First(hSnapThread, &te))
{
do
{
if(te.th32OwnerProcessID == ProcessId) {
CloseHandle(hSnapThread);
return te.th32ThreadID;
}

} while(Thread32Next(hSnapThread, &te));
}
CloseHandle(hSnapThread);
return 0;
}*/

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

DWORD WINAPI Thread(LPVOID lpParam){

DWORD dwThreadId,dwProcessId,dwOGLOffset;
CONTEXT Context;
LDT_ENTRY SelEntry;
HMODULE hModule;
Context.ContextFlags=CONTEXT_FULL|CONTEXT_DEBUG_REGISTERS;
DWORD dwTLSIndex=0;
DLLVERSIONINFO oglVersion;

while(((hdHalfLife=FindWindow("Valve001",NULL))==NULL)
&&((hdHalfLife=FindWindow(NULL,"Counter-Strike"))==NULL))
Sleep(100);

while((hModule=GetModuleHandle("Opengl32.dll"))==NULL)
Sleep(100);

if(GetDllVersion(hModule,&oglVersion)){

if(oglVersion.dwMajorVersion==5&&oglVersion.dwMinorVersion==1){
dwTLSIndex=0xAC80C;
}
else if(oglVersion.dwMajorVersion==6&&oglVersion.dwMinorVersion==0){
dwTLSIndex=0xAB958;
}
else if(oglVersion.dwMajorVersion==6&&oglVersion.dwMinorVersion==1){
dwTLSIndex=0xA100C;
}
else
{
//MessageBox(hdHalfLife,"Incompatible OpenGL Version...\n\nSorry man...","Inexinferis FX Series - Karman",0);
ExitThread(0);
return 0;
}
}
else
{
//MessageBox(hdHalfLife,"Can't Get OpenGL Version...\n\nWrong OpenGL???","Inexinferis FX Series - Karman",0);
ExitThread(0);
return 0;
}

//DWORD ProcessId = GetCurrentProcessId();
//DWORD ProcessThreadId = GetProcessThreadId(ProcessId);
dwThreadId=GetWindowThreadProcessId(hdHalfLife,&dwProcessId);
HANDLE hThread=OpenThread(THREAD_GET_CONTEXT|THREAD_SUSPEND_RESUME|THREAD_QUERY_INFORMATION,FALSE,dwThreadId);

if(!hThread){
//MessageBox(hdHalfLife,"Couldn't Get Proccess Info...\n\nAntivirus???","Inexinferis FX Series - Karman",0);
CloseHandle(hThread);
ExitThread(0);
return 0;
}

GetThreadContext(hThread,&Context);
GetThreadSelectorEntry(hThread, Context.SegFs, &SelEntry);
dwFSBase = (PBYTE)((SelEntry.HighWord.Bits.BaseHi<<24)|(SelEntry.HighWord.Bits.BaseMid<<16)|SelEntry.BaseLow);

if(!dwFSBase||IsBadReadPtr((PVOID)dwFSBase,sizeof(DWORD))){
//MessageBox(hdHalfLife,"Couldn't Get TEB From Opengl32.dll\n\nMake Sure that you are Running the Game in OpenGl Mode...","Inexinferis FX Series - Karman",0);
CloseHandle(hThread);
ExitThread(0);
return 0;
}

dwOGLOffset=((DWORD)hModule)+dwTLSIndex;
if(!dwTLSIndex||IsBadReadPtr((PVOID)dwOGLOffset,sizeof(DWORD))){
//MessageBox(hdHalfLife,"Couldn't Read From Opengl32.dll Address\n\nMaybe your OpenGL driver is not compatible...","Inexinferis FX Series - Karman",0);
CloseHandle(hThread);
ExitThread(0);
return 0;
}
//multiple redirect...
do{
Sleep(10);
dwFSBase2=(PBYTE)(*(PDWORD)((DWORD)dwFSBase+(*(PDWORD)dwOGLOffset)));
}while(dwFSBase2==NULL);

/*
dwFSBase2=(PBYTE)(*(PDWORD)((DWORD)dwFSBase+(*(PDWORD)0x5F1CC80C)));
if(!dwFSBase2){
CloseHandle(hThread);
ExitThread(0);
return 0;
}*/

//MessageBox(hdHalfLife,"http://www.inexinferis.com.ar/foro","Inexinferis FX Series - Karman",0);
SuspendThread(hThread);

////////
// Hooks

// 0x01D46862 opengl32.glClear [EAX+32C] -> 0x69609A20 [12]
pglClear= (glClear_t)Detour1((PBYTE)(*(PDWORD)(dwFSBase2+0x32C)),(PBYTE)New_glClear,12);

// 0x01D3CF1D opengl32.glVertex2f [EAX+92C] -> 0x69606320 [12]
pglVertex2f= (glVertex2f_t)Detour1((PBYTE)(*(PDWORD)(dwFSBase+0x92C)),(PBYTE)New_glVertex2f,12);

pglVertex3f= (glVertex3f_t)Detour1((PBYTE)(*(PDWORD)(dwFSBase+0x94C)),(PBYTE)New_glVertex3f,12);

// 0x01D936C5 opengl32.glVertex3fv [EAX+950] -> 0x696073F0 [12]
pglVertex3fv= (glVertex3fv_t)Detour1((PBYTE)(*(PDWORD)(dwFSBase+0x950)),(PBYTE)New_glVertex3fv,12);

// 0x01D93681 opengl32.glBegin [EAX+7CC] -> 0x695FD250 [8]
pglBegin= (glBegin_t)Detour1((PBYTE)(*(PDWORD)(dwFSBase+0x7CC)),(PBYTE)New_glBegin, 8);

////////

ResumeThread(hThread);
CloseHandle(hThread);

ExitThread(0);
return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID lpvReserved){

if(fdwReason==DLL_PROCESS_ATTACH){

DisableThreadLibraryCalls(hInstance);
hThread=CreateThread(NULL,0,Thread,NULL,0,NULL);
}
return (TRUE);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

PROYECTO MS Visual C++ 2010 Express
http://www.mediafire.com/?yttdt8712ymvj2r

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: