读书笔记_windows下的混合钩子(HOOK)_part 3_HookImportsOfImage函数解析
来源:互联网 发布:yahoo股票数据接口 编辑:程序博客网 时间:2024/06/06 18:29
HookImportsOfImage函数解析
以下是_IMAGE_DOS_HEADER的结构,是在winnt.h头文件下的,指的是DOS.exe文件的头
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number
WORD e_cblp; // Bytes on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Initial SP value
WORD e_csum; // Checksum
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
PIMAGE_NT_HEADERS结构如下所示,作为PE文件的头,包含了三部分内容。
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER OptionalHeader;
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
PIMAGE_IMPORT_DESCRIPTOR之前介绍过,在winnt.h头文件中的定义如下:
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics; // 0 for terminating null import descriptor
DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
};
DWORD TimeDateStamp; // 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)
DWORD ForwarderChain; // -1 if no forwarders
DWORD Name;
DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
PIMAGE_IMPORT_BY_NAME的结构如下所示:
typedef struct _IMAGE_IMPORT_BY_NAME {
WORD Hint;
BYTE Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
以上四个定义的结构已经完成,注意变量pc_dlltar要hook的模块名称,pc_fnctar为要hook的目标函数。
PMDL的结构如下:
// MDL references defined in ntddk.h
typedef struct _MDL {
struct _MDL *Next;
CSHORT Size;
CSHORT MdlFlags;
struct _EPROCESS *Process;
PVOID MappedSystemVa;
PVOID StartVa;
ULONG ByteCount;
ULONG ByteOffset;
} MDL, *PMDL;
// MDL Flags
MDL(Memory Descriptor List)内存描述表,用来描述一块内存区域,其中包含了该内存区域的起始地址、拥有者进程、字节数据以及标志。
具体函数的执行如下,每个关键语句都有中文注释
NTSTATUS HookImportsOfImage ( PIMAGE_DOS_HEADER image_addr, HANDLE h_proc)
{
PIMAGE_DOS_HEADER dosHeader;
PIMAGE_NT_HEADERS pNTHeader;
PIMAGE_IMPORT_DESCRIPTOR importDesc;
PIMAGE_IMPORT_BY_NAME p_ibn;
DWORD importsStartRVA;
PWORD pd_IAT, pd_INTO;
int count, index;
char *dll_name = NULL;
char *pc_dlltar = "kernel32.dll";
char *pc_fnctar = "GetProcAddress";
PMDL p_mdl;
PDWORD MappedImTable;
// 导入的是IMAGE_INFO结构中的 PVOID ImageBase变量
dosHeader = (PIMAGE_DOS_HEADER) image_addr;
// 宏,对指针的操作
pNTHeader = MakePtr ( PIMAGE_NT_HEADERS, dosHeader, dosHeader->e_lfanew );
// 通过PE文件的Signature字段来判断该文件是否是标准的PE文件
if ( pNTHeader->Signature != IMAGE_NT_SIGNATURE)
return STATUS_INVALID_IMAGE_FORMAT;
// 导入段的RVA
importsStartRVA = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
if ( !importsStartRVA )
return STATUS_INVALID_IMAGE_FORMAT;
// 导入段的RVA与模块在内存中的起始地址(dosHeader)相加,得到
// 指向第一个IMAGE_IMPORT_DESCRIPTOR的指针
importDesc = ( PIMAGE_IMPORT_DESCRIPTOR ) (importsStartRVA + (DWORD)dosHeader);
// 过滤每个IMAGE_IMPORT_DESCRIPTOR
for(count = 0; importDesc[count].Characteristics != 0; count++)
{
// 得到导入模块的dll的名称
dll_name = (char*)(importDesc[count].Name + (DWORD)dosHeader);
// 得到IAT
pd_IAT = (PDWORD)(((DWORD)dosHeader) + (DWORD)importDesc[count].FirstThunk);
// 得到指向IMAGE_IMPORT_BY_NAME结构的指针数组
pd_INTO = (PDWORD)(((DWORD)dosHeader) + (DWORD)importDesc[count].OriginalFirstThunk);
// IAT中的过滤,找到特定的dll与要hook的函数
for ( index = 0; pd_IAT[index] != 0; index++)
{
// if this is an import by ordinal
// the high bit is set
if((pd_INTO[index] & IMAGE_ORDINAL_FLAG) != IMAGE_ORDINAL_FLAG)
{
// 得到函数名结构
p_ibn = (PIMAGE_IMPORT_BY_NAME)(pd_INTO[index] + ((DWORD)dosHeader));
// 对比dll名与函数名,找到所需要的
if((_stricmp(dll_name, pc_dlltar) == 0) && (strcmp(p_ibn->Name, pc_fnctar) ==0))
{
// Use the trick you already learned to map a different
// virtual address to the same physical page so no permission problems
//
// Map the memory into our domain so we can change the
// permissions on the MDL
// 改变内存属性,以便修改IAT属性
// MDL方法修改内存属性,以后的文章中会详细介绍
p_mdl = MmCreateMdl(NULL, &pd_IAT[index], 4);
if(!p_mdl)
return STATUS_UNSUCCESSFUL;
MmBuildMdlForNonPagedPool(p_mdl);
// Change the flags of MDL
p_mdl->MdlFlags = p_mdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
MappedImTable = MmMapLocakedPages(p_mdl, KernelMode);
// Address of the "new function"
// 将“GetProcAddress”指向自己定义的函数
*MappedImTable = d_shareM;
// Free MDL
MmUnmapLoackedPages(MappedImTable, p_mdl);
IoFreeMdl(p_mdl);
}
}
}
return STATUS_SUCCESS;
}
- 读书笔记_windows下的混合钩子(HOOK)_part 3_HookImportsOfImage函数解析
- 读书笔记_windows下的混合钩子(HOOK)_part 1
- 读书笔记_windows下的混合钩子(HOOK)_part 2
- 读书笔记_windows下的混合钩子(HOOK)_part 5_钩子的内存空间
- 读书笔记_windows下的混合钩子(HOOK)_part 4_使用MDL修改内存保护机制
- 读书笔记_windows的APIHook技术_part 2
- 读书笔记_windows内核编程基础_part 1
- 读书笔记_windows内核调试_part 1
- 读书笔记_windows内核编程基础_part 2
- Hook(钩子)函数
- 读书笔记_windows下的验证机制
- 读书笔记_windows内核调试_part 2_内核对话过程
- Delphi - 关于钩子函数HOOK(来自别人的BLOG)
- Wordpress的钩子(hook)
- Apache Hook机制解析(下)——实战:在自己的代码中使用Apache的钩子
- Apache Hook机制解析(下)——实战:在自己的代码中使用Apache的钩子
- 钩子函数(HOOK)完整的教程
- 读书笔记_Windows的启动过程
- android中自定义checkbox大小和图片
- 《OpenGL编程基础》前言&第一章笔记
- Flash Builder4.6(SDK4.6)新的功能
- delphi xe编译报Unit not found: 'System.pas' or binary equivalents 的解决办法
- 需要知道的Applet基础知识
- 读书笔记_windows下的混合钩子(HOOK)_part 3_HookImportsOfImage函数解析
- C# 数据库中图像信息的读取与写入
- JQuery Chapter2 选择器
- 宝马高层透露更多2014款i3电动车细节
- record not found or changed by another user 解决方法
- mysql水平分表和垂直分表和数据库分区
- Android应用问题: Re-installation failed due to different application signatures.
- 2011-10-11
- vB.net DbHelper类(完整)