*/
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <psapi.h>#pragma comment(lib, "Psapi.lib")#define __printf printfvoid HideLibrary(HMODULE hModule, LPVOID pCallBackAddr, LPVOID lParam);typedef struct
{
HMODULE lpDllBase;
LPVOID lpNewDllBase;
PTHREAD_START_ROUTINE pAddress;
LPVOID lParam;
}UNLOADLIB_CALLBACK, *PUNLOADLIB_CALLBACK;typedef
LPVOID WINAPI VIRTUALALLOC(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
);typedef
BOOL WINAPI VIRTUALFREE(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD dwFreeType
);
typedef
BOOL WINAPI HEAPDESTROY(
HANDLE hHeap
);typedef
HMODULE WINAPI LOADLIBRARY(
LPCTSTR lpFileName
);typedef
HANDLE WINAPI CREATETHREAD(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);typedef void * __cdecl MEMCPY(void *, const void *, size_t);
BOOL incLibraryCount(HMODULE hMe)
{
//FreeLibrary后很多系统dll也会free掉,所以将所有已加载的再load一次以增加计数
HANDLE hModsSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0); if(INVALID_HANDLE_VALUE == hModsSnap)
{
return FALSE;
} MODULEENTRY32 meModuleEntry;
meModuleEntry.dwSize = sizeof(MODULEENTRY32); if(!Module32First(hModsSnap, &meModuleEntry))
{
CloseHandle(hModsSnap);
return FALSE;
}
do
{
if(LoadLibrary(meModuleEntry.szModule) == hMe)
FreeLibrary(hMe); } while(Module32Next(hModsSnap, &meModuleEntry)); CloseHandle(hModsSnap); return TRUE;
}//枚举指定进程的所有线程
DWORD WINAPI EnumAndSetThreadState(LPVOID lParam)
{
HANDLE hThreadSnap = NULL;
THREADENTRY32 te32;
memset(&te32,0,sizeof(te32));
te32.dwSize = sizeof(THREADENTRY32);
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0); DWORD myThreadId = GetCurrentThreadId();
DWORD pid = GetCurrentProcessId(); if (Thread32First(hThreadSnap, &te32))
{
do
{
if (pid == te32.th32OwnerProcessID)
{
if(myThreadId != te32.th32ThreadID)
{
HANDLE hThread = OpenThread(
THREAD_SUSPEND_RESUME,
FALSE,
te32.th32ThreadID); if(hThread != NULL)
{
if((int)lParam)
ResumeThread(hThread);
else
SuspendThread(hThread); CloseHandle(hThread);
}
}
}
}
while (Thread32Next(hThreadSnap,&te32));
}
CloseHandle( hThreadSnap ); return 0;
}DWORD WINAPI GotoCallBackAddr(LPVOID lParam)
{
PUNLOADLIB_CALLBACK cbFunc = (PUNLOADLIB_CALLBACK)lParam; DWORD dwThreadId;
HANDLE hThread; if(cbFunc->pAddress)
{
hThread = CreateThread(
NULL,
0,
cbFunc->pAddress,
cbFunc->lParam,
0,
&dwThreadId); if(hThread)
CloseHandle(hThread);
} //那份dll的拷贝不需要了,释放~
VirtualFree(cbFunc->lpNewDllBase, 0, MEM_DECOMMIT);
delete cbFunc; return 0;
}
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <psapi.h>#pragma comment(lib, "Psapi.lib")#define __printf printfvoid HideLibrary(HMODULE hModule, LPVOID pCallBackAddr, LPVOID lParam);typedef struct
{
HMODULE lpDllBase;
LPVOID lpNewDllBase;
PTHREAD_START_ROUTINE pAddress;
LPVOID lParam;
}UNLOADLIB_CALLBACK, *PUNLOADLIB_CALLBACK;typedef
LPVOID WINAPI VIRTUALALLOC(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
);typedef
BOOL WINAPI VIRTUALFREE(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD dwFreeType
);
typedef
BOOL WINAPI HEAPDESTROY(
HANDLE hHeap
);typedef
HMODULE WINAPI LOADLIBRARY(
LPCTSTR lpFileName
);typedef
HANDLE WINAPI CREATETHREAD(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);typedef void * __cdecl MEMCPY(void *, const void *, size_t);
BOOL incLibraryCount(HMODULE hMe)
{
//FreeLibrary后很多系统dll也会free掉,所以将所有已加载的再load一次以增加计数
HANDLE hModsSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0); if(INVALID_HANDLE_VALUE == hModsSnap)
{
return FALSE;
} MODULEENTRY32 meModuleEntry;
meModuleEntry.dwSize = sizeof(MODULEENTRY32); if(!Module32First(hModsSnap, &meModuleEntry))
{
CloseHandle(hModsSnap);
return FALSE;
}
do
{
if(LoadLibrary(meModuleEntry.szModule) == hMe)
FreeLibrary(hMe); } while(Module32Next(hModsSnap, &meModuleEntry)); CloseHandle(hModsSnap); return TRUE;
}//枚举指定进程的所有线程
DWORD WINAPI EnumAndSetThreadState(LPVOID lParam)
{
HANDLE hThreadSnap = NULL;
THREADENTRY32 te32;
memset(&te32,0,sizeof(te32));
te32.dwSize = sizeof(THREADENTRY32);
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0); DWORD myThreadId = GetCurrentThreadId();
DWORD pid = GetCurrentProcessId(); if (Thread32First(hThreadSnap, &te32))
{
do
{
if (pid == te32.th32OwnerProcessID)
{
if(myThreadId != te32.th32ThreadID)
{
HANDLE hThread = OpenThread(
THREAD_SUSPEND_RESUME,
FALSE,
te32.th32ThreadID); if(hThread != NULL)
{
if((int)lParam)
ResumeThread(hThread);
else
SuspendThread(hThread); CloseHandle(hThread);
}
}
}
}
while (Thread32Next(hThreadSnap,&te32));
}
CloseHandle( hThreadSnap ); return 0;
}DWORD WINAPI GotoCallBackAddr(LPVOID lParam)
{
PUNLOADLIB_CALLBACK cbFunc = (PUNLOADLIB_CALLBACK)lParam; DWORD dwThreadId;
HANDLE hThread; if(cbFunc->pAddress)
{
hThread = CreateThread(
NULL,
0,
cbFunc->pAddress,
cbFunc->lParam,
0,
&dwThreadId); if(hThread)
CloseHandle(hThread);
} //那份dll的拷贝不需要了,释放~
VirtualFree(cbFunc->lpNewDllBase, 0, MEM_DECOMMIT);
delete cbFunc; return 0;
}
DWORD WINAPI UnLoadLibrary(LPVOID lParam)
{
//__asm INT 3
__printf("UnLoadLibrary Entry.\r\n"); BYTE HeapDestroy_HookCode_bak[4];
BYTE HeapDestroy_HookCode[4] = "\xC2\x04\x00";//RETN 0004
MODULEINFO modinfo;
DWORD oldProtect; PUNLOADLIB_CALLBACK cbFunc = (PUNLOADLIB_CALLBACK)lParam; HMODULE hDllInstance = cbFunc->lpDllBase;
char dllpath_bak[MAX_PATH]; GetModuleFileName(hDllInstance, dllpath_bak, sizeof(dllpath_bak));
GetModuleInformation(GetCurrentProcess(), hDllInstance, &modinfo, sizeof(MODULEINFO)); //给所有dll(除了自己)增加计数,防止FreeLibrary的时候那些dll给系统卸载掉
incLibraryCount(hDllInstance); //保险起见,挂起其他线程,搞定后再恢复
EnumAndSetThreadState((LPVOID)FALSE); //FreeLibrary之后原来存放api地址的内存也会被释放,
//但是FreeLibrary之后还有些动作,趁现在还没free,关键API记下来
VIRTUALALLOC *_VirtualAlloc = (VIRTUALALLOC*)
GetProcAddress(GetModuleHandle("kernel32.dll"), "VirtualAlloc");
LOADLIBRARY *_LoadLibrary = (LOADLIBRARY*)
GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
CREATETHREAD *_CreateThread = (CREATETHREAD*)
GetProcAddress(GetModuleHandle("kernel32.dll"), "CreateThread");
MEMCPY *_memcpy = (MEMCPY*)
GetProcAddress(GetModuleHandle("ntdll.dll"), "memcpy"); //这个很关键,并不是我要调用,是 FreeLibrary 时系统会调用,我要hook它,
//不能给系统破坏这个heap,否则之后的dll貌似能工作,
//但却不能用new或malloc申请内存, VirtualAlloc可以代替之,
//但如果改写好多代码是划不来的,况且一些代码不好改,如list<T>的push内部的new HEAPDESTROY *_HeapDestroy = (HEAPDESTROY*)
GetProcAddress(GetModuleHandle("kernel32.dll"), "HeapDestroy"); VirtualProtect(_HeapDestroy, 3, PAGE_EXECUTE_READWRITE, &oldProtect); //修改第一条指令为直接返回
_memcpy(HeapDestroy_HookCode_bak, _HeapDestroy, 3);
_memcpy(_HeapDestroy, HeapDestroy_HookCode, 3);
//Sleep(100);
//终于到这里了~~~^_^!
FreeLibrary(hDllInstance);//释放 //修复刚hook的函数
_memcpy(_HeapDestroy, HeapDestroy_HookCode_bak, 3);
//_memcpy(_RtlFreeHeap, RtlFreeHeap_HookCode_bak, 3); //在原来的dll基址申请同样大小的内存,并把之前的那份dll拷贝还原回去
if(_VirtualAlloc(hDllInstance,
modinfo.SizeOfImage,
MEM_COMMIT|MEM_RESERVE,
PAGE_EXECUTE_READWRITE) == NULL
)
{
//失败,加载原来dll, 以正常方式工作
//注意,不宜在dllmain中调用HideLibrary,LoadLibrary将导致dllmain再次被调用,导致死循环啦
HMODULE hDll = _LoadLibrary(dllpath_bak); //重新计算回调函数在hDll地址空间的地址
cbFunc->pAddress = (LPTHREAD_START_ROUTINE)
((DWORD)cbFunc->pAddress - (DWORD)hDllInstance + (DWORD)hDll); LPTHREAD_START_ROUTINE pFunc1 = (LPTHREAD_START_ROUTINE)
((DWORD)EnumAndSetThreadState - (DWORD)hDllInstance + (DWORD)hDll); //恢复被挂起的线程
_CreateThread(0, 0, pFunc1, (LPVOID)TRUE, 0, 0); //调用回调函数
if(cbFunc->pAddress)
_CreateThread(0, 0, cbFunc->pAddress, cbFunc->lParam, 0, 0); return 0;
} _memcpy(hDllInstance, cbFunc->lpNewDllBase, modinfo.SizeOfImage); //恢复被挂起的线程
EnumAndSetThreadState((LPVOID)TRUE); //跳回原dll地址空间的GotoCallBackAddr,由它来释放这边VirtualAlloc申请的指针
_CreateThread(0, 0, GotoCallBackAddr, cbFunc, 0, 0); return 0;
}DWORD WINAPI HideLibrary02(LPVOID lParam)
{
//__asm INT 3
__printf("HideLibrary02 Entry.\r\n"); PUNLOADLIB_CALLBACK cbFunc = (PUNLOADLIB_CALLBACK)lParam; MODULEINFO modinfo; GetModuleInformation(GetCurrentProcess(), cbFunc->lpDllBase, &modinfo, sizeof(MODULEINFO)); //申请一块和当前dll同样大小的内存
cbFunc->lpNewDllBase = VirtualAlloc(NULL, modinfo.SizeOfImage, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE); if(cbFunc->lpNewDllBase == NULL)
return FALSE; //给当前dll做份拷贝,复制所有数据到刚申请的内存,
memcpy(cbFunc->lpNewDllBase, modinfo.lpBaseOfDll, modinfo.SizeOfImage); //计算在copy中UnLoadLibrary的地址,并另起线程到该地址执行
void *pNewUnLoadLibrary = LPVOID((DWORD)cbFunc->lpNewDllBase + (DWORD)UnLoadLibrary - (DWORD)modinfo.lpBaseOfDll); DWORD ThreadId;
HANDLE hThread = CreateThread(0,0,
(LPTHREAD_START_ROUTINE)pNewUnLoadLibrary, (LPVOID)cbFunc, CREATE_SUSPENDED, &ThreadId); if(hThread == NULL)
{
VirtualFree(cbFunc->lpNewDllBase, 0, MEM_DECOMMIT);
delete cbFunc; return FALSE;
} ResumeThread(hThread);
CloseHandle(hThread); return TRUE;
}
void HideLibrary(HMODULE hModule, LPVOID pCallBackAddr, LPVOID lParam)
{
__printf("HideLibrary Entry.\r\n"); PUNLOADLIB_CALLBACK lparam = new UNLOADLIB_CALLBACK; lparam->lpDllBase = hModule;
lparam->lpNewDllBase = NULL;
lparam->pAddress = (PTHREAD_START_ROUTINE)pCallBackAddr;
lparam->lParam = lParam; HANDLE hThread = CreateThread(0,0,
HideLibrary02, (LPVOID)lparam, 0, NULL); if(hThread == NULL)
{
__printf("CreateThread HideLibrary02 Failed.\r\n"); delete lparam;
return;
} CloseHandle(hThread); return;
}///////////////////////////////////////////////////////////
//example
//rundll32 UnloadLibrary.dll,TestDWORD WINAPI testThread(LPVOID lParam)
{
char *ptest = new char[512]; sprintf(ptest, "My Pid: %d\r\n 用一些软件查看下,找不到这个dll吧?", GetCurrentProcessId()); MessageBox(0, ptest, (char*)lParam, 0); delete ptest; return 0;
}
DWORD WINAPI testThread02(LPVOID lParam)
{ HMODULE hModule = (HMODULE)lParam;
char *ptest = new char[512]; sprintf(ptest, "testThread02\r\n"); Sleep(500); MessageBox(0, ptest, "start", 0); //不设置回调函数,成功还好,一旦失败则gameover
HideLibrary(hModule, 0, 0); sprintf(ptest, "My Pid: %d\r\n 用一些软件查看下,找不到这个dll吧?", GetCurrentProcessId());
MessageBox(0, ptest, "ok", 0);
delete ptest; return 0;
}HMODULE hDll;
extern "C"
{
__declspec(dllexport) int Test();
}int Test()
{
//1
//主要线程开始工作后再HideLibrary不是很安全
//CreateThread(0, 0, testThread02, hDll, 0, 0);
//
//2
//free掉dll后再开启主要工作线程妥当些
char *p = strdup("hello");
HideLibrary(hDll, testThread, p); Sleep(60000); return 0;
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
hDll = (HMODULE)hModule; }
break; }
return TRUE;
}
LZ应该知道并非所有的C++程序都能翻译成VB程序,C++的数据结构远比VB复杂得多。比如链表,即使用VB写出来,也非常复杂,得不偿失!