Метод поиска аналогичного кода в двоичном файле новой версии

#dll #diff #ida #radare2

Вопрос:

Попала в руки такая задача. Есть две библиотеки DLL. Как мне объяснили во втором файле (new.dll) это новый выпуск первого файла (old.dll). Оба файла скомпилированы для x64. Мне нужно найти то, из чего несколько функций превратились в старые.dll в new.dll. Ниже приведен пример одной из функций. Пожалуйста, выскажите свои мысли о моем подходе к поиску новой версии кода: я начал с использования rdare2, чтобы найти все функции в старой.dll (более 40 тысяч), создал файл с подписями и установил его на новый файл. В конце концов, ничего не было найдено. Я прихожу к выводу, что изменения носят более чем косметический характер. Затем я решил выполнить поиск следующим образом:

  1. Я выполняю поиск по фрагментам кода функции. Я беру пролог перед вызовом функции и ищу эту последовательность байтов в new.dll.
  2. Я пытаюсь найти константы, строки и другие магические числа, которые появляются в функции, и ищу их в new.dll.
  3. Я анализирую все функции, вызывающие нужную функцию, и пытаюсь найти аналогичный набор вызывающих функций в new.dll.
  4. Я пытаюсь определить последовательность вызова функций до самого первого (сверху) и нахожу аналогичную последовательность вызовов в новом файле.
  5. Я анализирую все функции, которые вызываются из нужной функции, и пытаюсь найти аналогичный набор вызываемых функций в new.dll
  6. Здесь я признаю, что все вышесказанное мне не помогло. Далее, я думаю, что, поскольку существуют такие вызовы для вызова qword ptr [rax 18h] (их в анализируемой функции 8), то, вероятно, это вызовы методов объекта (объектов). Вероятно, вы можете найти vftable и понять, к какому классу принадлежат эти методы, и уже создать набор классов.метод, который вызывается в моей функции. Затем выполните поиск в новом.dll, где вызывается такая последовательность методов из соответствующих классов.
  7. Вероятно, вы можете попытаться найти, где был создан объект и откуда он взялся в моей функции. Затем найдите аналогичный след в new.dll. Не уверен, что этот метод можно применить без отладки этой библиотеки dll. Неясно, как запустить dll, потому что экспортируются только три функции: DllGetLCID PPMain DllEntryPoint

Какой из перечисленных подходов к поиску является утопией, а какой нет? Может быть, есть более проверенные варианты? Пример одной из функций:

 .text:00000001806FFB30                               f1              proc near               ; CODE XREF: sub_1806F3630 172↑p
.text:00000001806FFB30                                                                       ; sub_1806FFC70 27↓p ...
.text:00000001806FFB30
pperrinfo        = qword ptr -260h
perrinfo          = qword ptr -258h
var_250         = qword ptr -250h
var_248         = dword ptr -248h
var_244         = qword ptr -244h
var_23C         = word ptr -23Ch
var_30          = qword ptr -30h
; __unwind { // __GSHandlerCheck
push    rbp
push    rbx
push    rsi
push    rdi
push    r14
lea      rbp, [rsp-160h] ; Load Effective Address
sub     rsp, 260h       ; Integer Subtraction
mov    rax, cs:__security_cookie
xor     rax, rsp        ; Logical Exclusive OR
mov    [rbp 180h var_30], rax
mov    rbx, rcx
mov    esi, r8d
lea      rcx, [rsp 280h pperrinfo] ; pperrinfo
mov    rdi, rdx
call     cs:CreateErrorInfo ; Indirect Call Near Procedure
xor     r14d, r14d      ; Logical Exclusive OR
test    eax, eax        ; Logical Compare
jns     short loc_1806FFB80 ; Jump if Not Sign (SF=0)
mov   ecx, 8B843h
call     Mso20Win32Client_1159 ; Call Procedure
jmp    loc_1806FFC52   ; Jump
; ---------------------------------------------------------------------------
loc_1806FFB80:                          ; CODE XREF: f1 3F↑j
mov   rdx, cs:qword_181031910
test    rdx, rdx        ; Logical Compare
jz       short loc_1806FFB9D ; Jump if Zero (ZF=1)
mov   rcx, [rsp 280h pperrinfo]
mov   rdx, [rdx]
mov   rax, [rcx]
mov   rdx, [rdx]
call    qword ptr [rax 18h] ; Indirect Call Near Procedure
loc_1806FFB9D:                          ; CODE XREF: f1 5A↑j
mov     rcx, [rsp 280h pperrinfo]
mov     rdx, rdi
mov     rax, [rcx]
call      qword ptr [rax 30h] ; Indirect Call Near Procedure
mov     rcx, [rsp 280h pperrinfo]
mov     edx, esi
mov     rax, [rcx]
call      qword ptr [rax 38h] ; Indirect Call Near Procedure
mov     rcx, cs:qword_181038800
lea       rax, [rsp 280h var_23C] ; Load Effective Address
mov     r9d, 100h
mov     [rsp 280h var_250], rax
lea       r8, [rsp 280h var_23C] ; Load Effective Address
mov     [rsp 280h var_244], r9
mov     edx, 61850043h
mov     [rsp 280h var_248], 1
mov     [rsp 280h var_23C], r14w
call      Mso30Win32Client_27 ; Call Procedure
mov     rcx, [rsp 280h pperrinfo]
add      eax, eax        ; Add
mov     rdx, [rsp 280h var_250]
mov     dword ptr [rsp 280h var_244 4], eax
mov     rax, [rcx]
call      qword ptr [rax 20h] ; Indirect Call Near Procedure
mov     rcx, [rsp 280h pperrinfo]
mov     rdx, rbx
mov     rax, [rcx]
call      qword ptr [rax 28h] ; Indirect Call Near Procedure
mov     rcx, [rsp 280h pperrinfo]
lea       r8, [rsp 280h perrinfo] ; Load Effective Address
lea       rdx, unk_180C909A8 ; Load Effective Address
mov     rax, [rcx]
call      qword ptr [rax] ; Indirect Call Near Procedure
test      eax, eax        ; Logical Compare
js         short loc_1806FFC47 ; Jump if Sign (SF=1)
mov     rdx, [rsp 280h perrinfo] ; perrinfo
xor      ecx, ecx        ; dwReserved
call      cs:SetErrorInfo ; Indirect Call Near Procedure
mov     rcx, [rsp 280h perrinfo]
mov     rax, [rcx]
call      qword ptr [rax 10h] ; Indirect Call Near Procedure
loc_1806FFC47:                          ; CODE XREF: f1 FD↑j
mov     rcx, [rsp 280h pperrinfo]
mov     rax, [rcx]
call      qword ptr [rax 10h] ; Indirect Call Near Procedure
loc_1806FFC52:                          ; CODE XREF: f1 4B↑j
mov     rcx, [rbp 150h]
xor      rcx, rsp        ; Logical Exclusive OR
call      sub_1801BFAE0   ; Call Procedure
add     rsp, 260h       ; Add
pop     r14
pop     rdi
pop     rsi
pop     rbx
pop     rbp
retn                    ; Return Near from Procedure
; } // starts at 1806FFB30
f1              endp