Анализ Dissect Data Structure
Конечно не секрет, что типы данных не правильно определяются. Вот пример для 50-ти адресов
Слева как определил данные CE. Справа как определил их я по логу ниже
Понравились данные с размером в 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 Комментариев
Рекомендуемые комментарии
Комментариев нет
Пожалуйста, войдите, чтобы комментировать
Вы сможете оставить комментарий после входа в
Войти