Некоторые люди не понимают, что обычным статическим анализом нельзя обойтись, чтобы описать весь control-flow какого-либо модуля.
Основные их аргументы - если ф-ция есть, то обязательно будет ссылка на него.
Пример:
открываем notepad.exe в IDA, находим кусок высокоуровнего seh'а(scopetable entry):
.text:01001898 stru_1001898 _msEH <0FFFFFFFFh, offset loc_100752A, offset loc_100753E>
Смотрим сами обработчики - ссылок из кода на них нет, но(!) есть data xref:
.text:01007528 jmp short loc_1007557
.text:0100752A
.text:0100752A loc_100752A: ; DATA XREF: .text:stru_1001898
.text:0100752A mov eax, [ebp+ms_exc.exc_ptr]
.text:0100752D mov ecx, [eax]
.text:0100752F mov ecx, [ecx]
.text:01007531 mov [ebp+var_28], ecx
.text:01007534 push eax
.text:01007535 push ecx
.text:01007536 call _XcptFilter
.text:0100753B pop ecx
.text:0100753C pop ecx
.text:0100753D retn
.text:0100753E
.text:0100753E loc_100753E: ; DATA XREF: .text:stru_1001898
.text:0100753E mov esp, [ebp+ms_exc.old_esp]
.text:01007541 mov esi, [ebp+var_28]
.text:01007544 cmp [ebp+var_1C], 0
.text:01007548 jnz short loc_1007551
.text:0100754A push esi ; int
.text:0100754B call ds:_exit
.text:01007551 ; ---------------------------------------------------------------------------
IDA прекрасно все находит и резолвит, т.к. есть:
.text:0100739D push 70h
.text:0100739F push offset stru_1001898
.text:010073A4 call __SEH_prolog
А теперь идем в тот же notepad.exe, делаем поиск по ф-ции GetSystemTimeAsFileTime, по xref прыгаем на место вызова её и видим:
.text:010070CC sub_10070B1 endp
.text:010070CC
.text:010070CC ; ---------------------------------------------------------------------------
.text:010070CF db 5 dup(0CCh)
.text:010070D4 ; ---------------------------------------------------------------------------
.text:010070D4 mov edi, edi
.text:010070D6 push ebp
.text:010070D7 mov ebp, esp
.text:010070D9 sub esp, 10h
.text:010070DC mov eax, dword_1009604
.text:010070E1 test eax, eax
.text:010070E3 jz short loc_10070EC
.text:010070E5 cmp eax, 0BB40h
.text:010070EA jnz short loc_1007139
.text:010070EC
.text:010070EC loc_10070EC: ; CODE XREF: .text:010070E3
.text:010070EC push esi
.text:010070ED lea eax, [ebp-8]
.text:010070F0 push eax
.text:010070F1 call ds:GetSystemTimeAsFileTime
.text:010070F7 mov esi, [ebp-4]
Опачки, ф-ция не распозналась IDA'ой. Превратим принудительно её в ф-цию нажав p, после чего видно, что на ф-цию нет перекрестных ссылок, её никто не вызывает из данного модуля. То есть в графе, если им описать данный модуль по xref'aм, эта ф-ция будет отсутствовать.
На логичный вопрос - зачем она тогда нужна в коде, если ее никто не вызывает? Ответ прост - раз есть, то скорее всего кто-то вызывает( или в микрософте любят компилировать с выключенной оптимизацией =] ), и этот кто-то - просто другой модуль ( CRT ) и делается это динамически:
notepad зовет _initterm, который находится в рантаймовской либе msvcrt.dll:
msvcrt!_initterm+0xb:
77c39d72 8b06 mov eax,dword ptr [esi]
77c39d74 85c0 test eax,eax
77c39d76 7402 je msvcrt!_initterm+0x13 (77c39d7a)
77c39d78 ffd0 call eax <= вызов нашей ф-ции (0x010070D4)
Можно конечно эвристически определить, что по такому-то адресу находится код, на который никто не ссылается, собс-но так IDA и поступает, но, если представить на секунду, что код может быть в принципе каким угодно ( обфусцированным, зашифрованным и т.д.), то эвристика не поможет, а ссылок нa него нет - итог: fail.
В принципе это все достаточно очевидно, но видимо не для всех(надеюсь данный пример поможет).
Основные их аргументы - если ф-ция есть, то обязательно будет ссылка на него.
Пример:
открываем notepad.exe в IDA, находим кусок высокоуровнего seh'а(scopetable entry):
.text:01001898 stru_1001898 _msEH <0FFFFFFFFh, offset loc_100752A, offset loc_100753E>
Смотрим сами обработчики - ссылок из кода на них нет, но(!) есть data xref:
.text:01007528 jmp short loc_1007557
.text:0100752A
.text:0100752A loc_100752A: ; DATA XREF: .text:stru_1001898
.text:0100752A mov eax, [ebp+ms_exc.exc_ptr]
.text:0100752D mov ecx, [eax]
.text:0100752F mov ecx, [ecx]
.text:01007531 mov [ebp+var_28], ecx
.text:01007534 push eax
.text:01007535 push ecx
.text:01007536 call _XcptFilter
.text:0100753B pop ecx
.text:0100753C pop ecx
.text:0100753D retn
.text:0100753E
.text:0100753E loc_100753E: ; DATA XREF: .text:stru_1001898
.text:0100753E mov esp, [ebp+ms_exc.old_esp]
.text:01007541 mov esi, [ebp+var_28]
.text:01007544 cmp [ebp+var_1C], 0
.text:01007548 jnz short loc_1007551
.text:0100754A push esi ; int
.text:0100754B call ds:_exit
.text:01007551 ; ---------------------------------------------------------------------------
IDA прекрасно все находит и резолвит, т.к. есть:
.text:0100739D push 70h
.text:0100739F push offset stru_1001898
.text:010073A4 call __SEH_prolog
А теперь идем в тот же notepad.exe, делаем поиск по ф-ции GetSystemTimeAsFileTime, по xref прыгаем на место вызова её и видим:
.text:010070CC sub_10070B1 endp
.text:010070CC
.text:010070CC ; ---------------------------------------------------------------------------
.text:010070CF db 5 dup(0CCh)
.text:010070D4 ; ---------------------------------------------------------------------------
.text:010070D4 mov edi, edi
.text:010070D6 push ebp
.text:010070D7 mov ebp, esp
.text:010070D9 sub esp, 10h
.text:010070DC mov eax, dword_1009604
.text:010070E1 test eax, eax
.text:010070E3 jz short loc_10070EC
.text:010070E5 cmp eax, 0BB40h
.text:010070EA jnz short loc_1007139
.text:010070EC
.text:010070EC loc_10070EC: ; CODE XREF: .text:010070E3
.text:010070EC push esi
.text:010070ED lea eax, [ebp-8]
.text:010070F0 push eax
.text:010070F1 call ds:GetSystemTimeAsFileTime
.text:010070F7 mov esi, [ebp-4]
Опачки, ф-ция не распозналась IDA'ой. Превратим принудительно её в ф-цию нажав p, после чего видно, что на ф-цию нет перекрестных ссылок, её никто не вызывает из данного модуля. То есть в графе, если им описать данный модуль по xref'aм, эта ф-ция будет отсутствовать.
На логичный вопрос - зачем она тогда нужна в коде, если ее никто не вызывает? Ответ прост - раз есть, то скорее всего кто-то вызывает( или в микрософте любят компилировать с выключенной оптимизацией =] ), и этот кто-то - просто другой модуль ( CRT ) и делается это динамически:
notepad зовет _initterm, который находится в рантаймовской либе msvcrt.dll:
msvcrt!_initterm+0xb:
77c39d72 8b06 mov eax,dword ptr [esi]
77c39d74 85c0 test eax,eax
77c39d76 7402 je msvcrt!_initterm+0x13 (77c39d7a)
77c39d78 ffd0 call eax <= вызов нашей ф-ции (0x010070D4)
Можно конечно эвристически определить, что по такому-то адресу находится код, на который никто не ссылается, собс-но так IDA и поступает, но, если представить на секунду, что код может быть в принципе каким угодно ( обфусцированным, зашифрованным и т.д.), то эвристика не поможет, а ссылок нa него нет - итог: fail.
В принципе это все достаточно очевидно, но видимо не для всех(надеюсь данный пример поможет).
Комментариев нет:
Отправить комментарий