替换 IAT 中的导入函数地址实现 Hook API

news/2024/7/5 20:45:28
详细说明《Windows 核心编程》中有。贴段代码,我写得比他写得简洁多了。自己会查找 Image Import descriptor 的地址,而不像书中所用的调用 ImageHlp.dll 或者 DbgHelp.dll 中的函数 ImageDirectoryToData 来实现。为了使用一些 PE 结构类型,请 #include (不会导入他的函数)。

使用方法:

HookAPI((PBYTE) GetModuleHandle(NULL), "User32.dll", MessageBox, MyMessageBox);

取消Hook:

HookAPI((PBYTE) GetModuleHandle(NULL), "User32.dll", MyMessageBox, MessageBox);

原本以为用这种方法能 Hook User32.dll 中的 SetScrollInfo 实现 ClassXP 自绘 Scroll 的。因为需要 HookAPI((PBYTE) GetModuleHandle("User32.dll"), "User32.dll", SetScrollInfo, MySetScrollInfo) ,后来发现 User32.dll 根本不是导入自己的函数,而是直接调用——早该想到了,晕死!

所以替换 IAT 方法 Hook,还是有限制的,没办法在ClassXP中使用:(只好替换SetScrollInfo的入口点代码了:(


PVOID HookAPI(PBYTE pbModule, PCSTR pszName, PVOID pvOrg, PVOID pvNew)
{
    PIMAGE_THUNK_DATA r;
    PIMAGE_NT_HEADERS p;
    PIMAGE_IMPORT_DESCRIPTOR q;
    
    p = (PIMAGE_NT_HEADERS) (pbModule + ((PIMAGE_DOS_HEADER) pbModule)->e_lfanew);
    q = (PIMAGE_IMPORT_DESCRIPTOR) (pbModule + p->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

    for (; q->Name; q++)
    {
        if (lstrcmpiA(pszName, (PCSTR) (pbModule + q->Name)) == 0)
        {
            for (r = (PIMAGE_THUNK_DATA) (pbModule + q->FirstThunk); r->u1.Function; r++)
            {
                if ((PVOID) r->u1.Function == pvOrg)
                {
                    WriteProcessMemory(GetCurrentProcess(), &r->u1.Function, &pvNew, sizeof(PVOID), NULL);
                    return pvOrg;
                }
            }
        }
    }

    return NULL;
}

   下面是替换函数入口的方法,只能用于X86的平台中,尚不完善。 PVOID HookApi(PVOID pvOrg, PVOID pvNew) {     DWORD dwProtect;      if (VirtualProtect(pvOrg, 16, PAGE_READWRITE, &dwProtect))     {         PBYTE p = (PBYTE) pvOrg;         PDWORD q = (PDWORD) (p + 1);          *p = 0xE9;         *q = (LONG) pvNew - (LONG) (p + 5);          VirtualProtect(pvOrg, 16, dwProtect, &dwProtect);          return pvOrg;     }      return NULL; }

http://www.niftyadmin.cn/n/2559824.html

相关文章

Vim及gcc/g++使用

一:vim使用 首先了解三种常用模式: 普通模式是控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入插入模式或者到底行模式。 插入模式:只有在插入模式下,才可以做文字输入,按ESC可以回到普通模式…

配置 UltraEdit 为 MASM32 的IDE

一段老文字,存此,权当存档。(主要是为 UE 的语法高亮文件 WordFile.txt 存档:) 闲着没事,随意写一下怎样配置 UltraEdit,使之成为 MASM32 的IDE。 一、准备工作 这里先假设: 1. Ultr…

Linux调试器-gdb使用、makefile、进度条及yum

一:gdb -g 向可执行程序中添加调试信息: 然后用gdp调试:gdb ./test -->run ->start run:运行程序 start:开始逐步调试; n 进行下一步调试(不进入函数); s 进行下一步调试(进入…

Intent中的各种FLAG

Task Task就是一个任务栈,里面用来存放Activity,第一个进去的(Activity)处于栈的最下面,而最后创建的(Activity)则处于栈的最上面。从Task中取出(Activity)是从最顶端取…

冯诺依曼体系、操作系统、进程(PCB,getpid(),fork)

首先,简画下各进程间关系: 一:冯诺依曼体系 硬件结构决定软件行为----数据信号流向,控制信号的流向。 当然对冯诺依曼体系的理解不能停留在概念上,需要深入对软件数据流的理解,接下里将会解释从我登上qq开…

LinearLayout 与RelativeLayout的区别

LinearLayout:是线性布局控件,它包含的子控件以横向或纵向的方式排列,超过边界时,某些控件将缺失或消失。 RelativeLayout:是相对布局,允许子元素指定以相对于父元素或兄弟元素的位置,这是实际布局中最常用的方式之一…

x86机器码识别及其反汇编算法

x86机器码识别及其反汇编算法x86体系结构CPU的每条指令都可能由以下六个域组成,并且它们在指令中的排列顺序是不能改变的。这六个域分别是:prefixescodeModR/MSIBdisplacementimmediate在任何一条指令中code域是必须出现的,其他的域都是可选的…

进程优先级、环境变量、虚拟地址空间

一:进程优先级 cpu分配资源的先后顺序即为进程的优先级; 优先级高的进程有优先执行权利。配置进程优先级对多任务环境的linux很有用,可以改善系统性能; 可以把进程运行到指定的cpu上,把不重要的进程安排到某个CPU&…