Форум: "WinAPI";
Текущий архив: 2005.01.16;
Скачать: [xml.tar.bz2];
ВнизИзменение таблици импорта Найти похожие ветки
← →
Doc-N (2004-11-14 17:58) [0]Данная функция ищет секцию импорта модуля CallModule и меняет OrigProc на HookProc в таблице импорта. То есть теперь при вызове из модуля OrigProc импортированной функции, которую мы поменяли вызовется наша.
uses Windows, TlHelp32{$IFDEF XPALG}, ImageHlp{$ENDIF};
.....
procedure ReplaceIATEntryInOneMod(CallModulName:String; OrigProc:FARPROC; HookProc:FARPROC; CallModule:HMODULE);
var
dwSize:ULONG;
{$IFDEF XPALG}
{$ELSE}
pDosHeader:PImageDosHeader;
pNtHeader:PImageNtHeaders;
{$ENDIF}
PImportDesc:PImageImportDescriptor;
dwProtect:DWORD;
dwNewProtect:DWORD;
pThunk:PImageThunkData;
function MakePtr(base:Dword;Offset:DWORD):Pointer;
begin
Result:=Pointer(Base+Offset);
end;
begin
{$IFDEF XPALG}
PImportDesc:=ImageDirectoryEntryToData(pointer(CallModule), True, IMAGE_DIRECTORY_ENTRY_IMPORT, dwSize);
if PImportDesc=nil then Exit;
{$ELSE}
if IsBadReadPtr(Pointer(CallModule),sizeof(PImageNtHeaders)) then Exit;
pDosHeader:=PImageDosHeader(CallModule);
if pDosHeader.e_magic<>IMAGE_DOS_SIGNATURE then exit;
pNtHeader:=PImageNtHeaders(MakePtr(DWord(pDOSHeader),DWord(pDOSHeader._lfanew)));
if pNTHeader.signature<>IMAGE_NT_SIGNATURE then exit;
pImportDesc:=PImageImportDescriptor(MakePtr(CallModule, pNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
if (PImportDesc=PImageImportDescriptor(pNtHeader)) then exit;
{$ENDIF}
while PImportDesc^.Name>0 do
begin
if lstrcmpi(PChar(CallModulName),MakePtr(dword(CallModule),dword(PImportDesc^.Name)))=0 then
break
else
Inc(PImportDesc);
end;
if PImportDesc^.Name=0 then
Exit;
pThunk:=PImageThunkData(MakePtr(DWord(CallModulName), Dword(pImportDesc^.FirstThunk)));
repeat
if pThunk^.u1.Functionn=OrigProc then // Ошибка!!! Что не так?
begin
if not IsBadWritePtr(Pointer(@pThunk^.u1.Functionn),sizeof(DWORD)) then
begin
WriteProcessMemory(GetCurrentProcess(), pThunk.u1.Functionn, @HookProc, sizeof(HookProc), dwSize);
end
else
begin
if VirtualProtect(Pointer(@pThunk.u1.Functionn),sizeof(DWORD),PAGE_EXECUTE_READWRITE,@dwProtect) then
begin
WriteProcessMemory(GetCurrentProcess(), pThunk.u1.Functionn, @HookProc, sizeof(HookProc), dwSize);
dwNewProtect:=dwProtect;
VirtualProtect(Pointer(@pThunk.u1.Functionn),sizeof(DWORD),dwNewProtect,@dwProtect);
end;
end;
end;
Inc(pThunk);
until pThunk^.u1.Ordinal<>0
end;
Описания функций взяты с http://delphiworld.narod.ru/base/catch_dll_functions_calling.html
Указатель на таблицу импортов совпадает в обоих случаях (ALGXP).
Указатель на PThunk получаю вроде бы верный.
Подскажите где ошибка.
P.S.
(Рихтера уже прочитал, но ошибку все равно не нахожу)
← →
Doc-N (2004-11-14 18:00) [1]В заглавии ошибочка - "таблицы".
Приношу свои извинения.
← →
Doc-N (2004-11-16 18:24) [2]pThunk^<> nil
но watch показывает вместо структурі U1 nil
никто не подскажет почему?
← →
Ученик (2004-11-17 00:04) [3]Ошибок несколько
pThunk:=PImageThunkData(MakePtr(DWord(CallModule), Dword(pImportDesc^.FirstThunk)));
WriteProcessMemory(GetCurrentProcess(), @pThunk.u1.Functionn, @HookProc, sizeof(HookProc), dwSize);
until pThunk^.u1.Ordinal=0
и цикл repeat unitl доджен быть внутри
while PImportDesc^.Name>0 do
begin
end
И неплохо бы увидеть сам вызов ReplaceIATEntryInOneMod
← →
Doc-N (2004-11-26 17:10) [4]Увидеть вызов ReplaceIATEntryInOneMod...
Нет проблем:
procedure ReplaceIATEntryInAllMods(CallModulName:String; OrigProc:FARPROC; HookProc:FARPROC; ExcludeAPIHookMod:Boolean);
var
ThisModule:HMODULE;
h:THandle;
Me:MODULEENTRY32;
begin
if ExcludeAPIHookMod then
ThisModule:=HInstance//ModulFromAdress(@ReplaceIATEntryInAllMods)
else
ThisModule:=0;
h:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
if h=1 then RaiseLastOSError;
Me.dwSize:=sizeof(MODULEENTRY32);
Module32First(h,Me);
if Me.hModule <> ThisModule then //себя не трогать
ReplaceIATEntryInOneMod(CallModulName, OrigProc, HookProc, Me.hModule);
while Module32Next(h,Me) do
if Me.hModule <> ThisModule then //себя не трогать
ReplaceIATEntryInOneMod(CallModulName, OrigProc, HookProc, Me.hModule);
end;
А вот код вообще всего модуля, может кому нибудь пригодится, как руководство что делать не надо:
unit APIHook2;
interface
uses Windows, Classes;
{$DEFINE XPALG}
{$Z4}
type
PAPIHook = ^TAPIHook;
TAPIHook = class(TObject)
sCallModName:String; // Module containing the function (ANSI)
sFuncName:String; // Function name in callee (ANSI)
pOrig:TFarProc; // Original function address in calleer
pHook:TFarProc; // Hook function address
bExcludeAPIHookMod:Boolean; // Hook module w/CAPIHook implementation?
public
// Hook a function in all modules
constructor Create(CallModName,FuncName:String; HookProc:TFarProc; ExcludeAPIHookMod:Boolean); virtual;
// Unhook a function from all modules
destructor Destroy; override;
end;
var
HookList:TList;
implementation
uses SysUtils, TlHelp32{$IFDEF XPALG}, ImageHlp{$ENDIF}, tmp;
const cPushOpCode:Byte = $68; // The PUSH opcode on x86 platforms
SIZE_OF_NT_SIGNATURE = SizeOf(DWord);
IMAGE_MAX_SECTIONS = MAXWORD + 1; //Note that the Windows NT loader limits the Number of Sections to 96.
IMAGE_MAX_IMPORT_MODULES = MAXWORD + 1;
IMAGE_MAX_IMPORT_MODULE_ENTRIES = MAXWORD + 1;
var
HookGetProcAdress:TAPIHook;
HookLoadLibraryExA:TAPIHook;
HookLoadLibraryExW:TAPIHook;
HookLoadLibraryA:TAPIHook;
HookLoadLibraryW:TAPIHook;
GPAProc:TFarProc;
type
{$Z4}
// _IMAGE_IMPORT_BY_NAME
PImage_import_by_name = ^_IMAGE_IMPORT_BY_NAME;
_IMAGE_IMPORT_BY_NAME = packed record
Hint: Word;
Name: packed array[0..0] of char;
end;
TImage_import_by_mame = _IMAGE_IMPORT_BY_NAME;
IMAGE_IMPORT_BY_NAME = _IMAGE_IMPORT_BY_NAME;
// _u1
_u1=packed record
case Integer of
0: (ForwarderString:PByte);
1: (Functionn:PDWORD);
2: (Ordinal: DWORD);
3: (AddressOfData:PImage_import_by_name);
end;
// _IMAGE_THUNK_DATA
PImageThunkData=^_IMAGE_THUNK_DATA;
_IMAGE_THUNK_DATA=packed record
u1:_u1;
end;
TImageThunkData = _IMAGE_THUNK_DATA;
IMAGE_THUNK_DATA = _IMAGE_THUNK_DATA;
// THunk ThunkData
//
PImportLookupTable = ^TImportLookupTable;
TImportLookupTable = packed array[0..IMAGE_MAX_IMPORT_MODULE_ENTRIES - 1] of TImageThunkData;
//
PImportAddressTable = ^TImportAddressTable;
TImportAddressTable = packed array[0..IMAGE_MAX_IMPORT_MODULE_ENTRIES - 1] of TImageThunkData;
// _IMAGE_IMPORT_DESCRIPTOR
PImageImportDescriptor = ^TImageImportDescriptor;
_IMAGE_IMPORT_DESCRIPTOR = packed record
ImportLookupTable:PImportLookupTable;
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
ImportModuleName:PChar;
ImportAddressTable:PImportAddressTable; // RVA to IAT (if bound this IAT has actual addresses)
end;
TImageImportDescriptor = _IMAGE_IMPORT_DESCRIPTOR;
IMAGE_IMPORT_DESCRIPTOR= _IMAGE_IMPORT_DESCRIPTOR;
///////////////////////////////////////////////////////////
← →
Doc-N (2004-11-26 17:13) [5]function GetProcAddressReal(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
type
TGPAPROC=function (hModule: windows.HMODULE; lpProcName: windows.LPCSTR): FARPROC; stdcall;
begin
Result:=tgpaproc(GPAProc)(hModule,lpProcName)
end;
procedure ReplaceIATEntryInOneMod(CallModulName:String; OrigProc:FARPROC; HookProc:FARPROC; CallModule:HMODULE);
var
peb:PPEB;
dwSize:ULONG;
dwAddressToIntercept:DWord;
{$IFDEF XPALG}
{$ELSE}
pDosHeader:PImageDosHeader;
pNtHeader:PImageNtHeaders;
{$ENDIF}
PImportDesc:PImageImportDescriptor;
dwProtect:DWORD;
dwNewProtect:DWORD;
pThunk:PImageThunkData;
function MakePtr(base:Dword;Offset:DWORD):Pointer;
begin
Result:=Pointer(Base+Offset);
end;
begin
peb:=GetCurrentPEB;
try
LockLoader(peb); //только в NT/XP
{$IFDEF XPALG}
PImportDesc:=ImageDirectoryEntryToData(pointer(CallModule), True, IMAGE_DIRECTORY_ENTRY_IMPORT, dwSize);
if PImportDesc=nil then Exit;
{$ELSE}
if IsBadReadPtr(Pointer(CallModule),sizeof(PImageNtHeaders)) then Exit;
pDosHeader:=PImageDosHeader(CallModule);
if pDosHeader.e_magic<>IMAGE_DOS_SIGNATURE then exit;
pNtHeader:=PImageNtHeaders(MakePtr(DWord(pDOSHeader),DWord(pDOSHeader._lfanew)));
if pNTHeader.signature<>IMAGE_NT_SIGNATURE then exit;
pImportDesc:=PImageImportDescriptor(MakePtr(CallModule, pNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
if (PImportDesc=PImageImportDescriptor(pNtHeader))
or (pNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size=0) or
(pNtHeader.OptionalHeader.NumberOfRvaAndSizes<16) then exit;
{$ENDIF}
dwAddressToIntercept:=DWord(OrigProc);
while Assigned(PImportDesc^.ImportModuleName) do
begin
if lstrcmpi(PChar(CallModulName),MakePtr(dword(CallModule),dword(PImportDesc^.ImportModuleName)))=0 then
begin
pThunk:=PImageThunkData(MakePtr(DWord(CallModule), Dword(pImportDesc^.ImportAddressTable)));
repeat
if DWord(pThunk^.u1.Functionn)=dwAddressToIntercept then
begin
if not IsBadWritePtr(Pointer(@pThunk^.u1.Functionn),sizeof(DWORD)) then
begin
WriteProcessMemory(GetCurrentProcess(), pThunk.u1.Functionn, @HookProc, sizeof(HookProc), dwSize);
end
else
begin
if VirtualProtect(Pointer(@pThunk.u1.Functionn),sizeof(DWORD),PAGE_EXECUTE_READWRITE,@dwProtect) then
begin
WriteProcessMemory(GetCurrentProcess(), pThunk.u1.Functionn, @HookProc, sizeof(HookProc), dwSize);
dwNewProtect:=dwProtect;
VirtualProtect(Pointer(@pThunk.u1.Functionn),sizeof(DWORD),dwNewProtect,@dwProtect);
end;
end;
end;
Inc(pThunk);
until pThunk^.u1.Ordinal<>0;
break;
end
else
Inc(PImportDesc);
end;
finally
UnlockLoader(peb); //только в NT/XP
end;
end;
procedure ReplaceIATEntryInAllMods(CallModulName:String; OrigProc:FARPROC; HookProc:FARPROC; ExcludeAPIHookMod:Boolean);
var
ThisModule:HMODULE;
h:THandle;
Me:MODULEENTRY32;
begin
if ExcludeAPIHookMod then
ThisModule:=HInstance//ModulFromAdress(@ReplaceIATEntryInAllMods)
else
ThisModule:=0;
h:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
if h=1 then RaiseLastOSError;
Me.dwSize:=sizeof(MODULEENTRY32);
Module32First(h,Me);
if Me.hModule <> ThisModule then //себя не трогать
ReplaceIATEntryInOneMod(CallModulName, OrigProc, HookProc, Me.hModule);
while Module32Next(h,Me) do
if Me.hModule <> ThisModule then //себя не трогать
ReplaceIATEntryInOneMod(CallModulName, OrigProc, HookProc, Me.hModule);
end;
procedure FixupNewlyLoadedModule(hmod:HMODULE; dwFlags:DWORD); stdcall;
var
I: Integer;
begin
if (hmod<>0) and ((dwFlags and LOAD_LIBRARY_AS_DATAFILE)=0) then
for I := 0 to HookList.Count - 1 do
ReplaceIATEntryInOneMod(TAPIHook(HookList[i]).sCallModName,TAPIHook(HookList[i]).pOrig,TAPIHook(HookList[i]).pHook,hmod) ;
end;
{ TAPIHook }
constructor TAPIHook.Create(CallModName, FuncName: String;
HookProc: TFarProc; ExcludeAPIHookMod: Boolean);
begin
HookList.Add(self);
sCallModName:=CallModName;
sFuncName:=FuncName;
pHook:=HookProc;
bExcludeAPIHookMod:=ExcludeAPIHookMod;
pOrig:=GetProcAddressReal(GetModuleHandle(pansichar(sCallModName)), pchar(sFuncName));
if pOrig=nil then
RaiseLastOSError;
ReplaceIATEntryInAllMods(sCallModName,pOrig,pHook,bExcludeAPIHookMod);
end;
destructor TAPIHook.Destroy;
begin
ReplaceIATEntryInAllMods(sCallModName,pHook,pOrig,bExcludeAPIHookMod);
HookList.Remove(Self);
inherited;
end;
function MyGetProcAddress(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
var
I: Integer;
begin
Result:=GetProcAddressReal(hModule,lpProcName);
for I := 0 to HookList.Count - 1 do
if TAPIHook(HookList[i]).pOrig=Result then
begin
Result:=TAPIHook(HookList[i]).pHook;
Break;
end;
end;
function MyLoadLibraryA(lpLibFileName: PAnsiChar): HMODULE; stdcall;
type
tloadliba=function (lpLibFileName: PAnsiChar): HMODULE; stdcall;
begin
Result:=tloadliba(HookLoadLibraryA.pOrig)(lpLibFileName);
FixupNewlyLoadedModule(Result,0);
end;
function MyLoadLibraryW(lpLibFileName: PWideChar): HMODULE; stdcall;
type
tloadlibw=function (lpLibFileName: PWideChar): HMODULE; stdcall;
begin
Result:=tloadlibw(HookLoadLibraryW.pOrig)(lpLibFileName);
FixupNewlyLoadedModule(Result,0);
end;
function MyLoadLibraryExA(lpLibFileName: PAnsiChar; hFile: THandle; dwFlags: DWORD): HMODULE; stdcall;
type
tloadlibexa=function (lpLibFileName: PAnsiChar; hFile: THandle; dwFlags: DWORD): HMODULE; stdcall;
begin
Result:=tloadlibexa(HookLoadLibraryW.pOrig)(lpLibFileName, hFile, dwFlags);
FixupNewlyLoadedModule(Result,0);
end;
function MyLoadLibraryExW(lpLibFileName: PWideChar; hFile: THandle; dwFlags: DWORD): HMODULE; stdcall;
type
tloadlibexw=function (lpLibFileName: PWideChar; hFile: THandle; dwFlags: DWORD): HMODULE; stdcall;
begin
Result:=tloadlibexw(HookLoadLibraryW.pOrig)(lpLibFileName, hFile, dwFlags);
FixupNewlyLoadedModule(Result,0);
end;
var
I:Integer;
initialization
HookList:=TList.Create;
HookList.Clear;
GPAProc:=GetProcAddress(GetModuleHandle(kernel32),"GetProcAddress");
HookGetProcAdress := TAPIHook.Create("Kernel32.dll", "GetProcAddress", @MyGetProcAddress, False);
HookLoadLibraryA := TAPIHook.Create("Kernel32.dll", "LoadLibraryA", @MyLoadLibraryA, False);
HookLoadLibraryW := TAPIHook.Create("Kernel32.dll", "LoadLibraryW", @MyLoadLibraryW, False);
HookLoadLibraryExA := TAPIHook.Create("Kernel32.dll", "LoadLibraryExA", @MyLoadLibraryExA, False);
HookLoadLibraryExW := TAPIHook.Create("Kernel32.dll", "LoadLibraryExW", @MyLoadLibraryExW, False);
finalization
for i:=HookList.Count-1 downto 0 do
TAPIHook(HookList[i]).Free;
HookList.Free;
end.
← →
Doc-N (2004-11-26 17:15) [6]
//только в NT/XP
// в 98 нет :(
unit tmp;
interface
uses windows;
type
TPEB = packed record
{000} InheritedAddressSpace : ByteBool;
{001} ReadImageFileExecOptions : ByteBool;
{002} BeingDebugged : ByteBool;
{003} SpareBool : ByteBool;
{004} Mutant : Pointer;
{008} ImageBaseAddress : Pointer;
{00C} LdrData : Pointer; //PPEB_LDR_DATA; { Modules list }
{010} ProcessParameters : Pointer; //PRTL_USER_PROCESS_PARAMETERS; { _RTL_USER_PROCESS_PARAMETERS }
{014} SubSystemData : Pointer;
{018} ProcessHeap : Pointer;
{01C} FastPebLock : PRTLCriticalSection;
{020} FastPebLockRoutine : Pointer;
{024} FastPebUnlockRoutine : Pointer;
{028} EnvironmentUpdateCount : Cardinal;
{02C} KernelCallbackTable : Pointer;
{030} SystemReserved : Cardinal;
{034} ExecuteOptions : Cardinal; {Pos 0, 2 Bits, SpareBits : Pos 2, 30 Bits }
{038} FreeList : Pointer; { _PEB_FREE_BLOCK }
{03C} TlsExpansionCounter : Cardinal;
{040} TlsBitmap : Pointer;
{044} TlsBitmapBits : array[0..1] of Cardinal;
{04C} ReadOnlySharedMemoryBase : Pointer;
{050} ReadOnlySharedMemoryHeap : Pointer;
{054} ReadOnlyStaticServerData : Pointer;
{058} AnsiCodePageData : Pointer;
{05C} OemCodePageData : Pointer;
{060} UnicodeCaseTableData : Pointer;
{064} NumberOfProcessors : Cardinal;
{068} NtGlobalFlag : Cardinal;
{06C} Reserved0 : DWord;
{070} CriticalSectionTimeout : TLARGEINTEGER;
{078} HeapSegmentReserve : Cardinal;
{07C} HeapSegmentCommit : Cardinal;
{080} HeapDeCommitTotalFreeThreshold : Cardinal;
{084} HeapDeCommitFreeBlockThreshold : Cardinal;
{088} NumberOfHeaps : Cardinal;
{08C} MaximumNumberOfHeaps : Cardinal;
{090} ProcessHeaps : Pointer;
{094} GdiSharedHandleTable : Pointer;
{098} ProcessStarterHelper : Pointer;
{09C} GdiDCAttributeList : Cardinal;
{0A0} LoaderLock : PRTLCriticalSection;
{0A4} OSMajorVersion : Cardinal;
{0A8} OSMinorVersion : Cardinal;
{0AC} OSBuildNumber : Word;
{0AE} OSCSDVersion : Word;
{0B0} OSPlatformId : Cardinal;
{0B4} ImageSubsystem : Cardinal;
{0B8} ImageSubsystemMajorVersion : Cardinal;
{0BC} ImageSubsystemMinorVersion : Cardinal;
{0C0} ImageProcessAffinityMask : Cardinal;
{0C4} Reserved2 : array[0..34] of DWord;
{150} Reserved3 : DWord;
{154} Reserved4 : array[0..31] of DWord;
{1D4} Win32WindowStation : THandle;
{1D8} Reserved5 : DWord;
{1DC} Reserved6 : DWord;
{1E0} CSDVersion : PWord;
{1E4} Reserved7 : DWord;
{1E8}
end;
PPEB = ^TPEB;
////////////////////
PClientId = ^TClientId;
TClientId = record
UniqueProcess: THandle; // Process ID
UniqueThread: THandle; // Thread ID
end;
CLIENT_ID = TClientId;
//////////////////////////////
PNtTib = ^TNtTib;
_NT_TIB = record
ExceptionList : Pointer; // ^_EXCEPTION_REGISTRATION_RECORD
StackBase : Pointer;
StackLimit : Pointer;
SubSystemTib : Pointer;
case Integer of
0: (FiberData : Pointer);
1: (Version : ULONG;
{ end; }
ArbitraryUserPointer: Pointer;
Self : PNtTib);
end;
TNtTib = _NT_TIB;
///////////////////
PTeb = ^TTeb;
TTeb = packed record
Tib : TNtTib;
Environment : PWideChar;
ClientId : TClientId;
RpcHandle : THandle;
ThreadLocalStorage: Pointer; // PPointer
Peb : PPeb;
LastErrorValue : DWORD;
end;
_TEB = TTeb;
function GetCurrentPEB: PPEB;
procedure LockLoader(PEB: PPEB);
procedure UnlockLoader(PEB: PPEB);
implementation
function GetCurrentPEB: PPEB;
asm
mov eax, fs:[TTeb.Peb]
//
//: Segment override.
//Instructs the assembler that the
//expression after the colon belongs
//to the segment given by the segment
//register name (CS, DS, SS, FS, GS,
//or ES) before the colon. The result
//is a memory reference with the value
//of the expression after the colon.
//When a segment override is used in an
//instruction operand, the instruction
//is prefixed with an appropriate
//segment-override prefix instruction to
//ensure that the indicated segment is selected.
//
end;
procedure LockLoader(PEB: PPEB);
begin
EnterCriticalSection(peb^.LoaderLock^);
end;
procedure UnlockLoader(PEB: PPEB);
begin
LeaveCriticalSection(PEB^.LoaderLock^);
end;
end.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2005.01.16;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.038 c