PDA

Просмотр полной версии : Простая антиотладка на Delphi


TaNkist
15.10.2006, 13:19
Простая Антиотладка на Delphi.
Надеюсь, ты человек грамотный и знаешь, что такое отладчик (debugger). Если нет, то знай, что отладчик – программа, позволяющая следить за выполнением другой проги, отлавливать вызовы определенных функций. Дебаггер позволяет отловить ошибки или разобраться в работе какого-нибудь софта. Примерами являются OllyDebugger, SoftICE, gdb и десятки других мене известных и популярных.
Как ты понимаешь мало-какому програмеру понравиться, когда его прогу отлаживают. Особенно это не нравится шароварщикам и вирусописателям. Ведь если первые могут лишиться денег. То вторые рискуют поплатиться свободой и провести ближайшие пару лет в тюрьме. Поэтому хакеры учатся противодействовать отладчикам. В Интернете большинство материалов, посвященных антиотладке, рассчитаны на профессионалов, я же постараюсь объяснить все просто даже для новичков, а в качестве языка программирования у нас будет выступать Delphi.
Использование специальной api-функций.
В Windows есть специальная api-функция, позволяющая определить находимся ли мы под отладкой. Имя ей IsDebuggerPresent. Она не принимает параметров и возвращает true, если отладчик присутствует. Кстати, в заголовочном файле Windows.pas этой функции нет, поэтому объявить ее нужно самому.
function IsDebuggerPresent():boolean; stdcall; external 'kernel32.dll';
begin
if IsDebuggerPresent()=true then MessageBox(0,'debugger present','DebuggerChecker',0)
else MessageBox(0,'No debugger','DebuggerChecker',0);
end.

Поиск отладчика
Как и любая программа, отладчик имеет свой процесс, а значит может быть обнаружен через список процессов. Получить этот список можно разными способами. Мы будем работать с ToolHelp Api.
var
Snap: dword;
Process: TPROCESSENTRY32;
begin
Snap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if snap<>INVALID_HANDLE_VALUE then
begin
Process.dwSize:=SizeOf(TPROCESSENTRY32);
repeat
if lstrcmp(Process.szExeFile,'OLLYDBG.EXE')=0 then
begin
MessageBox(0,'OllyDBG work!','DebuggerChecker',0);
halt;
end;
until not Process32Next(Snap, Process);
end;
MessageBox(0,'OllyDBG not work!','DebuggerChecker',0);
end.
Большинство отладчиков общаются с пользователями через графический интерфейс. Т.е. мы можем вычислить дебаггер, найдя его окно. Поиск окон осуществляется функцией FindWindow.
var h:HWND;
begin
h := findwindow(nil,'OllyDbg');
If h<>0 then MessageBoxA(0,'OllyDbg work!','DebuggerChecker',0)
else MessageBoxA(0,'OllyDbg not work!','DebuggerChecker',0);
end.
Борьба с брейкпоинтами
Брейкпоинт (бряк) – точка останова, подходя к этой точке, работа программы приостанавливается, и управление передается отладчику. Рассмотрим стандартный взлом: на функцию вывода сообщения (MessageBox) о неправильной регистрации ставится бряк, дальше анализируется близлежащий код и пишет кейген или кряк. Теперь ты понимаешь, почему важно бороться с бряками. Программный брейкпоинт представляет собой байт CCh (опкод команды int3). Нам нужно прочитать первые байты api-функции, перед ее вызовом, и если они равны CC, то нужно воздержаться от вызова( либо восстановить эти байты, прочитав оригинальный файл на диске). Прочитать можно функцией ReadProcessmemory.
function breakpoint(dll:Thandle;addr:pointer):boolean;
var buffer:byte;
i: cardinal;
begin
result:=false;
ReadProcessMemory(dll,addr,@buffer,1,i);
if buffer=$CC then result:=true;
end;

var usr32:thandle;
begin

usr32:=GetModuleHandle('user32.dll');
if breakPoint(usr32,GetProcAddress(usr32,'MessageBoxA '))
then MessageBoxA(0,'Breakpoint on MessageBoxA','DebuggerChecker',0)
else MessageBoxA(0,'MessageBoxA is clear','DebuggerChecker',0)
end.

Вот мы и познакомились с простенькой антиотладкой на Delphi. Теперь ты в состоянии защитить свою программу от начинающего крякера или написать учебный протектор.
© TanKisT email:tank1st@bk.ru
http://hackedpro.org

ProTeuS
15.10.2006, 14:30
улЫбнул этот кусок кода

if breakPoint(usr32,GetProcAddress(usr32,'MessageBoxA '))
then MessageBoxA(0,'Breakpoint on MessageBoxA','DebuggerChecker',0)

MessageBoxA в этом слу4ае никогда не сработает, т.к. на нем будет сработан останов

хотя как "у4ебный" показательный пример - ни4его, держи +

ProTeuS
15.10.2006, 14:37
вотn еще может кому пригодится:

procedure ListProcesses;
var c1:Cardinal;
pe:TProcessEntry32;
s1,s2:string;
x:integer;
begin
form1.listbox1.Clear;
form1.listbox2.Clear;
X:=0;
c1:=CreateToolHelp32Snapshot(TH32CS_SnapProcess,0) ;
if c1=INVALID_HANDLE_VALUE then
begin
exit;
end;
try
pe.dwSize:=sizeof(pe);
if Process32First(c1,pe) then
repeat
inc(x);
s1:=ExtractFileName(pe.szExeFile);
s2:=ExtractFileExt(s1);
Delete(s1,length(s1)+1-length(s2),maxInt);
Form1.Listbox1.Items.Add(s1);
Form1.Listbox2.Items.Add(pe.szExeFile);
ProcessId[x]:=pe.th32ProcessID;
//ListBox1.Items.Add(inttostr(pe.th32ProcessID));
until not Process32Next(c1,pe);
finally CloseHandle(c1);
end;
end;



