Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 12 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Новогодний трейсер часть 2. Брейкпоинты.

Обсудить статью на форуме

Очень удобно, когда все крэкерские инструменты, книги и статьи в одном месте. Используйте сборник от EXELAB - вот тут.
Все, кажись протрезвел... Снова готов к бою. Ну я там и наворотил в первой части. Будем исправлять. :)

Трассировать мы уже можем. Терь нам бы брейкпоинтов понаставить...
Как ставятся брейкпоинты в обычных (не в айсе) дебагерах? Да очень просто! Вот к примеру решили мы поставить bpx на 401000h. Дебагер подрубается к процессу или запускает процесс для дебага. Потом читает байт по адресу 401000h, запоминает его и записывает на его место число CCh. А CCh - это в свою очередь опкод команды int 3h. Т.е. Debug Break. Как тока программа выполнит этот int 3h, будет сгенерено событие EXCEPTION_DEBUG_EVENT с кодом EXCEPTION_BREAKPOINT. В этот момент дебагер ставит байт по адресу 401000h на место и смещает eip на 1 назад (int 3 оно уже выполнило). Таким образом, скока брейк поинтов - стока и байт нужно будет запомнить. И так теперь можно сделать из нашего трейсера чо-нить типа SoftIce Symbol Loader. Т.е прога, которая открывает в дебагере нужный exe с адреса = Entry point ( тот что указан в PE заголовке).
Собственно код:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
sti:tstartupinfo;
lpPi:tprocessinformation;
DE:_Debug_event;
Cont:_Context;
implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
Const b:array[0..1] of byte=(0,$cc);
Var f:file of longint;
x:longint;
i:cardinal;
begin

assignfile(f,'C:\w\notepad.exe');
reset(f);
seek(f,$2a); //читаем OEP из PE
read(f,x);
closefile(f);
x:=x+$400000; //типа imagebase

//добавим еще Create_suspended чтобы процесс без нас никуда не убежал :)
CreateProcess(nil,'C:\w\notepad.exe',nil,nil,false,DEBUG_PROCESS
or DEBUG_ONLY_THIS_PROCESS or Create_suspended,nil,nil,StI,lpPI);

readprocessmemory(lppi.hProcess,pointer(x),@b[0],1,i); //запоминаем байт
writeprocessmemory(lppi.hProcess,pointer(x),@b[1],1,i); //пишем $cc
resumethread(lppi.hThread);

{цикл ожидания EP}
While true do
Begin
if not WaitForDebugEvent(de,0) then
application.ProcessMessages;
if de.dwDebugEventCode=EXCEPTION_DEBUG_EVENT then
if DE.Exception.ExceptionRecord.ExceptionCode=EXCEPTION_BREAKPOINT
then
begin
cont.ContextFlags:=CONTEXT_CONTROL;
GetThreadContext(lppi.hThread,cont);
{Эти брейкпоинты не тока мы генерим, но и маздай так что
приходится проверку делать: EIP=Entry Point или нет}

if cont.eip-1=x then // тошо EXCEPTION_BREAKPOINT генерится после int 3.
Begin
cont.eip:=cont.eip-1;
cont.EFlags:=cont.EFlags or $100; //флаг T
setThreadContext(lppi.hThread,cont);
//ставим байт на место
writeprocessmemory(lppi.hProcess,pointer(x),@b[0],1,i);
break;
end;
ContinueDebugEvent(lppi.dwProcessId, lppi.dwThreadid,DBG_CONTINUE);
end;
ContinueDebugEvent(lppi.dwProcessId, lppi.dwThreadid,DBG_CONTINUE);
end;

{tracing... 0% complete}
While true do
Begin

if not WaitForDebugEvent(de,0) then
application.ProcessMessages;


if de.dwDebugEventCode=EXCEPTION_DEBUG_EVENT then
if DE.Exception.ExceptionRecord.ExceptionCode=EXCEPTION_BREAKPOINT
then
Begin
GetThreadContext(lppi.hThread,cont);
cont.EFlags:=cont.EFlags or $100;
setThreadContext(lppi.hThread,cont);
{Здесь мог бы быть ваш код :))) }
ContinueDebugEvent(lppi.dwProcessId, lppi.dwThreadid,DBG_CONTINUE);
end
Else
if DE.Exception.ExceptionRecord.ExceptionCode=EXCEPTION_SINGLE_STEP
then
Begin
cont.ContextFlags:=CONTEXT_CONTROL;
GetThreadContext(lppi.hThread,cont);
cont.EFlags:=cont.EFlags or $100;
setThreadContext(lppi.hThread,cont);
{Здесь мог бы быть ваш код :))) }
ContinueDebugEvent(lppi.dwProcessId, lppi.dwThreadid,DBG_CONTINUE);
end;

end;

end;

end.

P.S. Я тут Reset и Read юзал для работы с файлом. Но лучше все сделать через апи (createfile, readfile и т.д.), потому что если будет запущена прога которую мы вот ща типа трейсить будем, то делфи будет орать про I/O error. Естественно, тошо делфа не умеет открывать файл для Shared доступа :(

Автор: Hex
E-mail: hex@xtin.org



Обсуждение статьи: Новогодний трейсер часть 2. Брейкпоинты. >>>


Материалы находятся на сайте https://exelab.ru



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS