Notepad Hook
0x00 前言
昨天花了半天写了个四不像的玩意儿,本来打算以恶意代码的方式去写,但今天不怎么想完 善功能了,所以全局hook和自删除之类的就没有了(其实是debug太麻烦。),结果就是这 个程序很沙雕,你必须先打开记事本再运行它才行。不过获取记事本信息是没什么问题的。
0x01 行为
完全是想到什么写什么,所以有些功能完全没发挥作用呢。。 PS:这里所有生成的文件都存放在你的C:/User/username/Documents/文件夹下。
- 要注入的DLL文件以资源的形式嵌在启动器中,首先将其释放到文件夹下,名为 notepadhook.dll
- 复制启动器自身到文件夹下
- 将复制的启动器路径添加到注册表的自启动项中
- 枚举进程快照,找到notepad.exe,将DLL文件注入
- 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 测试
首先打开一个记事本,然后启动程序
打开一个文本文件
修改一下然后保存
去到我的文档文件夹下
可以看到生成了4个文件,第一个是释放的DLL文件,第二个是自我复制的文件,后两个就是获取的信息了,打开看看
可以看到除了有我们打开的那个文件,还有其他一些乱七八糟的,这可能是ReadFile这个函数调用时都被钩取了。
这里面就很干净了,保存的是修改后的文本。
注意测试完成后要删除注册表启动项哦
0x09 总结
复习了下Windows API吧。。。