diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae53b3b --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +.vs +*.suo +*.sdf +*.opensdf +*.obj +*.pdb +*.idb +*.ilk +*.log +*.tlog +*.txt +*.db diff --git a/Release/blackhat.dll b/Release/blackhat.dll new file mode 100644 index 0000000..7da0dd3 Binary files /dev/null and b/Release/blackhat.dll differ diff --git a/Release/blackhat.exp b/Release/blackhat.exp new file mode 100644 index 0000000..8b29d60 Binary files /dev/null and b/Release/blackhat.exp differ diff --git a/Release/blackhat.iobj b/Release/blackhat.iobj new file mode 100644 index 0000000..1e675e4 Binary files /dev/null and b/Release/blackhat.iobj differ diff --git a/Release/blackhat.ipdb b/Release/blackhat.ipdb new file mode 100644 index 0000000..73420ee Binary files /dev/null and b/Release/blackhat.ipdb differ diff --git a/Release/blackhat.lib b/Release/blackhat.lib new file mode 100644 index 0000000..7e5fcc9 Binary files /dev/null and b/Release/blackhat.lib differ diff --git a/Release/hook.lib b/Release/hook.lib new file mode 100644 index 0000000..7db98e6 Binary files /dev/null and b/Release/hook.lib differ diff --git a/Release/injector.exe b/Release/injector.exe new file mode 100644 index 0000000..756995b Binary files /dev/null and b/Release/injector.exe differ diff --git a/Release/injector.iobj b/Release/injector.iobj new file mode 100644 index 0000000..2e06746 Binary files /dev/null and b/Release/injector.iobj differ diff --git a/Release/injector.ipdb b/Release/injector.ipdb new file mode 100644 index 0000000..08339c0 Binary files /dev/null and b/Release/injector.ipdb differ diff --git a/blackhat.sln b/blackhat.sln new file mode 100644 index 0000000..96153d8 --- /dev/null +++ b/blackhat.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "injector", "injector\injector.vcxproj", "{32828B4A-428F-457D-93AF-BD201D83E83A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hook", "hook\hook.vcxproj", "{2B541B0D-E176-4BB6-A434-653D8770F2B2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blackhat", "blackhat\blackhat.vcxproj", "{0D098609-0DD3-4849-B6A9-264BDEB14861}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {32828B4A-428F-457D-93AF-BD201D83E83A}.Debug|Win32.ActiveCfg = Debug|Win32 + {32828B4A-428F-457D-93AF-BD201D83E83A}.Debug|Win32.Build.0 = Debug|Win32 + {32828B4A-428F-457D-93AF-BD201D83E83A}.Release|Win32.ActiveCfg = Release|Win32 + {32828B4A-428F-457D-93AF-BD201D83E83A}.Release|Win32.Build.0 = Release|Win32 + {2B541B0D-E176-4BB6-A434-653D8770F2B2}.Debug|Win32.ActiveCfg = Debug|Win32 + {2B541B0D-E176-4BB6-A434-653D8770F2B2}.Debug|Win32.Build.0 = Debug|Win32 + {2B541B0D-E176-4BB6-A434-653D8770F2B2}.Release|Win32.ActiveCfg = Release|Win32 + {2B541B0D-E176-4BB6-A434-653D8770F2B2}.Release|Win32.Build.0 = Release|Win32 + {0D098609-0DD3-4849-B6A9-264BDEB14861}.Debug|Win32.ActiveCfg = Debug|Win32 + {0D098609-0DD3-4849-B6A9-264BDEB14861}.Debug|Win32.Build.0 = Debug|Win32 + {0D098609-0DD3-4849-B6A9-264BDEB14861}.Release|Win32.ActiveCfg = Release|Win32 + {0D098609-0DD3-4849-B6A9-264BDEB14861}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/blackhat/Release/blackhat.dll.recipe b/blackhat/Release/blackhat.dll.recipe new file mode 100644 index 0000000..56ef31c --- /dev/null +++ b/blackhat/Release/blackhat.dll.recipe @@ -0,0 +1,11 @@ + + + + + D:\blackhat\Release\blackhat.dll + + + + + + \ No newline at end of file diff --git a/blackhat/blackhat.vcxproj b/blackhat/blackhat.vcxproj new file mode 100644 index 0000000..3d73a42 --- /dev/null +++ b/blackhat/blackhat.vcxproj @@ -0,0 +1,92 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {0D098609-0DD3-4849-B6A9-264BDEB14861} + blackhat + 10.0 + + + + Application + true + v142 + MultiByte + + + DynamicLibrary + false + v142 + true + MultiByte + + + + + + + + + + + + + $(DXSDK_DIR)Include;$(IncludePath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + + + + Level3 + Disabled + true + + + true + + + + + Level3 + MaxSpeed + true + true + true + ..\..\source2013\mp\src\common;..\..\source2013\mp\src\public;..\..\source2013\mp\src\public\tier0;..\..\source2013\mp\src\public\tier1;..\..\source2013\mp\src\public\tier2;..\..\source2013\mp\src\public\mathlib;..\..\source2013\mp\src\public\vstdlib;..\..\source2013\mp\src\game\shared;..\..\source2013\mp\src\game\client;..\hook\;%(AdditionalIncludeDirectories) + CLIENT_DLL;%(PreprocessorDefinitions) + + + true + true + true + ..\Release;..\..\source2013\mp\src\lib\public;%(AdditionalLibraryDirectories) + legacy_stdio_definitions.lib;hook.lib;tier0.lib;tier1.lib;tier2.lib;mathlib.lib;vstdlib.lib;d3d9.lib;d3dx9.lib;%(AdditionalDependencies) + LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/blackhat/blackhat.vcxproj.filters b/blackhat/blackhat.vcxproj.filters new file mode 100644 index 0000000..cf4c76a --- /dev/null +++ b/blackhat/blackhat.vcxproj.filters @@ -0,0 +1,51 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/blackhat/blackhat.vcxproj.user b/blackhat/blackhat.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/blackhat/blackhat.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/blackhat/draw.cpp b/blackhat/draw.cpp new file mode 100644 index 0000000..aeaa737 --- /dev/null +++ b/blackhat/draw.cpp @@ -0,0 +1,116 @@ +#include "draw.h" +#include +#include +#include +#include + +Draw* g_pDraw = NULL; + +void __stdcall EndScene_Hook(IDirect3DDevice9* pDevice) +{ + g_pDraw->Render(pDevice); +} + +Draw::Draw() + : m_pRenderClk(NULL) +{ +} + +void Draw::Init() +{ + g_pDraw = this; + m_pDevice = NULL; + + HMODULE hD3D9 = GetModuleHandle("d3d9.dll"); + LPVOID pEndScene = (char*)hD3D9 + ENDSCENE_OFFSET; + + m_EndScene.set(Hook::HookFunction(pEndScene, EndScene_Hook, &m_pHook)); +} + +void Draw::Exit() +{ + m_pHook->DoUnHook(); + + m_pLine->Release(); + m_pFont->Release(); +} + +void Draw::InitDirectX() +{ + D3DXCreateLine(m_pDevice, &m_pLine); + D3DXCreateFontA(m_pDevice, DRAW_FONT_SIZE, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, + OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, + DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), + &m_pFont); +} + +void Draw::SetRenderCallback(IRenderCallback* pClk) +{ + m_pRenderClk = pClk; +} + +void Draw::Render(IDirect3DDevice9* pDevice) +{ + if (!m_pDevice) + { + m_pDevice = pDevice; + InitDirectX(); + } + + m_iPrintY = PRINT_START_Y; + + if (m_pRenderClk) + m_pRenderClk->Render(pDevice); + m_EndScene.get()(pDevice); +} + +void Draw::DrawLines(D3DXVECTOR2* points, int nPoints, D3DCOLOR color) +{ + m_pLine->Begin(); + m_pLine->Draw(points, nPoints, color); + m_pLine->End(); +} + +void Draw::DrawLine(int x1, int y1, int x2, int y2, D3DCOLOR color) +{ + D3DXVECTOR2 points[2]; + + points[0] = D3DXVECTOR2((float)x1,(float)y1); + points[1] = D3DXVECTOR2((float)x2, (float)y2); + + DrawLines(points, 2, color); +} + +void Draw::GetFontDrawRect(LPRECT pRect, int x, int y, unsigned int nChars) +{ + SetRect(pRect, x, y, x + nChars * 32, y + DRAW_FONT_SIZE * 2); +} + +void Draw::DrawTextA(int x, int y, const char* pText, D3DCOLOR color) +{ + RECT rect; + INT nLen = strlen(pText); + GetFontDrawRect(&rect, x, y, (unsigned int)nLen); + m_pFont->DrawTextA(NULL, pText, nLen, &rect, DT_LEFT | DT_TOP, color); +} + +void Draw::DrawTextW(int x, int y, const wchar_t* pText, D3DCOLOR color) +{ + RECT rect; + INT nLen = wcslen(pText); + GetFontDrawRect(&rect, x, y, (unsigned int)nLen); + m_pFont->DrawTextW(NULL, pText, nLen, &rect, DT_LEFT | DT_TOP, color); +} + +void Draw::Print(const char* pFmt, ...) +{ + char szLine[256]; + va_list ap; + + va_start(ap, pFmt); + vsnprintf_s(szLine, sizeof(szLine), pFmt, ap); + va_end(ap); + + DrawTextA(PRINT_START_X, m_iPrintY, szLine, PRINT_COLOR); + m_iPrintY += DRAW_FONT_SIZE + 2; +} \ No newline at end of file diff --git a/blackhat/draw.h b/blackhat/draw.h new file mode 100644 index 0000000..aa200c6 --- /dev/null +++ b/blackhat/draw.h @@ -0,0 +1,59 @@ +#ifndef __DRAW_H +#define __DRAW_H + +#include +#include +#include "hook.h" + +#define DRAW_FONT_SIZE 16 + +#define PRINT_START_X 2 +#define PRINT_START_Y 32 +#define PRINT_COLOR D3DCOLOR_RGBA(0,255,0,255) + +#define ENDSCENE_OFFSET 0x2279F + +class IRenderCallback +{ +public: + virtual void Render(IDirect3DDevice9* pDevice) = 0; +}; + +class Draw : public IRenderCallback +{ +public: + Draw(); + + void Init(); + void Exit(); + + void InitDirectX(); + + void SetRenderCallback(IRenderCallback* pClk); + virtual void Render(IDirect3DDevice9* pDevice); + + void DrawLines(D3DXVECTOR2* points, int nPoints, D3DCOLOR color); + void DrawLine(int x1, int y1, int x2, int y2, D3DCOLOR color); + + void GetFontDrawRect(LPRECT pRect, int x, int y, unsigned int nChars); + + void DrawTextA(int x, int y, const char* pText, D3DCOLOR color); + void DrawTextW(int x, int y, const wchar_t* pText, D3DCOLOR color); + + void Print(const char* pFmt, ...); +private: + IDirect3DDevice9* m_pDevice; + IRenderCallback* m_pRenderClk; + + FunctionPtr m_EndScene; + Hook* m_pHook; + + LPD3DXLINE m_pLine; + LPD3DXFONT m_pFont; + + int m_iPrintY; +}; + +extern Draw* g_pDraw; + +#endif \ No newline at end of file diff --git a/blackhat/dt_dump.cpp b/blackhat/dt_dump.cpp new file mode 100644 index 0000000..d90f1c8 --- /dev/null +++ b/blackhat/dt_dump.cpp @@ -0,0 +1,90 @@ +#include "convar.h" +#include "cdll_int.h" +#include "cdll_client_int.h" +#include "client_class.h" +#include "dt_recv.h" +#include + +static const char* s_szSendPropTypes[] = { + "Int", + "Float", + "Vector", + "VectorXY", + "String", + "Array", + "DataTable" +}; + +static void DumpDataTable(FILE* fOut, RecvTable* table, int tabs = 1) +{ + fprintf(fOut, "RecvTable %s\n", table->m_pNetTableName); + for (int i = 0; i < table->GetNumProps(); i++) + { + //Tabs + for (int j = 0; j < tabs; j++) + fputc('\t', fOut); + + RecvProp* prop = table->GetProp(i); + fprintf(fOut, "0x%04x %s %s", prop->GetOffset(), + s_szSendPropTypes[prop->GetType()], + prop->GetName()); + + RecvProp* array; + switch (prop->GetType()) + { + case DPT_Array: + array = prop->GetArrayProp(); + fprintf(fOut, "[%d] x %d", + prop->GetNumElements(), + prop->GetElementStride() + ); + break; + case DPT_DataTable: + DumpDataTable(fOut, prop->GetDataTable(), tabs + 1); + break; + } + + fprintf(fOut, "\n"); + } +} + +CON_COMMAND(blackhat_dump_classes, "Dump all client classes") +{ + FILE* fOut; + fopen_s(&fOut, "class.txt", "w"); + + ClientClass* item = clientdll->GetAllClasses(); + if (item) + { + do { + //fprintf(fOut, "[%d]\t%s\n", clientClass->m_pNetworkName, clientClass->m_pNetworkName); + RecvTable* recvTable = item->m_pRecvTable; + fprintf(fOut, "class %s [%d] ", item->GetName(), item->m_ClassID); + if (recvTable) + { + DumpDataTable(fOut, recvTable, 1); + } + else + fprintf(fOut, "\n"); + } while (item = item->m_pNext); + } + + fclose(fOut); +} + +CON_COMMAND(blackhat_dump_class_recvtable, "Dump class RecvTable") +{ + ClientClass* item = clientdll->GetAllClasses(); + if (item) + { + do { + if (!strcmp(item->GetName(), args.Arg(1))) + break; + } while (item = item->m_pNext); + } + + FILE* fOut; + fopen_s(&fOut, "class_1.txt", "w"); + DumpDataTable(fOut, item->m_pRecvTable); + fclose(fOut); +} \ No newline at end of file diff --git a/blackhat/dt_entity.cpp b/blackhat/dt_entity.cpp new file mode 100644 index 0000000..ffb8919 --- /dev/null +++ b/blackhat/dt_entity.cpp @@ -0,0 +1,168 @@ +#include "dt_entity.h" +#include "cdll_int.h" +#include "cdll_client_int.h" +#include "client_class.h" +#include "icliententity.h" +#include "dt_recv.h" + +//DT_BaseEntity +//Vector m_vecOrigin; +//QAngle m_angRotation; +//int m_nModelIndex; +//int m_iTeamNum; + +//DT_CollisionProperty m_CollisionRecvTable +//Vector m_vecMins; +//Vector m_vecMaxs; + +//DT_BaseAnimating +//int m_nSequence; +//int m_nHitboxSet; + +static int s_vecOrigin_offset = 0; +static int s_angRotation_offset = 0; +static int s_nModelIndex_offset = 0; +static int s_iTeamNum_offset = 0; + +static int s_vecMins_offset = 0; +static int s_vecMaxs_offset = 0; + +static int s_nSequence_offset = 0; +static int s_nHitboxSet_offset = 0; +static int s_iHealth_offset = 0; +static int s_iClass_offset = 0; +static int s_vecViewOffset_offset = 0; +static int s_deadflag_offset = 0; +static int s_angle_offset = 0; +static int s_hActiveWeapon_offset = 0; +static int s_fFlags_offset = 0; + +RecvTable* DT_FindClassTable(const char* pClassName) +{ + ClientClass* item = clientdll->GetAllClasses(); + if (item) + { + do { + if (!strcmp(item->GetName(), pClassName)) + return item->m_pRecvTable; + } while (item = item->m_pNext); + } + return NULL; +} + +int DT_FindPropOffset(RecvTable* table, const char* pPropName) +{ + for (int i = 0; i < table->GetNumProps(); i++) + { + RecvProp* prop = table->GetProp(i); + if (!strcmp(prop->GetName(), pPropName)) + { + return prop->GetOffset(); + } + + if (prop->GetType() == DPT_DataTable) + { + int offset = DT_FindPropOffset(prop->GetDataTable(), pPropName); + if (offset != -1) + return prop->GetOffset() + offset; + } + } + return -1; +} + +void DT_InitOffsets() +{ + RecvTable* DT_BaseEntity = DT_FindClassTable("CBaseEntity"); + + s_vecOrigin_offset = DT_FindPropOffset(DT_BaseEntity, "m_vecOrigin"); + s_angRotation_offset = DT_FindPropOffset(DT_BaseEntity, "m_angRotation"); + s_nModelIndex_offset = DT_FindPropOffset(DT_BaseEntity, "m_nModelIndex"); + s_iTeamNum_offset = DT_FindPropOffset(DT_BaseEntity, "m_iTeamNum"); + s_vecMins_offset = DT_FindPropOffset(DT_BaseEntity, "m_vecMins"); + s_vecMaxs_offset = DT_FindPropOffset(DT_BaseEntity, "m_vecMaxs"); + + RecvTable* DT_TFPlayer = DT_FindClassTable("CTFPlayer"); + + s_nSequence_offset = DT_FindPropOffset(DT_TFPlayer, "m_nSequence"); + s_nHitboxSet_offset = DT_FindPropOffset(DT_TFPlayer, "m_nHitboxSet"); + s_iHealth_offset = DT_FindPropOffset(DT_TFPlayer, "m_iHealth"); + s_iClass_offset = DT_FindPropOffset(DT_TFPlayer, "m_iClass"); + s_vecViewOffset_offset = DT_FindPropOffset(DT_TFPlayer, "m_vecViewOffset[0]"); + s_deadflag_offset = DT_FindPropOffset(DT_TFPlayer, "deadflag"); + s_angle_offset = s_deadflag_offset + 0x04; //PlayerState::v_angle predicted + s_hActiveWeapon_offset = DT_FindPropOffset(DT_TFPlayer, "m_hActiveWeapon"); + s_fFlags_offset = DT_FindPropOffset(DT_TFPlayer, "m_fFlags"); + + Msg("s_vecOrigin_offset 0x%04x\n", s_vecOrigin_offset); + Msg("s_angRotation_offset 0x%04x\n", s_angRotation_offset); + Msg("s_nModelIndex_offset 0x%04x\n", s_nModelIndex_offset); + Msg("s_iTeamNum_offset 0x%04x\n", s_iTeamNum_offset); + Msg("s_vecMins_offset 0x%04x\n", s_vecMins_offset); + Msg("s_vecMaxs_offset 0x%04x\n", s_vecMaxs_offset); + Msg("\n"); + Msg("s_nSequence_offset 0x%04x\n", s_nSequence_offset); + Msg("s_nHitboxSet_offset 0x%04x\n", s_nHitboxSet_offset); + Msg("s_vecViewOffset 0x%04x\n", s_vecViewOffset_offset); + Msg("s_deadflag_offset 0x%04x\n", s_deadflag_offset); + Msg("s_angle_offset 0x%04x\n", s_angle_offset); + Msg("s_hActiveWeapon_offset 0x%04x\n", s_hActiveWeapon_offset); + Msg("s_fFlags_offset 0x%04x\n", s_fFlags_offset); +} + +CON_COMMAND(blackhat_init_offsets, "") +{ + DT_InitOffsets(); +} + +void DT_ReadEntity(Entity* entity, IClientEntity* clEntity) +{ + if (!strcmp(clEntity->GetClientClass()->GetName(), "CTFPlayer")) + { + ((Player*)entity)->Read(clEntity); + } + else entity->Read(clEntity); +} + +const char* Entity::GetName() +{ + return m_pClassName; +} + +void Entity::Read(IClientEntity* entity) +{ + entindex = entity->entindex(); + m_pClassName = entity->GetClientClass()->GetName(); + m_pEntity = entity; + m_bDormant = entity->IsDormant(); + + char* base = (char*)entity->GetBaseEntity(); + + m_vecOrigin = *(Vector*)(base + s_vecOrigin_offset); + m_angRotation = *(QAngle*)(base + s_angRotation_offset); + m_nModelIndex = *(int*)(base + s_nModelIndex_offset); + m_iTeamNum = *(int*)(base + s_iTeamNum_offset); + m_vecMins = *(Vector*)(base + s_vecMins_offset); + m_vecMaxs = *(Vector*)(base + s_vecMaxs_offset); +} + +bool Entity::IsPlayer() +{ + return !strcmp(m_pClassName, "CTFPlayer"); +} + +void Player::Read(IClientEntity* entity) +{ + Entity::Read(entity); + + char* base = (char*)entity->GetBaseEntity(); + + m_nSequence = *(int*)(base + s_nSequence_offset); + m_nHitboxSet = *(int*)(base + s_nHitboxSet_offset); + m_iHealth = *(int*)(base + s_iHealth_offset); + m_iClass = *(int*)(base + s_iClass_offset); + m_vecViewOffset = *(Vector*)((char*)base + s_vecViewOffset_offset); + deadflag = *(int*)((char*)base + s_deadflag_offset); + v_angle = *(QAngle*)((char*)base + s_angle_offset); + m_hActiveWeapon = *(CBaseHandle*)((char*)base + s_hActiveWeapon_offset); + m_fFlags = *(int*)((char*)base + s_fFlags_offset); +} \ No newline at end of file diff --git a/blackhat/dt_entity.h b/blackhat/dt_entity.h new file mode 100644 index 0000000..240c67c --- /dev/null +++ b/blackhat/dt_entity.h @@ -0,0 +1,93 @@ +#ifndef __DT_ENTITY_H +#define __DT_ENTITY_H + +#include "cdll_int.h" +#include "mathlib.h" +#include "edict.h" +#include +#include "icliententity.h" +#include "ehandle.h" + +class Entity +{ +public: + Entity() + : m_pPrev(NULL),m_pNext(NULL) + {} + + void Read(IClientEntity* entity); + virtual const char* GetName(); + virtual bool IsPlayer(); + + Entity* m_pPrev; + Entity* m_pNext; + + int entindex; + const char* m_pClassName; + IClientEntity* m_pEntity; + bool m_bDormant; + + Vector m_vecVelocity; + + Vector m_vecRenderOrigin; + QAngle m_angRenderAngles; + + //DT_BaseEntity + Vector m_vecOrigin; + QAngle m_angRotation; + int m_nModelIndex; + int m_iTeamNum; + + //DT_CollisionProperty m_CollisionRecvTable + Vector m_vecMins; + Vector m_vecMaxs; +}; + +#define TF_SCOUT 1 +#define TF_SOLDIER 3 +#define TF_PYRO 7 +#define TF_DEMOMAN 4 +#define TF_HEAVY 6 +#define TF_ENGINEER 9 +#define TF_MEDIC 5 +#define TF_SNIPER 2 +#define TF_SPY 8 + +class Player : public Entity +{ +public: + Player() : Entity(), + m_pModel(NULL) + {} + + void Read(IClientEntity* entity); + virtual bool IsPlayer() { return true; } + + //DT_BaseAnimating + int m_nSequence; + int m_nHitboxSet; + + //DT_BasePlayer + int m_iHealth; + + int m_iClass; + + Vector m_vecViewOffset; + + int deadflag; + QAngle v_angle; //View angle + CBaseHandle m_hActiveWeapon; + int m_fFlags; + + //Studiomodel + studiohdr_t* m_pModel; + matrix3x4_t m_Bones[MAXSTUDIOBONES]; + + int m_iHead; + int m_iBigHitbox; +}; + +void DT_InitOffsets(); +void DT_ReadEntity(Entity* entity, IClientEntity* clEntity); + +#endif \ No newline at end of file diff --git a/blackhat/hack.cpp b/blackhat/hack.cpp new file mode 100644 index 0000000..729750a --- /dev/null +++ b/blackhat/hack.cpp @@ -0,0 +1,955 @@ +#include "hack.h" +#include "cvar.h" +#include "convar.h" +#include "vstdlib.h" +#include "tier1.h" +#include "tier2.h" +#include "mathlib.h" +#include "cdll_int.h" +#include "engine/ivmodelinfo.h" +#include "engine/IEngineTrace.h" +#include "edict.h" +#include "icliententitylist.h" +#include "icliententity.h" +#include "iclientrenderable.h" +#include "iclientnetworkable.h" +#include "client_class.h" +#include "vmatrix.h" +#include "dt_entity.h" +#include "sigfunc.h" +#include "iclientmode.h" +#include "in_buttons.h" +#include + +Hack g_Hack; + +IVEngineClient013* engine = NULL; +IBaseClientDLL* clientdll = NULL; +IClientEntityList* entitylist = NULL; +IVModelInfoClient* modelinfo = NULL; +IEngineTrace* enginetrace = NULL; + +CGlobalVars* gpGlobals = NULL; +IClientMode *g_pClientMode = NULL; + +#define CLIENT_GLOBALVARS_OFFSET 0x5A +#define CLIENT_GETCLIENTMODENORMAL_OFFSET 0x04 + +#define VCLIENT_INIT 0 +#define VCLIENT_LEVELINITPREENTITY 5 +#define VCLIENT_LEVELINITPOSTENTITY 6 +#define VCLIENT_LEVELSHUTDOWN 7 +#define VCLIENT_CREATEMOVE 21 +#define VCLIENT_FRAMESTAGENOTIFY 35 +#define VCLIENT_CANRECORDDEMO 50 + +#define CLIENTMODE_CREATEMOVE 21 + +class CAimbotTraceFilter : public ITraceFilter +{ +public: + virtual bool ShouldHitEntity(IHandleEntity* pHandle, int contentsMask) + { + Entity* pEntity = g_Hack.GetEntity(pHandle->GetRefEHandle()); + if (!pEntity) + return false; + if (!pEntity->IsPlayer()) + return false; + Player* pLocalPlayer = (Player*)g_Hack.GetEntity(engine->GetLocalPlayer()); + Player* pPlayer = (Player*)pEntity; + + return g_Hack.IsPlayerEnemy(pLocalPlayer, pPlayer); + } + + virtual TraceType_t GetTraceType() const + { + return TRACE_EVERYTHING; + } +} g_AimbotTraceFilter; + +void __fastcall LevelInitPreEntity_Hook(void* thisptr, void* edx, const char* pMapName) +{ + g_Hack.LevelInitPreEntity(pMapName); +} + +void __fastcall LevelInitPostEntity_Hook(void* thisptr, void* edx) +{ + g_Hack.LevelInitPostEntity(); +} + +void __fastcall LevelShutdown_Hook(void* thisptr, void* edx) +{ + g_Hack.LevelShutdown(); +} + +void __fastcall FrameStageNotify_Hook(void* thisptr, void* edx, ClientFrameStage_t stage) +{ + g_Hack.FrameStageNotify(stage); +} + +void __fastcall CreateMove_Hook(void* thisptr, void* edx, float fInputTime, CUserCmd* pUserCmd) +{ + g_Hack.CreateMove(fInputTime, pUserCmd); +} + +LPVOID FunctionCallPtr(LPVOID lpAddr) +{ + LONG_PTR iOffset = *(PLONG_PTR)lpAddr; + return (LPVOID)(iOffset + (LONG_PTR)lpAddr + 0x04); +} + +void Hack::Init(HMODULE hThisModule) +{ + m_WorldToScreen.Identity(); + + InitGameVariables(); + + m_ThisModule = hThisModule; + Hook::Init(); + + CreateInterfaceFn vstdlibFactory = VStdLib_GetICVarFactory(); + ConnectTier1Libraries(&vstdlibFactory, 1); + MathLib_Init(2.2f, 2.2f, 0.0f, 2.0f); + + ConVar_Register(); + + CreateInterfaceFn engineFactory = Sys_GetFactory("engine.dll"); + CreateInterfaceFn clientFactory = Sys_GetFactory("client.dll"); + + engine = (IVEngineClient013*)engineFactory(VENGINE_CLIENT_INTERFACE_VERSION_13, NULL); + modelinfo = (IVModelInfoClient*)engineFactory(VMODELINFO_CLIENT_INTERFACE_VERSION, NULL); + enginetrace = (IEngineTrace*)engineFactory(INTERFACEVERSION_ENGINETRACE_CLIENT, NULL); + + clientdll = (IBaseClientDLL*)clientFactory(CLIENT_DLL_INTERFACE_VERSION, NULL); + entitylist = (IClientEntityList*)clientFactory(VCLIENTENTITYLIST_INTERFACE_VERSION, NULL); + + Msg("engine %p\n", engine); + Msg("clientdll %p\n", clientdll); + + if (!SigInit()) + { + Warning("!SigInit()"); + return; + } + + ULONG_PTR ClientInit = (*(PULONG_PTR*)clientdll)[VCLIENT_INIT]; + gpGlobals = (CGlobalVars*)**(LPVOID**)((char*)ClientInit + CLIENT_GLOBALVARS_OFFSET); + + ULONG_PTR CanRecordDemo = (*(PULONG_PTR*)clientdll)[VCLIENT_CANRECORDDEMO]; + Msg("IBaseClientDLL::CanRecordDemo %p\n", CanRecordDemo); + + FunctionPtr GetClientModeNormal; + GetClientModeNormal.set(FunctionCallPtr( + (char*)CanRecordDemo + CLIENT_GETCLIENTMODENORMAL_OFFSET) + ); + g_pClientMode = GetClientModeNormal.get()(); + Msg("g_pClientMode %p\n", g_pClientMode); + + m_CreateMove.set(Hook::HookVFunction(g_pClientMode, CLIENTMODE_CREATEMOVE, CreateMove_Hook)); + + m_LevelInitPreEntity.set(Hook::HookVFunction(clientdll, VCLIENT_LEVELINITPREENTITY, LevelInitPreEntity_Hook)); + m_LevelInitPostEntity.set(Hook::HookVFunction(clientdll, VCLIENT_LEVELINITPOSTENTITY, LevelInitPostEntity_Hook)); + m_LevelShutdown.set(Hook::HookVFunction(clientdll, VCLIENT_LEVELSHUTDOWN, LevelShutdown_Hook)); + + m_FrameStageNotify.set(Hook::HookVFunction(clientdll, VCLIENT_FRAMESTAGENOTIFY, FrameStageNotify_Hook)); + + DT_InitOffsets(); + + engine->GetScreenSize(m_iWidth, m_iHeight); + + m_Draw.Init(); + m_Draw.SetRenderCallback(this); +} + +void Hack::Exit() +{ + ConVar_Unregister(); + + m_Draw.Exit(); + + Hook::Exit(); +} + +void Hack::Render(IDirect3DDevice9* pDevice) +{ + m_Draw.Print("blackhat"); + m_Draw.Print("m_iEndSceneCounter %d", m_iEndSceneCounter); + m_Draw.Print("realtime %f", gpGlobals->realtime); + m_Draw.Print("frametime %f", gpGlobals->frametime); + m_Draw.Print("curtime %f", gpGlobals->curtime); + m_Draw.Print("interval_per_tick %f", gpGlobals->interval_per_tick); + + m_Draw.Print(""); + + m_Draw.Print("Hack::m_bInGame %d", m_bInGame); + if (m_bInGame) + { + m_Draw.Print("Map name %s", m_MapName.c_str()); + } + + RenderGame(); +} + +void Hack::InitGameVariables() +{ + m_bInGameRender = false; + m_iEndSceneCounter = 0; + + m_MapName = ""; + m_bInGame = false; + + m_pFirstEntity = NULL; + m_pLastEntity = NULL; + + m_fLastFrameUpdate = 0; + m_fFrameDelta = 0; + + m_pLocalPlayer = NULL; +} + +void Hack::LevelInitPreEntity(const char* pMapName) +{ + m_LevelInitPreEntity.get()(clientdll, pMapName); + + InitGameVariables(); + m_MapName = std::string(pMapName); +} + +void Hack::LevelInitPostEntity() +{ + m_LevelInitPostEntity.get()(clientdll); + + m_pLocalPlayer = (Player*)GetEntity(engine->GetLocalPlayer()); + m_bInGame = true; +} + +void Hack::LevelShutdown() +{ + m_LevelShutdown.get()(clientdll); + + m_bInGame = false; + + RemoveAllEntities(); +} + +void Hack::FrameStageNotify(ClientFrameStage_t stage) +{ + m_FrameStageNotify.get()(clientdll, stage); + + //FRAME_RENDER_END + + switch (stage) + { + case FRAME_NET_UPDATE_END: + //UpdateWorld(); + break; + case FRAME_RENDER_START: + //Interpolation and prediction comes after FRAME_RENDER_START + m_iEndSceneCounter = 0; + m_bInGameRender = true; + + SetupRender(); + + WorldUpdate(); + RenderUpdate(); + break; + case FRAME_RENDER_END: + if (m_bInGame) + FrameThink(); + m_bInGameRender = false; + break; + } +} + +Entity* Hack::AddEntity(IClientEntity* entity) +{ + Entity* hackEntity; + if (!strcmp(entity->GetClientClass()->GetName(), "CTFPlayer")) + hackEntity = new Player(); + else hackEntity = new Entity(); + DT_ReadEntity(hackEntity, entity); + + if (!m_pFirstEntity) m_pFirstEntity = hackEntity; + if (m_pLastEntity) m_pLastEntity->m_pNext = hackEntity; + + hackEntity->m_pPrev = m_pLastEntity; + m_pLastEntity = hackEntity; + + return hackEntity; +} + +Entity* Hack::GetEntity(int entindex) +{ + Entity* item = m_pFirstEntity; + if (item) + { + do { + if (item->entindex == entindex) + return item; + } while (item = item->m_pNext); + } + return NULL; +} + +Entity* Hack::GetEntity(const CBaseHandle& refHandle) +{ + Entity* item = m_pFirstEntity; + if (item) + { + do { + if (!item->m_pEntity) + continue; + if (item->entindex == refHandle.GetEntryIndex()) + return item; + } while (item = item->m_pNext); + } + return NULL; +} + +void Hack::RemoveEntity(Entity* hackEntity) +{ + if (hackEntity == m_pFirstEntity) + m_pFirstEntity = hackEntity->m_pNext; + if (hackEntity == m_pLastEntity) + m_pLastEntity = hackEntity->m_pPrev; + if (hackEntity->m_pPrev) + hackEntity->m_pPrev->m_pNext = hackEntity->m_pNext; + if (hackEntity->m_pNext) + hackEntity->m_pNext->m_pPrev = hackEntity->m_pPrev; + delete hackEntity; +} + +void Hack::RemoveAllEntities() +{ + Entity* item = m_pFirstEntity; + Entity* next; + if (!item) + return; + m_pFirstEntity = NULL; + m_pLastEntity = NULL; + do { + next = item->m_pNext; + + delete item; + } while (item = next); +} + +void Hack::SetupRender() +{ + memcpy(&m_WorldToScreen, &engine->WorldToScreenMatrix(), sizeof(VMatrix)); +} + +void Hack::WorldUpdate() +{ + Entity* entity; + + if (!m_bInGame) + return; + + if (m_fLastFrameUpdate != 0) + { + m_fFrameDelta = gpGlobals->realtime - m_fLastFrameUpdate; + } + m_fLastFrameUpdate = gpGlobals->realtime; + + for (int i = 0; i < entitylist->GetHighestEntityIndex(); i++) + { + IClientEntity* clientEntity = entitylist->GetClientEntity(i); + if (!clientEntity) + continue; + if (clientEntity->IsDormant()) + continue; + + entity = GetEntity(clientEntity->entindex()); + if (!entity) + entity = AddEntity(clientEntity); + + EntityUpdate(entity, clientEntity); + } + + entity = m_pFirstEntity; + while (entity) + { + Entity* next = entity->m_pNext; + if (!entitylist->GetClientEntity(entity->entindex)) + RemoveEntity(entity); + entity = next; + } + + m_pLocalPlayer = (Player*)GetEntity(engine->GetLocalPlayer()); +} + +void Hack::EntityUpdate(Entity* entity, IClientEntity* clientEntity) +{ + DT_ReadEntity(entity, clientEntity); + + C_BaseEntity* baseEntity = clientEntity->GetBaseEntity(); + if (baseEntity) + { + C_BaseEntity__GetVelocity.get()(baseEntity, entity->m_vecVelocity); + } +} + +void Hack::PlayerUpdate(Player* player) +{ + player->m_pModel = modelinfo->GetStudiomodel(player->m_pEntity->GetModel()); + if (player->m_pModel) + { + player->m_pEntity->SetupBones(player->m_Bones, MAXSTUDIOBONES, + BONE_USED_BY_HITBOX, engine->GetLastTimeStamp()); + mstudiohitboxset_t* pSet = player->m_pModel + ->pHitboxSet(player->m_nHitboxSet); + for (int i = 0; i < pSet->numhitboxes; i++) + { + mstudiobbox_t* pHitbox = pSet->pHitbox(i); + + const char* pBoneName = player->m_pModel->pBone(pHitbox->bone)->pszName(); + if (strstr(pBoneName, "head")) + player->m_iHead = i; + + int iBigHitbox = -1; + float fBitHitboxSize = 0; + + Vector vSize = pHitbox->bbmin - pHitbox->bbmax; + float fHitboxSize = vSize.x * vSize.y * vSize.z; + if (fHitboxSize >= fBitHitboxSize) + { + iBigHitbox = i; + fBitHitboxSize = fHitboxSize; + } + } + } +} + +void Hack::RenderUpdate() +{ + Entity* entity = m_pFirstEntity; + while (entity) + { + IClientRenderable* render = entity->m_pEntity->GetClientRenderable(); + if (render) + { + entity->m_vecRenderOrigin = render->GetRenderOrigin(); + entity->m_angRenderAngles = render->GetRenderAngles(); + } + + if (entity->IsPlayer()) + { + PlayerUpdate((Player*)entity); + } + + entity = entity->m_pNext; + } +} + +void Hack::GetHitboxPosition(Player* player, int iHitbox, Vector& vOut) +{ + mstudiohitboxset_t* pSet = player->m_pModel + ->pHitboxSet(player->m_nHitboxSet); + mstudiobbox_t* pHitbox = pSet->pHitbox(iHitbox); + int iBone = pHitbox->bone; + Vector vMin, vMax; + VectorTransform(pHitbox->bbmin, player->m_Bones[iBone], vMin); + VectorTransform(pHitbox->bbmax, player->m_Bones[iBone], vMax); + vOut = (vMax + vMin) / 2; +} + +bool Hack::IsInCameraView(const Vector& world) +{ + const VMatrix& W2S = m_WorldToScreen; + + float w = W2S[3][0] * world[0] + W2S[3][1] * world[1] + W2S[3][2] * world[2] + W2S[3][3]; + return w > 0.01; +} + +bool Hack::WorldToScreen(const Vector& world, Vector& screen) +{ + const VMatrix& W2S = m_WorldToScreen; + + float w = W2S[3][0] * world[0] + W2S[3][1] * world[1] + W2S[3][2] * world[2] + W2S[3][3]; + if (w > 0.01) + { + float fl1DBw = 1 / w; + screen.x = (m_iWidth / 2) + (0.5 * ((W2S[0][0] * world[0] + W2S[0][1] * world[1] + + W2S[0][2] * world[2] + W2S[0][3]) * fl1DBw) * m_iWidth + 0.5); + screen.y = (m_iHeight / 2) - (0.5 * ((W2S[1][0] * world[0] + W2S[1][1] * world[1] + + W2S[1][2] * world[2] + W2S[1][3]) * fl1DBw) * m_iHeight + 0.5); + + screen.z = 0; + return true; + } + + screen = Vector(0); + return false; +} + +void Hack::DrawESPBox(const Vector& vOrigin, const QAngle& qAngle, + const Vector& vMin, const Vector& vMax, + D3DCOLOR color) +{ + const unsigned int VERTEX_NUM = 5; + Vector vertex[VERTEX_NUM]; + D3DXVECTOR2 points[VERTEX_NUM]; + + if (!IsInCameraView(vOrigin + vMin) && !IsInCameraView(vOrigin + vMax)) + return; + + matrix3x4_t posMatrix; + AngleMatrix(qAngle, vOrigin, posMatrix); + + float x = vMax.x - vMin.x; + float y = vMax.y - vMin.y; + float z = vMax.z - vMin.z; + + //1. Connected bottom vertices + //2. Build up lines + //3. Connected top vertices + + vertex[0] = vMin; + vertex[1] = vertex[0] + Vector(x, 0, 0); + vertex[2] = vertex[1] + Vector(0, y, 0); + vertex[3] = vertex[0] + Vector(0, y, 0); + vertex[4] = vertex[0]; + + //Bottom + for (int i = 0; i < VERTEX_NUM; i++) + { + Vector vOut; + VectorTransform(vertex[i], posMatrix, vOut); + + Vector vScreen; + WorldToScreen(vOut, vScreen); + points[i] = D3DXVECTOR2(vScreen.x, vScreen.y); + } + + m_Draw.DrawLines(points, VERTEX_NUM, color); + + //Lines + for (int i = 0; i < 4; i++) + { + Vector vStart1 = vertex[i]; + Vector vEnd1 = vStart1 + Vector(0, 0, z); + + Vector vStart,vEnd; + VectorTransform(vStart1, posMatrix, vStart); + VectorTransform(vEnd1, posMatrix, vEnd); + + Vector vScrStart, vScrEnd; + WorldToScreen(vStart, vScrStart); + WorldToScreen(vEnd, vScrEnd); + m_Draw.DrawLine(vScrStart.x, vScrStart.y, vScrEnd.x, vScrEnd.y, color); + } + + //Top + for (int i = 0; i < VERTEX_NUM; i++) + { + Vector vOut; + vertex[i] += Vector(0, 0, z); + VectorTransform(vertex[i], posMatrix, vOut); + + Vector vScreen; + WorldToScreen(vOut, vScreen); + points[i] = D3DXVECTOR2(vScreen.x, vScreen.y); + } + + m_Draw.DrawLines(points, VERTEX_NUM, color); +} + +bool Hack::IsPlayerEnemy(Player* localPlayer, Player* player) +{ + if (localPlayer == player) + return false; + if (localPlayer->m_iTeamNum == player->m_iTeamNum || player->m_iTeamNum == 0) + return false; + if (player->m_iHealth <= 0 || player->deadflag) + return false; + return true; +} + +void Hack::FrameThink() +{ + IClientEntity* localPlayer = entitylist->GetClientEntity(engine->GetLocalPlayer()); + if (!localPlayer) + return; + ClientClass* clientClass = localPlayer->GetClientClass(); +} + +static ConVar blackhat_esp_box("blackhat_esp_box", "1"); +static ConVar blackhat_esp_dormant("blackhat_esp_dormant", "0"); +static ConVar blackhat_esp_velocity("blackhat_esp_velocity", "0"); +static ConVar blackhat_esp_hitbox("blackhat_esp_hitbox", "0"); +static ConVar blackhat_esp_hitbox_name("blackhat_esp_hitbox_name", "0"); + +void Hack::RenderGame() +{ + Entity* entity = m_pFirstEntity; + if (!entity) + return; + Player* localPlayer = (Player*)GetEntity(engine->GetLocalPlayer()); + if (!localPlayer) + return; + + bool bDormantCheck = blackhat_esp_dormant.GetBool(); + do + { + if (entity == localPlayer) + continue; + if (entity->IsPlayer()) + { + Player* player = (Player*)entity; + if (!bDormantCheck) + { + if (player->m_bDormant) + continue; + } + if (!IsPlayerEnemy(localPlayer, player)) + continue; + Vector vScreen; + Vector& vOrigin = player->m_vecRenderOrigin; + if (WorldToScreen(vOrigin, vScreen)) + { + player_info_t info; + engine->GetPlayerInfo(player->entindex, &info); + + wchar_t wszNickName[64]; + MultiByteToWideChar(CP_UTF8, 0, info.name, -1, wszNickName, 64); + + if (blackhat_esp_box.GetBool()) + { + DrawESPBox(vOrigin, player->m_angRotation, + player->m_vecMins, player->m_vecMaxs, + D3DCOLOR_RGBA(0, 255, 0, 255)); + } + m_Draw.DrawTextW(vScreen.x, vScreen.y, wszNickName, D3DCOLOR_RGBA(0, 255, 0, 255)); + + if (blackhat_esp_velocity.GetBool()) + { + Vector vStart1 = vOrigin; + Vector vEnd1 = vStart1 + player->m_vecVelocity; + + Vector vStart, vEnd; + WorldToScreen(vStart1, vStart); + WorldToScreen(vEnd1, vEnd); + + m_Draw.DrawLine(vStart.x, vStart.y, vEnd.x, vEnd.y, D3DCOLOR_RGBA(0, 255, 255, 255)); + } + + if (blackhat_esp_hitbox.GetBool() && player->m_pModel) + { + mstudiohitboxset_t* pSet = player->m_pModel + ->pHitboxSet(player->m_nHitboxSet); + for (int i = 0; i < pSet->numhitboxes; i++) + { + mstudiobbox_t* pHitbox = pSet->pHitbox(i); + + Vector vOrigin; + QAngle qAngle; + + MatrixAngles(player->m_Bones[pHitbox->bone], qAngle, vOrigin); + + Vector vOrigin2D; + if (WorldToScreen(vOrigin, vOrigin2D)) + { + DrawESPBox(vOrigin, qAngle, pHitbox->bbmin, pHitbox->bbmax, D3DCOLOR_RGBA(0, 255, 0, 255)); + if (blackhat_esp_hitbox_name.GetBool()) + { + const char* pBoneName = player->m_pModel->pBone(pHitbox->bone)->pszName(); + m_Draw.DrawTextA(vOrigin2D.x, vOrigin2D.y, + pBoneName, D3DCOLOR_RGBA(0, 255, 0, 255)); + } + } + } + } + } + } + } while (entity = entity->m_pNext); + + m_Draw.Print("m_fLastFrameUpdate %f", m_fLastFrameUpdate); + m_Draw.Print("m_fFrameDelta %f", m_fFrameDelta); + + if (localPlayer) + { + m_Draw.Print("m_iClass %d", localPlayer->m_iClass); + m_Draw.Print("m_iTeamNum %d", localPlayer->m_iTeamNum); + m_Draw.Print("m_iHealth %d", localPlayer->m_iHealth); + Entity* pWeapon = GetEntity(localPlayer->m_hActiveWeapon); + if (pWeapon) + { + m_Draw.Print("m_hActiveWeapon %s", pWeapon->m_pClassName); + } + + m_Draw.Print("VELOCITY %f %f %f", + localPlayer->m_vecVelocity.x, + localPlayer->m_vecVelocity.y, + localPlayer->m_vecVelocity.z + ); + } +} + +void Hack::GetEyePosition(Vector& vOut) +{ + vOut = m_pLocalPlayer->m_vecOrigin + m_pLocalPlayer->m_vecViewOffset; +} + +void Hack::AimTraceLine(trace_t& tr, Vector vEnd) +{ + Ray_t ray; + + Vector vOrigin = m_pLocalPlayer->m_vecOrigin; + Vector vStart = vOrigin + m_pLocalPlayer->m_vecViewOffset; + + ray.Init(vStart, vEnd); + enginetrace->TraceRay(ray, MASK_SHOT, &g_AimbotTraceFilter, &tr); +} + +void Hack::AimTraceLine(trace_t& tr) +{ + Vector vOrigin = m_pLocalPlayer->m_vecOrigin; + Vector vStart; + Vector vDir; + + GetEyePosition(vStart); + AngleVectors(m_pLocalPlayer->v_angle, &vDir); + Vector vEnd = vStart + vDir * 2048.0f; + + CAimbotTraceFilter filter; + + AimTraceLine(tr, vEnd); +} + +void Hack::CreateMove(float fInputTime, CUserCmd* pUserCmd) +{ + m_CreateMove.get()(g_pClientMode, fInputTime, pUserCmd); + + m_fInputSampleTime = m_fInputSampleTime; + m_pUserCmd = pUserCmd; + if (m_pLocalPlayer) + m_pLocalPlayer->v_angle = pUserCmd->viewangles; + + Aimbot(); +} + +Entity* Hack::GetActiveWeapon() +{ + if (!m_pLocalPlayer->m_hActiveWeapon.IsValid()) + return NULL; + return GetEntity(m_pLocalPlayer->m_hActiveWeapon); +} + +#define RADPI 57.295779513082f + +void Hack::AimTo(const Vector& vSrc, const Vector& vDst, QAngle& qAngle) +{ + Vector vDelta = vSrc - vDst; + float fHyp = vDelta.Length2D(); + qAngle[0] = atanf(vDelta[2] / fHyp) * RADPI; + qAngle[1] = atanf(vDelta[1] / vDelta[0]) * RADPI; + qAngle[2] = 0; + if (vDelta[0] >= 0.0) + qAngle[1] += 180.0; + //Normalize angles + for (int i = 0; i < 2; i++) + { + while (qAngle[i] > 180.0) + qAngle[i] -= 360.0; + while (qAngle[i] < -180.0) + qAngle[i] += 360.0; + } +} + +Player* Hack::AimFindScreenTarget(Vector& vShoot, bool bAimHeadFirst) +{ + Player* pTarget = NULL; + Vector vTargetHitbox; + float fNear = FLT_MAX; + + Entity* pEntity = m_pFirstEntity; + if (!pEntity) + return NULL; + do { + if (!pEntity->IsPlayer()) + continue; + Player* pPlayer = (Player*)pEntity; + if (pPlayer->m_bDormant) + continue; + if (!IsPlayerEnemy(m_pLocalPlayer, pPlayer)) + continue; + + Vector vOrigin = pPlayer->m_vecOrigin; + Vector vScreen; + if (!WorldToScreen(vOrigin, vScreen)) + continue; + + float fScrDistance = (vScreen - Vector(m_iWidth / 2, m_iHeight / 2, 0)).Length2D(); + if (fScrDistance < fNear) + { + //Trace hitboxes + trace_t tr; + Vector vHitbox; + + tr.m_pEnt = NULL; + + if (bAimHeadFirst) + { + GetHitboxPosition(pPlayer, pPlayer->m_iHead, vHitbox); + AimTraceLine(tr, vHitbox); + } + + //Aim body if we can't trace head + if (tr.m_pEnt != pPlayer->m_pEntity->GetBaseEntity()) + { + GetHitboxPosition(pPlayer, pPlayer->m_iBigHitbox, vHitbox); + AimTraceLine(tr, vHitbox); + } + + //Check hitboxes + if (tr.m_pEnt != pPlayer->m_pEntity->GetBaseEntity()) + { + //We can't hit player + continue; + } + + //We found best target + pTarget = pPlayer; + vTargetHitbox = vHitbox; + fNear = fScrDistance; + } + } while (pEntity = pEntity->m_pNext); + + vShoot = vTargetHitbox; + return pTarget; +} + +static ConVar blackhat_aimbot("blackhat_aimbot", "1"); + +void Hack::Aimbot() +{ + if (!blackhat_aimbot.GetBool()) + return; + if (!(m_pUserCmd->buttons & IN_ATTACK)) + return; + //Setup LocalPlayer viewangles + m_pLocalPlayer->v_angle = m_pUserCmd->viewangles; + + //Select aimbot type + switch (m_pLocalPlayer->m_iClass) + { + case TF_SOLDIER: + case TF_DEMOMAN: + ProjectileAimbot(); + break; + default: + BulletAimbot(); + } +} + +void Hack::BulletAimbot() +{ + Player* pTarget; + Vector vShoot; + + //Determine aimbot mode + bool bAimHeadFirst = false; + if (m_pLocalPlayer->m_iClass == TF_SNIPER + || m_pLocalPlayer->m_iClass == TF_SPY) + { + bAimHeadFirst = true; + } + + //Find target + pTarget = AimFindScreenTarget(vShoot, bAimHeadFirst); + if (!pTarget) + return; + + Vector vEye; + GetEyePosition(vEye); + AimTo(vEye, vShoot, m_pUserCmd->viewangles); +} + +float Hack::GetWeaponProjectileSpeed() +{ + Entity* pWeapon = GetActiveWeapon(); + if (!pWeapon) + return 0.0; + const char* pName = pWeapon->m_pClassName; + if (!strcmp(pName, "CTFRocketLauncher")) + return 1100.0; + else if (!strcmp(pName, "CTFGrenadeLauncher")) + return 910.0; + return 0.0; +} + +static ConVarRef sv_gravity("sv_gravity"); + +void Hack::PredictPlayerPos(Player* player, float fDelta, Vector& vOut) +{ + vOut = player->m_vecOrigin + + player->m_vecVelocity * fDelta; + if (!(player->m_fFlags & FL_ONGROUND)) + { + float g = sv_gravity.GetFloat(); + vOut.z += (-g * fDelta * fDelta) / 2; + } +} + +void Hack::ProjectileAimbot() +{ + //aPos = aPos0 + aVel*t + (aAcc * t * t) / 2 + //bPos = bPos0 + bVel*t + + //bPos = aPos0 + aVel*t + (aAcc * t * t) / 2 - bPos0 - bVel*t + //t = 1 + + Player* pTarget; + Vector vShoot; + Vector vEye; + Vector vForward; + float fProjSpeed = GetWeaponProjectileSpeed(); + + //Find target + pTarget = AimFindScreenTarget(vShoot, false); + if (!pTarget) + return; + + //aPos = aPos0 + aVel*t + //bPos = bPos0 + bVel*t + + //aPos0 + aVel*t = bPos0 + bVel*t + //aVel*t - bVel*t = bPos0 -aPos0 + //t * (aVel - bVel) = bPos0 -aPos0 + //t = (bPos0 - aPos0) / (aVel - bVel) + + //aPos = aPos0 + aVel*t + (aAcc * t * t) / 2 + //bPos = bPos0 + bVel*t + + //aPos0 + aVel*t + (aAcc * t * t) / 2 = bPos0 + bVel*t + //aVel*t - bVel*t + (aAcc * t * t) / 2 = bPos0 - aPos0 + //t * (aVel - bVel) + aAcc * t * t / 2 = bPos0 - aPos0 + + GetEyePosition(vEye); + AngleVectors(m_pLocalPlayer->v_angle, &vForward); + + Vector aPos0 = pTarget->m_vecOrigin + (pTarget->m_vecMins + pTarget->m_vecMaxs) / 2; + Vector aVel = pTarget->m_vecVelocity; + + Vector bPos0 = vEye; + Vector bVel = vForward * fProjSpeed; + + float t0 = (bPos0[0] - aPos0[0]) / (aVel[0] - bVel[0]); + float t1 = (bPos0[1] - aPos0[1]) / (aVel[1] - bVel[1]); + float t2 = (bPos0[2] - aPos0[2]) / (aVel[2] - bVel[2]); + + Msg("%f %f %f\n", t0, t1, t2); + + float aAcc = -sv_gravity.GetFloat(); + + Vector vOut = Vector( + aPos0[0] + aVel[0] * t0, + aPos0[1] + aVel[1] * t1, + aPos0[2] + aVel[2] * t2 + + !(pTarget->m_fFlags & FL_ONGROUND) + ? (aAcc * t2 * t2) / 2 + : 0 + ); + AimTo(vEye, vOut, m_pUserCmd->viewangles); +} \ No newline at end of file diff --git a/blackhat/hack.h b/blackhat/hack.h new file mode 100644 index 0000000..599741b --- /dev/null +++ b/blackhat/hack.h @@ -0,0 +1,109 @@ +#ifndef __HACK_H +#define __HACK_H + +#include +#include +#include "hook.h" +#include "draw.h" +#include "cdll_int.h" +#include "mathlib.h" +#include "edict.h" +#include "dt_entity.h" +#include "usercmd.h" +#include + +class Hack : public IRenderCallback +{ +public: + void Init(HMODULE hThisModule); + void Exit(); + + virtual void Render(IDirect3DDevice9* pDevice); + + void InitGameVariables(); + + void LevelInitPreEntity(const char* pMapName); + void LevelInitPostEntity(); + void LevelShutdown(); + + void FrameStageNotify(ClientFrameStage_t stage); + + Entity* AddEntity(IClientEntity* entity); + Entity* GetEntity(int entindex); + Entity* GetEntity(const CBaseHandle& refHandle); + void RemoveEntity(Entity* hackEntity); + void RemoveAllEntities(); + + void SetupRender(); + void WorldUpdate(); + void EntityUpdate(Entity* entity, IClientEntity* clientEntity); + void PlayerUpdate(Player* player); + void RenderUpdate(); + + void GetHitboxPosition(Player* player, int iHitbox, Vector& vOut); + + bool IsInCameraView(const Vector& world); + bool WorldToScreen(const Vector& world, Vector& screen); + + void DrawESPBox(const Vector& vOrigin, const QAngle& qAngle, + const Vector& vMin, const Vector& vMax, + D3DCOLOR color); + + bool IsPlayerEnemy(Player* localPlayer, Player* player); + + void FrameThink(); + void RenderGame(); + + void GetEyePosition(Vector& vOut); + void AimTraceLine(trace_t& tr, Vector vEnd); + void AimTraceLine(trace_t& tr); + void CreateMove(float fInputTime, CUserCmd* pUserCmd); + + Entity* GetActiveWeapon(); + + void AimTo(const Vector& vSrc, const Vector& vDst, QAngle& qAngle); + Player* AimFindScreenTarget(Vector& vShoot, bool bAimHeadFirst = false); + void Aimbot(); + void BulletAimbot(); + + float GetWeaponProjectileSpeed(); + void PredictPlayerPos(Player* player, float fDelta, Vector& vOut); + void ProjectileAimbot(); +private: + HMODULE m_ThisModule; + Draw m_Draw; + + VMatrix m_WorldToScreen; + + bool m_bInGameRender; + int m_iEndSceneCounter; + + int m_iWidth; + int m_iHeight; + + FunctionPtr m_LevelInitPreEntity; + FunctionPtr m_LevelInitPostEntity; + FunctionPtr m_LevelShutdown; + + std::string m_MapName; + bool m_bInGame; + + FunctionPtr m_FrameStageNotify; + + Entity* m_pFirstEntity; + Entity* m_pLastEntity; + + float m_fLastFrameUpdate; + float m_fFrameDelta; + + Player* m_pLocalPlayer; + + FunctionPtr m_CreateMove; + + float m_fInputSampleTime; + CUserCmd* m_pUserCmd; +}; + +extern Hack g_Hack; + +#endif \ No newline at end of file diff --git a/blackhat/main.cpp b/blackhat/main.cpp new file mode 100644 index 0000000..cfbe0b6 --- /dev/null +++ b/blackhat/main.cpp @@ -0,0 +1,21 @@ +#include +#include "hack.h" + +DWORD WINAPI HackThread(LPVOID lpArg) +{ + g_Hack.Init((HMODULE)lpArg); + return 0; +} + +BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + CreateThread(NULL, 0, HackThread, hInst, 0, NULL); + } + else if (dwReason == DLL_PROCESS_DETACH) + { + g_Hack.Exit(); + } + return TRUE; +} \ No newline at end of file diff --git a/blackhat/sigfunc.cpp b/blackhat/sigfunc.cpp new file mode 100644 index 0000000..dacbf8f --- /dev/null +++ b/blackhat/sigfunc.cpp @@ -0,0 +1,18 @@ +#include "sigfunc.h" +#include "sigscan.h" + +FunctionPtr C_BaseEntity__GetVelocity; + +bool SigInit() +{ + HMODULE hClientDLL = GetModuleHandle("client.dll"); + C_BaseEntity__GetVelocity.set(SigScan::FindFunction(hClientDLL, GETVELOCITY_SIG, GETVELOCITY_MASK)); + if (!C_BaseEntity__GetVelocity.ptr()) + { + Warning("C_BaseEntity::EstimateAbsVelocity not found!\n"); + return false; + } + Msg("C_BaseEntity::EstimateAbsVelocity %p\n", C_BaseEntity__GetVelocity.ptr()); + + return true; +} diff --git a/blackhat/sigfunc.h b/blackhat/sigfunc.h new file mode 100644 index 0000000..1789be2 --- /dev/null +++ b/blackhat/sigfunc.h @@ -0,0 +1,14 @@ +#ifndef __SIGFUNC_H +#define __SIGFUNC_H + +#include "hook.h" +#include "vector.h" + +#define GETVELOCITY_SIG "\x55\x8B\xEC\x83\xEC\x0C\x56\x8B\xF1\xE8\x00\x00\x00\x00\x3B\xF0\x75\x2B\x8B\xCE\xE8\x00\x00\x00\x00\x8B\x45\x08\xD9\x86\x00\x00\x00\x00\xD9\x18" +#define GETVELOCITY_MASK "xxxxxxxxxx????xxxxxxx????xxxxx????xx" + +extern FunctionPtr C_BaseEntity__GetVelocity; + +bool SigInit(); + +#endif \ No newline at end of file diff --git a/hook/Release/hook.lib.recipe b/hook/Release/hook.lib.recipe new file mode 100644 index 0000000..a53f961 --- /dev/null +++ b/hook/Release/hook.lib.recipe @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/hook/hook.cpp b/hook/hook.cpp new file mode 100644 index 0000000..80745a9 --- /dev/null +++ b/hook/hook.cpp @@ -0,0 +1,152 @@ +#include "hook.h" +#include "MinHook.h" + +Hook* Hook::s_pFirst = NULL; +Hook* Hook::s_pLast = NULL; + +void Hook::Init() +{ + MH_Initialize(); +} + +void Hook::Exit() +{ + UnHookAll(); + MH_Uninitialize(); +} + +void Hook::UnHookAll() +{ + Hook* pItem = s_pFirst; + if (pItem) + { + Hook* pNext; + do { + pNext = pItem->m_pNext; + + pItem->DoUnHook(); + } while (pItem = pNext); + } + + s_pFirst = NULL; + s_pLast = NULL; +} + +void Hook::DoHook() +{ + m_pPrev = s_pLast; + + if (!s_pFirst) s_pFirst = this; + if (s_pLast) s_pLast->m_pNext = this; + + s_pLast = this; + //Delete! + delete this; +} + +void Hook::DoUnHook() +{ + if (m_pPrev) m_pPrev->m_pNext = m_pNext; + if (m_pNext) m_pNext->m_pPrev = m_pPrev; +} + +class FHook : public Hook +{ +public: + FHook(LPVOID pFunction, LPVOID pHook) + : m_pFunction(pFunction), m_pHook(pHook) + { + } + + virtual void DoHook() + { + MH_CreateHook(m_pFunction, m_pHook, &m_pTrampoline); + MH_EnableHook(m_pFunction); + + Hook::DoHook(); + } + + virtual void DoUnHook() + { + MH_DisableHook(m_pFunction); + MH_RemoveHook(m_pFunction); + + Hook::DoUnHook(); + } + + LPVOID HookFunction() + { + DoHook(); + return m_pTrampoline; + } +private: + LPVOID m_pFunction; + LPVOID m_pHook; + LPVOID m_pTrampoline; +}; + +LPVOID Hook::HookFunction(LPVOID pFunction, LPVOID pDetour, Hook** ppHook) +{ + FHook* pHook = new FHook(pFunction, pDetour); + LPVOID pTrampoline = pHook->HookFunction(); + if (ppHook) *ppHook = pHook; + return pTrampoline; +} + +class VMTHook : public Hook +{ +public: + VMTHook(LPVOID pInterface, UINT uIndex, LPVOID pHook) + { + m_pVMT = *(LPVOID**)pInterface; + m_uIndex = uIndex; + m_pHook = pHook; + } + + void EnableProtection(bool bEnable) + { + LPVOID* pPtr = &m_pVMT[m_uIndex]; + DWORD dwOldProtect; + VirtualProtect((LPVOID)pPtr, 4096, bEnable + ? PAGE_READONLY : PAGE_READWRITE, &dwOldProtect); + } + + virtual void DoHook() + { + m_pOriginal = m_pVMT[m_uIndex]; + EnableProtection(false); + m_pVMT[m_uIndex] = m_pHook; + EnableProtection(true); + + Hook::DoHook(); + } + + virtual void DoUnHook() + { + EnableProtection(false); + m_pVMT[m_uIndex] = m_pOriginal; + EnableProtection(true); + + Hook::DoUnHook(); + } + + LPVOID HookVFunction() + { + DoHook(); + return m_pOriginal; + } +private: + LPVOID* m_pVMT; + UINT m_uIndex; + LPVOID m_pHook; + LPVOID m_pOriginal; +}; + +LPVOID Hook::HookVFunction(LPVOID pInterface, UINT uIndex, + LPVOID pDetour, Hook** ppHook) +{ + VMTHook* pHook = new VMTHook(pInterface, uIndex, pDetour); + LPVOID pOriginal = pHook->HookVFunction(); + if (ppHook) *ppHook = pHook; + return pOriginal; +} diff --git a/hook/hook.h b/hook/hook.h new file mode 100644 index 0000000..9dd4c1a --- /dev/null +++ b/hook/hook.h @@ -0,0 +1,73 @@ +#ifndef __HOOK_H +#define __HOOK_H + +#include + +template +class FunctionPtr +{ +public: + explicit FunctionPtr(void* pFunc) + : m_pFuncPtr(pFunc) + { + } + + explicit FunctionPtr(DWORD_PTR dwFunc) + : m_pFuncPtr((void*)dwFunc) + { + } + + explicit FunctionPtr(T Func) + : m_Func(Func) + { + } + + FunctionPtr() + : m_pFuncPtr(NULL) + { + } + + T& get() + { + return m_Func; + } + + void* ptr() + { + return m_pFuncPtr; + } + + void set(LPVOID pAddr) + { + m_pFuncPtr = pAddr; + } +private: + union { + void* m_pFuncPtr; + T m_Func; + }; +}; + +class Hook +{ +public: + static void Init(); + static void Exit(); + + static void UnHookAll(); + + static LPVOID HookFunction(LPVOID pFunction, LPVOID pDetour, Hook** ppHook = NULL); + static LPVOID HookVFunction(LPVOID pInterface, UINT uIndex, LPVOID pDetour, Hook** ppHook = NULL); + + virtual void DoHook(); + virtual void DoUnHook(); + +private: + Hook* m_pPrev; + Hook* m_pNext; + + static Hook* s_pFirst; + static Hook* s_pLast; +}; + +#endif \ No newline at end of file diff --git a/hook/hook.vcxproj b/hook/hook.vcxproj new file mode 100644 index 0000000..fbd39dd --- /dev/null +++ b/hook/hook.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {2B541B0D-E176-4BB6-A434-653D8770F2B2} + hook + 10.0 + + + + Application + true + v142 + MultiByte + + + StaticLibrary + false + v142 + true + MultiByte + + + + + + + + + + + + + + + Level3 + Disabled + true + + + true + + + + + Level3 + MaxSpeed + true + true + true + ..\..\minhook\include;%(AdditionalIncludeDirectories) + + + true + true + true + + + libMinHook.x86.lib;%(AdditionalDependencies) + + + ..\..\minhook\lib;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + \ No newline at end of file diff --git a/hook/hook.vcxproj.filters b/hook/hook.vcxproj.filters new file mode 100644 index 0000000..5643d3c --- /dev/null +++ b/hook/hook.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/hook/hook.vcxproj.user b/hook/hook.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/hook/hook.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/hook/sigscan.cpp b/hook/sigscan.cpp new file mode 100644 index 0000000..a2f1b1a --- /dev/null +++ b/hook/sigscan.cpp @@ -0,0 +1,24 @@ +#include "sigscan.h" + +LPVOID SigScan::FindFunction(HMODULE hDll, const char* pSig, const char* pMask) +{ + PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)hDll; + PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS) + ((char*)pDos + pDos->e_lfanew); + char* pCode = (char*)pDos + pNt->OptionalHeader.BaseOfCode; + DWORD dwCodeLen = pNt->OptionalHeader.SizeOfCode; + DWORD dwSigLen = strlen(pMask); + + for (DWORD i = 0; i < dwCodeLen - dwSigLen; i++) + { + DWORD j; + for (j = 0; j < dwSigLen; j++) + { + if (pCode[i + j] != pSig[j] && pMask[j] != '?') + break; + } + if (j == dwSigLen) + return pCode + i; + } + return NULL; +} diff --git a/hook/sigscan.h b/hook/sigscan.h new file mode 100644 index 0000000..ef2b522 --- /dev/null +++ b/hook/sigscan.h @@ -0,0 +1,12 @@ +#ifndef __SIGSCAN_H +#define __SIGSCAN_H + +#include + +class SigScan +{ +public: + static LPVOID FindFunction(HMODULE hDll, const char* pSig, const char* pMask); +}; + +#endif \ No newline at end of file diff --git a/injector/Release/injector.exe.recipe b/injector/Release/injector.exe.recipe new file mode 100644 index 0000000..2d475ae --- /dev/null +++ b/injector/Release/injector.exe.recipe @@ -0,0 +1,11 @@ + + + + + D:\blackhat\Release\injector.exe + + + + + + \ No newline at end of file diff --git a/injector/injector.vcxproj b/injector/injector.vcxproj new file mode 100644 index 0000000..412ec32 --- /dev/null +++ b/injector/injector.vcxproj @@ -0,0 +1,73 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {32828B4A-428F-457D-93AF-BD201D83E83A} + injector + 10.0 + + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + + + + + + + + + + + + + Level3 + Disabled + true + + + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/injector/injector.vcxproj.filters b/injector/injector.vcxproj.filters new file mode 100644 index 0000000..0d8d9e4 --- /dev/null +++ b/injector/injector.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/injector/injector.vcxproj.user b/injector/injector.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/injector/injector.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/injector/main.cpp b/injector/main.cpp new file mode 100644 index 0000000..68947d1 --- /dev/null +++ b/injector/main.cpp @@ -0,0 +1,94 @@ +#include +#include +#include +#include + +#define PROCESS_NAME "hl2.exe" +#define MODULE_NAME "blackhat.dll" + +bool IsFileExists(const char* pFile) +{ + HANDLE hFile = CreateFile(pFile, GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + CloseHandle(hFile); + return true; + } + return false; +} + +#define INVALID_PID (DWORD)-1 + +DWORD FindProcess(const char* pExeName) +{ + static DWORD s_dwProcessList[1024]; + + DWORD cbNeeded; + EnumProcesses(s_dwProcessList, sizeof(s_dwProcessList), &cbNeeded); + for (DWORD i = 0; i < cbNeeded / sizeof(DWORD); i++) + { + char szPath[MAX_PATH]; + DWORD dwChars = sizeof(szPath); + DWORD dwPid = s_dwProcessList[i]; + HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION + | PROCESS_QUERY_INFORMATION, + FALSE, dwPid); + if (hProcess == INVALID_HANDLE_VALUE) + continue; + QueryFullProcessImageName(hProcess, 0, szPath, &dwChars); + CloseHandle(hProcess); + if (strstr(szPath, pExeName)) + return dwPid; + } + return INVALID_PID; +} + +void Inject(HANDLE hProcess, const char* pModulePath) +{ + DWORD_PTR dwFunc = (DWORD_PTR)GetProcAddress( + GetModuleHandle("kernel32.dll"), "LoadLibraryA"); + DWORD dwPathSize = strlen(pModulePath) + 1; + LPVOID lpFullPath = VirtualAllocEx(hProcess, NULL, dwPathSize, + MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + DWORD dwWrite; + WriteProcessMemory(hProcess, lpFullPath, pModulePath, (SIZE_T)dwPathSize, &dwWrite); + HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, + (LPTHREAD_START_ROUTINE)dwFunc, lpFullPath, 0, NULL); + WaitForSingleObject(hThread,INFINITE); + CloseHandle(hThread); + VirtualFreeEx(hProcess, lpFullPath, dwPathSize, MEM_DECOMMIT | MEM_RELEASE); +} + +int main() +{ + if (!IsFileExists(MODULE_NAME)) + { + fprintf(stderr, "%s doesn't exists!\n", MODULE_NAME); + return 1; + } + + char szFullPath[MAX_PATH]; + GetFullPathName(MODULE_NAME, MAX_PATH, szFullPath, NULL); + + DWORD dwPid; + printf("Waiting for %s\n", PROCESS_NAME); + while ((dwPid = FindProcess(PROCESS_NAME)) == INVALID_PID) + { + Sleep(100); + } + + printf("%d\t%s\n", dwPid, PROCESS_NAME); + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid); + if (hProcess == INVALID_HANDLE_VALUE) + { + fprintf(stderr, "Failed to open %s!\n", PROCESS_NAME); + return 1; + } + + Inject(hProcess, szFullPath); + printf("Injected."); + + CloseHandle(hProcess); + return 0; +} \ No newline at end of file