Archive

Posts Tagged ‘ldrunloaddll’

Erasing the Cached Module Pointer in NTDLL

May 5th, 2009

Darawk first documented this insecurity in his CloakDLL project but never fixed it, Shynd then fixed it in his HideModule class.

Here it is again, but upgraded for x64 and to work with my Cloaker class:

// TODO: Scan more than just the image. Scan the heap.
void Cloaker::Module::EraseCachedPointer()
{
// Exception handling
try
{
// SEH proxy
SehGuard Guard;

// Get handle to NTDLL
HMODULE Handle = GetModuleHandle(_T(”ntdll.dll”));

// Check handle is valid
if (!Handle)
throw std::runtime_error(”Cloaker::Module::EraseCachedPointer: Handle to ntdll.dll is invalid.”);

// Check DOS header is valid
PIMAGE_DOS_HEADER pDosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(Handle);
if (!pDosHeader || pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
throw std::runtime_error(”Cloaker::Module::EraseCachedPointer: DOS PE header is invalid.”);

// Check NT header is valid
PIMAGE_NT_HEADERS pNtHeader = reinterpret_cast<PIMAGE_NT_HEADERS>
((PCHAR)Handle + pDosHeader->e_lfanew);
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
throw std::runtime_error(”Cloaker::Module::EraseCachedPointer: NT PE header is invalid.”);

// Get beginning and end of search region (entire region)
// TODO: Scan heap too
DWORD_PTR* Begin = reinterpret_cast<DWORD_PTR*>(pNtHeader->OptionalHeader.ImageBase);
DWORD_PTR* End = reinterpret_cast<DWORD_PTR*>(pNtHeader->OptionalHeader.ImageBase + pNtHeader->OptionalHeader.SizeOfImage);

// Search for cached pointers
DWORD_PTR* Searcher = NULL;
for (Searcher = Begin; Searcher < End; Searcher++)
{
// Check for cached pointer
if (*Searcher != reinterpret_cast<DWORD_PTR>(m_Handle))
continue;

// Get information for page of memory
MEMORY_BASIC_INFORMATION mbi = { 0 };
if (!VirtualQuery(Searcher, &mbi, sizeof(mbi)))
continue;

// Check page flags to verify we can write to it
if ((mbi.Protect & PAGE_READWRITE) == PAGE_READWRITE ||
(mbi.Protect & PAGE_EXECUTE_READWRITE) == PAGE_EXECUTE_READWRITE)
*Searcher = 0;
}
}
// Catch access violations
catch (const SehException& e)
{
e;
TDBGOUT(_T(”SEH Error in Cloaker::EraseCachedPointer: “) << e << std::endl);
}
}

Credits to Darawk for documenting it, and Shynd for his HideModule class which I ripped the base of this function from.