Lua mod
###############################
Можно былобы добавить все основные команды движка.. систему хуков но я решил сделать это более уневерсально
Вы сами можете найти по сигнатурам нужную функцию и создать на нее представление.. либо представить луа функцию и хукнуть что надо...
Если игра поддерживает плагин систему asi( грузит loadlibrary все файлы *.asi из определенной папки , ищет условную экпортируемую функцию и передает ей условный интерфейс если нет то freelibrary.. но достаточна чтобы хоть раз загрузила ) добавить файл в папку с *.asi
Или инжектить ( перейменовав в *.dll ) любым инжектором..
Папка с луа скриптами находится на томже уровне что и файл( и имеет такоеже название без расшерения )
LuaMod Уневерсален и подходит для любого процесса..( сводиться все к изменению памяти/обращению к функциям/хуку функций
При загрузке dll выполняется следующий скприпт ( Отнасительно папки луа мода )
lua/main.lua
Все скрипты идут в 1-н поток
тоесть если надо поставить допустим задачу на время / фраймы то надо найти и хукнуть худфрайм игры и внем мини планировщик..
( если худфарйма еще нету как в cs1.6 , то нада хукнуть любую часто вызывающююся функции ( sleep например ) и вней проверять )
__print - пишет в консоль текст
1-й параметр - сам текс
2-й параметр (если есть деф= 1) - если 1 то добавлять в конец 0x0A иначе как есть
3-й , 4-й , 5-й параметры если они есть то это цвет текста формата RGB
3-й - R
4-й - G
5-й - B
__include - подключает скрипт
- аналог стандартной dofile толька ( dofile отнасительно текущей дир а include отнасительно lua/ )
__include_once - подключает скрипт толька 1-н раз
и там и там параметр относительный путь к файлу от lua/
Пример:
__include_once( "InitMem.lua" );
__mem - выделяет память ( обертка над делфийским менеджером памяти( GetMem ) но вы можете найти virtualAlloc и написать свой менеджер на луа )
1-й параметр - размер выделяемой памяти
возвращает указатель на 1-й байт памяти либо 0 если не удалось
__free - освободжает память ( имеет смысл толька если это неизмененный указатель на память полученную через __mem() )
1-й параметр - указатель на 1-й байт памяти
__copy - копирует память
1-й параметр - куда копировать
2-й параметр - откуда копировать
3-й параметр - размер ( байты )
4-й параметр ( если он есть ) - если 1 то ставить на копируемую и туда куда копируют разрешение PAGE_EXECUTE_READWRITE
__fill - заполняет память
1-й параметр - указатель на память
2-й параметр - размер
3-й параметр - байт которым заполнять
4-й параметр( если он есть ) - если 1 то ставить на память разрешение PAGE_EXECUTE_READWRITE
__protect - установить свое разрешение ( обертка над VirtualProtect )
1-й параметр - указатель на память
2-й параметр - размер
3-й параметр( если он есть ) - его как новое разрешение ( или PAGE_EXECUTE_READWRITE )
возвращает старое разрешение либо 0 если не удалось
__find - главная поисковая функция ( для строк, чисел и т.д. )
1-й параметр - Указатель на начальный адрес
2-й параметр - Указатель на предельный адрес поиска( начальный адрес + размер поисковой области )
3-й параметр - Указатель на 1-й байт шаблона
4-й параметр - Размер шаблона
5-й параметр - Оффсет ( результат + оффсет )
Сам шаблон - это буфер с байтами ( 0xFF - на месте него может быть любой символ ) с которыми сверяется память
возвращает адрес сопадения с шаблоном либо 0 если не найдено
__read - читает память
1-й параметр - Указатель на 1-й байт памяти
2-й параметр - Размер
3-й параметр( если он есть ) - если 1 то ставить на память разрешение PAGE_EXECUTE_READWRITE
возвращает Lua таблицу от 1 до размера где каждая ячейка байт из памяти
__write - пишет в память
1-й параметр - Указатель на 1-й байт памяти
2-й параметр - Размер( он впринцпе не важен ведь будет перебераться вся таблица , толька для 3-о параметра )
3-й параметр( если он есть ) - если 1 то ставить на память разрешение PAGE_EXECUTE_READWRITE
записывает в память таблицу ( каждая ячейка таблциы - байт в память )
прототип для всех фукнций чтения
1-й параметр - Указатель на память откуда читать
2-й параметр( если он есть ) - если 1 то ставить на память разрешение PAGE_EXECUTE_READWRITE ( кроме фунции __read_pstring )
__read_int - читает знаковый Int32 [ 4 Byte ]
__read_byte - читает беззнаковый Byte [ 1 Byte ]
__read_word - читает беззнаковый Word [ 2 Byte ]
__read_dword - читает беззнаковый DWord [ 4 Byte ]
__read_single - читает беззнаковый Single [ 4 Byte ]
__read_double - читает беззнаковый Double [ 8 Byte ]
__read_pstring - читает PString( до 1-о 0x00 )
алиасы на них
rInt не работает ( ошибся со знаком ) толька __read_int
rByte
rWord
rDword
rSingle
rDouble
rPString
прототип для всех фукнций записи
1-й параметр - Указатель на память куда писать
2-й параметр - Значение которое надо записать
3-й параметр( если он есть ) - если 1 то ставить на память разрешение PAGE_EXECUTE_READWRITE ( кроме фунции __read_pstring )
__int - приводит число к Int32
1-й параметр - число
возвращает число
__dword - приводт число к DWord
1-й параметр - число
возвращает число
Прототип для функций:
1-й параметр - число
2-й параметр ( если по смыслу он нужен( в not толька 1-н например ) ) - число
3-й и т .д.
Пример:
__and( 1 , 4 , 5 , 12 );
Возвращают DWord
__shr
__shl
__not
__and
__or
__xor
__rbit
__div
__mod
Тоже самое но возвращают не DWord а Int32
__ishr
__ishl
__inot
__iand
__ior
__ixor
__irbit
__idiv
__imod
__get_module - Обертка над GetModuleHandleA ( тоесть по имени возращает адрес 1-й байта модуля ( хандл модуля ) или 0 если нету )
1-й параметр - имя модуля
Пример:
HLBase = __get_module("hw.dll");
__get_address - Обертка над GetProcAddress ( тоесть по адресу модуля обходит экспорт и ищет по имени функцию )
1-й параметр - адрес 1-о байта модуля( хандл )
2-й параметр - имся функции ( функция должна экпортироваться модулем )
__load_library - Обертка над LoadLibraryA ( тоесть по имени dll загружает ее ( она может быть в system32 | curr dir | full path ) ) Возвращает адрес 1-о байта уже загруженного модуля
1-й параметр - название модуля
__get_module_size - получает полный размер модуля ( из PE заголовка ) Возвращает размер
1-й параметр - адрес 1-о байта модуля
Любая функция в конечном счете может принимать как единичный параметр толька следующие типы:
DWord( регистры , стэк )
Single( всегда толька стэк )
Double( всегда толька стэк )
Любая функция в конечном счете может возвращать параметры толька следующих 3-х типов:
DWord( всегда толька EAX(регистр) )
Single( всегда толька FPU )
Double( всегда толька FPU )
__type - функция создает тип; Возвращает ид
1-й праметр строка вида "([^\=])\=(.*)"
Пример:
id = __type( "my_function = function( PChar ): DWord; cdecl;" );
доступны в качаестве параметров и типа ретурна следующие типы
Int == Int32
DWord == DWord
PChar == PAnsiString
Single == Single
Double == Double
Фораматы передачи параметров:
cdecl - C формат
fastcall - формат Delphi( именно делфи, первые 3-е которые могу в рег. остальные прямо через стэк )
stdcall - формат WinApi ( при обращиниее между cdecl и stdcall разницы ну будет ( толька на прдеставление ) )
own - свой формат ( оставшиеся параметры обратна через стэк )
доступны для own следующие фарматы регистров
EAX , EDX , ECX , EBX , ESI , EDI
Пример:
id = __type( "my_function = function( EAX^DWord , Single , EDX^DWord , Double , ECX^DWord ): DWord; own;" );
а также
direct_own - свой формат ( оставшиеся параметры прямо через стэк )
Пример:
id = __type( "my_function = function( EAX^DWord , Single , EDX^DWord , Double , ECX^DWord ): DWord; direct_own;" );
ну или так
id = __type( "my_function = function( DWord , Single , DWord , Double , DWord ): DWord; fastcall;" );
Можно указать на очистку стека ( retn sizeof(stack.argv) ):
id = __type( "my_function = function( PChar ): DWord; cdecl^std;" );
ну или так
id = __type( "my_function = function( PChar ): DWord; stdcall;" );
( толька ^std можна и с овн и с фасткалл )
__create - создает обертку по заранее созданному типу и возвращает луа функцию
1-й параметр - ид который вернула команда __type либо имя указанное при создании __type
2-й параметр - абсолютный адрес функции ( ну которую надо будет вызвать )
Пример:
нашли тем или иным способом адрес функци ( Addr = 0xFFFFFFFF; -- для примера )
Знаем тип функции:
f_id = __type( "my_function = function( DWord, DWord ):PChar; cdecl;" );
Создаем луа обертку:
function_ob = __create( f_id , Addr ); -- Или так __create( "my_function" , Addr );
И далее вызов:
print( function_ob( 1 , 2 ) );
Так же и с представлениями:
__submit - Создает представление нужного ( указанного вами типа ) функцию которая будет вызывать Lua функцию; Возвращает Абсолютный адрес функции представления
1-й параметр - ид который вернула команда __type либо имя указанное при создании __type
2-й параметр - луа функция - которую следует вызывать
Пример: ( он кстате есть в Example_miniHLSDK )
[CODEBOX]
-- Пример: Хукним HUD_Frame на луа
HUD_Frame__Orig = 0;
HUD_Frame__Gate = 0;
function HUD_Frame__Hook( _time )
print( tostring( _time ) );
HUD_Frame__Gate( _time );
end;
function SETHOOK_FRAME()
--Адрес 1-ого байта функции
HUD_Frame__Orig = rDword( PClient + exporttable_t.HUD_Frame.Offset );
--Создание луа функции обертки( тип описан в exporttable_t )
HUD_Frame__Gate = __create( exporttable_t.HUD_Frame.FType , HUD_Frame__Orig );
--Представление луа функци HUD_Frame__Hook ( возвращает путь к 1-му байту функции представления )
local NewAddr = __submit( exporttable_t.HUD_Frame.FType , HUD_Frame__Hook );
--Перезаписываем адрес в таблице оригинальной функции функцией предстовления
wDword( PClient + exporttable_t.HUD_Frame.Offset , NewAddr );
end;
--SETHOOK_FRAME();
[/CODEBOX]