其他分享
首页 > 其他分享> > 静态修改输入表hook

静态修改输入表hook

作者:互联网

最近在重读加密与解密因此写下相关笔记和感悟方便以后使用

随书文件 https://book.pediy.com/bk4.txt

PE结构

基地址

VCexe一般基址是400000h

DLL一般是10000000H

虚拟地址 VA virtual address

相对虚拟地址 RVA

相对于pe载入地址

image-20220507122127334

RVA转FOV

判断RVA在哪个区内

用RVA减去该区VA加上该区PointerToRaw得到FOV

IID 输入表

image-20220507123912681

OriginalFirstThunk 指向输入名称表(INT)的RVA 保存导入名称

FirstThunk 保存导入地址

绑定操作就是遍历 OriginalFirstThunk 对应的函数的入口地址 用他们重写FirstThunk指向的数组

DLL注入

在通常情况下,程序加载DLL的时机主要有以下3个:

一是在进程创建阶段加载输人表中的DLL,即俗称的“静态输人”;

二是通过调用LoadLibrary(Ex)主动加载,称为“动态加载”;

三是由于系统机制的要求,必须加载系统预设的一些基础服务模块,例如Shell扩展模块、网络服务接
口模块或输人法模块等。

因此,在进行DLL注人时,也不外乎通过这3种手段进行。

通过干预输入表处理过程加载目标dll

当一个进程被创建后,不会直接到EXE本身的入口处执行,

首先被执行的是ndll.ll中的LdrInitializeThunk函数(ntdll是Windows操作系统中一个非常重要的基础模块,它在进程创建阶段就已经被映射到新进程中了)。
LdrInitializeThunk会调用LdrpInitializeProcess对进程的一些必要内容进行初始化

LdrpInitializeProcess会继续调用LdrpWalkImportDescriptor对输人表进行处理,即加载输人表中的模块,并填充应用程序的IAT。

所以,只要在输人表被处理之前进行干预,为输人表增加一个项目,使其指向要加载的目标DLL,或者替换原输入表中的DLL并对调用进行转发,那么新进程的主线程在输人表初始化阶段就会主动加载目标DLL。

静态修改输入表

先编写我们的注入dll

VS2022

// dllmain.cpp : 定义 DLL 应用程序的入口点。

#include "pch.h"
#include "stdio.h"
#pragma warning(disable : 4996)
#include "pch.h"
#define __T(x)      L ## x
#define _T(x)       __T(x)
extern "C" _declspec(dllexport) void Msg();
void Msg()
{
}
BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        MessageBox(NULL, _T("DLL注入标题"), _T("DLL注入内容"), MB_OK);
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

image-20220509104710288

三项IID 加上IID尾 加上我们新增的一个 共需要5*14h 即64h空间来存放新IID

image-20220509105122919

段reloc有足够空间存放(其实前面的段也有)

image-20220509105335909

直接复制原IID到 .reloc段末尾

image-20220509105520719

然后找个地方存放我们DLL相关信息 即firstthunk和OriginalFirstThunk和dll名称和函数名称

因为.reloc段空间足够 我在底下写相关信息 (记得中间留下2*14h的空间 是新的IID和IID结尾的空间

先填写dll名称和导入函数名称

image-20220509110911596

然后通过FOV计算RVA

先计算导入函数名称

FOV为F54B

段PointerToRawData为F400h

VirtualAddress 为25000h

所以RVA为F54B-F400+25000 =02514B 即firstthunk和OriginalFirstThunk值

image-20220509111628835

再计算导入dll名称

FOV为F540h

所以RVA为F540-F400+25000 =025140

而firstthunk和OriginalFirstThunk的RVA为25130与25138

然后向IID填入相关数据

image-20220509112604631

然后修改reloc可写

然后修改导入表地址

此时新导入表FOV为F480 RVA为025080 再修改size为64h

image-20220509112710166

即可

然后去除bound

然后开始报错) 我的exe为64位自己编写的C++ dll为自己导出的64位dll报错

image-20220509114829768

32位程序 随书文件中的32位dll 成功hook

32位程序 自己编写的32位dll hook失败 原流程运行

64位程序 自己编写的32位或64位dll以及随书的32或64位dll均报错

随书的notepad.exe 自己编写的32位dll hook成功 并可正常使用原功能

标签:RVA,IID,静态,32,dll,hook,DLL,输入,加载
来源: https://www.cnblogs.com/FW-ltlly/p/16248752.html