- 1,936
- 3,166
Когда-то давно по беседам гулял для старой версии RakSAMP Lite этот скрипт.
Скрипт просто обновлен под новую версию.
Скрипт просто обновлен под новую версию.
Lua:
local ffi = require("ffi")
ffi.cdef[[
int VirtualProtect(void* lpAddress, unsigned long dwSize, unsigned long flNewProtect, unsigned long* lpflOldProtect);
void* VirtualAlloc(void* lpAddress, unsigned long dwSize, unsigned long flAllocationType, unsigned long flProtect);
int VirtualFree(void* lpAddress, unsigned long dwSize, unsigned long dwFreeType);
]]
local function VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect)
return ffi.C.VirtualProtect(ffi.cast('void*', lpAddress), dwSize, flNewProtect, lpflOldProtect)
end
local buff = {
free = {}
}
local function VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect, blFree)
local alloc = ffi.C.VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect)
if blFree then
table.insert(buff.free, alloc)
end
return ffi.cast('intptr_t', alloc)
end
local function copy(dst, src, len)
return ffi.copy(ffi.cast('void*', dst), ffi.cast('const void*', src), len)
end
local script_states = {
rak_client = {
offset = 0x4D369C,
pointer = 0x0,
original_func = nil,
rakclient_vmt = nil
},
settings = {
min_port = 40001,
max_port = 40002,
current_port = 0,
max_change_port_time = 5,
change_port_time = os.clock()
}
}
local vmt_hook = {hooks = {}}
function vmt_hook.new(vt)
local new_hook = {}
local org_func = {}
local old_prot = ffi.new('unsigned long[1]')
local virtual_table = ffi.cast('intptr_t**', vt)[0]
new_hook.this = virtual_table
new_hook.hookMethod = function(cast, func, method)
jit.off(func, true) --off jit compilation | thx FYP
org_func[method] = virtual_table[method]
VirtualProtect(virtual_table + method, 4, 0x4, old_prot)
virtual_table[method] = ffi.cast('intptr_t', ffi.cast(cast, func))
VirtualProtect(virtual_table + method, 4, old_prot[0], old_prot)
return ffi.cast(cast, org_func[method])
end
new_hook.unHookMethod = function(method)
VirtualProtect(virtual_table + method, 4, 0x4, old_prot)
local alloc_addr = VirtualAlloc(nil, 5, 0x1000, 0x40, false)
local trampoline_bytes = ffi.new('uint8_t[?]', 5, 0x90)
trampoline_bytes[0] = 0xE9
ffi.cast('int32_t*', trampoline_bytes + 1)[0] = org_func[method] - tonumber(alloc_addr) - 5
copy(alloc_addr, trampoline_bytes, 5)
virtual_table[method] = ffi.cast('intptr_t', alloc_addr)
VirtualProtect(virtual_table + method, 4, old_prot[0], old_prot)
org_func[method] = nil
end
new_hook.unHookAll = function()
for method, func in pairs(org_func) do
new_hook.unHookMethod(method)
end
end
table.insert(vmt_hook.hooks, new_hook.unHookAll)
return new_hook
end
function onLoad()
script_states.rak_client.pointer = ffi.cast("intptr_t*", script_states.rak_client.offset)[0]
if script_states.rak_client.pointer == nil then
return print("[Connect] Cannot get RakClient pointer.")
end
script_states.rak_client.rakclient_vmt = vmt_hook.new(script_states.rak_client.pointer)
script_states.rak_client.original_func = script_states.rak_client.rakclient_vmt.hookMethod("bool(__thiscall*)(void* this, const char* host, unsigned short serverPort, unsigned short clientPort, unsigned int depreciated, int threadSleepTimer)", onRakClientConnect, 1)
print("[Connect] Loaded. Author: heroku.")
print(("[Connect] RakClient pointer: 0x%x"):format(script_states.rak_client.pointer))
end
function onRakClientConnect(this, host, serverPort, clientPort, depreciated, threadSleepTimer)
if script_states.settings.change_port_time <= os.clock() then
math.randomseed(os.clock())
script_states.settings.current_port = math.random(script_states.settings.min_port, script_states.settings.max_port)
script_states.settings.change_port_time = os.clock() + script_states.settings.max_change_port_time
end
local boolResult = script_states.rak_client.original_func(this, host, serverPort, script_states.settings.current_port, depreciated, threadSleepTimer)
return boolResult
end
registerHandler('onUnload', function()
for i, addr in ipairs(buff.free) do
ffi.C.VirtualFree(addr, 0, 0x8000)
end
for i, unHookFunc in ipairs(vmt_hook.hooks) do
unHookFunc()
end
end)
Последнее редактирование: