可以用在什麼地方就不解釋了....XD
參考資料:
- http://bbs.pediy.com/showthread.php?t=124325 (看雪學院 )
- http://msdn.moonsols.com/ (裡面有很多 Windows Structures 的資料)
(不知道為什麼副檔名.c餵給cl就 吃屎 了...Q____Q,所以說是C++)
缺點是可能會造成DLL重載、GetModuleHandle抓不到
(反正就說要隱藏了嘛哈哈哈哈)
不過應該還沒有完全隱藏起來,GetModuleHandle還是會掃過...明明Link都斷掉了阿 OTZ
後來發現不能把整個structure給填0,後面如果用到GetModuleHandle會crash
發生的記憶體存取錯誤的地方也附上了,但是有點懶得繼續追
如果有人找到GetModuleHandle用的Link在哪裡的話記得告訴我
Source: https://gist.github.com/Inndy/d9d1d37221a3a99a3c71
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Windows.h> | |
// #include <ntstatus.h> | |
#include <Winternl.h> | |
#include <stdio.h> | |
#include <locale.h> | |
// #define FAST_GET_PEB | |
#ifndef STATUS_SUCCESS | |
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) | |
#endif | |
typedef struct _W7_X86_PEB_LDR_DATA // 9 elements, 0x30 bytes (sizeof) | |
{ | |
ULONG32 Length; /*0x00*/ | |
UINT8 Initialized; /*0x04*/ | |
UINT8 _PADDING0_[0x3]; /*0x05*/ | |
VOID* SsHandle; /*0x08*/ | |
struct _LIST_ENTRY InLoadOrderModuleList; /*0x0C*/ // 2 elements, 0x08 bytes (sizeof) | |
struct _LIST_ENTRY InMemoryOrderModuleList; /*0x14*/ // 2 elements, 0x08 bytes (sizeof) | |
struct _LIST_ENTRY InInitializationOrderModuleList; /*0x1C*/ // 2 elements, 0x08 bytes (sizeof) | |
VOID* EntryInProgress; /*0x24*/ | |
UINT8 ShutdownInProgress; /*0x28*/ | |
UINT8 _PADDING1_[0x3]; /*0x29*/ | |
VOID* ShutdownThreadId; /*0x2C*/ | |
} W7_X86_PEB_LDR_DATA, *W7_X86_PPEB_LDR_DATA; | |
typedef struct _W7_X86_LDR_DATA_TABLE_ENTRY // 24 elements, 0x78 bytes (sizeof) | |
{ | |
struct _LIST_ENTRY InLoadOrderLinks; /*0x000*/ // 2 elements, 0x8 bytes (sizeof) | |
struct _LIST_ENTRY InMemoryOrderLinks; /*0x008*/ // 2 elements, 0x8 bytes (sizeof) | |
struct _LIST_ENTRY InInitializationOrderLinks; /*0x010*/ // 2 elements, 0x8 bytes (sizeof) | |
VOID* DllBase; /*0x018*/ | |
VOID* EntryPoint; /*0x01C*/ | |
ULONG32 SizeOfImage; /*0x020*/ | |
struct _UNICODE_STRING FullDllName; /*0x024*/ // 3 elements, 0x8 bytes (sizeof) | |
struct _UNICODE_STRING BaseDllName; /*0x02C*/ // 3 elements, 0x8 bytes (sizeof) | |
ULONG32 Flags; /*0x034*/ | |
UINT16 LoadCount; /*0x038*/ | |
UINT16 TlsIndex; /*0x03A*/ | |
union // 2 elements, 0x8 bytes (sizeof) | |
{ | |
struct _LIST_ENTRY HashLinks; /*0x03C*/ // 2 elements, 0x8 bytes (sizeof) | |
struct // 2 elements, 0x8 bytes (sizeof) | |
{ | |
VOID* SectionPointer; /*0x03C*/ | |
ULONG32 CheckSum; /*0x040*/ | |
}; | |
}; | |
union // 2 elements, 0x4 bytes (sizeof) | |
{ | |
ULONG32 TimeDateStamp; /*0x044*/ | |
VOID* LoadedImports; /*0x044*/ | |
}; | |
struct _ACTIVATION_CONTEXT* EntryPointActivationContext; /*0x048*/ | |
VOID* PatchInformation; /*0x04C*/ | |
struct _LIST_ENTRY ForwarderLinks; /*0x050*/ // 2 elements, 0x8 bytes (sizeof) | |
struct _LIST_ENTRY ServiceTagLinks; /*0x058*/ // 2 elements, 0x8 bytes (sizeof) | |
struct _LIST_ENTRY StaticLinks; /*0x060*/ // 2 elements, 0x8 bytes (sizeof) | |
VOID* ContextInformation; /*0x068*/ | |
ULONG32 OriginalBase; /*0x06C*/ | |
union _LARGE_INTEGER LoadTime; /*0x070*/ // 4 elements, 0x8 bytes (sizeof) | |
} W7_X86_LDR_DATA_TABLE_ENTRY, *W7_X86_PLDR_DATA_TABLE_ENTRY; | |
PPEB __stdcall GetPEB() { | |
#ifdef FAST_GET_PEB | |
DWORD peb = 0; | |
__asm { | |
mov eax, fs:[0x30]; | |
mov [peb], eax; | |
} | |
return (PPEB)peb; | |
#else | |
typedef NTSTATUS (WINAPI *pNtQueryInformationProcess) ( | |
HANDLE ProcessHandle, | |
PROCESSINFOCLASS ProcessInformationClass, | |
PVOID ProcessInformation, | |
ULONG ProcessInformationLength, | |
PULONG ReturnLength | |
); | |
HMODULE hNTDLL = LoadLibrary("ntdll"); | |
if (hNTDLL == NULL) { | |
printf("[-] LoadLibrary(\"ntdll\") Failed\n"); | |
return NULL; | |
} | |
pNtQueryInformationProcess theNtQueryInformationProcess = | |
(pNtQueryInformationProcess)GetProcAddress(hNTDLL, "NtQueryInformationProcess"); | |
if (theNtQueryInformationProcess == NULL) { | |
printf("[-] GetProcAddress(hNTDLL, \"NtQueryInformationProcess\") Failed\n"); | |
return NULL; | |
} | |
PROCESS_BASIC_INFORMATION PBI = { 0 }; | |
DWORD RetLength = 0; | |
NTSTATUS ret = theNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, | |
&PBI, sizeof(PBI), &RetLength); | |
if (ret != STATUS_SUCCESS) { | |
printf("[-] NtQueryInformationProcess(...) Failed\n"); | |
return NULL; | |
} | |
if (RetLength < 8) { | |
printf("[-] NtQueryInformationProcess(...) Failed (not enough returned length)\n"); | |
return NULL; | |
} | |
return PBI.PebBaseAddress; | |
#endif | |
} | |
wchar_t * ReadUnicodeString (PUNICODE_STRING str, wchar_t buffer[], int buff_size) { | |
int i, length; | |
if (str == NULL) | |
return NULL; | |
buff_size = (buff_size - 1) / sizeof(wchar_t); | |
length = str->Length; | |
if (length > buff_size) | |
length = buff_size; | |
CopyMemory(buffer, str->Buffer, length * sizeof(wchar_t)); | |
buffer[length] = 0; | |
return buffer; | |
} | |
BOOL ModuleExists(HMODULE module) { | |
PPEB peb = GetPEB(); | |
if (peb == NULL) | |
return FALSE; | |
PLIST_ENTRY modlist = &peb->Ldr->InMemoryOrderModuleList; | |
PLIST_ENTRY p = modlist->Flink; | |
do { | |
W7_X86_PLDR_DATA_TABLE_ENTRY data = (W7_X86_PLDR_DATA_TABLE_ENTRY)(p - 1); | |
if (data->DllBase == module) | |
return TRUE; | |
p = p->Flink; | |
} while (p != modlist); | |
return FALSE; | |
} | |
void EraseUnicodeString(PUNICODE_STRING str) { | |
str->Length = 0; | |
SecureZeroMemory(str->Buffer, str->Length * sizeof(wchar_t)); | |
} | |
void BreakLink(PLIST_ENTRY link) { | |
link->Blink->Flink = link->Flink; | |
link->Flink->Blink = link->Blink; | |
} | |
BOOL EraseModule(HMODULE module) { | |
if (module == NULL || ModuleExists(module) == FALSE) | |
return FALSE; | |
PPEB peb = GetPEB(); | |
if (peb == NULL) | |
return FALSE; | |
// Find the link structure | |
PLIST_ENTRY modlist = &peb->Ldr->InMemoryOrderModuleList; | |
PLIST_ENTRY p = modlist->Flink; | |
W7_X86_PLDR_DATA_TABLE_ENTRY data; | |
do { | |
data = (W7_X86_PLDR_DATA_TABLE_ENTRY)(p - 1); | |
if (data->DllBase == module) | |
break; | |
p = p->Flink; | |
} while (p != modlist); | |
// Break Link | |
BreakLink(&data->InLoadOrderLinks); | |
BreakLink(&data->InMemoryOrderLinks); | |
BreakLink(&data->InInitializationOrderLinks); | |
// Erase DLL Name and DLL Path | |
EraseUnicodeString(&data->BaseDllName); | |
EraseUnicodeString(&data->FullDllName); | |
// Erase PE header | |
PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)data->DllBase; | |
PIMAGE_NT_HEADERS nt_header = (PIMAGE_NT_HEADERS)(((char *)dos_header) + dos_header->e_lfanew); | |
DWORD OldProtection; | |
VirtualProtect(dos_header, 0x1000, PAGE_EXECUTE_READWRITE, &OldProtection); | |
SecureZeroMemory(dos_header, sizeof(PIMAGE_DOS_HEADER)); | |
SecureZeroMemory(nt_header, sizeof(IMAGE_NT_HEADERS)); | |
VirtualProtect(dos_header, 0x1000, OldProtection, &OldProtection); | |
// Erase entire information block | |
/*** Notice: If you do this, "GetModuleHandle" will make your application crash | |
ntdll.dll+0x57D7B: | |
772D7D7B 8D47 2C lea eax,dword ptr ds:[edi+0x2C] | |
772D7D7E 50 push eax ; Eax is invalid address | |
772D7D7F FF75 08 push dword ptr ss:[ebp+0x8] ; The dll that we search for | |
772D7D82 E8 7ED9FFFF call ntdll.RtlEqualUnicodeString ; And... Crash :( | |
772D7D87 84C0 test al,al | |
772D7D89 0F84 280D0000 je ntdll.772D8AB7 | |
772D7D8F F747 34 00000010 test dword ptr ds:[edi+0x34],0x10000000 | |
772D7D96 0F85 1B0D0000 jnz ntdll.772D8AB7 | |
772D7D9C 8B45 10 mov eax,dword ptr ss:[ebp+0x10] | |
772D7D9F 8938 mov dword ptr ds:[eax],edi | |
772D7DA1 E9 86FEFFFF jmp ntdll.772D7C2C | |
*/ | |
//SecureZeroMemory(data, sizeof(W7_X86_LDR_DATA_TABLE_ENTRY)); | |
// Clean strucuture | |
data->DllBase = NULL; | |
data->EntryPoint = NULL; | |
data->SizeOfImage = 0; | |
data->LoadCount = 0; | |
return TRUE; | |
} | |
void EnumerateModule(PLIST_ENTRY list, const char * description, int offset) { | |
if (description != NULL) | |
printf("[+] Enumerating Modules (%s)\n", description); | |
else | |
printf("[+] Enumerating Modules\n"); | |
int count = 0; | |
PLIST_ENTRY p = list->Flink; | |
do { | |
count++; | |
printf("[*] Node: %.8X -> %.8X", p, p->Flink); | |
W7_X86_PLDR_DATA_TABLE_ENTRY data = (W7_X86_PLDR_DATA_TABLE_ENTRY)(p - offset); | |
printf(" .... Structure At %.8X, DllBase = %.8X\n", data, data->DllBase); | |
wchar_t buffer[512]; | |
wprintf(L" DllName: %s\n", ReadUnicodeString(&data->BaseDllName, buffer, sizeof(buffer))); | |
wprintf(L" FullPath: %s\n", ReadUnicodeString(&data->FullDllName, buffer, sizeof(buffer))); | |
printf("\n"); | |
p = p->Flink; | |
} while (p != list); | |
printf("[*] --> Module Count = %d\n", count); | |
} | |
int main () { | |
// to print chinese widechar | |
setlocale(LC_CTYPE, ""); | |
#ifdef FAST_GET_PEB | |
const char * __fast_get_peb = "Enabled"; | |
#else | |
const char * __fast_get_peb = "Disabled"; | |
#endif | |
PPEB peb = GetPEB(); | |
if (peb == NULL) { | |
printf("[-] GetPEB() Failed\n"); | |
return -1; | |
} | |
printf("\x5B\x2B\x5D\x20\x50\x72\x6F\x63\x65\x65\x73\x73\x20\x4D\x6F\x64"); | |
printf("\x75\x6C\x65\x20\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6E\x67\x20"); | |
printf("\x61\x6E\x64\x20\x45\x72\x61\x73\x69\x6E\x67\x0A\x20\x20\x20\x20"); | |
printf("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"); | |
printf("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"); | |
printf("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x42\x79\x20\x49\x6E\x6E"); | |
printf("\x64\x79\x0A"); | |
printf("[*] FAST_GET_PEB: %s\n", __fast_get_peb); | |
printf("[+] PEB = %.8X\n", peb); | |
PPEB_LDR_DATA pebldr = peb->Ldr; | |
printf("[+] PEB_LDR_DATA = %.8X\n", pebldr); | |
W7_X86_PPEB_LDR_DATA w7ldr = (W7_X86_PPEB_LDR_DATA)pebldr; | |
printf("[+] InLoadOrderModuleList = %.8X\n" | |
"[+] InMemoryOrderModuleList = %.8X\n" | |
"[+] InInitializationOrderModuleList = %.8X\n", | |
w7ldr->InLoadOrderModuleList, | |
w7ldr->InMemoryOrderModuleList, | |
w7ldr->InInitializationOrderModuleList); | |
// EnumerateModule(&w7ldr->InLoadOrderModuleList, "InLoadOrderModuleList", 0); | |
EnumerateModule(&w7ldr->InMemoryOrderModuleList, "InMemoryOrderModuleList", 1); | |
// EnumerateModule(&w7ldr->InInitializationOrderModuleList, "InInitializationOrderModuleList", 2); | |
HMODULE hNTDLL = GetModuleHandle("ntdll"); | |
printf("[+] Erase Module... ntdll.dll (%.8X)\n", hNTDLL); | |
EraseModule(hNTDLL); | |
printf("[+] Enumerate DLL again...\n"); | |
EnumerateModule(&w7ldr->InLoadOrderModuleList, "InLoadOrderModuleList", 0); | |
EnumerateModule(&w7ldr->InMemoryOrderModuleList, "InMemoryOrderModuleList", 1); | |
EnumerateModule(&w7ldr->InInitializationOrderModuleList, "InInitializationOrderModuleList", 2); | |
printf("[*] GetModuleHandle(\"ntdll\") says... %.8X\n", GetModuleHandle("ntdll")); | |
printf("[!] Press Ctrl - C to Exit\n"); | |
while (1) ; | |
} |
沒有留言:
張貼留言