- Статус
 - Оффлайн
 
- Регистрация
 - 1 Фев 2020
 
- Сообщения
 - 1,310
 
- Реакции
 - 509
 
			
				code_language.lua:
			
		
		
		local ffi = require "ffi"
ffi.cdef[[
    void* GetProcAddress(void* hModule, const char* lpProcName);                      // @note: получает адрес функции
    void* LoadLibraryA(const char* lpLibFileName);                                    // @note: загружает dll в память
    typedef void* (__cdecl *CreateInterfaceFn)(const char* pName, int* pReturnCode);  // @note: тип указателя на функцию CreateInterface
]]
--@note: создаем таблицу для хранения функций
local vt = {}
--@note: функция для получения интерфейса из модуля
function vt.get_interface(module_name, interface_name)
    local module_handle = ffi.C.LoadLibraryA(module_name)
    local create_interface_fn = ffi.cast("CreateInterfaceFn", ffi.C.GetProcAddress(module_handle, "CreateInterface"))
    local interface_ptr = create_interface_fn(interface_name, nil)
    return interface_ptr
end
--@note: функция для получения указателя на функцию из виртуальной таблицы
function vt.getvfunc(obj, index)
    local vtable = ffi.cast("intptr_t**", obj)[0] --@note: получаем указатель на таблицу виртуальных функций
    return ffi.cast("intptr_t", vtable[index])    --@note: возвращаем указатель на функцию по её индексу
end
--@note: создаем класс для работы с интерфейсом
vt.library = {}
vt.library.__index = vt.library
--@note: конструктор класса
function vt.library.new(interface_ptr)
    local self = setmetatable({}, vt.library)   --@note: создаём новый объект и устанавливаем ему таблицу как мета-таблицу
    self.interface = interface_ptr              --@note: сохраняем указатель на интерфейс
    return self                                 --@note: возвращаем объект
end
--@note: метод для вызова функции из виртуальной таблицы по индексу
function vt.library:call_vfunc(index, ret_type, ...)
    local func_ptr = ffi.cast(ret_type .. "(__thiscall*)(void*, ...)", vt.getvfunc(self.interface, index))
    return func_ptr(self.interface, ...)
end
return vt
	пример использования:
			
				code_language.lua:
			
		
		
		local vt = require "library"
local gameui_interface = vt.get_interface("client.dll", "GameUI011")
local gameui = vt.library.new(gameui_interface)
gameui:call_vfunc(19, "void", "yougame.biz", "lol", true, false, nil, nil, nil, nil, nil)
	кидать "библиотеку" нужно по пути: Counter-Strike: Global Offensive\lua
переделал код. теперь его можно использовать не только для вызова msg_box, но и других функций, которые находятся в виртуальной таблице
		
			
				Последнее редактирование: