在自己品读了kanxue大哥的加密解密之后,不禁想在论坛上写篇这样的文章.大伙都知道,在windows下当一个可执行文件运行时,Windows加载器将可执行模块映射到进程的地址空间中,加载器分析可执行模块的输入表,并设法找出任何需要的DLL,并将它们映射到进程的地址空间中。由于输入表是根据DLL名来进行查找,首先是查找当前目录下有没这文件,没有话在去查找系统目录C:\\Windows\\system32有没这文件,所以我们可以完全趁这个机会去劫持DLL,把他劫持下来后就可以在里面进行我们要做的事情。例如:
1.//补丁前,程序运行方式如下
1.//补丁后,程序运行方式如下
为了让我们自己开发的补丁DLL有导出函数,我们可以用 #parma comment(..),如:- #pragma comment(linker, "/EXPORT:testadd=_TESTDLLLIB_testadd,@1")
复制代码 我写了个DLL,分别是补丁前和补丁后,我把代码贴出来,大家可以自己研究研究。
1.补丁前DLL。- //tstDll.dll 补丁前
- //By symanli
- #include "stdafx.h"
- #include "dll.h"
- BOOL APIENTRY DllMain( HANDLE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved
- )
- {
- return TRUE;
- }
- //原始函数
- int testadd(int a,int b)
- {
- ::MessageBox(NULL,"这是补丁前的DLL","TODO",MB_OK);
- return a+b;
- }
复制代码 2.补丁后- //这是补丁代码。by symanli
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // 头文件
- #include <Windows.h>
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // 宏定义
- #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
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // TESTDLLLIB 命名空间
- namespace TESTDLLLIB
- {
- HMODULE m_hModule = NULL; // 原始模块句柄
- DWORD m_dwReturn[1] = {0}; // 原始函数返回地址
-
-
- // 加载原始模块
- inline BOOL WINAPI Load()
- {
- TCHAR tzPath[MAX_PATH];
- TCHAR tzTemp[MAX_PATH * 2];
-
- //将原始DLL名改成其他的名字,我们用LoadLibrary去加载他。
- lstrcpy(tzPath, TEXT("tstDllold.dll"));
- 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];
-
- 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 TESTDLLLIB;
- // 入口函数
- BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
- {
- if (dwReason == DLL_PROCESS_ATTACH)
- {
- DisableThreadLibraryCalls(hModule);
-
- for (INT i = 0; i < sizeof(m_dwReturn) / sizeof(DWORD); i++)
- {
- m_dwReturn[i] = TlsAlloc();
- }
-
- return Load();
- }
- else if (dwReason == DLL_PROCESS_DETACH)
- {
- for (INT i = 0; i < sizeof(m_dwReturn) / sizeof(DWORD); i++)
- {
- TlsFree(m_dwReturn[i]);
- }
-
- Free();
- }
-
- return TRUE;
- }
- // 导出函数
- ALCDECL TESTDLLLIB_testadd(void)
- {
- ::MessageBox(NULL,"这是补丁后的DLL","TODO",MB_OK);
- // 保存返回地址到 TLS
- //__asm PUSH m_dwReturn[0 * TYPE long];
- //__asm CALL DWORD PTR [TlsSetValue];
-
- // 调用原始函数
- GetAddress("testadd");
- __asm JMP EAX;
- // 获取返回地址并返回
- // __asm PUSH EAX;
- // __asm PUSH m_dwReturn[0 * TYPE long];
- // __asm CALL DWORD PTR [TlsGetValue];
- // __asm XCHG EAX, [ESP];
- // __asm RET;
- }
- #pragma comment(linker, "/EXPORT:testadd=_TESTDLLLIB_testadd,@1")
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
复制代码- //exe调用代码
- #pragma comment(lib,"tstDll.lib")//导入先前DLL的lib,就是最原始的LIB
- void CTstExeDlg::OnButton1()
- {
- // TODO: Add your control notification handler code here
- int _sum =testadd(10,20);
- CString szSum;
- szSum.Format("结果是:[%d]",_sum);
- AfxMessageBox(szSum);
- }
复制代码 3.结果
1.补丁前:
2.补丁后
别的我就不多了。我写了个例子程序,可以下载来研究下。大家通过这种原理可以做出类似劫持其他应用程序的程序。希望斑竹加精哦。哈哈
|