ClientHook (Hook)

Что это такое:

Функции которые client.dll передаёт процессу half-life. В разных модах half-life, в разных версиях CS, под разными анти-читами бывают разные способы их получения. По сути дела имея все client.dll функции, можно сделать всё что-угодно, открывается доступ ко всем игровым функциям. Я рассмотрю несколько стандартных способов их получения.

 

Вариант 1:

Инжектируемый хак -> IATHook на GetProcessAddress -> в нём можно получить все функции напрямую.

Но, есть одна проблема: из-за постоянно обновляющихся игровых версий иногда возникают проблемы с этим. Например - в Counter-Strike версий 1.5 ниже, эти функции передавались прямым длл-экспортом.

В CS 1.6 до начала 2009 года, client.dll по сути не была полноценной dll и единственная функция которая передавалась была HUD_GetStudioModelInterface. Ниже приведу код (by h1web), который позволял получить таблицу экспорта (за исключением функций, которые инициализировались перед HUD_GetStudioModelInteface один раз - больше не вызывались)

Code:
DWORD	ExportTable;
ExportTable_t	* pExportTable = NULL;
ExportTable_t oExportTable; // Таблица экспорта typedef struct ExportTable_s
{
int(*Initialize)(cl_enginefunc_t *, int);
int(*HUD_Init)(void);
int(*HUD_VidInit)(void);
void(*HUD_Redraw)(float, int);
void(*HUD_UpdateClientData)(client_data_t*, float);
int(*HUD_Reset)(void);
void(*HUD_PlayerMove)(struct playermove_s*, int);
void(*HUD_PlayerMoveInit)(struct playermove_s*);
char(*HUD_PlayerMoveTexture)(char *);
void(*IN_ActivateMouse)(void);
void(*IN_DeactivateMouse)(void);
void(*IN_MouseEvent)(int mstate);
void(*IN_ClearStates)(void);
void(*IN_Accumulate)(void);
void(*CL_CreateMove)(float, struct usercmd_s*, int);
int(*CL_IsThirdPerson)(void);
void(*CL_CameraOffset)(float *);
struct kbutton_s *(*KB_Find)(const char*);
void(*CAM_Think)(void);
void(*V_CalcRefdef)(struct ref_params_s *pparams);
int(*HUD_AddEntity)(int, struct cl_entity_s *, const char *);
void(*HUD_CreateEntities)(void);
void(*HUD_DrawNormalTriangles)(void);
void(*HUD_DrawTransparentTriangles)();
void(*HUD_StudioEvent)(const struct mstudioevent_s *, const struct cl_entity_s *);
void(*HUD_PostRunCmd)(struct local_state_s*, struct local_state_s*, struct usercmd_s*, int, double, unsigned int);
void(*HUD_Shutdown)(void);
void(*HUD_TxferLocalOverrides)(struct entity_state_s *, const struct clientdata_s *);
void(*HUD_ProcessPlayerState)(struct entity_state_s *, const struct entity_state_s *);
void(*HUD_TxferPredictionData)(struct entity_state_s *, const struct entity_state_s *, struct clientdata_s *, const struct clientdata_s *, struct weapon_data_s *, const struct weapon_data_s *);
void(*Demo_ReadBuffer)(int, unsigned char *);
int(*HUD_ConnectionlessPacket)(struct netadr_s*, const char*, char*, int*);
int(*HUD_GetHullBounds)(int, float*, float*);
void(*HUD_Frame)(double time);
int(*HUD_Key_Event)(int, int, const char *);
void(*HUD_TempEntUpdate)(double, double, double, struct tempent_s **, struct tempent_s **, int(*Callback_AddVisibleEntity)(struct cl_entity_s*), void(*Callback_TempEntPlaySound)(struct tempent_s *pTemp, float damp );
struct cl_entity_s *(*HUD_GetUserEntity)(int index);
void (*HUD_VoiceStatus)(int entindex, qboolean bTalking);
int (*HUD_DirectorMessage) (unsigned char, unsigned int, unsigned int, unsigned int);
int (*HUD_GetStudioModelInterface)(int, struct r_studio_interface_s**, struct engine_studio_api_s*);
int (*HUD_ChatInputPosition)( int *x, int *y );
int (*HUD_GetPlayerTeam)(int index);
// void (*ClientFactory)(void);
} ExportTable_t; // Наша функция void MyHUD_Redraw(float x, int y) { oExportTable.HUD_Redraw(x,y); } // В GetProcessAddress if (!strcmp(lpProcName, "HUD_GetStudioModelInterface")) { char* pRetAddress = (char*)_ReturnAddress(); pRetAddress++; ExportTable = (*(PDWORD)(pRetAddress))-0x9C; CreateThread(0,0,(LPTHREAD_START_ROUTINE)&ClientHook,(void*)ExportTable,0,0); } // Hook void ClientHook(DWORD ExportTable)
{
pExportTable = (ExportTable_t*)ExportTable;
memcpy(&oExportTable, pExportTable, sizeof(ExportTable_t));

pExportTable->HUD_Redraw = &MyHUD_Redraw;

}

 

Точно-также проделываем со всеми нужными функциями. Ещё раз повторю: функцию Initialize например, вы не сможете хукнуть таким образом.

Хорошо, этот способ на данный момент подходит для автоматического ClientHook'а на NoSteam CS 1.6, с версией патча > 36 (Может и больше.. я непомню когда точно произошёл тот апдейт).

На стим можно без проблем получать все функции через GetProcessAddress напрямую.

 

Статья неполная, возможно будет дополнена.

Copyright (c) Troll

Hosted by uCoz