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

Анализ Dissect Data Structure


MasterGH

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

Конечно не секрет, что типы данных не правильно определяются. Вот пример для 50-ти адресов

 

Слева как определил данные CE. Справа как определил их я по логу ниже

image.png

Понравились данные с размером в 1 байт, привлекают в нимание. Как только я переключил на ноль или 1, то персонаж перестал двигаться и не реагировал на движение.

 

Лог инструкций

Спойлер

-- 40BBC080 - начало структуры
-- Маска "Offset: + СМЕЩЕНИЕ : ОПКОД {СТРУКТУРА + ИНДЕКС} {РАСЧЕТ АДРЕСА ВНУТРИ ОПКОДА} "
-- Расчет видется после выпонения инструкции. Могут быть перезаписи регистров. Об этом в комментариях

-- Запустили отладку начиная с 40BBC080 на 100 адресов побайтно

8 байт (тут нет сюрпризова). 
-- mov Смело добавлять 8 байт, когда есть mov и 64 разрядные регистры
-- mov Смело добавлять 4 байт, когда есть mov и 32 разрядные регистры 
Offset: + 0 : 1408FD4AD - 48 8B 01  - mov rax,[rcx] 40BBC080 40BBC080 
Offset: + 1 : 1408FD4AD - 48 8B 01  - mov rax,[rcx] 40BBC081 40BBC080 
Offset: + 2 : 140635731 - 48 8B 03  - mov rax,[rbx] 40BBC082 40BBC080 
Offset: + 3 : 140635797 - 48 8B 11  - mov rdx,[rcx] 40BBC083 40BBC080 
Offset: + 4 : 1406742DF - 48 8B 01  - mov rax,[rcx] 40BBC084 40BBC080 
Offset: + 5 : 1406742FE - 48 8B 07  - mov rax,[rdi] 40BBC085 40BBC080 
Offset: + 6 : 140674312 - 48 8B 07  - mov rax,[rdi] 40BBC086 40BBC080 
Offset: + 7 : 140AE8E04 - 48 8B 19  - mov rbx,[rcx] 40BBC087 40BBC080 

4 байта (перезапись +E, можно восстановить если посмотреть [rdx+0C], где 0C смещение совпадает с Offset: + C и размером в 4 байта)
-- movsxd. Смело добавлять 4 байта
Offset: + C : 1406356F8 - 48 63 41 0C  - movsxd  rax,dword ptr [rcx+0C] 40BBC08C 40BBC08C 
Offset: + D : 13FB97370 - 48 63 41 0C  - movsxd  rax,dword ptr [rcx+0C] 40BBC08D 40BBC08C 
-- Внимание перезапись edx
Offset: + E : 13FBA2E1E - 8B 52 0C     - mov edx,[rdx+0C] 40BBC08E 11FBA 
Offset: + F : 13FB96CD4 - 49 63 41 0C  - movsxd  rax,dword ptr [r9+0C] 40BBC08F 40BBC08C 

8 байт (перезапись rcx, можно выкрутиться, т.к. смещение +10 от начала структуры) 
-- mov Смело добавлять 8 байт, когда есть mov и 64 разрядные регистры
  Offset: + 10 : 13FB93928 - 48 8B 49 10  - mov rcx,[rcx+10] 40BBC090 2E12610 
  Offset: + 11 : 13FB93928 - 48 8B 49 10  - mov rcx,[rcx+10] 40BBC091 2E12610 
Offset: + 12 : 14050E44B - 48 8B 57 10  - mov rdx,[rdi+10] 40BBC092 40BBC090 
Offset: + 13 : 1409481D0 - 48 8B 56 10  - mov rdx,[rsi+10] 40BBC093 40BBC090 
Offset: + 14 : 140529BBB - 48 8B 53 10  - mov rdx,[rbx+10] 40BBC094 40BBC090 
Offset: + 15 : 140529E0B - 48 8B 53 10  - mov rdx,[rbx+10] 40BBC095 40BBC090 
  Offset: + 16 : 13FB93928 - 48 8B 49 10  - mov rcx,[rcx+10] 40BBC096 2E12610 
  Offset: + 17 : 13FB93928 - 48 8B 49 10  - mov rcx,[rcx+10] 40BBC097 2E12610 

