disassemble(address): Disassembles the given address and returns a string in the format of "address - bytes - opcode : extra"
splitDisassembledString(disassembledstring): Returns 4 strings. The address, bytes, opcode and extra field
getInstructionSize(address): Returns the size of an instruction (basically it disassembles the instruction and returns the number of bytes for you)
getPreviousOpcode(address): Returns the address of the previous opcode (this is just an estimated guess)
MasterGH
Сообщения
-
Функции для работы с адресами -
Пользовательские тип данных в hex-окне (пример)function bytes_to_value_function(b1,b2,b3,b4) -- для примера local table = {b1, b2, b3, b4} local dword = byteTableToDword(table) local refDataFromAddress = getAddressSafe(dword) if dataPointer ~= nil then return refDataFromAddress end return dword end function value_to_bytes_function(integer) -- просто для примера return bXor(integer, 100) end local isFloat = false registerCustomTypeLua('Pointer 2', 4, bytes_to_value_function, value_to_bytes_function, isFloat)
Справка
CustomType class (Object) The custom type is an convertor of raw data, to a human readable interpretation. global functions registerCustomTypeLua(typename, bytecount, bytestovaluefunction, valuetobytesfunction, isFloat) Registers a Custom type based on lua functions The bytes to value function should be defined as "function bytestovalue (b1,b2,b3,b4)" and return an integer as result The value to bytes function should be defined as "function valuetobytes (integer)" and return the bytes it should write returns the Custom Type object registerCustomTypeAutoAssembler(script) Registers a custom type based on an auto assembler script. The script must allocate an "ConvertRoutine" and "ConvertBackRoutine" returns the Custom Type object getCustomType(typename) : Returns the custom type object, or nil if not found properties name: string functiontypename: string CustomTypeType: TCustomTypeType - The type of the script script: string - The custom type script scriptUsesFloat: boolean - True if this script interprets it's user side values as float methods byteTableToValue({bytetable},Address Optional) valueToByteTable(value, Address Optional)
-
Lua генерирует и исполняет кодФункция loadstring позволяет исполнять текст как код. Попробуем генерировать числа, сравнения чисел и логику И, ИЛИ.
Цель: просто пример.
Создать пары случайных чисел А и Б.
Случайно сравнить попарно.
Создать случайно логику "И, ИЛИ" и сравнить результаты сравнения до тех пор, пока не будут истинныfunction CheckTrue(parameter, strue, sfalse) if parameter then print(strue) else print(sfalse) end end ProgrammCompare_AxB = {} function ProgrammCompare_AxB:New(_name, _tableStringCondition) local obj = {} obj.programmName = _name obj.tableStringCondition = _tableStringCondition obj.stringCondition = '' obj.randomProgramm = '' function obj:MakeProgramm() obj.stringCondition = obj.tableStringCondition[math.random(1, #obj.tableStringCondition)] print(obj.stringCondition) obj.randomProgramm = 'function ' ..obj.programmName..'(a, b) return a '..obj.stringCondition..' b end' end function obj:RunProgramm(a, b) loadstring (obj.randomProgramm)() result = nil loadstring (string.format('result = %s(%s,%s)', obj.programmName, a, b))() CheckTrue ( result, string.format('a = %s, b = %s, result = true', a, b), string.format('a = %s, b = %s, result = false', a,b) ) return result end setmetatable(obj, self) obj.__index = ProgrammCompare_AxB return obj end compareProgramm1 = ProgrammCompare_AxB:New('ProgrammCompare_AxB_1', { '>', '<', '>=', '<=', '==', '~=' }) compareProgramm2 = ProgrammCompare_AxB:New('ProgrammCompare_AxB_2', { 'and', 'or' }) repeat compareProgramm1:MakeProgramm() compareProgramm2:MakeProgramm() -- Подбирать значения local a = compareProgramm1:RunProgramm(math.random(1, 100), math.random(1, 100)) local b = compareProgramm1:RunProgramm(math.random(1, 100), math.random(1, 100)) local c = compareProgramm2:RunProgramm(a, b) until c
Пример вывода в Cheat Engine:
>= or a = 83, b = 75, result = true a = 18, b = 86, result = false a = true, b = false, result = true
Т.е.
(83 >= 75 or 18 >= 86) == true, т.к. первое условие верное 83 >= 75 83 >= 75 = true 18 >= 86 = false
-
Часть1. Lua простые регулярные выраженияЕсть такой плагин "AA Maker" и там довольно интересные регулярные выражения на Lua. Разберем некоторые выражения
Выражение ''%[(.*)%]' - захват всего, что в квадратных скобках
Пример
local s = 'mov eax, [ecx + 4]' print(string.match(s, '%[(.*)%]')) \--> ecx + 4
Символ "%" нужно всегда ставить перед специальными символами такими как ^$()%.[]*+-?
Символ "%[" и "%]" означают квадратные скобки в строке
Разбирая комбинацию (.*).
Точка означает любой символ, а символ умножить означает повторение любого символа
Круглые скобки означают "подшаблон"
Подшаблоны
В шаблон можно включить подшаблоны, выделив их круглыми скобками. Если найденная строка соответствует шаблону, то ее подстроки, соответствующие подшаблонам, будут доступны для будущего использования. Подшаблоны пронумерованы согласно их левым круглым скобкам. Например, в шаблоне "(a*(.)%w(%s*))", часть строки, соответствующая "a*(.)%w(%s*)" будет зафиксирована как первый подшаблон (и поэтому имеет номер 1); любые символы попавшие под соответствие "." будут зафиксированы как подшаблон номер 2, и часть строки, соответствующая "%s*" получит номер 3.
Специальный вариант использования подшаблонов - получение текущей позиции в строке. Для этого используются пустые подшаблоны (). Например, если мы применим шаблон "()aa()" к строке "flaaap", то получим два результата: 3 и 5.
Шаблон не может содержать вложенные ноли. Используйте %z вместо этого.
Т.е. можем извлечь содержимое инструкции.
Примеры"(.*)" - захват всей строки "/(.*)/" - захват всего, что находится между КРАЙНИМИ символами / "/(.-)/" - захват всего, что находится между ПЕРВЫМИ ДВУМЯ символами /
Пример из ААMaker плагина
local _,_,x = string.find(opcode, '%[(.*)%]') из функции ниже
Функция
string.find("СТРОКА", "ШАБЛОН") возвращает номер позиции начала начала и конца шаблона
Пример
print(string.find('some string', 'me')) \--> 3 4
Вся функция с комментариями из AAMaker
\-- Таблица паттернов для нескольких инструкций inc, mov, fld, fstp (ключи таблицы) \-- Они нужны для создания автоматического АА кода, через замену строк другими строками \- {$Type} — очевидно для типа byte, word, dword \- [x] — очевидно обращение к адресу \- {$Value} — это значение \- \r\n — переход на следующую строку \-- Что будем делать с этой таблицой будет видно по коду или смотрите плагин PATTERN = { ['inc'] = 'mov{$Type}[x],{$Value}', ['mov'] = 'mov{$Type}[x],{$Value}\r\n{$OriginalCode}', ['fld'] = 'mov{$Type}[x],{$Value}\r\n{$OriginalCode}', ['fstp'] = '{$OriginalCode}\r\n'..'mov{$Type}[x],{$Value}' } \-- Не очень понятно зачем квадратные скобки у ключей. Можно написать не ['inc'], а 'inc' \-- Функция проверки паттерна function checkPattern() -- Получение имени адреса из адреса dv_address1 (выделенный адрес в дизассемблере) local address = getNameFromAddress(dv_address1) -- Получение инструкции по имени адреса local _,opcode = splitDisassembledString(disassemble(address)) -- ComboBox.Text свойство равно "Injection" или "AOBScanModule" local choose = getProperty(cmbCheatType,"Text") if choose == 'Injection' or choose == 'AOBScanModule' then -- Перебор по ключу и значению таблицы PATTERN for key,value in pairs(PATTERN) do -- Если в опкоде нашли ключ из таблицы паттернов -- Где key это inc, mov, fld, fstp (см. выше таблицу PATTERN) -- Где opcode это например инструкция 'inc [edx + 4]' if string.find(opcode,key) ~= nil then local _,_,x = string.find(opcode, '%[(.*)%]') if x ~= nil then -- В value будет значение 'mov{$Type}[x],{$Value}' patternInjectAsmCode = value -- Нашли паттерн и вернули его return true end end end end -- Паттерн не нашли в таблице, вернули false patternInjectAsmCode = '{$OriginalCode}' return false end \-- patternInjectAsmCode
Чтобы посмотреть результат, сделал скрин отладки Lua кода
Функции по работе со строками. Link
-
Часть2. Lua простые регулярные выраженияЕсли нужно найти начало и конец подстроки. Пример
Попробуем найти слово lab в троке gamehacklab.ru
print(string.find('gamehacklab.ru', 'lab')) >9 11
Если не найдена подстрока, то вернет nil.
С помощью string.match можем выводить не индексы, а строкуprint(string.match('gamehacklab.ru', 'lab')) >lab
С помощью string.gmatch можем выводить последовательно строки
Где 'a.' означает символ 'a' и еще один следующий любой
local result = string.gmatch('gamehacklab.ru', 'a.') print(result()) print(result()) print(result()) вывод >am >ac >ab
Здесь комбинация символов "%a+" означает искать слово пока оно не закончится
s = "hello world from Lua" for w in string.gmatch(s, "%a+") do print(w) end Вывод > hello > world > from > Lua
А здесь заполняем таблицу ключ — значение из строки, которую можно было бы взять из файла
t = {} s = "X=0, Y=0, Z=0" for k, v in string.gmatch(s, "(%w+)=(%w+)") do t[k] = v end for i, v in pairs(t) do print(i..' = '..v) end Вывод >Z = 0 >X = 0 >Y = 0
Пока на этом все... Более сложные примеры в предыдущей части записи
-
Notepad++ и CE Lua. Автозавершение строк
Можно в редакторе сделать автозавершение инструкци для CE Lua и даже для CE Autoassembler.
Накидал пример, может быть, кому интересно будет для других языков.
Установка. Поместить файл в директорию на скриншоте
lua.xml
-
Задачка по IDA и Python (старое)Пост принадлежит автору partoftheworlD, GamehackLab[RU]. (ref)
Подключение к питону происходит с помощью:
import idc import idautils import idaapi
У меня есть наработки некоторые, возможно что-то пригодится.
import idc import idaapi class Func(object): def __init__(self): self.reg_value = re.compile(r'') self.stack_view = [] self.level = 1 def range_reverse(self, start, stop): for i in FuncItems(stop): if start > i >= stop: yield i def run(self): if self.stack_view: for j in self.stack_view: current_function = idaapi.get_func(j) level = "-" * self.level print("{} Jump into -> 0x{}".format(level, hex(current_function.startEA)[2:].replace("L", "").upper())) for j in [i for i in self.range_reverse(current_function.endEA, current_function.startEA)]: print("{} 0x{} -- {}".format(level, hex(j)[2:].replace("L", "").upper(), idc.GetDisasm(j))) self.level += 1 else: print "Please input addresses to stack view buffer" pass if __name__ == '__main__': f = Func() f.stack_view = [0x214FE, 0x20F30, 0x214E0, 0x13F00] f.run()
В выводе получим
\- Jump into -> 0x214E0 \- 0x214E0 -- push ebp \- 0x214E1 -- mov ebp, esp \- 0x214E3 -- lea esp, [esp-10h] \- 0x214E7 -- mov [ebp+var_C], eax \- 0x214EA -- mov [ebp+var_4], edx \- 0x214ED -- mov [ebp+var_8], ecx \- 0x214F0 -- mov eax, [ebp+arg_0] \- 0x214F3 -- test eax, eax \- 0x214F5 -- jnz locret_21589 \- 0x214FB -- mov eax, [ebp+var_8] \- 0x214FE -- cmp word ptr [eax], 1Bh \- 0x21503 -- jnz locret_21589 \- 0x21509 -- push 0 \- 0x2150B -- mov eax, [ebp+var_8] \- 0x2150E -- movzx ecx, word ptr [eax] \- 0x21511 -- mov eax, [ebp+var_4] \- 0x21514 -- mov edx, 0B01Eh \- 0x21519 -- call sub_8E870 \- 0x2151E -- test eax, eax \- 0x21520 -- jnz short locret_21589 \- 0x21522 -- push 0 \- 0x21524 -- mov eax, [ebp+var_4] \- 0x21527 -- mov ecx, 0 \- 0x2152C -- mov edx, 87h ; '‡' \- 0x21531 -- call sub_8E870 \- 0x21536 -- and eax, 4 \- 0x21539 -- jnz short locret_21589 \- 0x2153B -- mov eax, [ebp+var_C] \- 0x2153E -- test dword ptr [eax+160h], 4 \- 0x21548 -- jz short locret_21589 \- 0x2154A -- mov eax, [ebp+var_4] \- 0x2154D -- mov dl, 1 \- 0x2154F -- call sub_13F00 \- 0x21554 -- mov [ebp+var_10], eax \- 0x21557 -- test eax, eax \- 0x21559 -- jz short locret_21589 \- 0x2155B -- mov eax, [ebp+var_10] \- 0x2155E -- cmp dword ptr [eax+378h], 0 \- 0x21565 -- jz short locret_21589 \- 0x21567 -- mov eax, [ebp+var_10] \- 0x2156A -- mov eax, [eax+378h] \- 0x21570 -- mov edx, [ebp+var_10] \- 0x21573 -- mov edx, [edx+378h] \- 0x21579 -- mov edx, [edx] \- 0x2157B -- call dword ptr [edx+2E8h] \- 0x21581 -- mov eax, [ebp+var_8] \- 0x21584 -- mov word ptr [eax], 0 \- 0x21589 -- leave \- 0x2158A -- retn 4 \-- Jump into -> 0x20F30 \-- 0x20F30 -- push ebp \-- 0x20F31 -- mov ebp, esp \-- 0x20F33 -- lea esp, [esp-10h] \-- 0x20F37 -- mov [ebp+var_C], eax \-- 0x20F3A -- mov [ebp+var_4], edx \-- 0x20F3D -- mov [ebp+var_8], ecx \-- 0x20F40 -- mov eax, [ebp+var_8] \-- 0x20F43 -- cmp word ptr [eax], 0 \-- 0x20F48 -- jz locret_20FCF \-- 0x20F4E -- mov edx, [ebp+var_4] \-- 0x20F51 -- mov eax, 5C29B4h \-- 0x20F56 -- call sub_C910 \-- 0x20F5B -- test al, al \-- 0x20F5D -- jz short loc_20FC3 \-- 0x20F5F -- mov eax, [ebp+var_4] \-- 0x20F62 -- mov [ebp+var_10], eax \-- 0x20F65 -- mov eax, [ebp+var_C] \-- 0x20F68 -- cmp word ptr [eax+150h], 0 \-- 0x20F71 -- jz short locret_20FCF \-- 0x20F73 -- mov eax, [ebp+var_C] \-- 0x20F76 -- mov edx, [ebp+var_8] \-- 0x20F79 -- mov ax, [eax+150h] \-- 0x20F80 -- cmp ax, [edx] \-- 0x20F83 -- jnz short locret_20FCF \-- 0x20F85 -- mov eax, [ebp+var_C] \-- 0x20F88 -- mov eax, [eax+154h] \-- 0x20F8E -- cmp eax, [ebp+arg_0] \-- 0x20F91 -- jnz short locret_20FCF \-- 0x20F93 -- mov eax, [ebp+var_C] \-- 0x20F96 -- mov eax, [eax+14Ch] \-- 0x20F9C -- cmp eax, [ebp+var_10] \-- 0x20F9F -- jnz short locret_20FCF \-- 0x20FA1 -- push [ebp+arg_0] \-- 0x20FA4 -- mov ecx, [ebp+var_8] \-- 0x20FA7 -- mov edx, [ebp+var_10] \-- 0x20FAA -- mov eax, [ebp+var_C] \-- 0x20FAD -- call sub_21590 \-- 0x20FB2 -- push [ebp+arg_0] \-- 0x20FB5 -- mov ecx, [ebp+var_8] \-- 0x20FB8 -- mov edx, [ebp+var_10] \-- 0x20FBB -- mov eax, [ebp+var_C] \-- 0x20FBE -- call sub_214E0 \-- 0x20FC3 -- mov eax, [ebp+var_C] \-- 0x20FC6 -- mov word ptr [eax+150h], 0 \-- 0x20FCF -- leave \-- 0x20FD0 -- retn 4 \--- Jump into -> 0x214E0 \--- 0x214E0 -- push ebp \--- 0x214E1 -- mov ebp, esp \--- 0x214E3 -- lea esp, [esp-10h] \--- 0x214E7 -- mov [ebp+var_C], eax \--- 0x214EA -- mov [ebp+var_4], edx \--- 0x214ED -- mov [ebp+var_8], ecx \--- 0x214F0 -- mov eax, [ebp+arg_0] \--- 0x214F3 -- test eax, eax \--- 0x214F5 -- jnz locret_21589 \--- 0x214FB -- mov eax, [ebp+var_8] \--- 0x214FE -- cmp word ptr [eax], 1Bh \--- 0x21503 -- jnz locret_21589 \--- 0x21509 -- push 0 \--- 0x2150B -- mov eax, [ebp+var_8] \--- 0x2150E -- movzx ecx, word ptr [eax] \--- 0x21511 -- mov eax, [ebp+var_4] \--- 0x21514 -- mov edx, 0B01Eh \--- 0x21519 -- call sub_8E870 \--- 0x2151E -- test eax, eax \--- 0x21520 -- jnz short locret_21589 \--- 0x21522 -- push 0 \--- 0x21524 -- mov eax, [ebp+var_4] \--- 0x21527 -- mov ecx, 0 \--- 0x2152C -- mov edx, 87h ; '‡' \--- 0x21531 -- call sub_8E870 \--- 0x21536 -- and eax, 4 \--- 0x21539 -- jnz short locret_21589 \--- 0x2153B -- mov eax, [ebp+var_C] \--- 0x2153E -- test dword ptr [eax+160h], 4 \--- 0x21548 -- jz short locret_21589 \--- 0x2154A -- mov eax, [ebp+var_4] \--- 0x2154D -- mov dl, 1 \--- 0x2154F -- call sub_13F00 \--- 0x21554 -- mov [ebp+var_10], eax \--- 0x21557 -- test eax, eax \--- 0x21559 -- jz short locret_21589 \--- 0x2155B -- mov eax, [ebp+var_10] \--- 0x2155E -- cmp dword ptr [eax+378h], 0 \--- 0x21565 -- jz short locret_21589 \--- 0x21567 -- mov eax, [ebp+var_10] \--- 0x2156A -- mov eax, [eax+378h] \--- 0x21570 -- mov edx, [ebp+var_10] \--- 0x21573 -- mov edx, [edx+378h] \--- 0x21579 -- mov edx, [edx] \--- 0x2157B -- call dword ptr [edx+2E8h] \--- 0x21581 -- mov eax, [ebp+var_8] \--- 0x21584 -- mov word ptr [eax], 0 \--- 0x21589 -- leave \--- 0x2158A -- retn 4 \---- Jump into -> 0x13F00 \---- 0x13F00 -- push ebp \---- 0x13F01 -- mov ebp, esp \---- 0x13F03 -- lea esp, [esp-0Ch] \---- 0x13F07 -- mov [ebp+var_4], eax \---- 0x13F0A -- mov [ebp+var_8], dl \---- 0x13F0D -- jmp short loc_13F33 \---- 0x13F10 -- cmp [ebp+var_8], 0 \---- 0x13F14 -- jnz short loc_13F27 \---- 0x13F16 -- mov edx, [ebp+var_4] \---- 0x13F19 -- mov eax, 59ECF0h \---- 0x13F1E -- call sub_C910 \---- 0x13F23 -- test al, al \---- 0x13F25 -- jnz short loc_13F45 \---- 0x13F27 -- mov eax, [ebp+var_4] \---- 0x13F2A -- mov eax, [eax+1F8h] \---- 0x13F30 -- mov [ebp+var_4], eax \---- 0x13F33 -- cmp [ebp+var_4], 0 \---- 0x13F37 -- jz short loc_13F45 \---- 0x13F39 -- mov eax, [ebp+var_4] \---- 0x13F3C -- cmp dword ptr [eax+1F8h], 0 \---- 0x13F43 -- jnz short loc_13F10 \---- 0x13F45 -- mov edx, [ebp+var_4] \---- 0x13F48 -- mov eax, 59ECF0h \---- 0x13F4D -- call sub_C910 \---- 0x13F52 -- test al, al \---- 0x13F54 -- jz short loc_13F5E \---- 0x13F56 -- mov eax, [ebp+var_4] \---- 0x13F59 -- mov [ebp+var_C], eax \---- 0x13F5C -- jmp short loc_13F65 \---- 0x13F5E -- mov [ebp+var_C], 0 \---- 0x13F65 -- mov eax, [ebp+var_C] \---- 0x13F68 -- leave \---- 0x13F69 -- retn
Надо будет поправить пару строк, чтобы выводилась не функция целиком, а как при трассировке:
for j in [i for i in self.range_reverse(current_function.endEA, current_function.startEA)]:
-
Задачка по IDA и Python (старое)Вдохновение появилось после просмотра видео по Ultimap
Когда в Ultimap появляются Nx адресов с одним счетчиком, то хочется увидеть эти связи на графиках IDA. Появилась идея загуглить как в IDA через IDC скрипт отрисовать ветвь кода или ветви кода, на которых эти самые адреса связаны между собой, а все вложенные другие скрывать. Пока из подсказок я нашел это и это
Допустим для тренировки даны два адреса из одной ветви кода (это я точно знаю, т.к. получен не из ultimap, а из tracelog)
Адрес1 - Tutorial-i386.exe+2578F - 29 83 AC040000 - sub [ebx+000004AC],eax" или адрес 0x00402B77
Адрес2 - Tutorial-i386.exe+16DBED - 89 45 FC - mov [ebp-04],eax или адрес 0x0056DBEDИ вот думаю, как скрипт ниже переделать, чтобы сначала вывести текстовый маршрут, а потом и хотя бы одну ветвь кода. Т.е. поднимаясь вверх по иерархии вызовов нужно остановиться до Адреса2.
#include <idc.idc> static main() { auto ea, func, ref; // получаем текущий адрес курсора ea = 0x00402B77; // в цикле от начала (SegStart) до конца (SegEND) текущего сегмента for (func = SegStart(ea); func != BADADDR && func < SegEnd(ea); func = NextFunction(func)) { // если текущий адрес является адресом функции if (GetFunctionFlags(func) != -1) { Message("Function %s at 0x%x\n", GetFunctionName(func), func); // находим все ссылки на данную функцию и выводим for (ref = RfirstB(func); ref != BADADDR; ref = RnextB(func, ref)) { Message(" called from %s(0x%x)\n", GetFunctionName(ref), ref); } } } }
Пока просто вывод от стартовой функции без условий
Как будет время попробую доделать...
p.s. Ну ничего так idc скрипты. Много всего, но смысл тот же, что и в CE Lua у некоторых функций. Еще не разобрался как Python подключить к IDA, пока на idc скриптах.
Будет интересно еще посмотреть эту же задачу на Hydra и Radare, ну и в CE (в новой версии появилось окно диаграмм)
-
Unity API (игровой движок)API
-
Panda3D API (игровой движок) -
Frostbite API (игровой движок) -
CryEngine API (игрвой движок)https://docs.cryengine.com/display/CEPROG/CRYENGINE+API+Reference
Изучив API, можно управлять иерархией сущностей, сценами, физикой и т.п. в играх созданных на этом движке.
Игровой бинарный код будет состоять из функций игрового движка и функций разработчиков игры. Можно управлять сущностями на основе API движка или же функциями разработчиков.
-
UnrealEngine API (игровой движок)UnrealEngine - популярный игровой движок с открытым API.
Открытое API должно позволить управлять иерархией сущностей (акторы). Т.е. создать сущности, удалять, менять положение в иерархии. Управлять сценами с этими сущностями, физикой, Meshes, эффектами, звуками...
Единственное нужно разобраться в этом API, собрать dll модуль на языке программирования и загрузить его в игру... ну, и возможно, управлять этим модулем извне.
-
Windows APIAPI Windows - это пользовательские функции для работы с процессами и памятью. Все программы, приложения, сервисы, в том числе и программа CE используют эти функции и даже игры. Функции что-то делают, что-то вызывают, какие-то результаты возвращают. Смотрим справки
Win32.chm - справочник
Другие ресурсы:
Софт для работы с API:
Книги:
Книга "[RU] Джефри Рихтер Windows для профессионалов. 4 издание.pdf" -
ASM APIОпкоды из Intel-ловской документации
Instruction_Set_Reference.pdf
64-ia-32-architectures-software-developer-vol-2a-manual.pdf
64-ia-32-architectures-software-developer-vol-2b-manual.pdf -
CE Auto Assembler APIAuto Assembler
(описание команд Autoassebler c примерами).
Там же вставки C-языка
{$CCODE playerbase=RCX newhealth=RBX} int isplayer=*(*int)(playerbase+0xb8); if (isplayer) newhealth=100000; else newhealth=0; {$ASM}
Руководство по C языку (https://www.geeksforgeeks.org/c-programming-language/)
Там же вставки Lua языка
{$LUACODE playerbase=RCX newhealth=RBX} if readInteger(playerbase+0xb8)==1 then newhealth=100000 else newhealth=0 end {$ASM}
Руководство по Lua (https://www.lua.org/manual/5.4/)
Lua классы в CE (https://wiki.cheatengine.org/index.php?title=Cheat_Engine:Lua) -
CE Lua APICE 7.5.0.7431
Wiki:
(содержит более полное описание классов с примерами)
-
Рубрика "Lua код сегодня" №6 (проверка по md5)- Получить md5 открытого процесса и записать его в
MD5_CHEKING
вручную
\-- Функция для ручного вывода md5 ранее подключенного процесcа. Для установки MD5_CHEKING PrintMd5CurrentProcess()
- Пример проверки md5
function onOpenProcess(processid) reinitializeSymbolhandler() local md5Process = GetMd5Process(processid) PrintMd5Process(process, md5Process) local isSupportedVersion = CheckingMd5CurrentProcess(md5Process) local lineResult = isSupportedVersion and 'Is supported version.' or 'Is not supported version.' if not isSupportedVersion then speakEnglish(lineResult, false) messageDialog('Error', lineResult, mtError, mbClose) end end
ce_md5.lua
md5 - это алгоритм некоторой суммы байтов exe-шника. Позволит точно идентифицировать exe-шник, для которого будет сделана .CT таблица с указателями или сигнатурами.
В случае несоответствия будет показан диалог сообщения и звуковое оповещение проговаривания текста ошибки.Будет необходимо проверять md5, чтобы смещения у структур точно не поменялись.
- Получить md5 открытого процесса и записать его в
-
С чего начатьВозникают вопросы "с чего начать?", "в каком направлении следовать?", "каких целей и результатов добиться?". Каждый выбирает, что ему ближе. Как я вижу есть несколько направлений:
Цель - ознакомление с gamehacking, чтобы понять интересно это или нет и сразу вторая цель - определить способ мотивировать себя в изучении программирования. Ведь gamehacking - это самый интересный способ начать программировать от ручных операций до автоматизации. Каждый раз можно вспоминать эти цели, чтобы понять добились ли мы поставленных целей и нужно ли начать заново с новой игрой или начать заново чтобы улучшить предыдущий результат, например, через новые приемы или создавая новые типы читов. Вновь и вновь можно что-то новое и интересное реализовать.
Я разделил путь на два пункта: ознакомление и продолжение.
- Ознакомление можно начать с поиска и заморозки адресов игровых значений в CE и создание .CT таблиц, чтобы ими пользоваться. Затем узнать, что в большинстве случаев требуются правильные указатели в CE, чтобы не искать адреса при запуске игры заново. Для этого требуется разобраться, как искать указатели. Если нет игры под рукой можно взять программу тренировки, которая находится рядом с exe-шником CE. Там на английском написано, что и как требуется для поиска указателей. Если что не понятно, то можно найти видео о том, как проходить эти туториалы.
В принципе для ознакомления с gamehacking заморозки значений по указателям и создания .CT таблиц в CE будет достаточно. Стоит не забывать указывать версию игры для, которой .CT таблица работает.
- Все, что идет за рамками ознакомления - это путь творческий. Здесь мы можем штамповать .CT таблицы с огромным количеством чит-опций, генерировать трейнеры на CE. Или отказаться от CE и программировать на языках программирования. Где конкретно больше пользы или что будет более вдохновлять можно определить в процессе. Программирование в принципе может быть довольно сложным как с CE (aa-, lua-, c- скрипты), так и без CE - любой язык программирования. Пользование CE может быть источником вдохновения, а использование языка программирования будет пользой для обучения программированию. Это безусловно будет помощью и мотивацией в учебе и даже в выборе специальности.
Рано или поздно будет складываться общая картина. Вероятно, постепенно придем к тому, что сможем понимать и менять любой игровой функционал от мелких изменений до очень сложных модов и патчей.
Что же мы хотим? Получить мотивацию, опыт? Я бы предложил получать и то и другое. В качестве опыта - выбирать направление и инструментарий самому. Например, мне было бы интересно работать с отладкой, графами, структурами, CT-таблицами, базами данных, встроенной консолью для команд, а также решением задач с нейронными сетями с PyTorch ( классификации, предсказания, выбора лучших решений, обучения и прочего). Фактически игровой процесс - набор новых правил и целей. Единственное не потерять кучу времени впустую, всегда нужно искать пользу. Хотя бы в мотивации, изучении технологий, которые можно применить с пользой.
-
Правила форумаПравила форума для пользователей
Предлагаю ознакомиться с существующими правилами форума. Правила могут меняться (в этой же теме).
Вы соглашаетесь не публиковать оскорбительные, непристойные, вульгарные, клеветнические, ненавистнические, угрожающие или любые другие материалы, которые могут нарушать какие-либо применимые законы. Это может привести к тому, что вы будете заблокированы (и ваш поставщик услуг будет проинформирован). IP-адреса всех сообщений записываются для обеспечения соблюдения этих условий.
Вы соглашаетесь с тем, что администратор и модераторы этого форума имеют право удалять, редактировать, перемещать или закрывать любую тему в любое время по своему усмотрению. Как пользователь, вы соглашаетесь с тем, что любая информация, которую вы ввели выше, будет храниться в базе данных и будет доступна поисковым службам в Интернете в открытом доступе. Хотя на форуме возможны скрытые темы для определенных групп пользователей.
Система форума использует файлы cookie для хранения информации на вашем локальном компьютере. Файлы cookie служат для улучшения просмотра. Адрес электронной почты скрыт, используется для подтверждения ваших регистрационных данных и пароля (и для отправки новых паролей, если вы забыли свой текущий), а также для новостной рассылки. На форуме работает система Google аналитики. Аналитика используется для улучшения индексации и качества предоставляемой информации, а именно создания лучших тегов и для установки приоритетов наиболее интересным темам.
Удаление учетной записи не приведет к автоматическому удалению ваших сообщений, а только вашего доступа к ним.Нажимая «Зарегистрироваться» вы соглашаетесь соблюдать эти условия.
Рекомендуется :
- большие файлы публиковать в виде ссылок (более 10 Мб) и хранить у себя в облаке (яндекс диск, google диск и т.п.);
- хранить копию файлов у себя на всякий случай, потому что он может быть удален по разным причинам. Также это касается статей и постов, которые имеют особую ценность;
- не обязательно, но рекомендуется публиковать ссылки на репозитории с исходниками;
- рекомендуется публиковать обучающие материалы и оказывать помощь в вопросах.
Todo: разместить в пользовательском соглашении