Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Windows.h>
- #include <string>
- #include <iostream>
- #include <list>
- #include <psapi.h>
- std::string GetProcessName(DWORD processID)
- {
- std::string result;
- TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
- HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
- PROCESS_VM_READ,
- FALSE, processID);
- if (hProcess) {
- HMODULE hMod;
- DWORD cbNeeded;
- if (EnumProcessModules(hProcess, &hMod, sizeof(hMod),
- &cbNeeded)) {
- GetModuleBaseName(hProcess, hMod, szProcessName,
- sizeof(szProcessName) / sizeof(TCHAR));
- }
- }
- for (size_t i = 0 ; i < MAX_PATH && szProcessName[i] ; ++i) {
- if (szProcessName[i] >= 32 && szProcessName[i] < 128) {
- result.push_back(static_cast<char>(szProcessName[i]));
- } else {
- result.push_back('?');
- }
- }
- CloseHandle(hProcess);
- return result;
- }
- bool Same(const std::string &s1, const std::string &s2)
- {
- if (s1.size() != s2.size()) {
- return false;
- }
- for (size_t i = 0 ; i < s1.size() ; ++i) {
- if (tolower(s1[i]) != tolower(s2[i])) {
- return false;
- }
- }
- return true;
- }
- DWORD FindProcess(const std::string &name)
- {
- DWORD aProcesses[1024], cbNeeded, cProcesses;
- unsigned int i;
- if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) {
- return 0;
- }
- cProcesses = cbNeeded / sizeof(DWORD);
- for (i = 0; i < cProcesses; i++) {
- if (aProcesses[i] != 0) {
- std::string processName = GetProcessName(aProcesses[i]);
- if (Same(processName, name)) {
- return aProcesses[i];
- }
- }
- }
- return 0;
- }
- HANDLE FindModule(HANDLE process, const std::string &name)
- {
- HMODULE hMods[1024];
- DWORD cbNeeded;
- if (EnumProcessModules(process, hMods, sizeof(hMods), &cbNeeded)) {
- for (size_t i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
- TCHAR szModName[MAX_PATH];
- if (!hMods[i]) {
- continue;
- }
- if (size_t len = GetModuleFileNameEx(process, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) {
- std::string name2;
- for (size_t j = 0 ; j < len ; ++j) {
- name2.push_back((static_cast<unsigned>(szModName[j]) > 32 && static_cast<unsigned>(szModName[j]) <= 127) ? szModName[j] : '?');
- }
- if (name.size() > name2.size()) {
- continue;
- }
- if (!Same(name2.substr(name2.size() - name.size()), name)) {
- continue;
- }
- return hMods[i];
- }
- }
- }
- return 0;
- }
- bool ReadMemoryBYTES(HANDLE process, UINT64 address, unsigned char *buffer, UINT32 size)
- {
- DWORD flOldProtect;
- VirtualProtectEx(process, (LPVOID) address, size, PAGE_EXECUTE_READ, &flOldProtect);
- SIZE_T br = 0;
- bool result = false;
- if (ReadProcessMemory(process, reinterpret_cast<LPVOID>(address), buffer, size, &br)) {
- if (br == size) {
- result = true;
- }
- }
- VirtualProtectEx(process, (LPVOID) address, size, flOldProtect, &flOldProtect);
- return result;
- }
- void WriteMemoryBYTES(HANDLE process, UINT64 address, const void *bytes, unsigned int len)
- {
- DWORD flOldProtect;
- SIZE_T uNumberOfBytesWritten;
- VirtualProtectEx(process, (LPVOID) address, len, PAGE_WRITECOPY, &flOldProtect);
- WriteProcessMemory(process, (LPVOID) address, bytes, len, &uNumberOfBytesWritten);
- FlushInstructionCache(process, (LPVOID) address, len);
- VirtualProtectEx(process, (LPVOID) address, len, flOldProtect, &flOldProtect);
- }
- class PatchData {
- public:
- class PatchItem {
- public:
- PatchItem(const UINT64 address, const char *oldData, const char *newData, const size_t size) :
- address(address), oldData(oldData, size), newData(newData, size), size(size)
- {
- }
- public:
- const UINT64 address;
- const std::string oldData;
- const std::string newData;
- const size_t size;
- };
- PatchData(const bool reverse) :
- reverse(reverse)
- {
- }
- void Add(const UINT64 address, const char *oldData, const char *newData, const size_t size)
- {
- if (reverse) {
- items.push_back(PatchItem(address, newData, oldData, size));
- } else {
- items.push_back(PatchItem(address, oldData, newData, size));
- }
- }
- const bool reverse;
- std::list<PatchItem> items;
- };
- std::string Hex(const void *data, const size_t size)
- {
- std::string result;
- char buffer[16];
- for (size_t i = 0 ; i < size ; ++i) {
- sprintf(buffer, "%02X", reinterpret_cast<const unsigned char*>(data)[i]);
- if (i) {
- result.push_back(' ');
- }
- result += buffer;
- }
- return result;
- }
- int main(int argc, char **argv)
- {
- if (argc > 2 || (argc == 2 && std::string("-r") != argv[1])) {
- std::cerr << "Usage: " << argv[0] << "[-r]" << std::endl;
- return 1;
- }
- const std::string processName = "l2server.exe";
- const std::string moduleName = "l2server.exe";
- const bool reverse = (argc == 2);
- PatchData data(reverse);
- data.Add(0x4ABC3A, "\x45\x3B\xD4\x45\x0F\x4C\xE2", "\x31\xDB\x89\x5C\x24\x3C\x90", 7);
- data.Add(0x4ABC4A, "\x3B\xCE\x45\x0F\x4C\xF1", "\x8D\x74\x24\xA0\x31\xFF", 6);
- data.Add(0x4AC31E, "\x44\x3B\xCF\x41\x0F\x4C\xF9", "\x31\xDB\x89\x5C\x24\x68\x90", 7);
- data.Add(0x4AC32C, "\x45\x3B\xC6\x45\x0F\x4C\xF0", "\x44\x8D\x77\xA0\x45\x31\xE4", 7);
- std::cerr << "Searching for process " << processName << std::endl;
- DWORD pid = FindProcess(processName);
- if (!pid) {
- std::cerr << "Can't find process " << processName << std::endl;
- return 1;
- }
- std::cerr << "Found " << processName << std::endl;
- std::cerr << "Opening process " << pid << std::endl;
- HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid);
- if (!process) {
- std::cerr << "Can't open process " << pid << ": " << GetLastError() << std::endl;
- return 1;
- }
- std::cerr << "Process " << pid << " open" << std::endl;
- std::cerr << "Searching for module " << moduleName << std::endl;
- HANDLE module = FindModule(process, moduleName);
- if (!module) {
- std::cerr << "Can't find module " << moduleName << std::endl;
- return 1;
- }
- std::cerr << "Found module " << moduleName << " at " << module << std::endl;
- for (std::list<PatchData::PatchItem>::const_iterator i = data.items.begin() ; i != data.items.end() ; ++i) {
- UINT64 addr = reinterpret_cast<UINT64>(module) + i->address;
- std::cerr << "Checking " << i->size << " bytes of old data at " << reinterpret_cast<void*>(addr) << std::endl;
- std::string buffer(i->size, '\x00');
- ReadMemoryBYTES(process, addr, reinterpret_cast<unsigned char*>(const_cast<char*>(buffer.data())), i->size);
- if (buffer != i->oldData) {
- std::cerr << "Data mismatch at " << reinterpret_cast<void*>(addr) << std::endl;
- std::cerr << "Expected " << Hex(i->oldData.data(), i->size) << std::endl;
- std::cerr << "Got " << Hex(buffer.data(), i->size) << std::endl;
- return 1;
- }
- }
- std::cerr << "Data match" << std::endl;
- for (std::list<PatchData::PatchItem>::const_iterator i = data.items.begin() ; i != data.items.end() ; ++i) {
- UINT64 addr = reinterpret_cast<UINT64>(module) + i->address;
- std::cerr << "Patching " << i->size << " bytes at " << reinterpret_cast<void*>(addr) << std::endl;
- WriteMemoryBYTES(process, addr, reinterpret_cast<const void*>(i->newData.data()), i->size);
- }
- std::cerr << "Done!" << std::endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement