CE 7.2 Операции с трейслогом
Я решил рассмотреть три новые функции:
- Пользовательские типы данных в hex-окне
- Фильтр на окне определения адресов
- Поиск данных в окне Tracer
1. Пользовательские тип данных в 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 writereturns 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 floatmethods
byteTableToValue({bytetable},Address Optional)
valueToByteTable(value, Address Optional)
Фильтр на окне определения адресов
В некоторых играх могут быть сотни адресов, среди которых могут быть адреса своего персонажа, дружественных и врагов. Множество адресов ресурсов.
Чтобы не щелкать на каждый адрес, можно, используя фильтр, исключать лишние варианты адресов. Тут предлагаю, самому подумать, какие условия использовать.
Условия в Lua задаются как "==, ~=, or, not, and" и так далее
Пишем свое условие
Также можно свою функцию сделать. Будет больше простора
А если хотим парсить содержимое дизассемблированной строки по EIP/RIP, узнавая, что там в скобках дизассембленой инструкции и лежит ли она в границы структуры, то используем disassmble(EIP/RIP), регулярки для извлечения того, что в квадратных скобках, disassemble и т.п.
Цитата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 fieldgetInstructionSize(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)
3. Поиск данных в окне Tracer
Обычный поиск, как на прошлых скринах
Примеры
-- ищет адрес по адресу referencedAddress == 0x0165F8BC -- ссылка на байты. Почему-то не работает. Ниже будет другой путь referencedBytes == dwordToByteTable(98) -- сравнение по инструкции. В конце инструкции нужно ставить пробел instruction == "ret " -- так будет искать все вхождения "mov" instruction:match("mov")
Ну и более интересная версия перебора и одновременного выделения записей.
Здесь нужно открыть окно "Трейсера" и рядом в Lua окне писать свои условия в функции "Compare()", "PrintData()", Selected()
-- Поиск окна Трейслога function GetTTreeViewTracelogs() local max = getFormCount() for i=0, max-1 do if(getForm(i).ClassName == 'TfrmTracer') then return getForm(i) end end return nil end function FindTraceLogData() -- Нашли окно Трейслога tracerForm = GetTTreeViewTracelogs() -- Перебираем все записи for index=0, tracerForm.Count do -- Если запись пуста, то пропускаем if tracerForm.Entry[index] ~= nil then local entry = tracerForm.Entry[index] if Compare(entry) then Selected(entry, index) PrintData(entry,index ) end end end end -- Можно свое условие addressEAX = 0x001FB780 function Compare(entry) return addressEAX == entry.context.EAX end function PrintData(entry) --print(tracerForm.Entry[index].instruction) print(disassemble(entry.context.RIP)) end function Selected(entry, index) tracerForm.lvTracer.Items[index].Selected = true end FindTraceLogData()
Документация
TfrmTracer class (Inheritance: Form->ScrollingWinControl->CustomControl->WinControl->Control->Component->Object) properties Count: integer - number of entries in the list selectionCount: integer - The number of selected entries Entry[index]: table - Information about each entry. Read only. (Index starts at 0) table is formatted as: { address: integer - address of the instruction instruction: string - disassembled instruction instructionSize: integer - bytesize of the instruction referencedAddress: integer - address the code references referencedData: bytearray - The bytes of the referenced data at the time of tracing context: contexttable - the state of the cpu when this instruction got executed (contains registers(EAX/RAX, ...), floating points(FP) and XMM values hasStackSnapshot: boolean - set to true if there is a stack entry selected: boolean - Set to true if the entry is selected } StackEntry[index]: bytearray - The stacksnapshot of that entry. Nil if not available methods --------------------------------------------------- Treeview Class : (Inheritance: CustomControl->WinControl->Control->Component->Object) createTreeView(owner) properties Items: TreeNodes - The Treenodes object of the treeview (ReadOnly) Selected: TreeNode - The currently selected treenode methods beginUpdate() endUpdate() getItems() getSelected() setSelected() fullCollapse() : Collapses all the nodes, including the children's nodes fullExpand() : Expands all the nodes and all their children saveToFile(filename): Saves the contents of the treeview to disk --------------- TreeNodes class : (Inheritance: TObject) properties Count : Integer - The total number of Treenodes this object has Item[]: TreeNode - Array to access each node [] = Item[] methods clear() getCount() getItem(integer) : Return the TreeNode object at the given index (based on the TreeView's Treenodes) add(text:string): Returns a new root Treenode object insert(treenode, string): Returns a new treenode object that has been inserted before the given treenode insertBehind(treenode, string): Returns a new treenode object that has been inserted after the given treenode --------------- TreeNode class : (Inheritance: TObject) properties Text: string - The text of the treenode Parent: Treenode - The treenode this object is a child of. (can be nil) (ReadOnly) Level: Integer - The level this node is at HasChildren: boolean - Set to true if it has children, or you wish it to have an expand sign Expanded: boolean - Set to true if it has been expanded Count : Integer - The number of children this node has Items[]: Treenode - Array to access the child nodes of this node [] = Items[] Index: Integer - The index based on the parent AbsoluteIndex: Integer - The index based on the TreeView's Treenodes object (Items) Selected: Boolean - Set to true if currently selected MultiSelected: Boolean - Set to true if selected as well, but not the main selected object Data: Pointer - Space to store 4 or 8 bytes depending on which version of CE is used methods delete() deleteChildren() makeVisible() expand(recursive:boolean=TRUE OPTIONAL) : Expands the given node collapse(recursive:boolean=TRUE OPTIONAL) : collapses the given node getNextSibling(): Returns the treenode object that's behind this treenode on the same level add(text:string): Returns a Treenode object that is a child of the treenode used to create it ------------------------------------------ wordToByteTable(number): {} - Converts a word to a bytetable dwordToByteTable(number): {} - Converts a dword to a bytetable qwordToByteTable(number): {} - Converts a qword to a bytetable floatToByteTable(number): {} - Converts a float to a bytetable doubleToByteTable(number): {} - Converts a double to a bytetable extendedToByteTable(number): {} - Converts an extended to a bytetable stringToByteTable(string): {} - Converts a string to a bytetable wideStringToByteTable(string): {} - Converts a string to a widestring and converts that to a bytetable byteTableToWord(table, OPTIONAL signed:boolean): number - Converts a bytetable to a word byteTableToDword(table, OPTIONAL signed:boolean): number - Converts a bytetable to a dword byteTableToQword(table): number - Converts a bytetable to a qword byteTableToFloat(table): number - Converts a bytetable to a float byteTableToDouble(table): number - Converts a bytetable to a double byteTableToExtended(table): number - Converts a bytetable to an extended and converts that to a double byteTableToString(table): string - Converts a bytetable to a string byteTableToWideString(table): string - Converts a bytetable to a widestring and converts that to a string bOr(int1, int2) : Binary Or bXor(int1, int2) : Binary Xor bAnd(int1, int2) : Binary And bShl(int, int2) : Binary shift left bShr(int, int2) : Binary shift right bNot(int) : Binary not
Для вывода referencedBytes из трейслога можно использовать byteTableToDword(referencedBytes) (смотрим документации выше) получая из TfrmTracer.Entry[index].referencedBytes или в строке поиска у Трейслога вбить
byteTableToDword(referencedBytes) > 0 and print(string.format("0x%08X - 0x%08X", RIP, byteTableToDword(referencedBytes))) == 1
Практическое применение
Больше всего могут интересовать реальные практические примеры. Если будет время, желание может быть сделаю, а так просто общий обзор.
-
1
-
2
0 Комментариев
Рекомендуемые комментарии
Комментариев нет
Пожалуйста, войдите, чтобы комментировать
Вы сможете оставить комментарий после входа в
Войти