关于hook ntdll 代码详解

UNHOOK ntdll

复制代码
DWORD unhook() {
	//创建该结构体用于获取该dll的信息 将所有成员变量初始化为零
	MODULEINFO mi = {};
	//获取当前内存的ntdll的句柄
	HMODULE ntdllModule = GetModuleHandleA("ntdll.dll");
	//HANDLE(-1)表示获取当前进程的句柄 该函数用于获取该进程的信息
	GetModuleInformation(HANDLE(-1), ntdllModule, &mi, sizeof(mi));
	//获取该ntdll的基地址
	LPVOID ntdllBase = (LPVOID)mi.lpBaseOfDll;
	//调用CreateFileA打开新的一个ntdll
	HANDLE ntdllFile = CreateFileA("c:\\windows\\system32\\ntdll.dll", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
	//将该新的ntdll映射到内存中 但是还没有映射到当前进程中
	HANDLE ntdllMapping = CreateFileMapping(ntdllFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
	//MapViewOfFile将文件映射的视图映射到调用进程的地址空间中 也就是当前的进程
	LPVOID ntdllMappingAddress = MapViewOfFile(ntdllMapping, FILE_MAP_READ, 0, 0, 0);

	//获取该ntdll的PE结构的DOS头 (旧的)
	PIMAGE_DOS_HEADER hookedDosHeader = (PIMAGE_DOS_HEADER)ntdllBase;
	PIMAGE_NT_HEADERS hookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ntdllBase + hookedDosHeader->e_lfanew);

	for (WORD i = 0; i < hookedNtHeader->FileHeader.NumberOfSections; i++) {
		//每个节的头是固定大小且是连续的。一个节头挨着一个节头的比如rdata的节头完了之后就是紧挨着data节头的。IMAGE_SIZEOF_SECTION_HEADER确实是40字节
		PIMAGE_SECTION_HEADER hookedSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader) + ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));
		//获取节的头之后判断name是不是等于text,因为要覆盖的是text的内容 hookedSectionHeader->Name获取的是字节不是char 因此要转为char strcmp要求是char *
		if (!strcmp((char*)hookedSectionHeader->Name, (char*)".text")) {
			DWORD oldProtection = 0;
			//VirtualProtect修改旧的 ntdll的保护属性为可读可写可执行(PAGE_EXECUTE_READWRITE),并且将原来的保护属性保存在oldProtection中 以下仅仅支持.text节的 
			bool isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtection);
			//两个dll由于第一个节是空的在内存中,而text节又是第二个节,因此VirtualAddress是一样的 这样就将旧ntdll中test节的内容覆盖成了新的
			memcpy((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), (LPVOID)((DWORD_PTR)ntdllMappingAddress + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize);
			//还原保护属性
			isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, oldProtection, &oldProtection);
		}
	}

	CloseHandle(ntdllFile);
	CloseHandle(ntdllMapping);
	FreeLibrary(ntdllModule);

	return 0;
}

关于代码中的IMAGE_SIZEOF_SECTION_HEADER

节的头是连续的 每个节的头的大小 即IMAGE_SIZEOF_SECTION_HEADER都等于40

找一个dll看看 确实节的头是连续 也确实大小是 5*8=40字节

节头存放的是节的各种信息包括 节的名称、虚拟地址、大小等但是 不是存放的具体内容

相关推荐
学术阿凡提几秒前
Spring Boot 集成 Fastjson2 完整教程:从入门到避坑
spring boot·安全·json
JiaWen技术圈10 分钟前
内核子系统 nf_tables 深度解析
linux·服务器·安全·运维开发
LIUAWEIO15 分钟前
鸽鸽工具网:免费在线工具大全,打开网页即用
人工智能·安全·ai·json
忡黑梨37 分钟前
eNSP_从直连到BGP全网互通
c语言·网络·数据结构·python·算法·网络安全
moonsims1 小时前
NavCore惯性测量导航-轻量级安全惯导 / UAV 安全触发 IMU 模块-异构双IMU架构-低噪声稳定感知+高动态异常检测
安全·架构
乐迪信息1 小时前
乐迪信息:实时预警,秒级响应:船舶AI异常行为检测算法
大数据·人工智能·算法·安全·目标跟踪
其实防守也摸鱼1 小时前
带你了解与配置phpmyadmin
笔记·安全·网络安全·pdf·编辑器·工具·调试
测试员周周2 小时前
【AI测试系统】第1篇:LangGraph 实战:用 State Graph 搭建 AI测试流水线(4 步编排 + RAG 增强 + 完整代码)
linux·windows·python·功能测试·microsoft·单元测试·多轮对话
byoass2 小时前
企业云盘权限管理深度对比:巴别鸟、联想Filez、腾讯企微云盘
网络·安全·云计算·企业微信
菩提小狗2 小时前
每日安全情报报告 · 2026-04-27
网络安全·漏洞·cve·安全情报·每日安全