Skip to content

Instantly share code, notes, and snippets.

@Hexer10
Last active January 6, 2021 18:19
Show Gist options
  • Save Hexer10/3a528163e2bb9339d8117e0d5bd5c0f7 to your computer and use it in GitHub Desktop.
Save Hexer10/3a528163e2bb9339d8117e0d5bd5c0f7 to your computer and use it in GitHub Desktop.
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
Copy link

Can you explain how you obtain the correct memory addresses?

@rinukkusu
Copy link

@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