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

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


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

Новогодний трейсер :)

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

Массу крэкерских инструментов, видеоуроков и статей вы сможете найти на видеокурсе от нашего сайта. Подробнее здесь.
Очнулся я тут от новогодней пьянки и решил написать чо-нить полезное. Вот к примеру там свой дебагер или еще чо-нить... Ну про дебагер это я загнул. Ну хотя б трейсер.

Чо такое трейсер - прога, которая пошагово выполняет код. Какие перспективы не правда ли? Делаем на основе трейсера загрузчик и прям сказка - можно запросто ломать проги, которые проверяют целостность своих данных - например дойдем до места где jnz не надо выполнять и просто переместим EIP на следующую команду (типа не выполнилось), и все красиво. Целостность не нарушена :)

Итак, как же его писать...
Для того чтобы сделать трейсер нам нужны будут Debug API. Вот я тут трейсер написал чтобы находить OEP. Значит ща код трейсера для поиска Entry Point в Notepad, а потом пояснения.
КОД:

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);

begin
CreateProcess(nil,'c:\w\notepad.exe',nil,nil,false,DEBUG_PROCESS
or DEBUG_ONLY_THIS_PROCESS,nil,nil,StI,lpPI);

While true do
Begin
WaitForDebugEvent(de,INFINITE);
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);
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
GetThreadContext(lppi.hThread,cont);
cont.EFlags:=cont.EFlags or $100;
setThreadContext(lppi.hThread,cont);
if (cont.eip>$400000) and (cont.eip<$600000) then
Begin
Showmessage('OEP='+inttohex(cont.eip,8));
halt;
end;
ContinueDebugEvent(lppi.dwProcessId, lppi.dwThreadid,DBG_CONTINUE);
end;

ContinueDebugEvent(lppi.dwProcessId, lppi.dwThreadid,DBG_CONTINUE);
end;

end;

end.

Оно работает так:
Создается процесс с параметрами DEBUG_PROCESS и DEBUG_ONLY_THIS_PROCESS. DEBUG_ONLY_THIS_PROCESS - нужно для того чтобы перехватывать сообщения только от процесса, который создадим, а не все подряд. После этого создастся процесс который будет отсылать дебаговые сообщения.
Делаем бесконечный цикл с WaitForDebugEvent, чтобы отлавливать дебаговые сообщения которые будет отсылать процесс. В этом цикле нам нужно будет обработать событие EXCEPTION_DEBUG_EVENT. Для этого события нам нужно будет обрабатывать 2 Exception кода: EXCEPTION_BREAKPOINT и EXCEPTION_SINGLE_STEP. Код остановки и код одиночного шага(выполнение одной команды).
Когда процесс создан для дебага нам нужно будет включить флаг трассировки чтобы программа генерила EXCEPTION_BREAKPOINT и EXCEPTION_SINGLE_STEP после каждой выполненой команды.
Получить данные о состоянии регистров выполняемого процесса можно через GetThreadContext, а установить их через SetThreadContext. GetThreadContext возвращает структуру _CONTEXT которая содержит данные о всех регистрах(в ключая EIP) и флагах выполняемого процесса. Но перед тем как читать данные о регистрах в эту структуру, нужно задать свойство ContextFlags=CONTEXT_CONTROL. Иначе будут возвращатся тока ноли.
При обработке кодов EXCEPTION_BREAKPOINT и EXCEPTION_SINGLE_STEP нужно постоянно включать флаг трассировки через свойство EFlags структуры _CONTEXT (cont.EFlags:=cont.EFlags or $100;)
После обработки каждого сообщения нужно разрешить программе выполняться дальше. Делается это через ContinueDebugEvent.
Ну и наконец в обработке EXCEPTION_SINGLE_STEP я читаю текущий eip процесса, чтобы найти EP. Так как в реале, процесс начинает выполнятся не с Entry point а с загрузки всяких DLL и т.д.

Можно конечно было взять его из PE заголовка. Но это жеж не прикольно :)



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



Обсуждение статьи: Новогодний трейсер :) >>>


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



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


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