还是那句话,你不是搞外挂你隐藏什么dll?
干 货 需 要 拉 到 最 下 面
本文章仅用于交流学习
1.何为DLL?
动态链接库英文为DLL,是Dynamic Link Library的缩写。DLL是一个包含可由多个程序,同时使用的代码和数据的库。例如,在 Windows 操作系统中,Comdlg32.dll 执行与对话框有关的常见函数。因此,每个程序都可以使用该 DLL 中包含的功能来实现“打开”对话框。这有助于避免代码重用和促进内存的有效使用。
通过使用 DLL,程序可以实现模块化,由相对独立的组件组成。例如,一个计帐程序可以按模块来销售。可以在运行时将各个模块加载到主程序中(如果安装了相应模块)。因为模块是彼此独立的,所以程序的加载速度更快,而且模块只在相应的功能被请求时才加载。
总而言之就是DLL这种技术可以使得程序模块化,同时让程序加载速度更快。
2.为啥要隐藏DLL?
一句话总结:没做啥坏事,干嘛隐藏自己呢?所以隐藏了自己,那有很大的可能性是要做坏事:
1.木马以DLL形式注入进正常进程并隐藏自己,导致无法追踪溯源,如键盘记录木马,感染型木马
2.游戏外挂通过该种方式躲避游戏自身的“模块检测”,如DXF的第三方木马检测
除了坏事儿之外,在一些常见的攻防对抗中,如若用到windows木马,不仅要注意免杀工作,有时也需要通过该技术实现持久性隐藏攻击。
3.DLL隐藏常见手法
一.手动载入
所谓手动载入就是自己去实现LoadLibrary函数,从理论上讲,这种方法隐藏效果是最棒的,但是实现一个基本的PEloader并不是一件容易的事情,如果还要考虑兼容性完美,就必须还得妥善处理TLS,资源,线程等问题。(不太易上手)
二.痕迹消除
这个就比较好说了,我们在注入DLL的时候,通常要选择去调用 LoadLibrary函数,然后再擦除痕迹,这样不用去处理那些TLS,资源,线程等为了解决兼容性产生的问题。但是Windows大家都清楚,表面风平浪静,背地里风起云涌,说不准现在你电脑的XXX安全卫士正在对你的电脑做些什么呢,这些都是你不通过技术手段看不到的东西,实际上没有什么好的方法把痕迹真正的消除。
以DLL擦除痕迹为例,网上大多数的方法都是通过PEB双向断链,需要很多的硬编码,麻烦不说,通过内存暴力搜索还是会露出尾巴来
攻防无绝对,攻防本身就是一个提升本身技术的过程,只要能够通过一个比较合适的方法,实现相应的功能,便具有可行性。
4.DLL编写与注入测试
一.DLL编写:
①.于vs中创建一个空的项目。
②.添加C语言代码如下:
BOOL WINAPI DllMain(HMODULE hDll, DWORD dwReason, LPVOID lpReserved)
{
DisableThreadLibraryCalls(hDll);
if (dwReason == DLL_PROCESS_ATTACH)
{
//================================== OPTIONAL =========================================
MessageBoxA(0, "Message Test","Message Title", 0);
}
return 1;
}
③.同时在项目属性中设置:
由图可见进程中已经注入进入了我们的DLL,且内存地址为0x78EB0000
三.手写代码实现注入
谈完DLL编写和利用工具注入测试,我们来大致了解一下代码实现注入,方法有很多,但原理大致相同,我在这里以线程注入dll为例:
代码编写:
voidInject(int pID, char* Path)
{
//获取进程句柄
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
//申请一块内存给DLL路径
LPVOID pReturnAddress = VirtualAllocEx(hProcess, NULL, strlen(Path) + 1, MEM_COMMIT, PAGE_READWRITE);
//写入路径到上一行代码申请的内存中
WriteProcessMemory(hProcess, pReturnAddress, Path, strlen(Path) + 1, NULL);
//获取LoadLibraryA函数的地址
HMODULE hModule = LoadLibrary("KERNEL32.DLL");
LPTHREAD_START_ROUTINE lpStartAddress = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "LoadLibraryA");
//创建远程线程-并获取线程的句柄
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, lpStartAddress, pReturnAddress, 0, NULL);
//等待线程事件
WaitForSingleObject(hThread, 2000);
//防止内存泄露
CloseHandle(hThread);
CloseHandle(hProcess);
}
intmain()
{
//传dll路径
const char* a = "(传入dll所在路径)";
//传入进程ID
Inject(传入进程id, (char*)a);
return 0;
}
代码解析:
首先,通过调用OpenProcess函数获取目标进程的句柄(hProcess)。OpenProcess函数使用了PROCESS_ALL_ACCESS参数,表示打开进程时拥有最高权限。然后,通过VirtualAllocEx函数在目标进程中申请一块内存(pReturnAddress),用于存储DLL文件路径。接着,使用WriteProcessMemory函数将DLL文件路径写入到刚才申请的内存空间中。
之后,通过调用LoadLibrary函数加载KERNEL32.DLL库,并使用GetProcAddress函数获取LoadLibraryA函数的地址(lpStartAddress)。
接下来,使用CreateRemoteThread函数在目标进程中创建一个远程线程,该线程将在目标进程的上下文中执行lpStartAddress函数,并将pReturnAddress作为参数传递给它。这样,目标进程就会执行LoadLibraryA函数,将DLL文件路径作为参数加载到自己的地址空间中。
最后,通过调用WaitForSingleObject函数等待远程线程事件的发生,直到线程执行完毕或超时。
整个过程完成后,关闭线程和进程句柄,释放相关资源,避免内存泄漏。
根据传入参数,记录我们要传入的数据:
进程ID:xxxx
路径:xxxxxx
而后将两个参数写入到程序对应的位置当中去,生成exe后丢到虚拟机中即可实现dll注入(此步还未复现)
成功注入之后,应该会弹出信息框,通过分析源代码,我们总结了一下注入流程:
1.在别人的程序里开辟内存空间A
2.将 LoadLibrary 函数参数写入A
3.获取LoadLibrary函数地址
4.在别人的程序里远程执行 LoadLibrary实现加载外部DLL
虚拟机中即可实现dll注入(此步还未复现)
成功注入之后,应该会弹出信息框,通过分析源代码,我们总结了一下注入流程:
1.在别人的程序里开辟内存空间A
2.将 LoadLibrary 函数参数写入A
3.获取LoadLibrary函数地址
4.在别人的程序里远程执行 LoadLibrary实现加载外部DLL
由此可见 LoadLibrary很重要,这个玩意竟然实现了注入!
防游戏检测之隐藏DLL技术
注意:以下情节仅作参考,请不要妄图使用这种低级隐藏技术对抗大厂
现在有些游戏对自身程序里的DLL文件都会进行扫描,如果发现多了哪个陌生的dll文件,就会默认为非法程序注入进来了,这时候游戏会掉线,或弹出非法提示!游戏的这种自我进程模块检测给我们的DLL注入型辅助 带来了很大不便,咋办呢,很多时候,DLL注入型辅助要比远程辅助来得方便,难道我们为此放弃DLL注入型外挂么?那有没有一种可以注入辅助DLL到游戏进程后,把辅助DLL自己隐藏起来,不被游戏发现的吗?回答是肯定的:有的!今天就教大家如果在DLL注入到游戏进程里后 隐藏自己的DLL,让所有应用层的程序都无法查询到自己的DLL文件8.5.2 版本开始 易语言的Game-EC 模块里的 DLL_隐藏 命令可以对以上烦恼迎刃而解全部搞定
原文始发于微信公众号(零羊Web):游戏安全-防检测之DLL隐藏
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论