📜 ⬆️ ⬇️

We write cheat for GTA San Andreas

Each gamer sooner or later thinks about simplifying the passage of certain levels of the game, the ability to cheat, etc. For this purpose, special programs are used, such as ArtMoney , but this is not always possible and sometimes it is tedious to periodically correct the data in memory to achieve the goals. Automate this process helps various cheats and trainers . About creating a cheat will be discussed further.

GTA San Andreas was chosen as the test subject and we will torment it. In order to "twist" the game picture as we need, it is enough to change some areas of memory. How to do it? After all, in Windows processes are isolated from each other and just do not get into the memory of another process. Of course, you can use the WinAPI function WriteProcessMemory () , but we will proceed differently by adding our own code to the game. There are several ways to do this, including injecting into the required process, but antiviruses "dislike" this method and may raise an alarm. Therefore, we use the property of Windows to search for libraries, first in the folder with the running program, and then in other places. This method is usually in antivirus does not cause suspicion.
You need to see which functions from which libraries are imported by the program, find the one from which the least functions are imported and write a DLL filter for it. In the case of GTA San Andreas, such a library turned out to be Dinput8.dll, from which only one function is imported — DirectInput8Create () .
Now you need to create your DLL, in which, among other things, the DirectInput8Create () function must be exported. When called, the similar one from the same-name system library WWindows should be called. Otherwise, the work of the game will be disrupted!
You can create a DLL in almost any programming language. I chose PureBasic.

