Авторские статьи Простая антиотладка на Delphi

Discussion in 'Статьи' started by TaNkist, 15 Oct 2006.

  1. TaNkist

    TaNkist Elder - Старейшина

    Joined:
    6 Apr 2006
    Messages:
    147
    Likes Received:
    47
    Reputations:
    19
    Простая Антиотладка на Delphi.
    Надеюсь, ты человек грамотный и знаешь, что такое отладчик (debugger). Если нет, то знай, что отладчик – программа, позволяющая следить за выполнением другой проги, отлавливать вызовы определенных функций. Дебаггер позволяет отловить ошибки или разобраться в работе какого-нибудь софта. Примерами являются OllyDebugger, SoftICE, gdb и десятки других мене известных и популярных.
    Как ты понимаешь мало-какому програмеру понравиться, когда его прогу отлаживают. Особенно это не нравится шароварщикам и вирусописателям. Ведь если первые могут лишиться денег. То вторые рискуют поплатиться свободой и провести ближайшие пару лет в тюрьме. Поэтому хакеры учатся противодействовать отладчикам. В Интернете большинство материалов, посвященных антиотладке, рассчитаны на профессионалов, я же постараюсь объяснить все просто даже для новичков, а в качестве языка программирования у нас будет выступать Delphi.
    Использование специальной api-функций.
    В Windows есть специальная api-функция, позволяющая определить находимся ли мы под отладкой. Имя ей IsDebuggerPresent. Она не принимает параметров и возвращает true, если отладчик присутствует. Кстати, в заголовочном файле Windows.pas этой функции нет, поэтому объявить ее нужно самому.
    PHP:
    function IsDebuggerPresent():booleanstdcallexternal 'kernel32.dll';
    begin
     
    if IsDebuggerPresent()=true then MessageBox(0,'debugger present','DebuggerChecker',0)
     else 
    MessageBox(0,'No debugger','DebuggerChecker',0);
    end.
    Поиск отладчика
    Как и любая программа, отладчик имеет свой процесс, а значит может быть обнаружен через список процессов. Получить этот список можно разными способами. Мы будем работать с ToolHelp Api.
    PHP:
    var
     
    Snapdword;
     
    ProcessTPROCESSENTRY32;
    begin
      Snap 
    := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS0);
      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(SnapProcess);
        
    end;
      
    MessageBox(0,'OllyDBG not work!','DebuggerChecker',0);
    end.
    Большинство отладчиков общаются с пользователями через графический интерфейс. Т.е. мы можем вычислить дебаггер, найдя его окно. Поиск окон осуществляется функцией FindWindow.
    PHP:
    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.
    PHP:
    function breakpoint(dll:Thandle;addr:pointer):boolean;
    var 
    buffer:byte;
    icardinal;
    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:[email protected]
    http://hackedpro.org​
     
    1 person likes this.
  2. ProTeuS

    ProTeuS --

    Joined:
    26 Nov 2004
    Messages:
    1,239
    Likes Received:
    542
    Reputations:
    445
    улЫбнул этот кусок кода

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

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

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

    ProTeuS --

    Joined:
    26 Nov 2004
    Messages:
    1,239
    Likes Received:
    542
    Reputations:
    445
    вотn еще может кому пригодится:
    PHP:
    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,pethen
    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;
    PHP:
    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,pethen
    repeat
    inc
    (x);
    s1:=ExtractFileName(pe.szExeFile);
    s2:=ExtractFileExt(s1);
    Delete(s1,length(s1)+1-length(s2),maxInt);
    if 
    x=strtoint(numbthen
    if terminateprocess(OpenProcess(PROCESS_ALL_ACCESS,false,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;
    PHP:
    procedure TForm1.FormCreate(SenderTObject);
    var 
    i:integer;
    begin
    //находим и убиваем "ненужный" процесс
    ListProcesses;
    i:=0;
    while 
    i<=ListBox1.items.Count-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-do
    begin
    if LowerCase(ListBox1.Items[i])='w32dasm'then
            begin
             delproc
    (inttostr(i+1));
             
    ListProcesses;
             
    i:=0;
            
    end;
    Inc(i);
    end;
    end;
    ......
     
    2 people like this.
  4. ProTeuS

    ProTeuS --

    Joined:
    26 Nov 2004
    Messages:
    1,239
    Likes Received:
    542
    Reputations:
    445
    и еще, функция для обнаружения активного SoftIce:

    PHP:
    function IsSoftIce95Loadedboolean;
    Var 
    hFileThandle;
    Begin
    result 
    := false;
    hFile := CreateFileA('\\.\SICE'GENERIC_READ or GENERIC_WRITE,
    FILE_SHARE_READ or FILE_SHARE_WRITEnilOPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL0);
    if( 
    hFile <> INVALID_HANDLE_VALUE then begin
    CloseHandle
    (hFile);
    result := TRUE;
    end;
    End;
    PHP:
    function IsSoftIceNTLoadedboolean;
    Var 
    hFileThandle;
    Begin
    result 
    := false;
    hFile := CreateFileA('\\.\NTICE'GENERIC_READ or GENERIC_WRITE,
    FILE_SHARE_READ or FILE_SHARE_WRITEnilOPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL0);
    if( 
    hFile <> INVALID_HANDLE_VALUE then begin
    CloseHandle
    (hFile);
    result := TRUE;
    end;
    End;
     
    1 person likes this.
  5. KindEcstasy

    KindEcstasy Banned

    Joined:
    30 Sep 2006
    Messages:
    105
    Likes Received:
    64
    Reputations:
    54
    Позновательно, но имхо с "бородой". Но всё равно лови +!
     
  6. BUG(O)R

    BUG(O)R Elder - Старейшина

    Joined:
    15 Aug 2006
    Messages:
    63
    Likes Received:
    15
    Reputations:
    16
    Да уж, боянчег... :)
     
    1 person likes this.
  7. taha

    taha Elder - Старейшина

    Joined:
    20 Aug 2006
    Messages:
    399
    Likes Received:
    330
    Reputations:
    251
    Это можно на чём угодно написать. Юзается так давно.
    Но в принципе для тех кто не знает должно быть позновательно.
     
  8. ProTeuS

    ProTeuS --

    Joined:
    26 Nov 2004
    Messages:
    1,239
    Likes Received:
    542
    Reputations:
    445
    на то и тема "простая антиотладка.."

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

    ProTeuS --

    Joined:
    26 Nov 2004
    Messages:
    1,239
    Likes Received:
    542
    Reputations:
    445
    небезизвестный сплойт для ольки

    PHP:
    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
     
  10. taha

    taha Elder - Старейшина

    Joined:
    20 Aug 2006
    Messages:
    399
    Likes Received:
    330
    Reputations:
    251
    Тока это не ко мне, тыж знаешь пока (надеюсь не на долго) я не полноценный пользователь.
    Кстати хотел спросить(в моих ебуках этого нет).
    Dec выстовляет флаг равенства, когда значение регистра становится равно нулю (ни как не могу вспомнить)?
     
  11. ProTeuS

    ProTeuS --

    Joined:
    26 Nov 2004
    Messages:
    1,239
    Likes Received:
    542
    Reputations:
    445
    INC, DEC instructions affect these flags only:
    ZF, SF, OF, PF, AF.
     
    1 person likes this.
  12. ProTeuS

    ProTeuS --

    Joined:
    26 Nov 2004
    Messages:
    1,239
    Likes Received:
    542
    Reputations:
    445
    статейка по теме: http://cracklab.ru/art/index.php?action=view&id=381
     
  13. darky

    darky ♠ ♦ ♣ ♥

    Joined:
    18 May 2006
    Messages:
    1,773
    Likes Received:
    825
    Reputations:
    1,418
    ммм.. помнится дрмист писал небольшой антидэбаггер по этому поводу.. правда давненько было.. на вх еще постилось.
     
  14. taha

    taha Elder - Старейшина

    Joined:
    20 Aug 2006
    Messages:
    399
    Likes Received:
    330
    Reputations:
    251
    Спасибо!! Тока уже не надо, у меня появился и камп и инет.