Приведу набор разбавленных описаниями
кусков антиотладочных фич. В общем кому надо они уже давно известны, но
я их прокомпилирую, и думаю кое-кому это будет полезно. Замечания по
сути материала приветствуются и полезны не только мне, но и вам. Зачем
нужна антиотладка? Чтобы такие чмошники как Неокс и его одноклассники
не смогли пробраться внутрь вашего злого кода. Т.е. чтобы их грязные
ванючие лапы не добрались до святости. Отформатируя диск при попытке
отладки мы эти лапы им отпилим, а заодно научим, что им в
программировании и реверсинге делать нечего. Конечно, на пабликовские
антиотладочные трюки имеются пабликовские способы их обнаружения, но
это будет пищей для того, чтобы сгенерировать что-то свое. Если
переход, значит отладчик найден. Синтаксис FASM.
1)
mov eax, [fs:18h]; указатель на TEB
mov eax, [eax+30h]; указатель на PEB
movzx eax, byte [eax+2]; поле BegingDebugged в PEB
or eax, eax
jne @F
2)
mov eax,[fs:30h]; указатель на PEB
movzx eax,byte [eax+2h]; поле BegingDebugged в PEB
or eax,eax
jne @F
3)
OllyWindowClass db 'OLLYDBG',0h
…
invoke FindWindow,OllyWindowClass,0
test eax,eax
jne @F
4)
mov eax,[fs:30h]; указатель на PEB
mov byte [eax+2h],0xba
invoke IsDebuggerPresent
mov eax,[fs:30h]
cmp byte [eax+2h],0xba
jne @F
Здесь просто неявная проверка на то, что IsDebuggerPresent похучен, ведь известно что IsDebuggerPresent берет значение из PEB как в способах 1 и 2.
5)
mov eax,[fs:30h]; указатель на PEB
mov eax,[eax+68h]; PEB.NtGlobalFlag
test eax,eax
jne @F
Обычно флаг NtGlobalFlag == 0, но если процесс отлаживается, то в нем присутствуют единичные биты указания отладочной кучи.
6)
invoke CloseHandle,0x0DEADC0DE
Вызов CloseHandle с невалидным указателем при обычном выполнении без отладчика не повлияет на исполнение последующего кода программы. Если эту строку исполнить в отладчике, то будет сгенерированно исключение, а т.к. оно не обрабатывается программой, оно будет передано отладчику. Это может вызвать пробему у неопытного реверсера.
7)
mov eax,[fs:18h]; указатель на TEB
mov eax,[eax+30h]; указатель на PEB
mov eax,[eax+18h]; PEB.ProcessHeap — куча по умолчанию
cmp dword [eax+10h],0; HEAP.ForceFlags
jne @F
Если поле HEAP.ForceFlags содержит флаги HEAP_FREE_CHECKING_ENABLED,
HEAP_TAIL_CHECKING_ENABLED или из набора HEAP_DEBUG_FLAGS, то процесс
отлаживается. Серце метода находится в функции создания кучи —
RtlCreateHeap, если процесс отлаживатеся, то о любом повреждении кучи
сообщается отладчику.
invoke SetProcessAffinityMask,-1,1
rdtsc
xor ecx,ecx
add ecx,eax
rdtsc
sub eax,ecx
cmp eax,0fffh
jnb @F
Известный каждому трюк с чтением временного штампа процессора.
9)
TrickFormatString db '%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s',0h
…
invoke OutputDebugString,TrickFormatString
Непатченная Олька падает при исполнении этого кода.
10)
invoke WindowFromPoint,13ah,100h
invoke AnimateWindow,eax,701h,90000h
Окно с кодом ольки таинственным образом исчезает
11)
Фичи с некорректными для оли полями заголовка PE-файла:
! Делаем LoaderFlag в OptionalHeader рандомным-большим, также поступаем и с NumberOfRVAOfSizes
! Делаем SizeOfCode и SizeOfInitData большими и рандомными
В итоге оля будет тупить.
12)
Если сделать имя файла для отладки %s%s.exe, то оля не сможет его загрузить.
Это наиболее простые и известные фичи. Пока.