Skip to content

Instantly share code, notes, and snippets.

@rkr35
Last active June 25, 2019 14:50
Show Gist options
  • Select an option

  • Save rkr35/863f4331177d94df730a5e05abee3c7c to your computer and use it in GitHub Desktop.

Select an option

Save rkr35/863f4331177d94df730a5e05abee3c7c to your computer and use it in GitHub Desktop.
Cheat Engine Damage + MessageBox
#include <Windows.h>
#include <chrono>
#include <sstream>
#include <thread>
using Address = DWORD_PTR;
class CeString {
private:
Address* buffer;
auto get_size_for_msg(std::size_t msg_len) const {
auto size = msg_len / double(sizeof Address);
size = std::ceil(size);
return std::size_t(size);
}
public:
CeString(const char* message) {
const auto msg_len = std::strlen(message) + 1;
const auto size_for_msg = get_size_for_msg(msg_len);
buffer = new Address[3 + size_for_msg];
// Header of 1's.
buffer[0] = ~0;
// Length of string.
buffer[1] = msg_len;
// The actual string placed in memory.
std::memcpy(buffer + 2, message, msg_len);
// The footer. Not sure what these bytes do,
// but all strings in the tutorial seem to have this final piece.
buffer[2 + size_for_msg] = 0x10000;
}
~CeString() {
delete[] buffer;
buffer = nullptr;
}
Address get_string_address() const {
return Address(&buffer[2]);
}
};
void ce_msg_box(const CeString& s) {
using CeMsgBoxPrototype = void(Address);
static const auto CeMsgBox = (CeMsgBoxPrototype*)0x1001596d0;
CeMsgBox(s.get_string_address());
}
void ce_msg_box(const char* s) {
ce_msg_box(CeString(s));
}
using MessageBuffer = std::ostringstream;
void ce_msg_box(const MessageBuffer& body) {
ce_msg_box(body.str().c_str());
}
void sleep() {
using namespace std::literals::chrono_literals;
std::this_thread::sleep_for(100ms);
}
bool should_display_test_string() {
return GetAsyncKeyState(VK_HOME);
}
void display_test_string() {
CeString s("The quick brown fox jumps over the lazy dog.");
{
// Show the address of the string,
// so we can examine in memory if everything is properly layed out.
MessageBuffer b;
b << std::hex << s.get_string_address();
ce_msg_box(b);
}
ce_msg_box(s);
}
bool should_detach_dll() {
return GetAsyncKeyState(VK_END);
}
HANDLE g_MyThreadHandle = nullptr;
bool should_damage() {
return GetAsyncKeyState(VK_DELETE);
}
void damage() {
using PlayerBase = Address;
static const auto player_base = *(PlayerBase*)0x1002cb9e0;
using DamageFuncPrototype = void(PlayerBase);
static const auto DamageFunc = (DamageFuncPrototype*)0x10002b2b0;
DamageFunc(player_base);
}
DWORD WINAPI MyThread(_In_ LPVOID lpParameter) {
while (true) {
if (should_damage()) {
damage();
}
if (should_display_test_string()) {
display_test_string();
}
if (should_detach_dll()) {
ce_msg_box("detach");
CloseHandle(g_MyThreadHandle);
FreeLibraryAndExitThread(HINSTANCE(lpParameter), 0);
break;
}
sleep();
}
return 0;
}
BOOL WINAPI DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved) {
if (fdwReason == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(hinstDLL);
g_MyThreadHandle = CreateThread(nullptr, 0, MyThread, hinstDLL, 0, nullptr);
}
return TRUE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment