打补丁?怎么少得了dll注入

dll注入的方法还是挺多的,dll替换,注册表等等,来说说比较常用的一种吧

这个方法不仅适用dll注入,inline Hook同样适用

既然是DLL注入,就需要写一个DLL,这个DLL的代码会在被注入的进程中运行,我的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
MessageBoxA(NULL, "I am dll.", "I am dll", 0);
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

当DLL被加载时,会进行弹窗,仅此而已

在开始之前需要先了解一下,关于窗口和进程的知识

  • 每个进程都有一个标识,这个我们都知道,特点是每次启动的值都不一样

  • 每个窗口也会有一个标识,和进程一样每次启动的值都不一样

那么所谓的DLL注入,就是在目标进程上开辟一个线程,并调用LoadLibrary

想在别的进程上创建一个线程,就需要这个进程的句柄

获取这个句柄就需要它的PID

而PID每次启动的值都不一样,那么每次注入都要看一眼PID?有些麻烦

这个时候窗口标识就需要用到了,可以通过窗口句柄获取到进程的PID

而获取窗口句柄需要窗口的标题和类名,这两个内容,可以通过spy++来找到

1572008641838

如上图,只需要拖动1572008662314到目标窗口上去就好了

来看代码把,把窗口句柄转换为进程ID:

1
2


当然你也可以使用遍历所有窗口的方式进行筛选,实现的方式可不止这一个

获取到窗口句柄,就可以创建远程线程了

在创建线程的时候,需要一个函数地址,和一个函数参数

只需要一个参数?有没有想到LoadLibrary函数,这个函数只需要一个参数

也就是说我们完全可以使用LoadLibrary的地址来作为线程地址

那么LoadLibrary函数还需要一个参数,既然是在别的进程上创建线程,那么参数的内容也要在目标进程中,我们要在目标进程上开辟内存空间并写入参数值:

1
2
3
4
// 在目标进程分配内存,内存大小为参数的大小
VOID *pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
//将参数值写入到目标进程中
WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)pFilePath, dwBufSize, NULL);

参数写进去了,还需要LoadLibrary的地址,就可以创建远程线程了:

1
2


函数的地址有了,参数的地址有了,可以创建远程线程了:

1
2


来看看效果:

1572009493193

1572009373345

注入成功

Author: YuanBi
Link: https://www.basicbit.cn/2018/11/16/2018-11-17-DLL注入/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.