• Я зарабатываю 100 000 RUB / месяц на этом сайте!

    А знаешь как? Я всего-лишь публикую (создаю темы), а админ мне платит. Трачу деньги на мороженое, робуксы и сервера в Minecraft. А ещё на паль из Китая. 

    Хочешь так же? Пиши и узнавай условия: https://t.me/alex_redact
    Реклама: https://t.me/yougame_official

Вопрос Хукаю voice_data_t

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
6 Дек 2021
Сообщения
58
Реакции
4
Код:
Expand Collapse Copy
local ffi = require('ffi')

ffi.cdef[[
    typedef unsigned char uint8_t;
    typedef unsigned int uint32_t;
    typedef unsigned long long uint64_t;

    struct voicedata_t {
        char pad_0000[8];
        uint32_t client;
        uint32_t audible_mask;
        uint64_t xuid;
        void* voice_data_;
        uint32_t proximity;
        uint32_t format;
        uint32_t sequence_bytes;
        uint32_t section_number;
        uint32_t uncompressed_sample_offset;
    };
]]

local detour = (function()
    local detour_lib = {}

    local cast = ffi.cast
    local copy = ffi.copy
    local new = ffi.new
    local typeof = ffi.typeof
    local tonumber = tonumber
    local insert = table.insert
    
    local function opcode_scan(module, pattern, offset)
        local sig = client.find_signature(module, pattern)
        if not sig then
            error(string.format('failed to find signature: %s', module))
        end
        return cast('uintptr_t', sig) + (offset or 0)
    end
    
    local jmp_ecx = opcode_scan('engine.dll', '\xFF\xE1')
    local get_proc_addr = cast('uint32_t**', cast('uint32_t', opcode_scan('engine.dll', '\xFF\x15\xCC\xCC\xCC\xCC\xA3\xCC\xCC\xCC\xCC\xEB\x05')) + 2)[0][0]
    local fn_get_proc_addr = cast('uint32_t(__fastcall*)(unsigned int, unsigned int, uint32_t, const char*)', jmp_ecx)
    local get_module_handle = cast('uint32_t**', cast('uint32_t', opcode_scan('engine.dll', '\xFF\x15\xCC\xCC\xCC\xCC\x85\xC0\x74\x0B')) + 2)[0][0]
    local fn_get_module_handle = cast('uint32_t(__fastcall*)(unsigned int, unsigned int, const char*)', jmp_ecx)
    
    local proc_cache = {}
    local function proc_bind(module_name, function_name, typedef)
        local cache_key = module_name .. function_name
        if proc_cache[cache_key] then
            return proc_cache[cache_key]
        end
    
        local ctype = typeof(typedef)
        local module_handle = fn_get_module_handle(get_module_handle, 0, module_name)
        local proc_address = fn_get_proc_addr(get_proc_addr, 0, module_handle, function_name)
        local call_fn = cast(ctype, jmp_ecx)
    
        local fn = function(...)
            return call_fn(proc_address, 0, ...)
        end
        proc_cache[cache_key] = fn
        return fn
    end
    
    local native_virtualprotect = proc_bind(
        'kernel32.dll',
        'VirtualProtect',
        'int(__fastcall*)(unsigned int, unsigned int, void* lpAddress, unsigned long dwSize, unsigned long flNewProtect, unsigned long* lpflOldProtect)'
    )

    local function virtualprotect(lpAddress, dwSize, flNewProtect, lpflOldProtect)
        return native_virtualprotect(cast('void*', lpAddress), dwSize, flNewProtect, lpflOldProtect)
    end
    
    detour_lib.hooks = {}
    function detour_lib.new(typedef, callback, hook_addr, size)
        size = size or 5
        local hook = {}
        local mt = {}
        
        local old_prot = new('unsigned long[1]')
        local org_bytes = new('uint8_t[?]', size)
        copy(org_bytes, hook_addr, size)
        
        local detour_addr = tonumber(cast('intptr_t', cast('void*', cast(typedef, callback))))
        hook.call = cast(typedef, hook_addr)
        
        mt.__call = function(self, ...)
            self.stop()
            local res = self.call(...)
            self.start()
            return res
        end
    
        local hook_bytes = new('uint8_t[?]', size, 0x90)
        hook_bytes[0] = 0xE9
        cast('int32_t*', hook_bytes + 1)[0] = (detour_addr - tonumber(cast('intptr_t', hook_addr)) - 5)
        hook.status = false
    
        local function set_status(bool)
            hook.status = bool
            virtualprotect(hook_addr, size, 0x40, old_prot)
            copy(hook_addr, bool and hook_bytes or org_bytes, size)
            virtualprotect(hook_addr, size, old_prot[0], old_prot)
        end
    
        hook.stop = function() set_status(false) end
        hook.start = function() set_status(true) end
        hook.start()
        
        insert(detour_lib.hooks, hook)
        return setmetatable(hook, mt)
    end
    
    function detour_lib.unhook_all()
        for _, hook in pairs(detour_lib.hooks) do
            if hook.status then
                hook.stop()
            end
        end
    
        proc_cache = {}
        collectgarbage('collect')
    end
    
    client.set_event_callback('shutdown', detour_lib.unhook_all)
    
    return detour_lib
end)()

local signature = "\x55\x8B\xEC\x83\xE4\xF8\xA1\xCC\xCC\xCC\xCC\x81\xEC\xCC\xCC\xCC\xCC\x53\x56\x8B\xF1\xB9\xCC\xCC\xCC\xCC\x57\xFF\x50\x34\x8B\x7D\x08"

local sub_102866A0 = client.find_signature("engine.dll", signature)
if not sub_102866A0 then
    error("Failed to find sub_102866A0 signature")
end

local function hook_sub_ANA0(this, voice_data)
    local a2 = voice_data.client
    local v17 = voice_data.sequence_bytes
    local v16 = voice_data.section_number
    local v2 = voice_data.uncompressed_sample_offset

    print(string.format("Voice packet: client=%d, sequence_bytes=%d, section_number=%d, uncompressed_sample_offset=%d",
        a2, v17, v16, v2))

    return detour_lib.hooks[1].call(this, voice_data)
end

local hook = detour.new("char(__thiscall*)(void*, struct voicedata_t*)", hook_sub_ANA0, sub_102866A0)
не могу понять в чем проблема вроде все правильно сделал но итог врубаю микро крашит
 
чекни ли сигнатуры правильные
 
предлагаю чекнуть мануал по ffi, попробовать закоментить весь код в хуке и оставить только ретурн ориг функции, и потом додуматся почему таблица в луа не является прокси объектом для поинтера
 
Назад
Сверху Снизу