截获API函数
转载一篇文章,也许有用,但我在MSDN上没有查到IMAGE_IMPORT_DESCRIPTOR的结构,
Kingron:你把它转成Delphi代码后记得给我发一份哦
====================================
下面是GoodHope的翻译:
unit x;
interface
const
IMAGE_ORDINAL_FLAG64 = $8000000000000000;
IMAGE_ORDINAL_FLAG32 = $80000000;
{$IFDEF _WIN64}
IMAGE_ORDINAL_FLAG = IMAGE_ORDINAL_FLAG64;
{$ELSE}
IMAGE_ORDINAL_FLAG = IMAGE_ORDINAL_FLAG32;
{$ENDIF}
type
tag_HOOKAPI = record
szFunc: LPCSTR;
pNewProc: FARPROC;
pOldProc: FARPROC;
end;
HOOKAPI = tag_HOOKAPI;
LPHOOKAPI = ^HOOKAPI;
THookAPI = tag_HOOKAPI;
LONG = Longint;
ULONGLONG = Int64;
PSTR = LPSTR;
PVOID = Pointer;
{$ALIGN OFF}
{$IFDEF _WIN64}
ULONG_PTR = ULONGLONG;
PULONG_PTR = ^ULONG_PTR;
{$ELSE}
ULONG_PTR = LONG;
PULONG_PTR = ^ULONG_PTR;
{$ENDIF}
SIZE_T = ULONG_PTR;
PSIZE_T = ^SIZE_T;
tag_IMAGE_IMPORT_DESCRIPTOR = record
case Boolean of
False:
(Characteristics: DWORD);
True:
(OriginalFirstThunk: DWORD;
TimeDateStamp: DWORD;
ForwarderChain: DWORD;
Name: DWORD;
FirstThunk: DWORD;
);
end;
IMAGE_IMPORT_DESCRIPTOR = tag_IMAGE_IMPORT_DESCRIPTOR;
PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR;
tag_IMAGE_DOS_HEADER = record
e_magic: WORD;
e_cblp: WORD;
e_cp: WORD;
e_crlc: WORD;
e_cparhdr: WORD;
e_minalloc: WORD;
e_maxalloc: WORD;
e_ss: WORD;
e_sp: WORD;
e_csum: WORD;
e_ip: WORD;
e_cs: WORD;
e_lfarlc: WORD;
e_ovno: WORD;
e_res: array [0 .. 4 - 1] of WORD;
e_oemid: WORD;
e_oeminfo: WORD;
e_res2: array [0 .. 10 - 1] of WORD;
e_lfanew: LONG;
end;
IMAGE_DOS_HEADER = tag_IMAGE_DOS_HEADER;
PIMAGE_DOS_HEADER = ^IMAGE_DOS_HEADER;
tag_IMAGE_FILE_HEADER = record
Machine: WORD;
NumberOfSections: WORD;
TimeDateStamp: DWORD;
PointerToSymbolTable: DWORD;
NumberOfSymbols: DWORD;
SizeOfOptionalHeader: WORD;
Characteristics: WORD;
end;
IMAGE_FILE_HEADER = tag_IMAGE_FILE_HEADER;
PIMAGE_FILE_HEADER = ^IMAGE_FILE_HEADER;
tag_IMAGE_DATA_DIRECTORY = record
VirtualAddress: DWORD;
Size: DWORD;
end;
IMAGE_DATA_DIRECTORY = tag_IMAGE_DATA_DIRECTORY;
PIMAGE_DATA_DIRECTORY = ^IMAGE_DATA_DIRECTORY;
tag_IMAGE_OPTIONAL_HEADER64 = record
Magic: WORD;
MajorLinkerVersion: BYTE;
MinorLinkerVersion: BYTE;
SizeOfCode: DWORD;
SizeOfInitializedData: DWORD;
SizeOfUninitializedData: DWORD;
AddressOfEntryPoint: DWORD;
BaseOfCode: DWORD;
ImageBase: ULONGLONG;
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: ULONGLONG;
SizeOfStackCommit: ULONGLONG;
SizeOfHeapReserve: ULONGLONG;
SizeOfHeapCommit: ULONGLONG;
LoaderFlags: DWORD;
NumberOfRvaAndSizes: DWORD;
DataDirectory: array [0 .. IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1]
of IMAGE_DATA_DIRECTORY;
end;
IMAGE_OPTIONAL_HEADER64 = tag_IMAGE_OPTIONAL_HEADER64;
PIMAGE_OPTIONAL_HEADER64 = ^IMAGE_OPTIONAL_HEADER64;
tag_IMAGE_OPTIONAL_HEADER = record
Magic: WORD;
MajorLinkerVersion: BYTE;
MinorLinkerVersion: BYTE;
SizeOfCode: DWORD;
SizeOfInitializedData: DWORD;
SizeOfUninitializedData: DWORD;
AddressOfEntryPoint: DWORD;
BaseOfCode: DWORD;
BaseOfData: DWORD;
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: array [0 .. IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1]
of IMAGE_DATA_DIRECTORY;
end;
IMAGE_OPTIONAL_HEADER32 = tag_IMAGE_OPTIONAL_HEADER;
PIMAGE_OPTIONAL_HEADER32 = ^IMAGE_OPTIONAL_HEADER32;
tag_IMAGE_NT_HEADERS64 = record
Signature: DWORD;
FileHeader: IMAGE_FILE_HEADER;
OptionalHeader: IMAGE_OPTIONAL_HEADER64;
end;
IMAGE_NT_HEADERS64 = tag_IMAGE_NT_HEADERS64;
PIMAGE_NT_HEADERS64 = IMAGE_NT_HEADERS64;
tag_IMAGE_NT_HEADERS = record
Signature: DWORD;
FileHeader: IMAGE_FILE_HEADER;
OptionalHeader: IMAGE_OPTIONAL_HEADER32;
end;
IMAGE_NT_HEADERS32 = tag_IMAGE_NT_HEADERS;
PIMAGE_NT_HEADERS32 = ^IMAGE_NT_HEADERS32;
{$IFDEF _WIN64}
IMAGE_NT_HEADERS = IMAGE_NT_HEADERS64;
PIMAGE_NT_HEADERS = PIMAGE_NT_HEADERS64;
{$ELSE}
IMAGE_NT_HEADERS = IMAGE_NT_HEADERS32;
PIMAGE_NT_HEADERS = PIMAGE_NT_HEADERS32;
{$ENDIF}
tag_IMAGE_IMPORT_BY_NAME = record
Hint: WORD;
Name: array [0 .. 0] of BYTE;
end;
IMAGE_IMPORT_BY_NAME = tag_IMAGE_IMPORT_BY_NAME;
PIMAGE_IMPORT_BY_NAME = ^IMAGE_IMPORT_BY_NAME;
tag_U1_64 = record
case BYTE of
1:
(ForwarderString: PBYTE;);
2:
(Function_: PDWORD;);
3:
(Ordinal: ULONGLONG;);
4:
(AddressOfData: PIMAGE_IMPORT_BY_NAME;);
end;
tag_IMAGE_THUNK_DATA64 = record
u1: tag_U1_64;
end;
IMAGE_THUNK_DATA64 = tag_IMAGE_THUNK_DATA64;
PIMAGE_THUNK_DATA64 = ^IMAGE_THUNK_DATA64;
tag_U1_32 = record
case BYTE of
1:
(ForwarderString: PBYTE;);
2:
(Function_: PDWORD);
3:
(Ordinal: DWORD);
4:
(AddressOfData: PIMAGE_IMPORT_BY_NAME);
end;
tag_IMAGE_THUNK_DATA32 = record
u1: tag_U1_32;
end;
IMAGE_THUNK_DATA32 = tag_IMAGE_THUNK_DATA32;
PIMAGE_THUNK_DATA32 = ^IMAGE_THUNK_DATA32;
{$IFDEF _WIN64}
IMAGE_THUNK_DATA = IMAGE_THUNK_DATA64;
PIMAGE_THUNK_DATA = PIMAGE_THUNK_DATA64;
{$ELSE}
IMAGE_THUNK_DATA = IMAGE_THUNK_DATA32;
PIMAGE_THUNK_DATA = PIMAGE_THUNK_DATA32;
{$ENDIF}
{$ALIGN ON}
function GetNamedImportDescriptor(hModule: hModule; szImportMod: LPCSTR)
: PIMAGE_IMPORT_DESCRIPTOR; stdcall;
function HookAPIByName(hModule: hModule;
szImportMod: LPCSTR;
pHookApi: LPHOOKAPI
): Boolean;
stdcall implementation
function MyMessageBoxW(hWnd: hWnd; lpText: LPCWSTR; lpCaption: LPCWSTR;
uType: UINT): Integer;
stdcall;
begin
Result := MessageBox(hWnd, 'TNT' , 'TNT' , uType);
end;
function GetNamedImportDescriptor(hModule: hModule; szImportMod: LPCSTR)
: PIMAGE_IMPORT_DESCRIPTOR;
var
pDOSHeader: PIMAGE_DOS_HEADER;
pNTHeader: PIMAGE_NT_HEADERS;
pImageDataDirectory: PIMAGE_DATA_DIRECTORY;
pImportDesc: PIMAGE_IMPORT_DESCRIPTOR;
szCurrMod: PSTR;
begin
Result := nil;
pDOSHeader := PIMAGE_DOS_HEADER(hModule);
if pDOSHeader.e_magic <> IMAGE_DOS_SIGNATURE then
Exit;
pNTHeader := PIMAGE_NT_HEADERS(DWORD(pDOSHeader) +
DWORD(pDOSHeader.e_lfanew));
if pNTHeader.Signature <> IMAGE_NT_SIGNATURE then
Exit;
pImageDataDirectory := @pNTHeader.OptionalHeader.DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT];
if (pImageDataDirectory.VirtualAddress = 0) then
Exit;
pImportDesc := PIMAGE_IMPORT_DESCRIPTOR(DWORD(pDOSHeader) +
DWORD(pImageDataDirectory.VirtualAddress));
while pImportDesc.Name <> 0 do
begin
szCurrMod := PSTR(DWORD(pDOSHeader) + DWORD(pImportDesc.Name));
if (CompareText(szCurrMod, szImportMod) = 0) then
Break;
Inc(pImportDesc);
end;
if pImportDesc.Name <> 0 then
Result := pImportDesc;
end;
function HookAPIByName(hModule: hModule; szImportMod: LPCSTR;
pHookApi: LPHOOKAPI): Boolean;
var
pImportDesc: PIMAGE_IMPORT_DESCRIPTOR;
pOrigThunk: PIMAGE_THUNK_DATA;
pRealThunk: PIMAGE_THUNK_DATA;
pByName: PIMAGE_IMPORT_BY_NAME;
mbi_thunk: TMemoryBasicInformation;
dwOldProtect: DWORD;
begin
Result := False;
pImportDesc := GetNamedImportDescriptor(hModule, szImportMod);
pOrigThunk := PIMAGE_THUNK_DATA(DWORD(hModule) +
DWORD(pImportDesc.OriginalFirstThunk));
if pImportDesc = nil then
Exit;
pRealThunk := PIMAGE_THUNK_DATA(DWORD(hModule) +
DWORD(pImportDesc.FirstThunk));
while pOrigThunk.u1.Function_ <> nil do
begin
if (pOrigThunk.u1.Ordinal and IMAGE_ORDINAL_FLAG) <> IMAGE_ORDINAL_FLAG then
begin
pByName := PIMAGE_IMPORT_BY_NAME(DWORD(hModule) +
DWORD(pOrigThunk.u1.AddressOfData));
if pByName.Name[0] = 0 then
Exit;
if CompareText(pHookApi.szFunc, PChar(@pByName.Name[0])) = 0 then
begin
VirtualQuery(pRealThunk, mbi_thunk, SizeOf(MEMORY_BASIC_INFORMATION));
VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize,
PAGE_READWRITE, @mbi_thunk.Protect);
if pHookApi.pOldProc = nil then
pHookApi.pOldProc := FARPROC(pRealThunk.u1.Function_);
pRealThunk.u1.Function_ := PDWORD(pHookApi.pNewProc);
VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize,
mbi_thunk.Protect, @dwOldProtect);
end;
end;
Inc(pOrigThunk);
Inc(pRealThunk);
end;
SetLastError(ERROR_SUCCESS);
Result := True;
end;
====================================
如何截获API函数(转)
该程序是基于HOOK原理,主要是将自己的函数放到目标PROCESS的地址空间,这里是使用HOOK实现.首先建立一个MOUSE的HOOK程序,然后在全局鼠标HOOK的DLL中做截获动作,可以在PROCESS_ATTACH时做,也可以在鼠标的HOOK链函数中做.
建立全局HOOK就不说了,可以在网上很多地方看到.主要是截获动作.通过PE格式(使用IMAGE)改变API函数在调用时的地址.DLL部分参考如下代码:
static int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
{
return MessageBox(hWnd, "TNT" , "TNT" , uType);
}
我定义了一个结构
typedef struct tag_HOOKAPI
{
LPCSTR szFunc;
PROC pNewProc;
PROC pOldProc;
} HOOKAPI, *LPHOOKAPI;
extern "C" __declspec(dllexport) PIMAGE_IMPORT_DESCRIPTOR GetNamedImportDescriptor(HMODULE hModule, LPCSTR szImportMod)
{
PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)hModule;
if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;
PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDOSHeader + (DWORD)(pDOSHeader->e_lfanew));
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
return NULL;
if (pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0)
return NULL;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pDOSHeader + (DWORD)(pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
while (pImportDesc->Name)
{
PSTR szCurrMod = (PSTR)((DWORD)pDOSHeader + (DWORD)(pImportDesc->Name));
if (stricmp(szCurrMod, szImportMod) == 0)
break;
pImportDesc++;
}
if (pImportDesc->Name == NULL)
return NULL;
return pImportDesc;
}
extern "C" __declspec(dllexport) HookAPIByName(HMODULE hModule , LPCSTR szImportMod , LPHOOKAPI pHookApi )
{
PIMAGE_IMPORT_DESCRIPTOR pImportDesc =
GetNamedImportDescriptor(hModule, szImportMod);
if (pImportDesc == NULL)
return FALSE;
PIMAGE_THUNK_DATA pRealThunk =
(PIMAGE_THUNK_DATA)((DWORD)hModule + (DWORD)(pImportDesc->FirstThunk));
while (pOrigThunk->u1.Function)
{
if ((pOrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) != IMAGE_ORDINAL_FLAG)
{
PIMAGE_IMPORT_BY_NAME pByName = (PIMAGE_IMPORT_BY_NAME)((DWORD)hModule + (DWORD)(pOrigThunk->u1.AddressOfData));
if (pByName->Name[0] == '\0')
return FALSE;
if (strcmpi(pHookApi->szFunc, (char *)pByName->Name) == 0)
{
MEMORY_BASIC_INFORMATION mbi_thunk;
VirtualQuery(pRealThunk, &mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION));
VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, PAGE_READWRITE, &mbi_thunk.Protect);
if (pHookApi->pOldProc == NULL)
pHookApi->pOldProc = (PROC)pRealThunk->u1.Function;
pRealThunk->u1.Function = (PDWORD)pHookApi->pNewProc;
DWORD dwOldProtect;
VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize,
mbi_thunk.Protect, &dwOldProtect);
}
}
pOrigThunk++;
pRealThunk++;
}
SetLastError(ERROR_SUCCESS);
return TRUE;
}