Od razu zaznaczam w wpisie nie znajdziecie wpełni działającego kodu cheat’a do CS 1.6. Cały wpis powstał podczas pisania własnego cheata zawierającego
- WH
- ESP
- Anty SS
Jednak już po napisaniu projekt zdecydowałem się na nie udostępnianie go dalej czy pokazywanie kodu. Spowodowane jest to przemyśleniem czy warto psuć dalej grę.
Wiele nauczyłem się podczas pisania tego jednak nie chce aby w jakiś zły sposób wpłynęło na społeczność graczy.
Pliki ASI są plikami pozwalającymi na załadowanie dowolnej dynamicznej biblioteki ( DLL ) do procesu gry. Popularną modyfikacją wykorzystującą ten plik jest CSX Guard
CSX Guard jest modyfikacją napisaną w delphi ja skupie się na pisaniu w C++.
Pliki ASI działają we wszystkich grach opartych na silniku GoldSrc ( Half-Life , CS 1.6 itp. itd. ).
Silnik GoldSrc wykorzystuje dll’ke mss32.dll która ładuje wszystkie pliki asi z głównego katalogu gry jako normalna dll’ka ( ale z innym rozszerzeniem ).
Dla starszych wersji engine np. 4554 Dllka jest ładowanie normalnie poprzez DllMain ale od nowszych wersji np. 6027 musimy już ładować nasz kod poprzez Rib_Main.
Do naszego projektu potrzebujemy niektórych plików z HLSDK można je ściągnąć stąd lub z mojej strony darkHack.zip Download
Cały projekt składa się z dwóch plików AsiMain.cpp oraz AsiMain.h
Zawartość AsiMain.cpp
#include "HLSDK/stdafx.h" #include "AsiMain.h" extern "C" DLLEXPORT S32 AILCALL RIB_Main(HPROVIDER provider_handle, U32 up_down, RIB_alloc_provider_handle_ptr RIB_alloc_provider_handle, RIB_register_interface_ptr RIB_register_interface, RIB_unregister_interface_ptr RIB_unregister_interface ) { if(up_down) { //code loaded } else { //code on unload } return 1; }
Zawartość AsiMain.h
#ifdef _WIN32 #define AILCALL __stdcall #else #define AILCALL #endif #ifndef C8 #define C8 char #endif #ifndef U32 #define U32 unsigned int #endif #ifndef S32 #define S32 signed int #endif #ifndef UINTa #define UINTa unsigned int #endif #define FAR typedef U32 HPROVIDER; typedef S32 RIBRESULT; typedef enum { RIB_NONE = 0, // No type RIB_CUSTOM, // Used for pointers to application-specific structures RIB_DEC, // Used for 32-bit integer values to be reported in decimal RIB_HEX, // Used for 32-bit integer values to be reported in hex RIB_FLOAT, // Used for 32-bit single-precision FP values RIB_PERCENT, // Used for 32-bit single-precision FP values to be reported as percentages RIB_BOOL, // Used for Boolean-constrained integer values to be reported as TRUE or FALSE RIB_STRING, // Used for pointers to null-terminated ASCII strings RIB_READONLY = 0x80000000 // Property is read-only } RIB_DATA_SUBTYPE; typedef enum { RIB_FUNCTION = 0, RIB_PROPERTY // Property: read-only or read-write data type } RIB_ENTRY_TYPE; typedef struct { RIB_ENTRY_TYPE type; C8 FAR *entry_name; UINTa token; RIB_DATA_SUBTYPE subtype; // Property subtype } RIB_INTERFACE_ENTRY; typedef HPROVIDER (*RIB_alloc_provider_handle_ptr) (long module); typedef RIBRESULT (*RIB_register_interface_ptr) (HPROVIDER provider, C8 const FAR *interface_name, S32 entry_count, RIB_INTERFACE_ENTRY const FAR *rlist); typedef RIBRESULT (*RIB_unregister_interface_ptr) (HPROVIDER provider, C8 const FAR *interface_name, S32 entry_count, RIB_INTERFACE_ENTRY const FAR *rlist); extern "C" DLLEXPORT S32 AILCALL RIB_Main(HPROVIDER provider_handle, U32 up_down, RIB_alloc_provider_handle_ptr RIB_alloc_provider_handle, RIB_register_interface_ptr RIB_register_interface, RIB_unregister_interface_ptr RIB_unregister_interface );
Kod powyżej tak naprawdę nie robi nić możemy do niego dodać ładowanie naszej biblioteki poprzez np.
HINSTANCE LoadME; LoadMe = LoadLibrary("..\\enter a Path To Your Dll here\\LoadMe.dll"); if (LoadMe != 0) printf("LoadMe library loaded!\n"); else printf("LoadMe library failed to load!\n");
Spróbujmy dodać teraz kod będzie reagował na komendę w konsoli i wypisywał coś do niej.
Na początku potrzebujemy IDA PRO lub programu podobnego do niego.
Otwieramy plik hw.so i zaczynamy jego analizę następnie Edit-> Segments-> Rebase Program i ustawiamy ImageBase na on 0x40000000.
Znajdujemy adres cl_enginefuncs w hw.so. Według IDE PRO jest to 0x40134260. Jako że ImageBase to 0x40000000, offset dla tej struktury jest równy 0x134260.
W AsiMain.cpp deklarujemy
cl_enginefunc_t *cl_enginefuncs;
Przed RibMain deklarujemy funkcje
void Hello() { cl_enginefuncs->Con_Printf("Hello You!\n"); }
W RibMain dodajemy
HANDLE hw=LoadLibraryA("hw.dll"); cl_enginefuncs=(cl_enginefunc_t*)((unsigned long)hw+0x134260); cl_enginefuncs->pfnAddCommand("SayHello",Hello);
Po wpisaniu w konsole SayHello dostaniemy wiadomość Hello You!
Paczka projektu:
darkHack.zip Download