Cheat code
;   GTA San Andreas. Prototype pDirectInput8Create(hinst, dwVersion.l, riidltf, *ppvOut, *punkOuter) ;  . Procedure.s GetSysDir() Protected Result.s="", len, *Mem *Mem=AllocateMemory(#MAX_PATH) If *Mem Len=GetSystemDirectory_(*Mem, #MAX_PATH) Result=PeekS(*Mem, Len)+"\" FreeMemory(*Mem) EndIf ProcedureReturn Result EndProcedure Procedure.b TestMemory(*Pointer, Size) ;       . Protected mbi.MEMORY_BASIC_INFORMATION Protected Result.b = #False, dwWrote If Size dwWrote = VirtualQuery_(*Pointer, @mbi, SizeOf(MEMORY_BASIC_INFORMATION)) If dwWrote If mbi\BaseAddress+mbi\RegionSize >= *Pointer+Size If mbi\Protect & (#PAGE_READONLY | #PAGE_READWRITE | #PAGE_EXECUTE_READ | #PAGE_EXECUTE_READWRITE) Result = #True EndIf EndIf EndIf EndIf ProcedureReturn Result EndProcedure Procedure WriteMemF(*Address, Infa.f) ;    Float . If TestMemory(*Address, 4) PokeF(*Address, Infa) EndIf EndProcedure Procedure WriteMemL(*Address, Infa.l) ;    Long . If TestMemory(*Address, 4) PokeL(*Address, Infa) EndIf EndProcedure Procedure.l ReadMemL(*Address) ;    Long . If TestMemory(*Address, 4) ProcedureReturn PeekL(*Address) Else ProcedureReturn -1 EndIf EndProcedure Procedure WinTimer() Protected *Point Static Count ;  (  1000000,  ). Maney = ReadMemL($00B7CE50) If Maney>=0 And Maney<1000000 WriteMemL($00B7CE50, 1000000) EndIf ;   . If TestMemory($00B6F5F0, SizeOf(Integer)) *Point = PeekI($00B6F5F0) If TestMemory(*Point, 4) ; . WriteMemF(*Point+1344, 100) ; . WriteMemF(*Point+1352, 100) ; ,   . WriteMemL(*Point+1504, 1000) WriteMemL(*Point+1508, 1000) ; ,   . WriteMemL(*Point+1532, 1000) WriteMemL(*Point+1536, 1000) ; SMG,   . WriteMemL(*Point+1560, 1000) WriteMemL(*Point+1564, 1000) ; ,   . WriteMemL(*Point+1588, 1000) WriteMemL(*Point+1592, 1000) ; ,   . WriteMemL(*Point+1616, 1000) WriteMemL(*Point+1620, 1000) ; ,   . WriteMemL(*Point+1644, 1000) WriteMemL(*Point+1648, 1000) ; ,   . WriteMemL(*Point+1672, 1000) WriteMemL(*Point+1676, 1000) ; /,   . WriteMemL(*Point+1700, 1000) WriteMemL(*Point+1704, 1000) EndIf EndIf ; . If TestMemory($00BA18FC, SizeOf(Integer)) *Point = PeekI($00BA18FC) If TestMemory(*Point, 4) ;   . WriteMemF(*Point+1216, 1000) EndIf EndIf If Count>10 Count=0 ;  -   ( 1000). WriteMemL($00B791B4, 1000) ;  -   ( 1000). WriteMemL($00B791B8, 1000) ;  -   ( 1000). WriteMemL($00B790A0, 1000) ;  -   ( 1000). WriteMemL($00B7919C, 1000) ;  -  ( 1000). WriteMemL($00B791C4, 1000) ;  -   ( 1000). WriteMemL($00B791A4, 1000) ;  -  ( 1000). WriteMemF($00B793DC, 1000) ;  -  ( 1000). ;WriteMemF($00B79480, 1000) ;  -  ( 1000). WriteMemF($00B793D8, 1000) ;  -  AK47 ( 1000). WriteMemF($00B794B4, 1000) ;  -    ( 1000). WriteMemF($00B794A8, 1000) ;  -  Desert Eagle ( 1000). WriteMemF($00B7949C, 1000) ;  -  M4 ( 1000). WriteMemF($00B794B8, 1000) ;  -  - ( 1000). WriteMemF($00B794AC, 1000) ;  -   ( 1000). WriteMemF($00B79494, 1000) ;  -  SMG ( 1000). WriteMemF($00B794B0, 1000) ;  -   ( 1000). WriteMemF($00B794A4, 1000) ;  -   ( 1000). WriteMemF($00B794A0, 1000) ;  -     ( 1000). WriteMemF($00B79498, 1000) Else Count+1 EndIf EndProcedure ;      . Procedure Thread(*Void) Shared hWnd_SanAndreas Protected Count Delay(4000) Count=0 Repeat ;   . hWnd_SanAndreas=FindWindow_(0, "GTA: San Andreas") If hWnd_SanAndreas<>0 ;    SetTimer_(hWnd_SanAndreas, 10, 800, @WinTimer()) ;    Break ;   . EndIf Delay(100) Count+1 If Count>20 ;   . Beep_(1000,200) Break EndIf ForEver EndProcedure ;      DLL. ProcedureDLL AttachProcess(Instance) Global WinAPI_DirectInput8Create=0, hLib_Dinput8, ThreadID ;   Dinput8.dll hLib_Dinput8 = LoadLibrary_(GetSysDir()+"Dinput8.dll") If hLib_Dinput8 WinAPI_DirectInput8Create.pDirectInput8Create = GetProcAddress_(hLib_Dinput8, "DirectInput8Create") EndIf If WinAPI_DirectInput8Create=0 MessageRequester("", "   ."+Chr(10)+" .") EndIf ;   . ThreadID=CreateThread(@Thread(), 0) EndProcedure ;      DLL. ProcedureDLL DetachProcess(Instance) Shared hWnd_SanAndreas If hLib_Dinput8 FreeLibrary_(hLib_Dinput8) hLib_Dinput8 = 0 EndIf If ThreadID And IsThread(ThreadID) KillThread(ThreadID) ThreadID=0 EndIf If hWnd_SanAndreas<>0 And IsWindow_(hWnd_SanAndreas) KillTimer_(hWnd_SanAndreas, 10) hWnd_SanAndreas=0 EndIf EndProcedure ;     WinAPI DirectInput8Create. ProcedureDLL DirectInput8Create(hinst, dwVersion.l, riidltf, *ppvOut, *punkOuter) If WinAPI_DirectInput8Create ProcedureReturn WinAPI_DirectInput8Create(hinst, dwVersion, riidltf, *ppvOut, *punkOuter) EndIf EndProcedure 

The AttachProcess () procedure is called by the system when loading a DLL. It loads the dinput8.dll system library. In this case, the absolute path of loading is clearly indicated, otherwise the library would load itself, but we don’t need it! If the library is successfully loaded, we get a pointer to its DirectInput8Create () function. In case of failure, a message is displayed, informing the user about the failure. After that, a parallel thread is started and the procedure ends. We need the thread so as not to "hang" the program. In the stream (the Thread () procedure), the game window is searched for, by the title “GTA: San Andreas”. As soon as the window is found, a timer is “hung” on it and the work of the thread stops on this. Of course, one could do without a timer and perform all actions in the stream, but for security reasons, it was decided to modify the memory from the main flow of the game.
The WinTimer () procedure is called on a timer every 800 milliseconds. It changes the values ​​of the required variables. But before the change, be sure to check whether this address is available to the process or not.
The cheat maintains the proper level of armor, player and vehicle health, player skills, as well as the number of rounds. In addition, the player is given lemon bucks and if he spends them, they reappear from nothing.
This cheat will appeal to those who like to unleash a war with the cops. It will be very difficult for them to destroy a player even by shooting him point-blank.

From this code you need to create a DLL with the name Dinput8.dll and place it in the same folder with the game.
To get a DLL, you need to select in the properties of the compiler in the list of "Format of executable file", the item "Shared Dll" with the loaded code in the IDE.
')
image

Source: https://habr.com/ru/post/146791/


All Articles