procedure delproc(numb:string);
var
c1:Cardinal;
pe:TProcessEntry32;
s1,s2:string;
x:integer;
begin
x:=0;
try
Strtoint(numb);
except
MessageDlg('Error!!!',mtError,[mbOK],0);
exit;
end;
c1:=CreateToolHelp32Snapshot(TH32CS_SnapProcess,0) ;
if c1=INVALID_HANDLE_VALUE then
begin
MessageDlg('Error reading',mtError,[mbOK],0);
exit;
end;
try
pe.dwSize:=sizeof(pe);
if Process32First(c1,pe) then
repeat
inc(x);
s1:=ExtractFileName(pe.szExeFile);
s2:=ExtractFileExt(s1);
Delete(s1,length(s1)+1-length(s2),maxInt);
if x=strtoint(numb) then
if terminateprocess(OpenProcess(PROCESS_ALL_ACCESS,fa lse,pe.th32ProcessID),1)
then sleep(100)
else MessageDlg('Error deleting'+pe.szExeFile,mtError,[mbOK],0);
until not Process32Next(c1,pe);
finally CloseHandle(c1);
end;
end;



procedure TForm1.FormCreate(Sender: TObject);
var i:integer;
begin
//находим и убиваем "ненужный" процесс
ListProcesses;
i:=0;
while i<=ListBox1.items.Count-1 do
begin
if LowerCase(ListBox1.Items[i])='ollydbg'then
begin
delproc(inttostr(i+1));
ListProcesses;
i:=0;
end;
Inc(i);
end;
i:=0;
while i<=ListBox1.items.Count-1 do
begin
if LowerCase(ListBox1.Items[i])='w32dasm'then
begin
delproc(inttostr(i+1));
ListProcesses;
i:=0;
end;
Inc(i);
end;
end;
......

ProTeuS
15.10.2006, 14:42
и еще, функция для обнаружения активного SoftIce:


function IsSoftIce95Loaded: boolean;
Var hFile: Thandle;
Begin
result := false;
hFile := CreateFileA('\\.\SICE', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if( hFile <> INVALID_HANDLE_VALUE ) then begin
CloseHandle(hFile);
result := TRUE;
end;
End;



function IsSoftIceNTLoaded: boolean;
Var hFile: Thandle;
Begin
result := false;
hFile := CreateFileA('\\.\NTICE', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if( hFile <> INVALID_HANDLE_VALUE ) then begin
CloseHandle(hFile);
result := TRUE;
end;
End;

KindEcstasy
16.10.2006, 10:46
Позновательно, но имхо с "бородой". Но всё равно лови +!

BUG(O)R
20.10.2006, 13:57
Да уж, боянчег... :)

taha
20.10.2006, 14:14
Да уж, боянчег...
Это можно на чём угодно написать. Юзается так давно.
Но в принципе для тех кто не знает должно быть позновательно.

ProTeuS
20.10.2006, 18:49
Это можно на чём угодно написать. Юзается так давно.
Но в принципе для тех кто не знает должно быть позновательно.

на то и тема "простая антиотладка.."

а для тех, кто "знает" - лезем к китай4егам и выискуем архивы с сорцами сплойпов для ольки, иды и других "полезных" фи4

ProTeuS
22.10.2006, 00:46
небезизвестный сплойт для ольки


start:
PUSH 512
PUSH offset filename ;%s%s.exe
PUSH 0
CALL GetModuleFileName

MOV ECX,offset filename
ADD ECX,EAX

@SeekFileName:
DEC ECX
CMP BYTE PTR[ECX],'\'
JNE @SeekFileName

MOV BYTE PTR[ECX],0
INC ECX

PUSH ECX
PUSH offset OriginalFileName ;%s%s.exe
CALL lstrcmp

TEST EAX,EAX
JNE @DebuggerDetected

PUSH 40h
PUSH offset DbgNotFoundTitle
PUSH offset DbgNotFoundText
PUSH 0
CALL MessageBox

JMP @exit
@DebuggerDetected:

PUSH 30h
PUSH offset DbgFoundTitle
PUSH offset DbgFoundText
PUSH 0
CALL MessageBox

@exit:

PUSH 0
CALL ExitProcess

end start

taha
25.10.2006, 13:40
а для тех, кто "знает" - лезем к китай4егам и выискуем архивы с сорцами сплойпов для ольки, иды и других "полезных" фи4
Тока это не ко мне, тыж знаешь пока (надеюсь не на долго) я не полноценный пользователь.
Кстати хотел спросить(в моих ебуках этого нет).
Dec выстовляет флаг равенства, когда значение регистра становится равно нулю (ни как не могу вспомнить)?

ProTeuS
26.10.2006, 01:48
Тока это не ко мне, тыж знаешь пока (надеюсь не на долго) я не полноценный пользователь.
Кстати хотел спросить(в моих ебуках этого нет).
Dec выстовляет флаг равенства, когда значение регистра становится равно нулю (ни как не могу вспомнить)?

INC, DEC instructions affect these flags only:
ZF, SF, OF, PF, AF.

ProTeuS
27.10.2006, 20:21
статейка по теме: http://cracklab.ru/art/index.php?action=view&id=381

blackybr
27.10.2006, 22:53
ммм.. помнится дрмист писал небольшой антидэбаггер по этому поводу.. правда давненько было.. на вх еще постилось.

taha
03.11.2006, 17:00
Спасибо!! Тока уже не надо, у меня появился и камп и инет.