我们要模拟写一个LPK.DLL,它与系统目录下的LPK.DLL导出表相同,并能加载系统目录下的LPK.DLL,并且能将导出表转发到真实的LPK.DLL
LPK.DLL比较特殊,在导入表中有一项不是函数是数据,因此数据这部分要单独处理。核心代码如下:
LpkEditControl这个数组有14个成员,如上定义即可,后面我们还需要将真正的数据复制过来。
1.加载系统目录下的LPK.DLL。关键: 使用LoadLibrary方式加载系统目录下的LPK.DLL。加载完成后就要实现导出函数的转发了
2.
获得原函数地址
3.
将我们构造的导出函数转发
4.在DLL初始化函数中加载我们要注入远程进程的代码:
5.测试,在Init中加入测试代码,把lpk复制到待测试软件同目录下,比如我们的记事本,notepad
1、构造一个与系统目录下LPK.DLL一样的导出表
2、加载系统目录下的LPK.DLL
3、将导出函数转发到系统目录下的LPK.DLL上
4、在初始化函数中加入我们要执行的代码
首先是定义导出函数
- #pragma comment(linker, "/EXPORT:LpkInitialize=_AheadLib_LpkInitialize,@1")
- #pragma comment(linker, "/EXPORT:LpkTabbedTextOut=_AheadLib_LpkTabbedTextOut,@2")
- #pragma comment(linker, "/EXPORT:LpkDllInitialize=_AheadLib_LpkDllInitialize,@3")
- #pragma comment(linker, "/EXPORT:LpkDrawTextEx=_AheadLib_LpkDrawTextEx,@4")
- //#pragma comment(linker, "/EXPORT:LpkEditControl=_AheadLib_LpkEditControl,@5")
- #pragma comment(linker, "/EXPORT:LpkExtTextOut=_AheadLib_LpkExtTextOut,@6")
- #pragma comment(linker, "/EXPORT:LpkGetCharacterPlacement=_AheadLib_LpkGetCharacterPlacement,@7")
- #pragma comment(linker, "/EXPORT:LpkGetTextExtentExPoint=_AheadLib_LpkGetTextExtentExPoint,@8")
- #pragma comment(linker, "/EXPORT:LpkPSMTextOut=_AheadLib_LpkPSMTextOut,@9")
- #pragma comment(linker, "/EXPORT:LpkUseGDIWidthCache=_AheadLib_LpkUseGDIWidthCache,@10")
- #pragma comment(linker, "/EXPORT:ftsWordBreak=_AheadLib_ftsWordBreak,@11")
- EXTERNC void __cdecl AheadLib_LpkEditControl(void);
- EXTERNC __declspec(dllexport) void (*LpkEditControl[14])() = {AheadLib_LpkEditControl};
1.加载系统目录下的LPK.DLL。关键: 使用LoadLibrary方式加载系统目录下的LPK.DLL。加载完成后就要实现导出函数的转发了
- inline BOOL WINAPI Load()
- {
- TCHAR tzPath[MAX_PATH];
- TCHAR tzTemp[MAX_PATH * 2];
- GetSystemDirectory(tzPath, MAX_PATH);
- lstrcat(tzPath, TEXT("\\lpk"));
- m_hModule=LoadLibrary(tzPath);
- if (m_hModule == NULL)
- {
- wsprintf(tzTemp, TEXT("无法加载 %s,程序无法正常运行。"), tzPath);
- MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
- };
- return (m_hModule != NULL);
- }
- 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;
- }
- // 导出函数
- ALCDECL AheadLib_LpkInitialize(void)
- {
- GetAddress("LpkInitialize");
- __asm JMP EAX;
- }
- ALCDECL AheadLib_LpkGetTextExtentExPoint(void)
- {
- GetAddress("LpkGetTextExtentExPoint");
- __asm JMP EAX;
- }
- .......................................太长了,请直接看源码附件
- BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
- {
- if (dwReason == DLL_PROCESS_ATTACH)
- {
- DisableThreadLibraryCalls(hModule);
- if(Load())
- {
- //LpkEditControl这个数组有14个成员,必须将其复制过来
- memcpy((LPVOID)(LpkEditControl+1), (LPVOID)((int*)GetAddress("LpkEditControl") + 1),52);
- _beginthread(Init,NULL,NULL);
- }
- else
- return FALSE;
- }
- else if (dwReason == DLL_PROCESS_DETACH)
- {
- Free();
- }
- return TRUE;
- }