以前写的一个隐藏DLL模块函数,记录下来,免得以后需要时难找。
隐藏的方法是把DLL模块的路径从进程的内存中清除掉,不过,还是有方法可以把隐藏的DLL路径找出来的,比如内存暴力搜索等。
隐藏DLL模块的路径后,会存在一些问题,比如你后面想拿DLL的路径,拿不到了,所以在隐藏之前需要把路径保存起来;还有,当程序要Load你隐藏的DLL时,会重新加载这个DLL,因为程序已经无法判断此DLL在此之前是否已经被加载过。
注意:此函数似乎对64位操作系统无效。
// 传入需要隐藏的DLL模块句柄
NTSTATUS HideModule(IN HMODULE hModule)
{
NTSTATUS status = -1;
DWORD dwReturnLen = 0;
PLIST_ENTRY ListHead = NULL;
PLIST_ENTRY Current = NULL;
PPEB_LDR_DATA pLdr = NULL;
PLDR_DATA_TABLE_ENTRY pstEntry = NULL;
PROCESS_BASIC_INFORMATION processInfo;
ZeroMemory(&processInfo, sizeof(PROCESS_BASIC_INFORMATION));
status = ZwQueryInformationProcess(
GetCurrentProcess(),
ProcessBasicInformation,
&processInfo,
sizeof(PROCESS_BASIC_INFORMATION),
&dwReturnLen);
if (!NT_SUCCESS(status))
return status;
pLdr = (PPEB_LDR_DATA)(*(PULONG)((ULONG)processInfo.PebBaseAddress + 0x00C));
ListHead = &pLdr->InLoadOrderModuleList;
Current = ListHead->Blink;
while (Current != ListHead)
{
pstEntry = CONTAINING_RECORD(Current, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (pstEntry->DllBase == hModule)
{
if (pstEntry->FullDllName.Length != 0)
{
ZeroMemory(pstEntry->FullDllName.Buffer, pstEntry->FullDllName.Length);
pstEntry->FullDllName.Length = 0;
pstEntry->FullDllName.MaximumLength = sizeof(WCHAR);
pstEntry->BaseDllName.Length = 0;
pstEntry->BaseDllName.MaximumLength = sizeof(WCHAR);
}
status = STATUS_SUCCESS;
break;
}
Current = pstEntry->InLoadOrderLinks.Blink;
}
return status;
}
NTSTATUS HideModule(IN HMODULE hModule)
{
NTSTATUS status = -1;
DWORD dwReturnLen = 0;
PLIST_ENTRY ListHead = NULL;
PLIST_ENTRY Current = NULL;
PPEB_LDR_DATA pLdr = NULL;
PLDR_DATA_TABLE_ENTRY pstEntry = NULL;
PROCESS_BASIC_INFORMATION processInfo;
ZeroMemory(&processInfo, sizeof(PROCESS_BASIC_INFORMATION));
status = ZwQueryInformationProcess(
GetCurrentProcess(),
ProcessBasicInformation,
&processInfo,
sizeof(PROCESS_BASIC_INFORMATION),
&dwReturnLen);
if (!NT_SUCCESS(status))
return status;
pLdr = (PPEB_LDR_DATA)(*(PULONG)((ULONG)processInfo.PebBaseAddress + 0x00C));
ListHead = &pLdr->InLoadOrderModuleList;
Current = ListHead->Blink;
while (Current != ListHead)
{
pstEntry = CONTAINING_RECORD(Current, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (pstEntry->DllBase == hModule)
{
if (pstEntry->FullDllName.Length != 0)
{
ZeroMemory(pstEntry->FullDllName.Buffer, pstEntry->FullDllName.Length);
pstEntry->FullDllName.Length = 0;
pstEntry->FullDllName.MaximumLength = sizeof(WCHAR);
pstEntry->BaseDllName.Length = 0;
pstEntry->BaseDllName.MaximumLength = sizeof(WCHAR);
}
status = STATUS_SUCCESS;
break;
}
Current = pstEntry->InLoadOrderLinks.Blink;
}
return status;
}