Перейти к содержанию
  • записи
    104
  • комментариев
    125
  • просмотров
    15 458

CE 7.2 Операции с трейслогом


MasterGH

1 005 просмотров

Я решил рассмотреть три новые функции:

 

  1. Пользовательские типы данных в hex-окне
  2. Фильтр на окне определения адресов
  3. Поиск данных в окне Tracer

 

1. Пользовательские тип данных в hex-окне

Спойлер

image.png

 

При чем эти типы костомные переносятся и в другие окна

image.pngimage.png

 

 

Пример как сделать:

Спойлер

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)

 

 

Фильтр на окне определения адресов

 

Спойлер

image.png

 

В некоторых играх могут быть сотни адресов, среди которых могут быть адреса своего персонажа, дружественных и врагов. Множество адресов ресурсов.

Чтобы не щелкать на каждый адрес, можно, используя фильтр, исключать лишние варианты адресов. Тут предлагаю, самому подумать, какие условия использовать.

 

Условия в Lua задаются как "==, ~=, or, not, and" и так далее

 

Пишем свое условие

image.png

 

Также можно свою функцию сделать. Будет больше простора

image.png

 

А если хотим парсить содержимое дизассемблированной строки по 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 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)

 

 

3. Поиск данных в окне Tracer

image.png

 

Обычный поиск, как на прошлых скринах

Спойлер

image.png

 

Примеры

Спойлер

-- ищет адрес по адресу
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()

 

 

image.png

 

Документация

Спойлер

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 Комментариев


Рекомендуемые комментарии

Комментариев нет

Пожалуйста, войдите, чтобы комментировать

Вы сможете оставить комментарий после входа в



Войти
×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.