8 байт
-- mov Смело добавлять 8 байт, когда есть mov и 64 разрядные регистры
Offset: + 30 : 140A6D37D - 48 8B 01  - mov rax,[rcx] 40BBC0B0 40BBC0B0 
Offset: + 31 : 140A6D37D - 48 8B 01  - mov rax,[rcx] 40BBC0B1 40BBC0B0 
Offset: + 32 : 140A6D37D - 48 8B 01  - mov rax,[rcx] 40BBC0B2 40BBC0B0 
Offset: + 33 : 140A6D37D - 48 8B 01  - mov rax,[rcx] 40BBC0B3 40BBC0B0 
Offset: + 34 : 140A6D37D - 48 8B 01  - mov rax,[rcx] 40BBC0B4 40BBC0B0 
Offset: + 35 : 140A6D37D - 48 8B 01  - mov rax,[rcx] 40BBC0B5 40BBC0B0 
Offset: + 36 : 140A6D37D - 48 8B 01  - mov rax,[rcx] 40BBC0B6 40BBC0B0 
Offset: + 37 : 140A6D37D - 48 8B 01  - mov rax,[rcx] 40BBC0B7 40BBC0B0 

А здесь идет уже новая структура

1 байт
-- "movzx" Смело добавлять 1 байт
Offset: + 38 : 140A73445 - 0FB6 46 08     - movzx eax,byte ptr [rsi+08] 40BBC0B8 40BBC0B8 
1 байт
Offset: + 39 : 140A734F7 - 0FB6 46 09     - movzx eax,byte ptr [rsi+09] 40BBC0B9 40BBC0B9 
-- "cmp al" Смело добавлять 1 байт
1 байт
Offset: + 3A : 140A734FB - 3A 46 0A       - cmp al,[rsi+0A] 40BBC0BA 40BBC0BA 
1 байт
Offset: + 3B : 140A736BB - 44 0FB6 46 0B  - movzx r8d,byte ptr [rsi+0B] 40BBC0BB 40BBC0BB 
1 байт
Offset: + 3C : 140A73537 - 0FB6 4E 0C     - movzx ecx,byte ptr [rsi+0C] 40BBC0BC 40BBC0BC 
1 байт
-- "cmp byte" Смело добавлять 1 байт
Offset: + 3D : 140A73380 - 80 7B 0D 00    - cmp byte ptr [rbx+0D],00 40BBC0BD 40BBC0BD 
1 байт
Offset: + 3F : 140A73310 - 80 7E 0F 00    - cmp byte ptr [rsi+0F],00 40BBC0BF 40BBC0BF 

4 байта
Offset: + 40 : 140A73314 - 89 4E 10       - mov [rsi+10],ecx 40BBC0C0 40BBC0C0 
Offset: + 41 : 140A732EE - 48 63 41 10    - movsxd  rax,dword ptr [rcx+10] 40BBC0C1 40BBC0C0 
Offset: + 42 : 140A732EE - 48 63 41 10    - movsxd  rax,dword ptr [rcx+10] 40BBC0C2 40BBC0C0 
Offset: + 43 : 140A732EE - 48 63 41 10    - movsxd  rax,dword ptr [rcx+10] 40BBC0C3 40BBC0C0 

4 байта
Offset: + 44 : 140A737EA - 89 46 14       - mov [rsi+14],eax 40BBC0C4 40BBC0C4 
Offset: + 45 : 140A7339A - 48 63 43 14    - movsxd  rax,dword ptr [rbx+14] 40BBC0C5 40BBC0C4 
Offset: + 46 : 140A7339A - 48 63 43 14    - movsxd  rax,dword ptr [rbx+14] 40BBC0C6 40BBC0C4 
Offset: + 47 : 140A737EA - 89 46 14       - mov [rsi+14],eax 40BBC0C7 40BBC0C4 

8байт
Offset: + 48 : 140A733A7 - 48 8B 4B 18    - mov rcx,[rbx+18] 40BBC0C8 40BBC0C8 
Offset: + 49 : 140A733A7 - 48 8B 4B 18    - mov rcx,[rbx+18] 40BBC0C9 40BBC0C8 
Offset: + 4A : 140A6D386 - 48 C7 40 18 00000000 - mov [rax+18],00000000 40BBC0CA 40BBC0C8 
Offset: + 4B : 140A736C8 - 48 89 7E 18    - mov [rsi+18],rdi 40BBC0CB 40BBC0C8 
Offset: + 4C : 140A733A7 - 48 8B 4B 18    - mov rcx,[rbx+18] 40BBC0CC 40BBC0C8 
Offset: + 4D : 140A733A7 - 48 8B 4B 18    - mov rcx,[rbx+18] 40BBC0CD 40BBC0C8 
Offset: + 4E : 140A6D386 - 48 C7 40 18 00000000 - mov [rax+18],00000000 40BBC0CE 40BBC0C8 
Offset: + 4F : 140A736C8 - 48 89 7E 18    - mov [rsi+18],rdi 40BBC0CF 40BBC0C8 

Offset: + 50 : 140A73350 - 48 8B 00       - mov rax,[rax] 40BBC0D0 3343C180 

 

 

Пытаюсь по логам определить алгоритм для Lua, чтобы скрипт сам ставил тип и смещение. Конечно есть сюрпризы, когда регистр перезаписывает сам себя и еще куча опкодов. Чтобы получить такой лог мож попробовать этот скрипт. Он черновой

Спойлер

addressStructure1 = 0x40BBC080 --> адрес начала структуры в любой игре
sizeStructure = 100     --> гипототический размер структуры 100 для быстрых поисков, по умолчанию 4096
indexStructure = 0      --> индекс внутри структуры, который будет перемещаться вместе с breakPointAddress
breakPointAddress = 0   --> адрес, на который сейчас постален брейкпоинт
waitTimeTillBreak = 200 --> частота активности смещеиня
resultText = ''         --> конкатенация частей текста в этой переменной
is64bits = targetIs64Bit()

skipTimer = true

table4Bytes = {'movsxd'}
tableFloat = {''}
tableWord = {'word'}
tableByte = {'byte'}

-- Функция пытается поставить брейкпоинт на следующий байт в структуре
function TryNextSetBreakPointToAddress()
  debug_removeBreakpoint(breakPointAddress)
  indexStructure = indexStructure + 1
  if indexStructure > sizeStructure then
    debugTimer.Enabled = false
    debugTimer.destroy()
    debug_continueFromBreakpoint(co_run)
    print(resultText) --> вывод результата с завершением отладки
    return
  end
  breakPointAddress = addressStructure1 + indexStructure
  debug_setBreakpoint(breakPointAddress, 1, bptAccess, bpmDebugRegister)
  debug_continueFromBreakpoint(co_run)
end

-- Любимая функция снятия отладочных данных
function debugger_onBreakpoint()
  debugTimer.Enabled = false
  skipTimer = true

  -- проверить обращение к структуре
  prevAddress = getPreviousOpcode(RIP)
  --local clearString = disassemble(prevAddress):gsub('%s','')
  local clearString = disassemble(prevAddress)
  local codeAddress, _, opcode = clearString:match('^(.-)%-(.-)%-(.-)$')
  local addressStructure = GetAddressFromOpcode(opcode)
  
  print(string.format('Offset: + %X : %s', indexStructure, disassemble(prevAddress))..' '..string.format('%X', addressStructure1 + indexStructure)..' '.. string.format('%X',addressStructure))
  if(addressStructure1 + indexStructure == addressStructure) then
    resultText = resultText..string.format('Offset: + %X : %s', indexStructure, disassemble(prevAddress)) .. '\r\n'
  end  
  TryNextSetBreakPointToAddress()
  debugTimer.Enabled = true
  return 1
