//
typedef void (__stdcall * MYAPI)();
HMODULE lpk_module = NULL;
HMODULE g_module = NULL;
BOOL g_bInit = FALSE;
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _PEB_LDR_DATA
{
ULONG Length;
BOOLEAN Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA,*PPEB_LDR_DATA;
typedef struct _LDR_MODULE
{
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
void* BaseAddress;
void* EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
HANDLE SectionHandle;
ULONG CheckSum;
ULONG TimeDateStamp;
} LDR_MODULE, *PLDR_MODULE;
void ApiInit();
MYAPI pLpkInitialize;
MYAPI pLpkTabbedTextOut;
MYAPI pLpkDllInitialize;
MYAPI pLpkDrawTextEx;
MYAPI pLpkEditControl;
MYAPI pLpkExtTextOut;
MYAPI pLpkGetCharacterPlacement;
MYAPI pLpkGetTextExtentExPoint;
MYAPI pLpkPSMTextOut;
MYAPI pLpkUseGDIWidthCache;
MYAPI pftsWordBreak;
void HideLibrary(HMODULE hModule, LPVOID pCallBackAddr, LPVOID lParam);
typedef struct
{
HMODULE lpDllBase;
LPVOID lpNewDllBase;
}UNLOADLIB_CALLBACK, *PUNLOADLIB_CALLBACK;
typedef
LPVOID WINAPI VIRTUALALLOC(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
);
typedef
BOOL WINAPI HEAPDESTROY(
HANDLE hHeap
);
typedef BOOL WINAPI FREELIBRARY(
HMODULE hLibModule
);
typedef void * __cdecl MEMCPY(void *, const void *, size_t);
DWORD WINAPI xThread(LPVOID lParam)
{
while
(TRUE)
{
Sleep(10000);
MessageBeep(MB_OK);
//
MessageBox(NULL,
"Test"
,
"Test"
, MB_OK);
}
}
DWORD WINAPI UnLoadLibrary(LPVOID lParam)
{
//__asm
INT 3
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));
//FreeLibrary
之后原来存放api地址的内存也会被释放,
//
但是FreeLibrary之后还有些动作,趁现在还没
free
,关键API记下来
VIRTUALALLOC *_VirtualAlloc = (VIRTUALALLOC*)
GetProcAddress(GetModuleHandle(
"kernel32.dll"
),
"VirtualAlloc"
);
MEMCPY *_memcpy = (MEMCPY*)
GetProcAddress(GetModuleHandle(
"ntdll.dll"
),
"memcpy"
);
FREELIBRARY *_FreeLibrary = (FREELIBRARY*)
GetProcAddress(GetModuleHandle(
"kernel32.dll"
),
"FreeLibrary"
);
//
这个很关键,并不是我要调用,是 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
)
{
ExitProcess(0);
}
_memcpy(hDllInstance, cbFunc->lpNewDllBase, modinfo.SizeOfImage);
return
0;
}
DWORD WINAPI HideLibrary02(HMODULE hMod)
{
MODULEINFO modinfo;
UNLOADLIB_CALLBACK cbFunc;
cbFunc.lpDllBase = hMod;
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做份拷贝,复制所有数据到刚申请的内存,
CopyMemory(cbFunc.lpNewDllBase, modinfo.lpBaseOfDll, modinfo.SizeOfImage);
//
计算在copy中UnLoadLibrary的地址,并另起线程到该地址执行
void *pNewUnLoadLibrary = LPVOID((DWORD)cbFunc.lpNewDllBase + (DWORD)UnLoadLibrary - (DWORD)modinfo.lpBaseOfDll);
__asm
{
lea eax, cbFunc
push eax
call pNewUnLoadLibrary
}
VirtualFree(cbFunc.lpNewDllBase, 0, MEM_DECOMMIT);
HANDLE hThread = CreateThread(0,0, xThread, NULL, 0, NULL);
CloseHandle(hThread);
return
TRUE;
}
void Hide(HMODULE hMod)
{
PLIST_ENTRY Head,Cur;
PPEB_LDR_DATA ldr;
PLDR_MODULE ldm;
__asm
{
mov eax , fs:[0x30]
mov ecx , [eax + 0x0c]
//Ldr
mov ldr , ecx
}
Head = &(ldr->InLoadOrderModuleList);
Cur = Head->Flink;
do
{
ldm = CONTAINING_RECORD( Cur, LDR_MODULE, InLoadOrderModuleList);
if
( hMod == ldm->BaseAddress)
{
/*
ldm->InLoadOrderModuleList.Blink->Flink =
ldm->InLoadOrderModuleList.Flink;
ldm->InLoadOrderModuleList.Flink->Blink =
ldm->InLoadOrderModuleList.Blink;
ldm->InInitializationOrderModuleList.Blink->Flink =
ldm->InInitializationOrderModuleList.Flink;
ldm->InInitializationOrderModuleList.Flink->Blink =
ldm->InInitializationOrderModuleList.Blink;
ldm->InMemoryOrderModuleList.Blink->Flink =
ldm->InMemoryOrderModuleList.Flink;
ldm->InMemoryOrderModuleList.Flink->Blink =
ldm->InMemoryOrderModuleList.Blink;
*/
ldm->LoadCount = 1;
//
设置加载次数为1
break
;
}
Cur= Cur->Flink;
}
while
(Head != Cur);
//FreeLibrary
(hMod);
HideLibrary02(g_module);
}
__declspec(naked) void LpkInitialize()
{
__asm
{
pushfd
cmp
g_bInit, 0
jne __init
pushad
call ApiInit
popad
__init:
popfd
jmp dword ptr [pLpkInitialize]
}
}
__declspec(naked) void LpkDllInitialize()
{
__asm
{
pushfd
cmp
g_bInit, 0
jne __init
pushad
call ApiInit
popad
__init:
popfd
jmp dword ptr [pLpkDllInitialize]
}
}
__declspec(naked) void LpkTabbedTextOut(){__asm jmp dword ptr [pLpkTabbedTextOut]}
__declspec(naked) void LpkDrawTextEx(){__asm jmp dword ptr [pLpkDrawTextEx]}
__declspec(naked) void LpkExtTextOut(){__asm jmp dword ptr [pLpkExtTextOut]}
__declspec(naked) void LpkGetCharacterPlacement(){__asm jmp dword ptr [pLpkGetCharacterPlacement]}
__declspec(naked) void LpkGetTextExtentExPoint(){__asm jmp dword ptr [pLpkGetTextExtentExPoint]}
__declspec(naked) void LpkPSMTextOut(){__asm jmp dword ptr [pLpkPSMTextOut]}
__declspec(naked) void LpkUseGDIWidthCache(){__asm jmp dword ptr [pLpkUseGDIWidthCache]}
__declspec(naked) void ftsWordBreak()
{
__asm jmp dword ptr [pftsWordBreak]
__asm nop
__asm nop
__asm nop
__asm nop
}
__declspec(naked) void LpkEditControl()
{
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm nop
__asm _emit 0
__asm _emit 0
__asm _emit 0
__asm _emit 0
}
FARPROC WINAPI MyGetProcAddress(HMODULE ModuleBase, PCHAR pFunctionName)
{
FARPROC pFunctionAddress = NULL;
__try
{
ULONG size = 0;
PIMAGE_EXPORT_DIRECTORY exports =(PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData(ModuleBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size);
ULONG addr = (ULONG)exports-(ULONG)ModuleBase;
PULONG functions =(PULONG)((ULONG) ModuleBase + exports->AddressOfFunctions);
PSHORT ordinals =(PSHORT)((ULONG) ModuleBase + exports->AddressOfNameOrdinals);
PULONG names =(PULONG)((ULONG) ModuleBase + exports->AddressOfNames);
ULONG max_name =exports->NumberOfNames;
ULONG max_func =exports->NumberOfFunctions;
ULONG i;
for
(i = 0; i < max_name; i++)
{
ULONG ord = ordinals[i];
if
(i >= max_name || ord >= max_func)
{
return
NULL;
}
if
(functions[ord] < addr || functions[ord] >= addr + size)
{
if
(strcmp((PCHAR) ModuleBase + names[i], pFunctionName) == 0)
{
pFunctionAddress =(FARPROC)((PCHAR)ModuleBase + functions[ord]);
break
;
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
pFunctionAddress = NULL;
}
return
pFunctionAddress;
}
DWORD g_dwHookGetModuleHandleW = NULL;
__declspec(naked) HMODULE WINAPI _HookGetModuleHandleW(LPCWSTR lpModuleName)
{
__asm
{
mov edi, edi
push ebp
mov ebp, esp
jmp g_dwHookGetModuleHandleW
}
}
HMODULE WINAPI HookGetModuleHandleW(LPCWSTR lpModuleName)
{
if
( !lstrcmpiW(lpModuleName, L
"lpk"
) || !lstrcmpiW(lpModuleName, L
"lpk.dll"
) )
{
return
lpk_module;
}
return
_HookGetModuleHandleW(lpModuleName);
}
DWORD g_dwHookGetProcAddress = NULL;
__declspec(naked) FARPROC WINAPI _HookGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
__asm
{
mov edi, edi
push ebp
mov ebp, esp
mov eax, g_module
cmp
eax, hModule
jne __exit
mov eax, lpk_module
mov hModule, eax
__exit:
jmp g_dwHookGetProcAddress
}
}
void ApiInit()
{
char reallpk[MAX_PATH]={0};
g_module = GetModuleHandleA(
"lpk.dll"
);
GetSystemDirectoryA((LPSTR)reallpk,MAX_PATH);
strcat(reallpk,
"\\lpk.dll"
);
if
(lpk_module=LoadLibraryA(reallpk))
{
pLpkInitialize = (MYAPI) GetProcAddress(lpk_module,
"LpkInitialize"
);
pLpkTabbedTextOut = (MYAPI) GetProcAddress(lpk_module,
"LpkTabbedTextOut"
);
pLpkDllInitialize = (MYAPI) GetProcAddress(lpk_module,
"LpkDllInitialize"
);
pLpkDrawTextEx = (MYAPI) GetProcAddress(lpk_module,
"LpkDrawTextEx"
);
pLpkExtTextOut = (MYAPI) GetProcAddress(lpk_module,
"LpkExtTextOut"
);
pLpkGetCharacterPlacement = (MYAPI) GetProcAddress(lpk_module,
"LpkGetCharacterPlacement"
);
pLpkEditControl = (MYAPI) GetProcAddress(lpk_module,
"LpkEditControl"
);
pLpkGetTextExtentExPoint = (MYAPI) GetProcAddress(lpk_module,
"LpkGetTextExtentExPoint"
);
pLpkPSMTextOut = (MYAPI) GetProcAddress(lpk_module,
"LpkPSMTextOut"
);
pLpkUseGDIWidthCache = (MYAPI) GetProcAddress(lpk_module,
"LpkUseGDIWidthCache"
);
pftsWordBreak = (MYAPI) GetProcAddress(lpk_module,
"ftsWordBreak"
);
CopyMemory((LPVOID)((DWORD)LpkEditControl-4),(PVOID)((DWORD)pLpkEditControl-4),0x44);
}
else
{
ExitProcess(0);
}
Hide(g_module);
//Hide
(g_module);
HMODULE hMod = GetModuleHandleA(
"kernel32.dll"
);
DWORD dwOld;
g_dwHookGetModuleHandleW = (DWORD)MyGetProcAddress(hMod,
"GetModuleHandleW"
);
VirtualProtect((PVOID)g_dwHookGetModuleHandleW, 5, PAGE_EXECUTE_READWRITE, &dwOld);
*(PBYTE)g_dwHookGetModuleHandleW = 0xE9;
*(PDWORD)(g_dwHookGetModuleHandleW + 1) = (DWORD)HookGetModuleHandleW - g_dwHookGetModuleHandleW - 5;
VirtualProtect((PVOID)g_dwHookGetModuleHandleW, 5, dwOld, &dwOld);
g_dwHookGetModuleHandleW += 5;
g_dwHookGetProcAddress = (DWORD)MyGetProcAddress(hMod,
"GetProcAddress"
);
VirtualProtect((PVOID)g_dwHookGetProcAddress, 5, PAGE_EXECUTE_READWRITE, &dwOld);
*(PBYTE)g_dwHookGetProcAddress = 0xE9;
*(PDWORD)(g_dwHookGetProcAddress + 1) = (DWORD)_HookGetProcAddress - g_dwHookGetProcAddress - 5;
VirtualProtect((PVOID)g_dwHookGetProcAddress, 5, dwOld, &dwOld);
g_dwHookGetProcAddress += 5;
g_bInit = TRUE;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
HMODULE hMod = NULL;
switch(ul_reason_for_call)
{
case
DLL_PROCESS_ATTACH:
if
( !g_bInit )
{
ApiInit();
}
break
;
case
DLL_PROCESS_DETACH:
break
;
case
DLL_THREAD_ATTACH:
break
;
case
DLL_THREAD_DETACH:
break
;
}
return
TRUE;
}