[DLL劫持] 3 DLL劫持之实践 例子
来源:互联网 发布:c语言输出ascii码 编辑:程序博客网 时间:2024/05/16 17:50
该系列文章是依据本人平时对动态链接库的学习,归纳总结,所做的学习笔记。如有错误或待改善之处,请留下您宝贵的意见或建议。
先说说DLL劫持的原理吧,以下这段来自百度百科对DLL劫持原理的说明:
由于输入表中只包含DLL名而没有它的路径名,因此加载程序必须在磁盘上搜索DLL文件。首先会尝试从当前程序所在的目录加载DLL,如果没找到,则在Windows系统目录中查找,最后是在环境变量中列出的各个目录下查找。利用这个特点,先伪造一个系统同名的DLL,提供同样的输出表,每个输出函数转向真正的系统DLL。程序调用系统DLL时会先调用当前目录下伪造的DLL,完成相关功能后,再跳到系统DLL同名函数里执行。这个过程用个形象的词来描述就是系统DLL被劫持(hijack)了。
利用这种方法取得控制权后,可以对主程序进行补丁。此种方法只对除kernel32.dll、ntdll.dll等核心系统库以外的DLL有效,如网络应用程序的ws2_32.dll、游戏程序中的d3d8.dll,还有大部分应用程序都调用的lpk.dll、sxs.dll,这些DLL都可被劫持。
伪造的dll制作好后,放到程序当前目录下,这样当原程序调用原函数时就调用了伪造的dll的同名函数,进入劫持DLL的代码,处理完毕后,再调用原DLL此函数。
这种补丁技术,对加壳保护的软件很有效,选择挂接的函数最好是在壳中没有被调用的,当挂接函数被执行时,相关的代码已被解压,可以直接补丁了。在有些情况下,必须用计数器统计挂接的函数的调用次数来接近OEP。此方法巧妙地绕过了壳的复杂检测,很适合加壳程序的补丁制作。
一些木马或病毒也会利用DLL劫持技术搞破坏,因此当在应用程序目录下发现系统一些DLL文件存在时,如lpk.dll,应引起注意。
下面就通过一个简单的例子,来实现一下DLL劫持:
1. 生成原始的DLL
创建一个dllTest工程,添加lib.h和lib.cpp文件:
Lib.h
#ifndef LIB_H#define LIB_Hextern "C" int __declspec(dllexport)add(int x, int y);#endif
Lib.cpp
#include "lib.h"int add(int x, int y){return x + y;}
编译生成dllTest.dll。
2. 编写应用程序(采用动态加载方式)
新建工程dllcall,添加文件dllcall.cpp,修改调用目录,生成,测试,ok!
(隐式方式:使用原来的.lib文件,使用之后的dll)
Dllcall.cpp
// dllCall.cpp : 以显式方式调用DLL#include <stdio.h>#include "windows.h"typedef int ( * lpAddFun)(int,int);int main(int argc, char* argv[]){ HINSTANCE hDll; //DLL句柄lpAddFun addFun; //函数指针 hDll = LoadLibrary("..\\Release\\dllTest.dll");if (hDll != NULL){addFun = (lpAddFun)GetProcAddress(hDll,"add");if(addFun!=NULL){ int result = addFun(2,3); printf("%d",result);}FreeLibrary(hDll);}system("pause");return 0;}
3. 使用AheadLib反编译DLL
使用工具AheadLib.exe,反编译dllTest.dll,生成dllTest.cpp,新建dll工程,编译该cpp,生成第二个dllTest.dll。
DllText.cpp
// 头文件#include <Windows.h>// 导出函数#pragma comment(linker, "/EXPORT:add=_AheadLib_add,@1")// 宏定义#define EXTERNC extern "C"#define NAKED __declspec(naked)#define EXPORT __declspec(dllexport)#define ALCPP EXPORT NAKED#define ALSTD EXTERNC EXPORT NAKED void __stdcall#define ALCFAST EXTERNC EXPORT NAKED void __fastcall#define ALCDECL EXTERNC NAKED void __cdecl// Hook 命名空间namespace Hook{HHOOK m_hHook;// HOOK 句柄// HOOK 函数LRESULT CALLBACK HookProc(INT iCode, WPARAM wParam, LPARAM lParam){if (iCode > 0){;}return CallNextHookEx(m_hHook, iCode, wParam, lParam);}// Hookinline BOOL WINAPI Hook(INT iHookId = WH_CALLWNDPROC){m_hHook = SetWindowsHookEx(iHookId, HookProc, NULL, GetCurrentThreadId());return (m_hHook != NULL);}// Unhookinline VOID WINAPI Unhook(){if (m_hHook){UnhookWindowsHookEx(m_hHook);}}}// AheadLib 命名空间namespace AheadLib{HMODULE m_hModule = NULL;// 原始模块句柄DWORD m_dwReturn[1] = {0};// 原始函数返回地址// 加载原始模块inline BOOL WINAPI Load(){TCHAR tzPath[MAX_PATH];TCHAR tzTemp[MAX_PATH * 2];lstrcpy(tzPath, TEXT("dllTestOrg"));///这一句是为了证明我的ws2_32.dll能被执行MessageBox(NULL, tzPath, TEXT("DLL Path"), MB_ICONSTOP);m_hModule = LoadLibrary(tzPath);if (m_hModule == NULL){wsprintf(tzTemp, TEXT("无法加载 %s,程序无法正常运行。"), tzPath);MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);}return (m_hModule != NULL);}// 释放原始模块inline VOID WINAPI Free(){if (m_hModule){FreeLibrary(m_hModule);}}// 获取原始函数地址FARPROC WINAPI GetAddress(PCSTR pszProcName){FARPROC fpAddress;CHAR szProcName[16];TCHAR tzTemp[MAX_PATH];if (m_hModule == NULL){if (Load() == FALSE){ExitProcess(-1);}}fpAddress = GetProcAddress(m_hModule, pszProcName);if (fpAddress == NULL){if (HIWORD(pszProcName) == 0){wsprintf(szProcName, "%d", pszProcName);pszProcName = szProcName;}wsprintf(tzTemp, TEXT("无法找到函数 %hs,程序无法正常运行。"), pszProcName);MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);ExitProcess(-2);}return fpAddress;}}using namespace AheadLib;// 入口函数BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved){if (dwReason == DLL_PROCESS_ATTACH){DisableThreadLibraryCalls(hModule);Hook::Hook();}else if (dwReason == DLL_PROCESS_DETACH){Free();Hook::Unhook();}return TRUE;}// 导出函数ALCDECL AheadLib_add(void){GetAddress("add");__asm JMP EAX;}
重新使用之前的应用程序测试
将第二个自己生成的dll替代原来的dll,将原来的dll名改成dllTestOrg.dll,放入相应的目录,测试,OK!
5. Dll劫持成功
附件:
AheadLib.exe的下载地址:http://download.csdn.net/detail/u010311064/7626887
本文的所有代码下载地址:http://download.csdn.net/detail/u010311064/7626907
- [DLL劫持] 3 DLL劫持之实践 例子
- dll劫持
- [DLL劫持] 1 DLL劫持之DLL基础(1)
- [DLL劫持] 2 DLL劫持之DLL基础(2)
- DLL注入 之线程劫持
- DLL劫持技术
- 如何防止DLL劫持
- DLL劫持防御策略
- DLL劫持防御策略
- dll劫持技术
- DLL劫持技术
- DLL劫持备忘录
- DLL补丁劫持制作
- DLL劫持漏洞原理
- DLL劫持的发展历程
- DLL劫持漏洞技术原理
- Hex workshop DLL劫持洞洞
- WIN7下DLL劫持,注入
- 性能测试面试题
- 通配符和正则表达式联系和区别
- cas入门之二十七:person directory(中)
- 好的师傅就是的离开回家开发
- Spiral Matrix II
- [DLL劫持] 3 DLL劫持之实践 例子
- 正确处理好工作任务和自身技术发展的关系
- 树与二叉树
- 使用Java8提供的Duration类制作字幕时间轴调整工具
- java 数组初始化
- C++的前置声明
- 使用一个天枰称量100g以下的任意整数重量最少需要多少砝码?每个砝码多少克?(砝码永远只能放在天枰的一边,每个砝码的重量必须是整数)
- 黑马程序员_交通灯控制系统
- bfs学习