- Версия SA-MP
-
- 0.3.7-R3
Поскольку гонщик так и не решился обновлять сф, я решил исправить эти баганные функции именно так, как они должны были работать.
Модификация исправляет опкоды:
Нужен только для SAMP 0.3.7-R3-1!
Установка: перекинуть один из вариантов:
- .asi - в корневую папку с игрой.
- .lua - в папку moonloader.
Выбирайте на свой вкус.
Модификация исправляет опкоды:
Lua:
sampIsLocalPlayerSpawned() -- 0B61
sampGetPlayerHealth(int id) -- 0B25
sampGetPlayerArmor(int id) -- 0B26
Нужен только для SAMP 0.3.7-R3-1!
Установка: перекинуть один из вариантов:
- .asi - в корневую папку с игрой.
- .lua - в папку moonloader.
Выбирайте на свой вкус.
Lua:
function applySampfuncsPatch()
local memory = memory or require 'memory'
local module = getModuleHandle("SAMPFUNCS.asi")
if module ~= 0 and memory.compare(module + 0xBABD, memory.strptr('\x8B\x43\x04\x8B\x5C\x24\x20\x8B\x48\x34\x83\xE1'), 12) then
memory.setuint16(module + 0x83349, 0x01ac, true)
memory.setuint16(module + 0x8343c, 0x01b0, true)
memory.setuint16(module + 0x866dd, 0x00f4, true)
memory.setuint16(module + 0x866e9, 0x0306, true)
memory.setuint8(module + 0x8e754, 0x40, true)
end
end
function main() applySampfuncsPatch() end
Rust:
use winapi::shared::minwindef::{BOOL, DWORD, HMODULE, LPVOID, TRUE};
use winapi::um::winnt::DLL_PROCESS_ATTACH;
use winapi::um::libloaderapi::GetModuleHandleA;
use winapi::um::winnt::{LPCSTR, PAGE_EXECUTE_READWRITE};
use winapi::um::memoryapi::VirtualProtect;
use libc::{memcmp, c_void};
const PATTERN: &[u8; 12] = b"\x8B\x43\x04\x8B\x5C\x24\x20\x8B\x48\x34\x83\xE1";
unsafe fn patch_address_u16(address: usize, value: u16) {
let mut old_protection: DWORD = PAGE_EXECUTE_READWRITE;
VirtualProtect(address as LPVOID, std::mem::size_of::<u16>(), old_protection, &mut old_protection);
*(address as *mut u16) = value;
VirtualProtect(address as LPVOID, std::mem::size_of::<u16>(), old_protection, &mut old_protection);
}
unsafe fn patch_address_u8(address: usize, value: u8) {
let mut old_protection: DWORD = PAGE_EXECUTE_READWRITE;
VirtualProtect(address as LPVOID, std::mem::size_of::<u8>(), old_protection, &mut old_protection);
*(address as *mut u8) = value;
VirtualProtect(address as LPVOID, std::mem::size_of::<u8>(), old_protection, &mut old_protection);
}
#[no_mangle]
pub extern "system" fn DllMain(_instance: HMODULE, reason: DWORD, _reserved: LPVOID) -> BOOL {
match reason {
DLL_PROCESS_ATTACH => {
unsafe {
let module = GetModuleHandleA("SAMPFUNCS.asi\0".as_ptr() as LPCSTR) as usize;
if module != 0 && memcmp((module + 0xBABD) as *const c_void, std::mem::transmute::<&[u8; 12], *const c_void>(PATTERN), 12) == 0 {
patch_address_u16(module + 0x83349, 0x01ac);
patch_address_u16(module + 0x8343c, 0x01b0);
patch_address_u16(module + 0x866dd, 0x00f4);
patch_address_u16(module + 0x866e9, 0x0306);
patch_address_u8(module + 0x8e754, 0x40);
}
}
},
_ => {}
}
TRUE
}
C++:
template <typename T>
void applyPatch(uintptr_t address, T value)
{
DWORD old_protection = PAGE_EXECUTE_READWRITE;
VirtualProtect((void*)address, sizeof(value), old_protection, &old_protection);
*reinterpret_cast<T*>(address) = value;
VirtualProtect((void*)address, sizeof(value), old_protection, &old_protection);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD fdwReason, LPVOID lpReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
uintptr_t handle;
if (handle = reinterpret_cast<uintptr_t>(GetModuleHandleA("SAMPFUNCS.asi")), handle != 0 && !memcmp(handle + 0xBABD, "\x8B\x43\x04\x8B\x5C\x24\x20\x8B\x48\x34\x83\xE1", 12))
{
applyPatch<uint16_t>(handle + 0x83349, 0x01ac);
applyPatch<uint16_t>(handle + 0x8343c, 0x01b0);
applyPatch<uint16_t>(handle + 0x866dd, 0x00f4);
applyPatch<uint16_t>(handle + 0x866e9, 0x0306);
applyPatch<uint8_t>(handle + 0x8e754, 0x40);
}
}
return TRUE;
}
Вложения
Последнее редактирование: