Исходник Гайд Lua vmt+jmp/call hook | Библиотека hooks.lua

whyega52

Гений, миллионер, плейбой, долбаеб
Модератор
2,762
2,586
Пишу либу для ракнет хуков, но все упирается в баг с вызовом мейна. Есть какие-нибудь способы это решить (подойдут уже даже костыли, главное, чтобы в скрипте, в который подключаешь либу ракнет хуков, которая в свою очередь юзает либу хуков, было все нормально)?
 

kin4stat

mq-team · kin4@naebalovo.team
Всефорумный модератор
2,743
4,804
Пишу либу для ракнет хуков, но все упирается в баг с вызовом мейна. Есть какие-нибудь способы это решить (подойдут уже даже костыли, главное, чтобы в скрипте, в который подключаешь либу ракнет хуков, которая в свою очередь юзает либу хуков, было все нормально)?
Бля вы тему вообще читать умеете? буквально пару постов назад писали решение блять

 
  • Нравится
Реакции: whyega52

whyega52

Гений, миллионер, плейбой, долбаеб
Модератор
2,762
2,586
Бля вы тему вообще читать умеете? буквально пару постов назад писали решение блять

Чет невнимательно прочитал ответ Фипа, почему-то подумал, что надо оффать компиляцию у каллбека, а не у хука.

Еще раз перечитав, понял, что изначально я думал судя по всемя верно и окончательно запутался. Компиляцию каллбеков надо отключать для всех видов хуков? Даже если это и так, то мейн в любом случае вызывается
Lua:
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
 
Последнее редактирование:

whyega52

Гений, миллионер, плейбой, долбаеб
Модератор
2,762
2,586
Опять не по теме, но хз куда можно еще написать, помимо задравчивания всем лс.


Пытаюсь прохукать входящие пакеты, по примеру с собейта, но как итог, пакеты не приходят после работы функции-обработчика
Lua:
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
    )
Lua:
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;   
]])
Lua:
function utils:callVirtualMethod(vt, prototype, method, ...) 
    local cast = ffi.cast                       
    local virtualTable = cast("intptr_t**", vt)[0]       
    return cast(prototype, virtualTable[method])(...)
end
 

samperkrytoi228

Новичок
19
2
братан, а если у меня первый скрипт выводит сообщение в чат "Route ended" через команду sampAddChatMessage("Route ended"). То как мне сделать код,чтобы при выводе "Route ended" в чат мой второй скрипт нажимал на пробел
 

whyega52

Гений, миллионер, плейбой, долбаеб
Модератор
2,762
2,586
братан, а если у меня первый скрипт выводит сообщение в чат "Route ended" через команду sampAddChatMessage("Route ended"). То как мне сделать код,чтобы при выводе "Route ended" в чат мой второй скрипт нажимал на пробел
Lua:
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
)
 
  • Нравится
Реакции: ARMOR и Z3roKwq

RTD

Потужно
Автор темы
Модератор
399
470
баг с вызовом мейна
Смириться и стараться не хукать много в одном скрипте, особенно то что часто вызывается. При ловле бага перазагружаться


Заметил такую особенность, корутины которые врапнуты мунлоадером(или сол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
1719441121722.png


Но мб дело в другом, потому что исключение с таким же кодом вылетает время от времени(а иногда каждый кадр) и от просто скрипта с
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
1719444057706.png
 
  • Нравится
Реакции: whyega52

Gorskin

♥ Love Lua ♥
Проверенный
1,331
1,160
Смириться и стараться не хукать много в одном скрипте, особенно то что часто вызывается. При ловле бага перазагружаться


Заметил такую особенность, корутины которые врапнуты мунлоадером(или сол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
Я понял что из-за этого бага с jit вызывается main, в функции main идёт создание хука, но если сделать проверку на загруженность main и не вызывать повторно создание хука то всё работает вроде бы нормально. У меня 3 хука в скрипте, один на пресент, ресет и на функцию создания взрыва в игре. При этом всём стабильная работа, просадок фпс не замечено, со скрипом максимум 305-310 фпс, без прыгает 307-309. Думаю хороший результат для большого скрипта где используется очень много редактирования памяти, замена указателей.
Дополню: сами хуки я вшил прямо в код скрипта, возможно это и помогло.
 
  • Нравится
Реакции: RTD

Gorskin

♥ Love Lua ♥
Проверенный
1,331
1,160
@RTD Возможно ли с помощью твоей либы хукать внутренность функции игры? Как пример код:
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);
Нужно каким-то образом реализовать хук, чтобы сделать прыжок на свою функцию, в ней произвести расчёты и вернуть функции модифицированное значение. Крч мне надо сделать исправление плавания при большом фпс на луа, а проблема в том что у меня нет даже представления как это сделать, на плюсах это понятнее сделать т.к уровень языка низкий. Я уже не говорю что нет нормальной возможности сделать _asm вставку на луа как на плюсах.
 

whyega52

Гений, миллионер, плейбой, долбаеб
Модератор
2,762
2,586
@RTD Возможно ли с помощью твоей либы хукать внутренность функции игры? Как пример код:
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);
Нужно каким-то образом реализовать хук, чтобы сделать прыжок на свою функцию, в ней произвести расчёты и вернуть функции модифицированное значение. Крч мне надо сделать исправление плавания при большом фпс на луа, а проблема в том что у меня нет даже представления как это сделать, на плюсах это понятнее сделать т.к уровень языка низкий. Я уже не говорю что нет нормальной возможности сделать _asm вставку на луа как на плюсах.
Скорее всего не получится реализовать naked хук, ибо как я знаю, ffi не дает создать функции без пролога и эпилога и в таком случае скорее всего стек поломается. Конечно, можно использовать байткод и просто загружать байты в память (опять же, в качестве функции), но реализация этого не самая быстрая задача (особенно, если хочешь передавать значения из луа в память)
 

RTD

Потужно
Автор темы
Модератор
399
470
@RTD Возможно ли с помощью твоей либы хукать внутренность функции игры? Как пример код:
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);
Нужно каким-то образом реализовать хук, чтобы сделать прыжок на свою функцию, в ней произвести расчёты и вернуть функции модифицированное значение. Крч мне надо сделать исправление плавания при большом фпс на луа, а проблема в том что у меня нет даже представления как это сделать, на плюсах это понятнее сделать т.к уровень языка низкий. Я уже не говорю что нет нормальной возможности сделать _asm вставку на луа как на плюсах.
С вас 1000 денег
upd: https://www.blast.hk/threads/215363/
Lua:
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)
 
Последнее редактирование:
  • Влюблен
  • Нравится
Реакции: whyega52 и Gorskin

Орк

Известный
179
118
Привет, я не понимаю как сделать этот хук
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@

Пробовал так
Lua:
isDialogResponded = hooks.jmp.new("void*(__thiscall*)(void *, int, int, int, char*)", isDialogResponded, (samp + 0x6FF4D))
Крашит
p.s сейчас это с телефона написал, дома буду напишу как действительно пробовал
 

RTD

Потужно
Автор темы
Модератор
399
470
Привет, я не понимаю как сделать этот хук


Пробовал так
Lua:
isDialogResponded = hooks.jmp.new("void*(__thiscall*)(void *, int, int, int, char*)", isDialogResponded, (samp + 0x6FF4D))
Крашит
p.s сейчас это с телефона написал, дома буду напишу как действительно пробовал
Я не разбираюсь в клео
топ причин краша: * не правильный размер хука * не правильное место хука * не правильный прототип
 

Орк

Известный
179
118
Я не разбираюсь в клео
топ причин краша: * не правильный размер хука * не правильное место хука * не правильный прототип
Других примеров не нашёл, похоже это только на нажатие отправки
Хотя мне оно и нужно