end

-- Простой таймер
if debugTimer == nil then
  debugTimer = createTimer(nil, false)
end
debugTimer.OnTimer = function(timer)
  if skipTimer then
    skipTimer = false
  else
    TryNextSetBreakPointToAddress() 
  end  
end
debugTimer.Interval = waitTimeTillBreak
debugTimer.Enabled = true
breakPointAddress = addressStructure1 + indexStructure
debug_setBreakpoint(breakPointAddress, 1, bptAccess, bpmDebugRegister)

function GetAddressFromOpcode (opcode)

		local rightLine = string.match(opcode, '%S*%s*(%S*)')
		local isPointer = string.match(opcode, '%[')
		if isPointer then
			rightLine = string.match(opcode, '%[(.*)%]')
			--00454664 - 8B 83 60030000        - mov eax,[ebx+00000360]
			if string.match(opcode, 'eax') then rightLine = string.gsub(rightLine, 'eax', string.format('%X', EAX)) end
			if string.match(opcode, 'ebx') then rightLine = string.gsub(rightLine, 'ebx', string.format('%X', EBX)) end
			if string.match(opcode, 'ecx') then rightLine = string.gsub(rightLine, 'ecx', string.format('%X', ECX)) end
			if string.match(opcode, 'edx') then rightLine = string.gsub(rightLine, 'edx', string.format('%X', EDX)) end
			if string.match(opcode, 'esi') then rightLine = string.gsub(rightLine, 'esi', string.format('%X', ESI)) end
			if string.match(opcode, 'edi') then rightLine = string.gsub(rightLine, 'edi', string.format('%X', EDI)) end
			if string.match(opcode, 'esp') then rightLine = string.gsub(rightLine, 'esp', string.format('%X', ESP)) end
			if string.match(opcode, 'ebp') then rightLine = string.gsub(rightLine, 'ebp', string.format('%X', EBP)) end

			if is64bits then
				if string.match(opcode, 'rax') then rightLine = string.gsub(rightLine, 'rax', string.format('%X', RAX)) end
				if string.match(opcode, 'rbx') then rightLine = string.gsub(rightLine, 'rbx', string.format('%X', RBX)) end
				if string.match(opcode, 'rcx') then rightLine = string.gsub(rightLine, 'rcx', string.format('%X', RCX)) end
				if string.match(opcode, 'rdx') then rightLine = string.gsub(rightLine, 'rdx', string.format('%X', RDX)) end
				if string.match(opcode, 'rsi') then rightLine = string.gsub(rightLine, 'rsi', string.format('%X', RSI)) end
				if string.match(opcode, 'rdi') then rightLine = string.gsub(rightLine, 'rdi', string.format('%X', RDI)) end
				if string.match(opcode, 'rsp') then rightLine = string.gsub(rightLine, 'rsp', string.format('%X', RSP)) end
				if string.match(opcode, 'rbp') then rightLine = string.gsub(rightLine, 'rbp', string.format('%X', RBP)) end

				if string.match(opcode, 'r8') then rightLine = string.gsub(rightLine, 'r8', string.format('%X', R8)) end
				if string.match(opcode, 'r9') then rightLine = string.gsub(rightLine, 'r9', string.format('%X', R9)) end
				if string.match(opcode, 'r10') then rightLine = string.gsub(rightLine, 'r10', string.format('%X', R10)) end
				if string.match(opcode, 'r11') then rightLine = string.gsub(rightLine, 'r11', string.format('%X', R11)) end
				if string.match(opcode, 'r12') then rightLine = string.gsub(rightLine, 'r12', string.format('%X', R12)) end
				if string.match(opcode, 'r13') then rightLine = string.gsub(rightLine, 'r13', string.format('%X', R13)) end
				if string.match(opcode, 'r14') then rightLine = string.gsub(rightLine, 'r14', string.format('%X', R14)) end
				if string.match(opcode, 'r15') then rightLine = string.gsub(rightLine, 'r15', string.format('%X', R15)) end
			end

			return getAddress(rightLine)
		else
			if string.match(opcode, 'eax') then rightLine = string.gsub(rightLine, 'eax', string.format('%X', EAX)) end
			if string.match(opcode, 'ebx') then rightLine = string.gsub(rightLine, 'ebx', string.format('%X', EBX)) end
			if string.match(opcode, 'ecx') then rightLine = string.gsub(rightLine, 'ecx', string.format('%X', ECX)) end
			if string.match(opcode, 'edx') then rightLine = string.gsub(rightLine, 'edx', string.format('%X', EDX)) end
			if string.match(opcode, 'esi') then rightLine = string.gsub(rightLine, 'esi', string.format('%X', ESI)) end
			if string.match(opcode, 'edi') then rightLine = string.gsub(rightLine, 'edi', string.format('%X', EDI)) end
			if string.match(opcode, 'esp') then rightLine = string.gsub(rightLine, 'esp', string.format('%X', ESP)) end
			if string.match(opcode, 'ebp') then rightLine = string.gsub(rightLine, 'ebp', string.format('%X', EBP)) end

			if is64bits then
				if string.match(opcode, 'rax') then rightLine = string.gsub(rightLine, 'rax', string.format('%X', RAX)) end
				if string.match(opcode, 'rbx') then rightLine = string.gsub(rightLine, 'rbx', string.format('%X', RBX)) end
				if string.match(opcode, 'rcx') then rightLine = string.gsub(rightLine, 'rcx', string.format('%X', RCX)) end
				if string.match(opcode, 'rdx') then rightLine = string.gsub(rightLine, 'rdx', string.format('%X', RDX)) end
				if string.match(opcode, 'rsi') then rightLine = string.gsub(rightLine, 'rsi', string.format('%X', RSI)) end
				if string.match(opcode, 'rdi') then rightLine = string.gsub(rightLine, 'rdi', string.format('%X', RDI)) end
				if string.match(opcode, 'rsp') then rightLine = string.gsub(rightLine, 'rsp', string.format('%X', RSP)) end
				if string.match(opcode, 'rbp') then rightLine = string.gsub(rightLine, 'rbp', string.format('%X', RBP)) end

				if string.match(opcode, 'r8') then rightLine = string.gsub(rightLine, 'r8', string.format('%X', R8)) end
				if string.match(opcode, 'r9') then rightLine = string.gsub(rightLine, 'r9', string.format('%X', R9)) end
				if string.match(opcode, 'r10') then rightLine = string.gsub(rightLine, 'r10', string.format('%X', R10)) end
				if string.match(opcode, 'r11') then rightLine = string.gsub(rightLine, 'r11', string.format('%X', R11)) end
				if string.match(opcode, 'r12') then rightLine = string.gsub(rightLine, 'r12', string.format('%X', R12)) end
				if string.match(opcode, 'r13') then rightLine = string.gsub(rightLine, 'r13', string.format('%X', R13)) end
				if string.match(opcode, 'r14') then rightLine = string.gsub(rightLine, 'r14', string.format('%X', R14)) end
				if string.match(opcode, 'r15') then rightLine = string.gsub(rightLine, 'r15', string.format('%X', R15)) end
			end
		end

		return getAddress(rightLine)
	end

 

 

 

  • Понравилось 1
  • Плюс 1

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


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

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

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

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



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

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

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