Last active
January 6, 2021 18:19
-
-
Save Hexer10/3a528163e2bb9339d8117e0d5bd5c0f7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'dart:convert'; | |
import 'dart:ffi'; | |
import 'dart:io'; | |
import 'package:ffi/ffi.dart'; | |
import 'package:win32/win32.dart'; | |
const healthOffset = 0x12FC58; | |
// List is not complete for all weapons | |
const ammoOffsets = { | |
0x2BE0D8, //Thompson | |
0x2BDFD8, //Thompson | |
0x2BE0A0, //M1A4 Carbine | |
0x2BDFA0, //M4A4 Carbine | |
0x2BE084, //Colt45 | |
0x2BDF84, // Colt45 | |
}; | |
void main() { | |
//TODO: Find process from executable and/or window name | |
print('Enter cod process id: '); | |
var pid = int.parse(stdin.readLineSync()); | |
// Open the process with Query, Read and Write permissions. | |
final hProcess = OpenProcess( | |
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, | |
FALSE, | |
pid); | |
var baseAddr = getBaseAddress(hProcess); | |
print('Available commands:'); | |
print('(e) enable -> Enable cheats'); | |
print('(d) disable -> Disable cheats'); | |
print('(q) quit -> Quit the process'); | |
Timer timer; | |
// Here we just listen for user inputs | |
stdin.transform(utf8.decoder).listen((event) { | |
event = event.toLowerCase().trim(); | |
if (event == 'e' || event == 'enable') { | |
if (timer != null) { | |
print('Cheat already enabled.'); | |
return; | |
} | |
// Start the timer to update the health and ammo every 200 ms | |
timer = Timer.periodic(const Duration(milliseconds: 200), (timer) { | |
setHealth(hProcess, baseAddr); | |
setAmmo(hProcess, baseAddr); | |
}); | |
print('Cheats enabled'); | |
} | |
if (event == 'd' || event == 'disable') { | |
if (timer == null) { | |
print('Cheat already disabled.'); | |
return; | |
} | |
// Stop the tiemer. | |
timer.cancel(); | |
timer = null; | |
print('Cheats disabled'); | |
} | |
if (event == 'q' || event == 'quit') { | |
exit(0); | |
} | |
}); | |
} | |
/// Returns the address from which the offsets are calculated. | |
int getBaseAddress(int hProcess) { | |
// The process cannot be 0. | |
if (hProcess == 0) { | |
print('Process not found.'); | |
exit(1); | |
} | |
final hModule = getModuleAddress(hProcess, 'gamex86.dll'); | |
// The module address cannot be 0 | |
if (hModule == 0) { | |
print('Module not found.'); | |
exit(2); | |
} | |
return hModule; | |
} | |
int getModuleAddress(int hProcess, String moduleName) { | |
// Get a list of all the modules in this process. | |
// Allocate the pointers to be used in [EnumProcessModulesEx] | |
final hMods = allocate<IntPtr>(count: 1024); | |
final cbNeeded = allocate<Uint32>(); | |
var addr = 0; | |
// This is used the loop all the modules of a process (ie the .dll s) | |
if (EnumProcessModulesEx( | |
hProcess, hMods, sizeOf<IntPtr>() * 1024, cbNeeded.cast(), 0x01) == | |
1) { | |
for (var i = 0; i < ((cbNeeded.value / sizeOf<IntPtr>()).floor()); i++) { | |
final szModName = allocate<Uint16>(count: MAX_PATH).cast<Utf16>(); | |
// Get the full path to the module's file. | |
final hModule = hMods.elementAt(i).value; | |
// Try to find the given module. | |
//TODO: Replace GetModuleFileNameEx with GetModuleBaseName | |
if (GetModuleFileNameEx(hProcess, hModule, szModName, MAX_PATH) != 0) { | |
var str = szModName.unpackString(MAX_PATH); | |
if (str.endsWith(moduleName)) { | |
addr = hModule; | |
break; | |
} | |
} | |
free(szModName); | |
} | |
} | |
free(hMods); | |
free(cbNeeded); | |
return addr; | |
} | |
void setHealth(int hProcess, int baseAddr, [var value = 1000]) { | |
// Get the location pointer. | |
final location = Pointer.fromAddress(baseAddr + healthOffset); | |
// Allocate the value pointer. | |
var intWrite = allocate<Int32>(count: sizeOf<Int32>()); | |
// Set the new value. | |
intWrite.value = value; | |
// Write into the process memory at [location]. | |
WriteProcessMemory(hProcess, location.cast(), intWrite.cast(), | |
sizeOf<Pointer<Int32>>(), nullptr); | |
} | |
void setAmmo(int hProcess, int baseAddr, [var value = 1050]) { | |
// Allocate the value pointers. | |
var intWrite = allocate<Uint32>(count: sizeOf<Uint32>()); | |
intWrite.value = value; | |
// Loop all the ammo offsets. | |
for (var offset in ammoOffsets) { | |
// Get the location pointer. | |
final location = Pointer.fromAddress(baseAddr + offset); | |
// Write into the process memory at [location]. | |
WriteProcessMemory(hProcess, location.cast(), intWrite.cast(), | |
sizeOf<Pointer<Uint32>>(), nullptr); | |
} | |
} |
@purplecandy You could either do that yourself with CheatEngine for instance: https://www.youtube.com/watch?v=Pst-4NwY2is
Or just visit a forum like UnKnoWnChEaTs because someone probably did that work already. 😸
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Can you explain how you obtain the correct memory addresses?