- Версия SA-MP
-
- 0.3.7 (R1)
Описание: почему-то на evolve-rp нельзя отключить/перебиндить бинды в лаунчере😡
плагин патчит отправку команд по бинду, отменяя их, а при отгрузке возвращает все обратно.
это мое первое подобное творение, экспертов прошу не судить, а написать развернутый код ревью =DD
плагин патчит отправку команд по бинду, отменяя их, а при отгрузке возвращает все обратно.
C++:
#include <windows.h>
#include <iostream>
#include <thread>
#include <psapi.h>
class xd {
public:
xd()
{
std::thread([&] {
while (!GetModuleHandleA("EvolveProcessing.asi")) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
function_address = find_pattern("EvolveProcessing.asi", "\xE8\x00\x00\x00\x00\x8D\x8D\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x8D\x8D\x00\x00\x00\x00\xC7\x45\x00\x00\x00\x00\x00", "x????xx????x????xx????xx?????");
patch_function((function_address));
}).detach();
};
~xd()
{
restore_original((function_address));
};
private:
uint32_t function_address = { 0 };
uint8_t* original_bytes = nullptr;
size_t original_size = 0;
uint32_t find_pattern(const char* sz_module, const char* pattern, const char* mask)
{
MODULEINFO mInfo = { 0 };
HMODULE hModule = GetModuleHandleA(sz_module);
if (!hModule)
return 0;
GetModuleInformation(GetCurrentProcess(), hModule, &mInfo, sizeof(MODULEINFO));
uintptr_t begin = (uintptr_t)mInfo.lpBaseOfDll;
DWORD size = mInfo.SizeOfImage;
size_t patternLen = strlen(mask);
for (DWORD i = 0; i < size; i++)
{
bool found = true;
for (size_t j = 0; j < patternLen; j++)
{
if (mask[j] != '?' && pattern[j] != *(char*)(begin + i + j))
{
found = false;
break;
}
}
if (found)
{
uint32_t call_instruction_address = static_cast<uint32_t>(begin + i);
int32_t relative_offset = *reinterpret_cast<int32_t*>(call_instruction_address + 1);
uint32_t function_address = call_instruction_address + relative_offset + 5; // 5 = call size
return function_address;
}
}
return 0;
}
void patch_function(uint32_t address) {
const uint8_t newBytes[] = { 0x6A, 0x00, 0x58, 0xC2, 0x04, 0x00 };
if (original_bytes == nullptr) {
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery((LPCVOID)address, &mbi, sizeof(mbi));
original_size = mbi.RegionSize;
original_bytes = new uint8_t[original_size];
memcpy(original_bytes, (LPVOID)address, original_size);
}
DWORD oldProtect;
VirtualProtect((LPVOID)address, sizeof(newBytes), PAGE_EXECUTE_READWRITE, &oldProtect);
memcpy((LPVOID)address, newBytes, sizeof(newBytes));
VirtualProtect((LPVOID)address, sizeof(newBytes), oldProtect, &oldProtect);
}
void restore_original(uint32_t address) {
if (original_bytes != nullptr) {
DWORD oldProtect;
VirtualProtect((LPVOID)address, original_size, PAGE_EXECUTE_READWRITE, &oldProtect);
memcpy((LPVOID)address, original_bytes, original_size);
VirtualProtect((LPVOID)address, original_size, oldProtect, &oldProtect);
delete[] original_bytes;
}
}
} xd;
Вложения
Последнее редактирование: