Notepad Hook

0x00 前言

昨天花了半天写了个四不像的玩意儿,本来打算以恶意代码的方式去写,但今天不怎么想完 善功能了,所以全局hook和自删除之类的就没有了(其实是debug太麻烦。),结果就是这 个程序很沙雕,你必须先打开记事本再运行它才行。不过获取记事本信息是没什么问题的。


0x01 行为

完全是想到什么写什么,所以有些功能完全没发挥作用呢。。 PS:这里所有生成的文件都存放在你的C:/User/username/Documents/文件夹下。

  1. 要注入的DLL文件以资源的形式嵌在启动器中,首先将其释放到文件夹下,名为 notepadhook.dll
  2. 复制启动器自身到文件夹下
  3. 将复制的启动器路径添加到注册表的自启动项中
  4. 枚举进程快照,找到notepad.exe,将DLL文件注入
  5. DLL文件使用Inline hook对ReadFile和WriteFile进行hook,将读取和保存的信息写入到 readlog.txt和writelog.txt

0x02 启动器

启动器本质上就是个DLL注入器,不过DLL文件以资源的形式嵌入到自身当中,所以要先释 放DLL文件到磁盘中。自我复制完全是为了开机自启动才写的,但没有谁一开机就会启动记 事本,所以运行起来是没用的,本来想hook CreateProcess将所有子进程都进行注入,以 此达到一旦启动记事本就会被hook的效果,但完全不想debug了。。。
0x03 notepadhook.dll hook的功能由这个DLL来实现,虽然说可以对native层的API进行hook,但我去看了眼文档,参数太过复杂,就hook记事本来说,hook ReadFile和WriteFile两个ring3层 API完全足够了。hook方式使用的是Inline hook中的mov eax, address; jmp rax这种方 式,这在64位中很常见。hook之后就是将数据缓冲区写入到readlog.txt和writelog.txt中了。


0x04 注册表操作

在这个程序中,对注册表进行了两个操作。 一是设置将自我复制的启动器添加到自启动的子键中,即 HKEY_CURRENT_USE\Software\Microsoft\Windows\CurrentVersion\Run,创建一个 新的键值,并将其值设置为路径即可
二是用于获取C:/User/username/Documents/这个路径,因为username是未知的,每个 计算机的用户名不同,可以通过获取 Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders这个键中的 Personal的值来获取这个路径,这应该是个缺省值,可以修改的。


0x05 枚举进程

这里我们只针对notepad进行hook,而DLL注入需要知道进程的pid,Windows貌似没有 提供直接通过进程名来获取pid的API,所以若想完成这个操作,通常可以通过枚举系统进 程快照的方式来获取进行信息,其实就是遍历一个类似链表的东西,熟悉下API就行了

DWORD GetPrcessIdByProcessName(const char* pszProcessName)
{
	DWORD dwProcessId = 0;
	PROCESSENTRY32 pe32 = { 0 };
	HANDLE hSnapshot = NULL;
	BOOL bRet = FALSE;
	::RtlZeroMemory(&pe32, sizeof(pe32));
	pe32.dwSize = sizeof(pe32);

	hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

	bRet = ::Process32First(hSnapshot, &pe32);
	while (bRet)
	{
		if (!::lstrcmpi(pe32.szExeFile, pszProcessName))
		{
			dwProcessId = pe32.th32ProcessID;
			break;
		}
		bRet = ::Process32Next(hSnapshot, &pe32);
	}
	return dwProcessId;
}


0x06 DLL注入

DLL注入是一种从外部操纵目标进程空间的方式,可以为程序添加额外功能,这种功能可以 是补丁性质的,也可以是恶意的。DLL注入其实可以研究得比较深,不过为了好写,这个程 序只用了最最常见的DLL注入方式——远线程注入。远线程注入的核心是 CreateRemoteThread函数,通过这个函数在某个进程中开启一个线程。具体步骤如下:
1.打开目标进程并获取其句柄 2.在目标进程中分配一块缓冲区 3.将DLL文件路径写入该缓冲区 4.获取LoadLibraryA/LoadLibraryW函数的地址 5.利用CreateRemoteThread开启一个线程,这个线程调用LoadLibrary函数,以DLL文件 路径为参数


0x07 API Hook

API Hook根据实现方式可以分为3类,Address Hook,Inline Hook和利用异常处理 Hook。 Address Hook的本质就是劫持函数表,有pwn基础的同学可以类比GOT覆盖,这样的表有 很多,如IAT,虚函数表,甚至一些系统中断表之类的。 Iline Hook就是一种简单的跳转操作,它直接修改函数开头的指令,令要hook的API开头跳 转到我们自定义的函数中,常用的有mov rax, address; jmp rax    push address; retn这 样的一些指令,不过Inline Hook操作的直接是代码段,所以有时会出现一些奇怪的问题。 利用异常处理进行hook感觉要相对复杂些,作为代表的就是模拟一个调试器的行为来进行 hook,在要hook的API开头写入0xcc,运行到此处时就会触发一个BreakPoint异常,然后 交给我们的调试器来处理,不过写起来挺麻烦。 Hook技术在PC端和移动端都很受欢迎,也出现了许多hook框架,利用这些框架可以更好 的完成某种功能,而非总是调用底层的API,这是很麻烦的。


0x08 测试

首先打开一个记事本,然后启动程序

Notepad Hook
打开一个文本文件

Notepad Hook

修改一下然后保存

Notepad Hook 

去到我的文档文件夹下

Notepad Hook 

可以看到生成了4个文件,第一个是释放的DLL文件,第二个是自我复制的文件,后两个就是获取的信息了,打开看看

Notepad Hook

可以看到除了有我们打开的那个文件,还有其他一些乱七八糟的,这可能是ReadFile这个函数调用时都被钩取了。

Notepad Hook

这里面就很干净了,保存的是修改后的文本。

注意测试完成后要删除注册表启动项哦

Notepad Hook

0x09 总结

复习了下Windows API吧。。。