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

ВИДЕОКУРС ВЗЛОМ
выпущен 1 марта!


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

БОЛЬШОЙ FAQ ПО DELPHI



Перехват вызовов функций из динамических библиотек

Автор: Den is Com

В России запущенно производство принципиально новых программно-аппаратных средств для взлома систем под названием: "Plug & Fuck". Устройства и софт работают отлично.

// проверено и работает для WIN 9x и WinNT
// в юните на первый взгляд, есть структуры , описание которых уже есть в Дельфи , но к сожалению не
// всех и не во всех версиях Дельфи эти структуры присутствуют. Да уж, это не С

Проблема скорее для хакера, а не для программиста. Но существуют ситуации, когда это необходимо. Сложно предположить ситуацию, в которой это может понадобится, но например: можете перехватывать надоевшее окошко о необходимости купить компонент :) . Разумеется этот код предназначен для более широких целей и в более широком варианте позволяет контролировать работу внешней программы, производя "мягкий" взлом - изменения присходят только в памяти и не касаются исполняемого файла на диске. Разумеется можно использовать и для более светлых целей. При использовании данного исходника будьте осторожны: при компилировании пректа с динамическими пакетами перехватываемая функция может находится в пакете, а не в файле программы. Перед перехватом функции необходимо заменить её функцией-ловушкой. Например для MessageBox


 type
 
 TMyProc= function (hWnd: HWND; lpText, lpCaption:
   PAnsiChar; uType: UINT): Integer; stdcall;
 PTMyProc=^TMyProc;
 
 function MyMessageBox(hWnd: HWND; lpText, lpCaption:
   PAnsiChar; uType: UINT): Integer; stdcall;
 begin
   ShowMessage('Message intercepted');
   result:=IDOK;
 end;
 

и сам перехват происходит так


 InterceptDllCall(hInstance,'user32.dll','MessageBoxA',
 Pointer(@MyMessageBox),PPointer(@myProc),nil);
 

теперь все вызовы MessageBox будут ссылаться на нашу функцию :) Надеюсь вы помните, что функции MessageBox в user32.dll нет - это только оболочка для MessageBoxА

и обратная операция - восстановление работоспособности старой функции


 InterceptDllCall(hInstance,'user32.dll','MessageBoxA',
 Pointer(myProc),nil,Pointer(@MyMessageBox));
 

Привожу полностью все файлы проекта:


 // Intercep.pas
 
 unit intercep;
 
 interface
 uses windows, dialogs, SysUtils;
 type
 
   PImageDosHeader = ^TImageDosHeader;
   {EXTERNALSYM _IMAGE_DOS_HEADER}
   _IMAGE_DOS_HEADER = packed record { DOS .EXE header                  }
     e_magic: Word; { Magic number                     }
     e_cblp: Word; { Bytes on last page of file       }
     e_cp: Word; { Pages in file                    }
     e_crlc: Word; { Relocations                      }
     e_cparhdr: Word; { Size of header in paragraphs     }
     e_minalloc: Word; { Minimum extra paragraphs needed  }
     e_maxalloc: Word; { Maximum extra paragraphs needed  }
     e_ss: Word; { Initial (relative) SS value      }
     e_sp: Word; { Initial SP value                 }
     e_csum: Word; { Checksum                         }
     e_ip: Word; { Initial IP value                 }
     e_cs: Word; { Initial (relative) CS value      }
     e_lfarlc: Word; { File address of relocation table }
     e_ovno: Word; { Overlay number                   }
     e_res: array[0..3] of Word; { Reserved words                   }
     e_oemid: Word; { OEM identifier (for e_oeminfo)   }
     e_oeminfo: Word; { OEM information; e_oemid specific}
     e_res2: array[0..9] of Word; { Reserved words                   }
     e_lfanew: LongInt; { File address of new exe header   }
   end;
   TImageDosHeader = _IMAGE_DOS_HEADER;
   //  {$EXTERNALSYM IMAGE_DOS_HEADER}
 
   IMAGE_DOS_HEADER = _IMAGE_DOS_HEADER;
 
   //***************************************
   PImageDataDirectory = ^TImageDataDirectory;
   _IMAGE_DATA_DIRECTORY = record
     VirtualAddress: DWORD;
     Size: DWORD;
   end;
   //  {$EXTERNALSYM _IMAGE_DATA_DIRECTORY}
   TImageDataDirectory = _IMAGE_DATA_DIRECTORY;
   IMAGE_DATA_DIRECTORY = _IMAGE_DATA_DIRECTORY;
   //  {$EXTERNALSYM IMAGE_DATA_DIRECTORY}
 
   //*************
   PImageOptionalHeader = ^TImageOptionalHeader;
   _IMAGE_OPTIONAL_HEADER = packed record
     { Standard fields. }
     Magic: Word;
     MajorLinkerVersion: Byte;
     MinorLinkerVersion: Byte;
     SizeOfCode: DWORD;
     SizeOfInitializedData: DWORD;
     SizeOfUninitializedData: DWORD;
     AddressOfEntryPoint: DWORD;
     BaseOfCode: DWORD;
     BaseOfData: DWORD;
     { NT additional fields. }
     ImageBase: DWORD;
     SectionAlignment: DWORD;
     FileAlignment: DWORD;
     MajorOperatingSystemVersion: Word;
     MinorOperatingSystemVersion: Word;
     MajorImageVersion: Word;
     MinorImageVersion: Word;
     MajorSubsystemVersion: Word;
     MinorSubsystemVersion: Word;
     Win32VersionValue: DWORD;
     SizeOfImage: DWORD;
     SizeOfHeaders: DWORD;
     CheckSum: DWORD;
     Subsystem: Word;
     DllCharacteristics: Word;
     SizeOfStackReserve: DWORD;
     SizeOfStackCommit: DWORD;
     SizeOfHeapReserve: DWORD;
     SizeOfHeapCommit: DWORD;
     LoaderFlags: DWORD;
     NumberOfRvaAndSizes: DWORD;
     DataDirectory: packed array[0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1] of
       TImageDataDirectory;
   end;
   // {$EXTERNALSYM _IMAGE_OPTIONAL_HEADER}
   TImageOptionalHeader = _IMAGE_OPTIONAL_HEADER;
   IMAGE_OPTIONAL_HEADER = _IMAGE_OPTIONAL_HEADER;
   // {$EXTERNALSYM IMAGE_OPTIONAL_HEADER}
 
   PImageNtHeaders = ^TImageNtHeaders;
   _IMAGE_NT_HEADERS = packed record
     Signature: DWORD;
     FileHeader: TImageFileHeader;
     OptionalHeader: TImageOptionalHeader;
   end;
   // {$EXTERNALSYM _IMAGE_NT_HEADERS}
   TImageNtHeaders = _IMAGE_NT_HEADERS;
   IMAGE_NT_HEADERS = _IMAGE_NT_HEADERS;
   // {$EXTERNALSYM IMAGE_NT_HEADERS}
 
   PImage_import_by_name = ^TImage_import_by_mame;
   _IMAGE_IMPORT_BY_NAME = packed record
 
     Hint: Word;
     Name: Byte;
   end;
   TImage_import_by_mame = _IMAGE_IMPORT_BY_NAME;
 
   _u1 = packed record
     case Integer of
 
       0: (ForwarderString: PByte);
       1: (Functionn: PDWORD);
       2: (Ordinal: DWORD);
       3: (AddressOfData: PImage_import_by_name);
   end;
   PImageThunkData = ^TImageThunkData;
   _IMAGE_THUNK_DATA = packed record
 
     u1: _u1;
   end;
   TImageThunkData = _IMAGE_THUNK_DATA;
   IMAGE_THUNK_DATA = _IMAGE_THUNK_DATA;
 
   _temp_charcteristics = record
     case Integer of
       0: (Characteristics: DWORD); // 0 for terminating null import descriptor
       1: (OriginalFirstThunk: PImageThunkData); // RVA to original unbound IAT
   end;
 
   PImageImportDescriptor = ^TImageImportDescriptor;
   _IMAGE_IMPORT_DESCRIPTOR = packed record
 
     t: _temp_charcteristics;
     TimeDateStamp: DWord; // 0 if not bound,
     // -1 if bound, and real date\time stamp
     //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
     // O.W. date/time stamp of DLL bound to (Old BIND)
 
     ForwarderChain: DWORD; // -1 if no forwarders
     Name: DWORD;
     FirstThunk: PImageThunkData;
       // RVA to IAT (if bound this IAT has actual addresses)
   end;
   TImageImportDescriptor = _IMAGE_IMPORT_DESCRIPTOR;
   IMAGE_IMPORT_DESCRIPTOR = _IMAGE_IMPORT_DESCRIPTOR;
   PPointer = ^Pointer;
 function InterceptDllCall(
 
   hLocalModule: HModule;
   c_szDllName: Pchar;
   c_szApiName: PChar;
   pApiNew: Pointer;
   p_pApiOrg: PPointer;
   pApiToChange: Pointer): Boolean;
 implementation
 
 function MakePtr(base: Dword; Offset: DWORD): Pointer;
 begin
   Result := Pointer(Base + Offset);
 end;
 
 function InterceptDllCall(
 
   hLocalModule: HModule;
   c_szDllName: Pchar;
   c_szApiName: PChar;
   pApiNew: Pointer;
   p_pApiOrg: PPointer;
   pApiToChange: Pointer): Boolean;
 
 var
   pDosHeader: PImageDosHeader;
 
   pNtHeader: PImageNtHeaders;
   PImportDesc: PImageImportDescriptor;
   dwProtect: DWORD;
   dwNewProtect: DWORD;
   dwAddressToInterCept: DWORD;
   pThunk: PImageThunkData;
 begin
   pDosHeader := PImageDosHeader(hLocalModule);
   Result := False;
   if (pApiToChange <> nil) then
     dwAddressToIntercept := DWORD(pApiToChange)
   else
     dwAddressToIntercept := Dword(GetProcAddress(GetModuleHandle(c_szDllName),
       c_szApiName));
 
   if IsBadReadPtr(Pointer(hLocalModule), sizeof(PImageNtHeaders)) then
     Exit;
 
   if pDosHeader.e_magic <> IMAGE_DOS_SIGNATURE then
     exit;
   pNtHeader := PImageNtHeaders(MakePtr(DWord(pDOSHeader),
     DWord(pDOSHeader.e_lfanew)));
   if pNTHeader.signature <> IMAGE_NT_SIGNATURE then
     exit;
   pImportDesc := PImageImportDescriptor(
 
     MakePtr(hLocalModule,
     pNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
 
   if (PImportDesc = PImageImportDescriptor(pNtHeader)) then
     exit;
 
   while (pImportDesc.Name > 0) do
   begin
 
     pThunk := PImageThunkData(MakePtr(DWord(hLocalModule),
       Dword(pImportDesc.FirstThunk)));
     while (pThunk.u1.Functionn <> nil) do
     begin
       if DWord(pThunk.u1.Functionn) = dwAddressToIntercept then
       begin
         if not IsBadWritePtr(Pointer(@pThunk.u1.Functionn), sizeof(DWORD)) then
         begin
           if (p_pApiOrg <> nil) then
             p_pApiOrg^ := Pointer(pThunk.u1.Functionn);
           pThunk.u1.Functionn := pApiNew;
           Result := True;
         end
         else
         begin
           if VirtualProtect(Pointer(@pThunk.u1.Functionn), sizeof(DWORD),
             PAGE_EXECUTE_READWRITE, @dwProtect) then
           begin
             if (p_pApiOrg <> nil) then
               p_pApiOrg^ := Pointer(pThunk.u1.Functionn);
             pThunk.u1.Functionn := PDWORD(pApiNew);
             Result := True;
             dwNewProtect := dwProtect;
             VirtualProtect(Pointer(@pThunk.u1.Functionn), sizeof(DWORD),
               dwNewProtect, @dwProtect);
           end;
         end;
       end;
       Inc(PThunk);
     end;
     Inc(pImportDEsc);
   end;
 end;
 
 end.
 
 // Project1.dpr
 
 program Project1;
 
 uses
   Forms,
   Unit1 in '..\..\Work\Temp\4\Unit1.pas' {Form1};
 
 {$R *.RES}
 
 begin
 
   Application.Initialize;
   Application.CreateForm(TForm1, Form1);
   Application.Run;
 end.
 
 // Unit1.dfm
 
 object Form1: TForm1
 
   Left = 192
     Top = 107
     Width = 435
     Height = 300
     Caption = 'Form1'
     Color = clBtnFace
     Font.Charset = DEFAULT_CHARSET
     Font.Color = clWindowText
     Font.Height = -11
     Font.Name = 'MS Sans Serif'
     Font.Style = []
     OldCreateOrder = False
     PixelsPerInch = 96
     TextHeight = 13
     object Button1: TButton
     Left = 72
       Top = 176
       Width = 273
       Height = 65
       Caption = 'Begin'
       Font.Charset = DEFAULT_CHARSET
       Font.Color = clWindowText
       Font.Height = -24
       Font.Name = 'MS Sans Serif'
       Font.Style = []
       ParentFont = False
       TabOrder = 0
       OnClick = Button1Click
   end
   object Button2: TButton
     Left = 304
       Top = 16
       Width = 105
       Height = 49
       Caption = 'MessageBox'
       TabOrder = 1
       OnClick = Button2Click
   end
 end
 
 // Unit1.pas
 
 unit Unit1;
 
 interface
 
 uses
 
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
   StdCtrls, intercep;
 
 type
 
   TMyProc = function(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT):
     Integer; stdcall;
   PTMyProc = ^TMyProc;
 
   TForm1 = class(TForm)
     Button1: TButton;
     Button2: TButton;
     procedure Button1Click(Sender: TObject);
     procedure Button2Click(Sender: TObject);
   private
     { Private declarations }
   public
     { Public declarations }
   end;
 
 var
 
   Form1: TForm1;
   myProc: PTMyProc;
 implementation
 
 function MyMessageBox(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT):
   Integer; stdcall;
 begin
   ShowMessage('Message intercepted');
 
   result := IDOK;
 end;
 {$R *.DFM}
 
 procedure TForm1.Button1Click(Sender: TObject);
 
 begin
   myProc := nil;
   MessageBox(0, 'Hello', 'Message 1', MB_OK);
   InterceptDllCall(hInstance, 'user32.dll', 'MessageBoxA',
     Pointer(@MyMessageBox), PPointer(@myProc), nil); //then ShowMessage('Ok');
   MessageBox(0, 'Hello', 'Message 2', MB_OK);
   InterceptDllCall(hInstance, 'user32.dll', 'MessageBoxA',
     Pointer(myProc), nil, Pointer(@MyMessageBox));
   MessageBox(0, 'Hello', 'Message 3 ', MB_OK);
 end;
 
 procedure TForm1.Button2Click(Sender: TObject);
 begin
   MessageBox(0, 'Hello', 'Message 4 ', MB_OK);
 end;
 
 end.
 




<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ



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



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


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