id = ffi.cast("int*", id)
Lua:
id = ffi.new("int[1]", id)
id = ffi.cast("int*", id)
id = ffi.new("int[1]", id)
Бля вы тему вообще читать умеете? буквально пару постов назад писали решение блятьПишу либу для ракнет хуков, но все упирается в баг с вызовом мейна. Есть какие-нибудь способы это решить (подойдут уже даже костыли, главное, чтобы в скрипте, в который подключаешь либу ракнет хуков, которая в свою очередь юзает либу хуков, было все нормально)?
Чет невнимательно прочитал ответ Фипа, почему-то подумал, что надо оффать компиляцию у каллбека, а не у хука.Бля вы тему вообще читать умеете? буквально пару постов назад писали решение блять
Lua - FastLink by СоМиК
Можно хукать не только серверные сообщения, а сообщения скриптов или клиента (sa:mp started и т.д) https://www.blast.hk/threads/39138/ Конкретно хук чата: https://www.blast.hk/threads/39138/page-2#post-433643 На данной версии ML эти хуки работают нестабильно и постоянно приводят к крашам...www.blast.hk
local function CTimer__Update()
-- ...
if (pSAMPInfo == 0) then return originalCTimer__Update() end
-- ...
rakClient = hooks.vmt.new(raknet.pRakClient[0])
raknet.originalOutgoingPacket = rakClient.hookMethod(
"bool(__thiscall*)(void*, uintptr_t, char, char, char)",
handleOutgoingPacket, 6
)
raknet.originalOutgoingRpc = rakClient.hookMethod(
"bool(__thiscall*)(void*, int*, uintptr_t, char, char, char, bool)",
handleOutgoingRpc, 25
)
raknet.originalIncomingRpc = hooks.jmp.new(
"void(__fastcall*)(void*, void*, unsigned char*, int, int)",
handleIncomingRpc, getOffsetFromBase("handleRpcPacket", samp)
)
jit.off(handleOutgoingPacket, true)
jit.off(handleOutgoingRpc, true)
jit.off(handleIncomingRpc, true)
originalCTimer__Update.stop()
return originalCTimer__Update.call()
end
originalCTimer__Update = hooks.jmp.new(
"void(__cdecl*)()",
CTimer__Update, getOffsetFromBase("CTimerUpdate")
)
jit.off(CTimer__Update, true)
function handleOutgoingPacket(this, bitStream, priority, reliability, orderingChannel)
-- ...
end
function handleOutgoingRpc(this, id, bitStream, priority, reliability, orderingChannel, shiftTimestamp)
end
function handleIncomingRpc(this, void, data, length, playerId)
end
local function handleIncomingPacket(this, void)
local packet = raknet.originalIncomingPacket(this)
while (packet ~= nil) do
if (packet.data == nil) or (packet.length == 0) then break end
utils:callVirtualMethod(raknet.pRakClient[0], "void(__thiscall*)(void*, Packet*)", 9, this, packet) -- DeallocatePacket
packet = raknet.originalIncomingPacket(this)
end
return packet -- судя по всему что-то опять недомудрил с ffi
end
--
raknet.originalIncomingPacket = rakClient.hookMethod(
"Packet*(__thiscall*)(void*, void)",
handleIncomingPacket, 8
)
ffi.cdef([[
typedef unsigned short PlayerIndex;
typedef struct {
int binaryAddress;
unsigned short port;
} PlayerID;
typedef struct {
PlayerIndex playerIndex;
PlayerID playerId;
unsigned int length;
unsigned int bitSize;
unsigned char* data;
bool deleteData;
} Packet;
]])
function utils:callVirtualMethod(vt, prototype, method, ...)
local cast = ffi.cast
local virtualTable = cast("intptr_t**", vt)[0]
return cast(prototype, virtualTable[method])(...)
end
братан, а если у меня первый скрипт выводит сообщение в чат "Route ended" через команду sampAddChatMessage("Route ended"). То как мне сделать код,чтобы при выводе "Route ended" в чат мой второй скрипт нажимал на пробел
local ffi = require("ffi")
local hooks = require("hooks")
local originalCChat_AddEntry
local samp = getModuleHandle("samp.dll")
local offsets = {
CChat_AddEntry = {
["DLR1"] = 0x67650,
["R1"] = 0x64010,
["R2"] = 0x640E0,
["R3"] = 0x67460,
["R4"] = 0x67BA0,
["R5"] = 0x67BE0
}
}
function CChat_AddEntry(this, nType, szText, szPrefix, textColor, prefixColor)
if (nType == 8) then
local text = ffi.string(szText)
if (text == "Route ended") then
print("ХУК СООБЩЕНИЯ, ЕЕЕЕ", text)
end
end
return originalCChat_AddEntry(this, nType, szText, szPrefix, textColor, prefixColor)
end
originalCChat_AddEntry = hooks.jmp.new(
"unsigned int(__thiscall*)(void *this, int nType, const char *szText, const char *szPrefix, unsigned int textColor, unsigned int prefixColor)",
CChat_AddEntry, (samp + offsets.CChat_AddEntry["R1"]) -- тут указывается версия SAMP
)
Смириться и стараться не хукать много в одном скрипте, особенно то что часто вызывается. При ловле бага перазагружатьсябаг с вызовом мейна
local imgui = require("mimgui")
imgui.OnFrame(function() return true end, function()
imgui.Begin("noname")
imgui.End()
end)
Я понял что из-за этого бага с jit вызывается main, в функции main идёт создание хука, но если сделать проверку на загруженность main и не вызывать повторно создание хука то всё работает вроде бы нормально. У меня 3 хука в скрипте, один на пресент, ресет и на функцию создания взрыва в игре. При этом всём стабильная работа, просадок фпс не замечено, со скрипом максимум 305-310 фпс, без прыгает 307-309. Думаю хороший результат для большого скрипта где используется очень много редактирования памяти, замена указателей.Смириться и стараться не хукать много в одном скрипте, особенно то что часто вызывается. При ловле бага перазагружаться
Заметил такую особенность, корутины которые врапнуты мунлоадером(или сол2?), то есть сам main() и созданное через lua_thread.create, повышают шансы на краш/баг или в случае https://www.blast.hk/threads/202297/ гарантируют краш(врапнутая корутина + хук который вызывается постоянно = отрицательный успех).
Но отказ от main и потоков все равно не панацея, как и jit.off, просто еще уменьшатся шансы краша и вы живете дольше, вероятно до самого конца игровой сессии в большинстве случаев :). Хук RakPeerAddPacketToProducerHooked спокойно долго жил у меня без main, но если я добавлял main/потоки или еще один хук CRadar_Draw, который тоже постоянно вызывается то уже ловил краши.
Если все эти рофлы с хуками не прикольные и постоянные, и вы не можете/лень от них отказаться по какой-то причине, то можно попробовать таскать с основным скриптом скрипт-помощник в котором только хуки и нет main/lua_thread.create, а делиться данными через https://wiki.blast.hk/moonloader/exports . Не уверен что это рабочая схема, не проверял, но может сработать или наоборот сделать еще печальнее
Сама эта ситуация похожа на то что было/есть с асинхронными запросами(особенно способ с lanes), со временем начинает лететь много исключений E24C4A02 и в какой-то момент луажит задалбливается их ловить и крашится игра
Советую еще сбилдить самому luajit с последних коммитов в режиме дебага, стек будет чище, ниже стандартный lua51.dll с архива муна 26
Типичный callstack при исключении когда есть скрипты с луа хуком, и далее 4 варианта рандома: пофиг(для меня почти всегда на чистой сборке), начинается спам main(уппс сломалась корутина, забыла место где остановилась хаха), краш игры или cannot resume non-suspended coroutine(очень редко)
moonloader 26 base - 0x6AEE0000
Посмотреть вложение 244679
Но мб дело в другом, потому что исключение с таким же кодом вылетает время от времени(а иногда каждый кадр) и от просто скрипта сВозможно это даже норма для муна/луажита хДLua:local imgui = require("mimgui") imgui.OnFrame(function() return true end, function() imgui.Begin("noname") imgui.End() end)
callstack с пустым moonloader 26, только скрипт с кодом выше, mimgui v1.7.1
moonloader 26 base - 0x6AEE1000
Посмотреть вложение 244683
struct SwimSpeedFix
{
void operator()(reg_pack& regs)
{
*(float*)(regs.esp + 0x1C) *= 1.0f / (CTimer::ms_fTimeStep / magic);
*(float*)(regs.esp + 0x20) *= 1.0f / (CTimer::ms_fTimeStep / magic);
*(float*)(regs.esp + 0x18) *= 1.0f / (CTimer::ms_fTimeStep / magic);
float f = *(float*)(regs.eax + 0x00);
asm_fld_st1();
asm_fmul(f);
asm_fld_st2();
}
}; MakeInline<SwimSpeedFix>(0x68A50E, 0x68A50E + 6);
Скорее всего не получится реализовать naked хук, ибо как я знаю, ffi не дает создать функции без пролога и эпилога и в таком случае скорее всего стек поломается. Конечно, можно использовать байткод и просто загружать байты в память (опять же, в качестве функции), но реализация этого не самая быстрая задача (особенно, если хочешь передавать значения из луа в память)@RTD Возможно ли с помощью твоей либы хукать внутренность функции игры? Как пример код:
Нужно каким-то образом реализовать хук, чтобы сделать прыжок на свою функцию, в ней произвести расчёты и вернуть функции модифицированное значение. Крч мне надо сделать исправление плавания при большом фпс на луа, а проблема в том что у меня нет даже представления как это сделать, на плюсах это понятнее сделать т.к уровень языка низкий. Я уже не говорю что нет нормальной возможности сделать _asm вставку на луа как на плюсах.Frame Vigilante:struct SwimSpeedFix { void operator()(reg_pack& regs) { *(float*)(regs.esp + 0x1C) *= 1.0f / (CTimer::ms_fTimeStep / magic); *(float*)(regs.esp + 0x20) *= 1.0f / (CTimer::ms_fTimeStep / magic); *(float*)(regs.esp + 0x18) *= 1.0f / (CTimer::ms_fTimeStep / magic); float f = *(float*)(regs.eax + 0x00); asm_fld_st1(); asm_fmul(f); asm_fld_st2(); } }; MakeInline<SwimSpeedFix>(0x68A50E, 0x68A50E + 6);
С вас 1000 денег@RTD Возможно ли с помощью твоей либы хукать внутренность функции игры? Как пример код:
Нужно каким-то образом реализовать хук, чтобы сделать прыжок на свою функцию, в ней произвести расчёты и вернуть функции модифицированное значение. Крч мне надо сделать исправление плавания при большом фпс на луа, а проблема в том что у меня нет даже представления как это сделать, на плюсах это понятнее сделать т.к уровень языка низкий. Я уже не говорю что нет нормальной возможности сделать _asm вставку на луа как на плюсах.Frame Vigilante:struct SwimSpeedFix { void operator()(reg_pack& regs) { *(float*)(regs.esp + 0x1C) *= 1.0f / (CTimer::ms_fTimeStep / magic); *(float*)(regs.esp + 0x20) *= 1.0f / (CTimer::ms_fTimeStep / magic); *(float*)(regs.esp + 0x18) *= 1.0f / (CTimer::ms_fTimeStep / magic); float f = *(float*)(regs.eax + 0x00); asm_fld_st1(); asm_fmul(f); asm_fld_st2(); } }; MakeInline<SwimSpeedFix>(0x68A50E, 0x68A50E + 6);
local ffi = require("ffi")
local hook = require("hooks")
--[[
push ebp
mov ebp, esp
pushad
push ebp
call lua_hook
add esp, 4
popad
pop ebp
restore original 6 opcodes
jmp back
]]
local proxy_call = [[
55
89 e5
60
55
e8 00 00 00 00
83 c4 04
61
5d
d9 c1
d8 08
d9 c2
e9 00 00 00 00
]]
local proxy_bytes = (function()
local bytes = {}
for byte in proxy_call:gmatch('(%x%x)') do
table.insert(bytes, tonumber(byte, 16))
end
return bytes
end)()
local proxy_bytes_size = #proxy_bytes
proxy_bytes = ffi.new('uint8_t[?]', proxy_bytes_size, proxy_bytes)
local alloc_addr = tonumber(ffi.cast('intptr_t', ffi.C.VirtualAlloc(nil, proxy_bytes_size, 0x1000, 0x40)))
ffi.copy(ffi.cast('void*', alloc_addr), proxy_bytes, proxy_bytes_size)
local hook_addr = 0x68A50E
local hook_size = 6
ffi.cast('uint32_t*', alloc_addr + proxy_bytes_size - 4)[0] = hook_addr - alloc_addr - proxy_bytes_size + hook_size
local old_prot = ffi.new('unsigned long[1]')
ffi.C.VirtualProtect(ffi.cast('void*', hook_addr), hook_size, 0x40, old_prot)
ffi.cast('uint8_t*', hook_addr)[0] = 0xE9
ffi.cast('uint32_t*', hook_addr + 1)[0] = alloc_addr - hook_addr - 5
ffi.fill(ffi.cast('void*', hook_addr + 5), hook_size - 5, 0x90)
ffi.C.VirtualProtect(ffi.cast('void*', hook_addr), hook_size, old_prot[0], old_prot)
local proxy_call_opcode_pos = (function()
for i = 0, proxy_bytes_size do
if proxy_bytes[i] == 0xE8 then
return i
end
end
end)()
local pCTimer__ms_fTimeStep = ffi.cast('float*', 0xB7CB5C)
local magic = 50.0 / 30.0
local table_hook
table_hook = hook.call.new('void(__cdecl*)(uintptr_t)', function(ebp)
local esp = ebp + 4
local m = ffi.cast('float*', esp + 0x18)
m[0] = m[0] * (1.0 / (pCTimer__ms_fTimeStep[0] / magic))
m[1] = m[1] * (1.0 / (pCTimer__ms_fTimeStep[0] / magic))
m[2] = m[2] * (1.0 / (pCTimer__ms_fTimeStep[0] / magic))
end,
alloc_addr + proxy_call_opcode_pos
)
addEventHandler('onScriptTerminate', function(scr)
if scr == script.this then
ffi.C.VirtualProtect(ffi.cast('void*', hook_addr), hook_size, 0x40, old_prot)
local orig = ffi.new('uint8_t[6]', {0xD9, 0xC1, 0xD8, 0x08, 0xD9, 0xC2})
ffi.copy(ffi.cast('void*', hook_addr), orig, 6)
ffi.C.VirtualProtect(ffi.cast('void*', hook_addr), hook_size, old_prot[0], old_prot)
ffi.C.VirtualFree(ffi.cast('void*', alloc_addr), 0, 0x8000)
end
end)
How to create the same dialog hook in Lua?
CLEO::isDialogResponded { IF 0AB1: @isDialogResponded 0 _Returned: id 0@ button 1@ list_item 2@ input_text 3@ } IF 0AA2: 31@ = "samp.dll" THEN CONST VAR1 = $2AFD VAR2 = $2BEC VAR3 = $2CDE VAR4 = $2DCB END 0AB1: @get_samp_version_id 0 _returned: ID 17@ IF 17@ > 0 THEN IF 17@ == 1 // 0.3.7 R1 THEN 0A8E: 30@ = 31@ + 0x21A0B8 // SAMP_DIALOG_INFO_OFFSET 0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0 0A8E: 29@ = 30@ + 0x20 // SAMP_DIALOG_LIST_BOX_OFFSET 0A8D: 29@ = read_memory 29@ size 4 virtual_protect 0 0A8E: 28@ = 30@ + 0x24 // SAMP_DIALOG_EDIT_BOX_OFFSET 0A8D: 28@ = read_memory 28@ size 4 virtual_protect 0 0A8E: 27@ = 30@ + 0x30 // SAMP_DIALOG_ID_OFFSET 0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0 0A8E: VAR2 = 31@ + 0x6C04D // SAMP_DIALOG_RESPONSE_OFFSET + 0xD 0A8E: 26@ = 31@ + 0x84850 // SAMP_GET_DIALOG_LIST_ITEM_OFFSET 0AA8: call_function_method 26@ struct 29@ num_params 1 pop 0 -1 _Return: 25@ 0A8E: 24@ = 31@ + 0x81030 // SAMP_GET_DIALOG_EDIT_BOX_TEXT_OFFSET 0AA8: call_function_method 24@ struct 28@ num_params 0 pop 0 _Returned: Input Text 23@ END IF 17@ == 2 // 0.3.7 R2 THEN 0A8E: 30@ = 31@ + 0x21A0C0 // SAMP_DIALOG_INFO_OFFSET 0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0 0A8E: 29@ = 30@ + 0x20 // SAMP_DIALOG_LIST_BOX_OFFSET 0A8D: 29@ = read_memory 29@ size 4 virtual_protect 0 0A8E: 28@ = 30@ + 0x24 // SAMP_DIALOG_EDIT_BOX_OFFSET 0A8D: 28@ = read_memory 28@ size 4 virtual_protect 0 0A8E: 27@ = 30@ + 0x30 // SAMP_DIALOG_ID_OFFSET 0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0 0A8E: VAR2 = 31@ + 0x6C0FD // SAMP_DIALOG_RESPONSE_OFFSET + 0xD 0A8E: 26@ = 31@ + 0x848F0 // SAMP_GET_DIALOG_LIST_ITEM_OFFSET 0AA8: call_function_method 26@ struct 29@ num_params 1 pop 0 -1 _Return: 25@ 0A8E: 24@ = 31@ + 0x810D0 // SAMP_GET_DIALOG_EDIT_BOX_TEXT_OFFSET 0AA8: call_function_method 24@ struct 28@ num_params 0 pop 0 _Returned: Input Text 23@ END IF 17@ == 3 // 0.3.DL THEN 0A8E: 30@ = 31@ + 0x21A0C0 // SAMP_DIALOG_INFO_OFFSET 0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0 0A8E: 29@ = 30@ + 0x20 // SAMP_DIALOG_LIST_BOX_OFFSET 0A8D: 29@ = read_memory 29@ size 4 virtual_protect 0 0A8E: 28@ = 30@ + 0x24 // SAMP_DIALOG_EDIT_BOX_OFFSET 0A8D: 28@ = read_memory 28@ size 4 virtual_protect 0 0A8E: 27@ = 30@ + 0x30 // SAMP_DIALOG_ID_OFFSET 0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0 0A8E: VAR2 = 31@ + 0x700DD // SAMP_DIALOG_RESPONSE_OFFSET + 0xD 0A8E: 26@ = 31@ + 0x888F0 // SAMP_GET_DIALOG_LIST_ITEM_OFFSET 0AA8: call_function_method 26@ struct 29@ num_params 1 pop 0 -1 _Return: 25@ 0A8E: 24@ = 31@ + 0x850D0 // SAMP_GET_DIALOG_EDIT_BOX_TEXT_OFFSET 0AA8: call_function_method 24@ struct 28@ num_params 0 pop 0 _Returned: Input Text 23@ END IF 17@ == 4 // 0.3.7 R3 THEN 0A8E: 30@ = 31@ + 0x26E898 // SAMP_DIALOG_INFO_OFFSET 0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0 0A8E: 29@ = 30@ + 0x20 // SAMP_DIALOG_LIST_BOX_OFFSET 0A8D: 29@ = read_memory 29@ size 4 virtual_protect 0 0A8E: 28@ = 30@ + 0x24 // SAMP_DIALOG_EDIT_BOX_OFFSET 0A8D: 28@ = read_memory 28@ size 4 virtual_protect 0 0A8E: 27@ = 30@ + 0x30 // SAMP_DIALOG_ID_OFFSET 0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0 0A8E: VAR2 = 31@ + 0x6FF4D // SAMP_DIALOG_RESPONSE_OFFSET + 0xD 0A8E: 26@ = 31@ + 0x88760 // SAMP_GET_DIALOG_LIST_ITEM_OFFSET 0AA8: call_function_method 26@ struct 29@ num_params 1 pop 0 -1 _Return: 25@ 0A8E: 24@ = 31@ + 0x84F40 // SAMP_GET_DIALOG_EDIT_BOX_TEXT_OFFSET 0AA8: call_function_method 24@ struct 28@ num_params 0 pop 0 _Returned: Input Text 23@ END IF 17@ == 5 // 0.3.7 R4 THEN 0A8E: 30@ = 31@ + 0x26E9C8 // SAMP_DIALOG_INFO_OFFSET 0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0 0A8E: 29@ = 30@ + 0x20 // SAMP_DIALOG_LIST_BOX_OFFSET 0A8D: 29@ = read_memory 29@ size 4 virtual_protect 0 0A8E: 28@ = 30@ + 0x24 // SAMP_DIALOG_EDIT_BOX_OFFSET 0A8D: 28@ = read_memory 28@ size 4 virtual_protect 0 0A8E: 27@ = 30@ + 0x30 // SAMP_DIALOG_ID_OFFSET 0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0 0A8E: VAR2 = 31@ + 0x7066D // SAMP_DIALOG_RESPONSE_OFFSET + 0xD 0A8E: 26@ = 31@ + 0x88EA0 // SAMP_GET_DIALOG_LIST_ITEM_OFFSET 0AA8: call_function_method 26@ struct 29@ num_params 1 pop 0 -1 _Return: 25@ 0A8E: 24@ = 31@ + 0x85680 // SAMP_GET_DIALOG_EDIT_BOX_TEXT_OFFSET 0AA8: call_function_method 24@ struct 28@ num_params 0 pop 0 _Returned: Input Text 23@ END IF 17@ == 6 // 0.3.7 R4 - v2 THEN 0A8E: 30@ = 31@ + 0x26E9C8 // SAMP_DIALOG_INFO_OFFSET 0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0 0A8E: 29@ = 30@ + 0x20 // SAMP_DIALOG_LIST_BOX_OFFSET 0A8D: 29@ = read_memory 29@ size 4 virtual_protect 0 0A8E: 28@ = 30@ + 0x24 // SAMP_DIALOG_EDIT_BOX_OFFSET 0A8D: 28@ = read_memory 28@ size 4 virtual_protect 0 0A8E: 27@ = 30@ + 0x30 // SAMP_DIALOG_ID_OFFSET 0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0 0A8E: VAR2 = 31@ + 0x7069D // SAMP_DIALOG_RESPONSE_OFFSET + 0xD 0A8E: 26@ = 31@ + 0x88ED0 // SAMP_GET_DIALOG_LIST_ITEM_OFFSET 0AA8: call_function_method 26@ struct 29@ num_params 1 pop 0 -1 _Return: 25@ 0A8E: 24@ = 31@ + 0x856B0 // SAMP_GET_DIALOG_EDIT_BOX_TEXT_OFFSET 0AA8: call_function_method 24@ struct 28@ num_params 0 pop 0 _Returned: Input Text 23@ END IF 17@ == 7 // 0.3.7 R5 THEN 0A8E: 30@ = 31@ + 0x26EB50 // SAMP_DIALOG_INFO_OFFSET 0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0 0A8E: 29@ = 30@ + 0x20 // SAMP_DIALOG_LIST_BOX_OFFSET 0A8D: 29@ = read_memory 29@ size 4 virtual_protect 0 0A8E: 28@ = 30@ + 0x24 // SAMP_DIALOG_EDIT_BOX_OFFSET 0A8D: 28@ = read_memory 28@ size 4 virtual_protect 0 0A8E: 27@ = 30@ + 0x30 // SAMP_DIALOG_ID_OFFSET 0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0 0A8E: VAR2 = 31@ + 0x7063D // SAMP_DIALOG_RESPONSE_OFFSET + 0xD 0A8E: 26@ = 31@ + 0x88E70 // SAMP_GET_DIALOG_LIST_ITEM_OFFSET 0AA8: call_function_method 26@ struct 29@ num_params 1 pop 0 -1 _Return: 25@ 0A8E: 24@ = 31@ + 0x85650 //SAMP_GET_DIALOG_EDIT_BOX_TEXT_OFFSET 0AA8: call_function_method 24@ struct 28@ num_params 0 pop 0 _Returned: Input Text 23@ END // Hook_RPC_DIALOGRESPONSE 0AC8: VAR1 = allocate_memory_size 17 0A8C: write_memory VAR1 size 4 value 0x08458B50 virtual_protect 1 VAR1 += 4 0A8C: write_memory VAR1 size 1 value 0xA3 virtual_protect 1 VAR1 += 1 0A8C: write_memory VAR1 size 4 value 0x00000000 virtual_protect 1 VAR1 += 4 0A8C: write_memory VAR1 size 2 value 0x6458 virtual_protect 1 VAR1 += 2 0A8C: write_memory VAR1 size 1 value 0xA1 virtual_protect 1 VAR1 += 1 0A8C: write_memory VAR1 size 4 value 0x00000000 virtual_protect 1 VAR1 += 4 0A8C: write_memory VAR1 size 1 value 0xC3 virtual_protect 1 VAR1 -= 16 VAR1 += 0x5 0AC7: VAR4 = var VAR3 offset 0A8C: write_memory VAR1 size 4 value VAR4 virtual_protect 1 VAR1 -= 0x5 // asm_call_hook 0A8C: write_memory VAR2 size 1 value 0xE8 virtual_protect 1 0062: VAR1 -= VAR2 // (int) 000E: VAR1 -= 5 VAR2 += 1 0A8C: write_memory VAR2 size 4 value VAR1 virtual_protect 1 // VAR2 += 0x4 0A8C: write_memory VAR2 size 1 value 0x90 virtual_protect 1 // NOP // END IF OR 27@ > -1 VAR3 > -1 25@ > -1 23@ > 0 THEN IF VAR3 == 1 THEN 22@ = 1 // LEFT_BUTTON_WAS_CLICKED VAR3 = -1 ELSE IF VAR3 == 0 THEN 22@ = 0 // RIGHT_BUTTON_WAS_CLICKED VAR3 = -1 ELSE 22@ = -1 // RESET_CLICKED_BUTTONS VAR3 = -1 END END 0485: return_true ELSE 059A: return_false END END END 0AB2: ret 4 27@ 22@ 25@ 23@
isDialogResponded = hooks.jmp.new("void*(__thiscall*)(void *, int, int, int, char*)", isDialogResponded, (samp + 0x6FF4D))
Я не разбираюсь в клеоПривет, я не понимаю как сделать этот хук
Пробовал так
КрашитLua:isDialogResponded = hooks.jmp.new("void*(__thiscall*)(void *, int, int, int, char*)", isDialogResponded, (samp + 0x6FF4D))
p.s сейчас это с телефона написал, дома буду напишу как действительно пробовал
Я не разбираюсь в клео
топ причин краша: * не правильный размер хука * не правильное место хука * не правильный прототип