Форум: "Основная";
Текущий архив: 2006.02.26;
Скачать: [xml.tar.bz2];
Вниззамена библиотек Найти похожие ветки
← →
jjj (2006-01-22 20:33) [0]Начну издалека. Есть стороннее приложение. У него есть библиотека, творящая всякую всячину. Я знаю что там есть штук десять нужных мне функций. И знаю их параметры. Я хочу знать, когда они вызываются и с какими параметрами. У меня появилась идея написать свою длл, которая экспортирует нужные мне функции, при обращении к ним она будет писать лог, и вызывать собственный оригинал из переименованной библиотеки-оригинала. Вот. Но всего функций в библиотеке около полутысячи. И не для всех я знаю описания параметров. Как можно перенаправить вызов неизвестной мне процедуры на другую библиотеку.
Короче, как можно сделать так, чтобы если из библиотеки вызывали некую функцию, она вызывала такую же функцию из другоей библиотеки с теми же параметрами, не получая/изменяя/извлекая их.
Спасибо уже за то, что дочитали до сюда :)
← →
Eraser © (2006-01-22 20:38) [1]
> jjj (22.01.06 20:33)
Нужно просто перехватывать функции целевой библиотеки.
Есть несколько методов, некоторые описаны у Рихтера.
http://www.podgoretsky.com/ftp/Docs/Classics/Richter/richter4ru.zip
← →
Grief © (2006-01-22 20:59) [2]хорошая книжка, я ее читал ужо...
Вы вероятно имеете ввиду статью “Система перехвата функций API платформы Win32”... Кажется мне, что мороки с этим будет много, особенно если перехватывать не один десяток процедур. Впрочем попробовать мона.
← →
Eraser © (2006-01-22 21:27) [3]
> Grief © (22.01.06 20:59) [2]
тут без мороки никак...
могу посоветовать готовое решение для начала
http://www.madshi.net/
← →
GuAV © (2006-01-22 21:39) [4]Перенаправление без изменения параметров, не зная параметров - дело не такое уж сложное, просто в теле своей jmp на исходную; а если нужно зафиксировать факт вызова, то запонмить регистры в стек, вызвать процедуру фиксирования, восстановить регистры из стека, jmp на исходную. Сложнее сделать сам перехват. Но если просто переименовать исходную, а свою назвать как исходную, это упрощается.
← →
VirEx © (2006-01-23 17:18) [5]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.
← →
VirEx © (2006-01-23 17:21) [6]как использовать:
сам перехват происходит так
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));
пример:
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.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2006.02.26;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.047 c