| 
 
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.
 |