📄 utils.c
字号:
* ntdll --> ntdll.dll
* ntdll. --> ntdll
* ntdll.xyz --> ntdll.xyz
*/
static VOID
LdrAdjustDllName (PUNICODE_STRING FullDllName,
PUNICODE_STRING DllName,
BOOLEAN BaseName)
{
WCHAR Buffer[MAX_PATH];
ULONG Length;
PWCHAR Extension;
PWCHAR Pointer;
Length = DllName->Length / sizeof(WCHAR);
if (BaseName)
{
/* get the base dll name */
Pointer = DllName->Buffer + Length;
Extension = Pointer;
do
{
--Pointer;
}
while (Pointer >= DllName->Buffer && *Pointer != L'\\' && *Pointer != L'/');
Pointer++;
Length = Extension - Pointer;
memmove (Buffer, Pointer, Length * sizeof(WCHAR));
Buffer[Length] = L'\0';
}
else
{
/* get the full dll name */
memmove (Buffer, DllName->Buffer, DllName->Length);
Buffer[DllName->Length / sizeof(WCHAR)] = L'\0';
}
/* Build the DLL's absolute name */
Extension = wcsrchr (Buffer, L'.');
if ((Extension != NULL) && (*Extension == L'.'))
{
/* with extension - remove dot if it's the last character */
if (Buffer[Length - 1] == L'.')
Length--;
Buffer[Length] = 0;
}
else
{
/* name without extension - assume that it is .dll */
memmove (Buffer + Length, L".dll", 10);
}
RtlCreateUnicodeString(FullDllName, Buffer);
}
PLDR_DATA_TABLE_ENTRY
LdrAddModuleEntry(PVOID ImageBase,
PIMAGE_NT_HEADERS NTHeaders,
PWSTR FullDosName)
{
PLDR_DATA_TABLE_ENTRY Module;
Module = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof (LDR_DATA_TABLE_ENTRY));
ASSERT(Module);
memset(Module, 0, sizeof(LDR_DATA_TABLE_ENTRY));
Module->DllBase = (PVOID)ImageBase;
Module->EntryPoint = (PVOID)NTHeaders->OptionalHeader.AddressOfEntryPoint;
if (Module->EntryPoint != 0)
Module->EntryPoint = (PVOID)((ULONG_PTR)Module->EntryPoint + (ULONG_PTR)Module->DllBase);
Module->SizeOfImage = LdrpGetResidentSize(NTHeaders);
if (NtCurrentPeb()->Ldr->Initialized == TRUE)
{
/* loading while app is running */
Module->LoadCount = 1;
} else {
/*
* loading while app is initializing
* dll must not be unloaded
*/
Module->LoadCount = 0xFFFF;
}
Module->Flags = 0;
Module->TlsIndex = -1;
Module->CheckSum = NTHeaders->OptionalHeader.CheckSum;
Module->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
RtlCreateUnicodeString (&Module->FullDllName,
FullDosName);
RtlCreateUnicodeString (&Module->BaseDllName,
wcsrchr(FullDosName, L'\\') + 1);
DPRINT ("BaseDllName %wZ\n", &Module->BaseDllName);
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
InsertTailList(&NtCurrentPeb()->Ldr->InLoadOrderModuleList,
&Module->InLoadOrderLinks);
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
return(Module);
}
static NTSTATUS
LdrpMapKnownDll(IN PUNICODE_STRING DllName,
OUT PUNICODE_STRING FullDosName,
OUT PHANDLE SectionHandle)
{
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status;
DPRINT("LdrpMapKnownDll() called\n");
if (LdrpKnownDllsDirHandle == NULL)
{
DPRINT("Invalid 'KnownDlls' directory\n");
return STATUS_UNSUCCESSFUL;
}
DPRINT("LdrpKnownDllPath '%wZ'\n", &LdrpKnownDllPath);
InitializeObjectAttributes(&ObjectAttributes,
DllName,
OBJ_CASE_INSENSITIVE,
LdrpKnownDllsDirHandle,
NULL);
Status = NtOpenSection(SectionHandle,
SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT("NtOpenSection() failed for '%wZ' (Status 0x%08lx)\n", DllName, Status);
return Status;
}
FullDosName->Length = LdrpKnownDllPath.Length + DllName->Length + sizeof(WCHAR);
FullDosName->MaximumLength = FullDosName->Length + sizeof(WCHAR);
FullDosName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
0,
FullDosName->MaximumLength);
if (FullDosName->Buffer == NULL)
{
FullDosName->Length = 0;
FullDosName->MaximumLength = 0;
return STATUS_SUCCESS;
}
wcscpy(FullDosName->Buffer, LdrpKnownDllPath.Buffer);
wcscat(FullDosName->Buffer, L"\\");
wcscat(FullDosName->Buffer, DllName->Buffer);
DPRINT("FullDosName '%wZ'\n", FullDosName);
DPRINT("LdrpMapKnownDll() done\n");
return STATUS_SUCCESS;
}
static NTSTATUS
LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
IN PUNICODE_STRING DllName,
OUT PUNICODE_STRING FullDosName,
IN BOOLEAN MapAsDataFile,
OUT PHANDLE SectionHandle)
{
WCHAR SearchPathBuffer[MAX_PATH];
WCHAR DosName[MAX_PATH];
UNICODE_STRING FullNtFileName;
OBJECT_ATTRIBUTES FileObjectAttributes;
HANDLE FileHandle;
char BlockBuffer [1024];
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_NT_HEADERS NTHeaders;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
ULONG len;
DPRINT("LdrpMapDllImageFile() called\n");
if (SearchPath == NULL)
{
/* get application running path */
wcscpy (SearchPathBuffer, NtCurrentPeb()->ProcessParameters->ImagePathName.Buffer);
len = wcslen (SearchPathBuffer);
while (len && SearchPathBuffer[len - 1] != L'\\')
len--;
if (len) SearchPathBuffer[len-1] = L'\0';
wcscat (SearchPathBuffer, L";");
wcscat (SearchPathBuffer, SharedUserData->NtSystemRoot);
wcscat (SearchPathBuffer, L"\\system32;");
wcscat (SearchPathBuffer, SharedUserData->NtSystemRoot);
wcscat (SearchPathBuffer, L";.");
SearchPath = SearchPathBuffer;
}
if (RtlDosSearchPath_U (SearchPath,
DllName->Buffer,
NULL,
MAX_PATH,
DosName,
NULL) == 0)
return STATUS_DLL_NOT_FOUND;
if (!RtlDosPathNameToNtPathName_U (DosName,
&FullNtFileName,
NULL,
NULL))
return STATUS_DLL_NOT_FOUND;
DPRINT("FullNtFileName %wZ\n", &FullNtFileName);
InitializeObjectAttributes(&FileObjectAttributes,
&FullNtFileName,
0,
NULL,
NULL);
DPRINT("Opening dll \"%wZ\"\n", &FullNtFileName);
Status = NtOpenFile(&FileHandle,
GENERIC_READ|SYNCHRONIZE,
&FileObjectAttributes,
&IoStatusBlock,
FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status))
{
DPRINT1("Dll open of %wZ failed: Status = 0x%08lx\n",
&FullNtFileName, Status);
RtlFreeHeap (RtlGetProcessHeap (),
0,
FullNtFileName.Buffer);
return Status;
}
RtlFreeHeap (RtlGetProcessHeap (),
0,
FullNtFileName.Buffer);
Status = NtReadFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
BlockBuffer,
sizeof(BlockBuffer),
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("Dll header read failed: Status = 0x%08lx\n", Status);
NtClose(FileHandle);
return Status;
}
/*
* Overlay DOS and NT headers structures to the
* buffer with DLL's header raw data.
*/
DosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
NTHeaders = (PIMAGE_NT_HEADERS) (BlockBuffer + DosHeader->e_lfanew);
/*
* Check it is a PE image file.
*/
if ((DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|| (DosHeader->e_lfanew == 0L)
|| (*(PULONG)(NTHeaders) != IMAGE_NT_SIGNATURE))
{
DPRINT("NTDLL format invalid\n");
NtClose(FileHandle);
return STATUS_UNSUCCESSFUL;
}
/*
* Create a section for dll.
*/
Status = NtCreateSection(SectionHandle,
SECTION_ALL_ACCESS,
NULL,
NULL,
PAGE_READONLY,
SEC_COMMIT | (MapAsDataFile ? 0 : SEC_IMAGE),
FileHandle);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
{
DPRINT("NTDLL create section failed: Status = 0x%08lx\n", Status);
return Status;
}
RtlCreateUnicodeString(FullDosName,
DosName);
return Status;
}
/***************************************************************************
* NAME EXPORTED
* LdrLoadDll
*
* DESCRIPTION
*
* ARGUMENTS
*
* RETURN VALUE
*
* REVISIONS
*
* NOTE
*
* @implemented
*/
NTSTATUS NTAPI
LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
IN PULONG LoadFlags OPTIONAL,
IN PUNICODE_STRING Name,
OUT PVOID *BaseAddress OPTIONAL)
{
NTSTATUS Status;
PLDR_DATA_TABLE_ENTRY Module;
TRACE_LDR("LdrLoadDll, loading %wZ%s%S\n",
Name,
SearchPath ? " from " : "",
SearchPath ? SearchPath : L"");
if (Name == NULL)
{
if (BaseAddress)
*BaseAddress = NtCurrentPeb()->ImageBaseAddress;
return STATUS_SUCCESS;
}
if (BaseAddress)
*BaseAddress = NULL;
Status = LdrpLoadModule(SearchPath, LoadFlags ? *LoadFlags : 0, Name, &Module, BaseAddress);
if (NT_SUCCESS(Status)
&& (!LoadFlags || 0 == (*LoadFlags & LOAD_LIBRARY_AS_DATAFILE)))
{
RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
Status = LdrpAttachProcess();
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
if (NT_SUCCESS(Status) && BaseAddress)
{
*BaseAddress = Module->DllBase;
}
}
return Status;
}
/***************************************************************************
* NAME EXPORTED
* LdrFindEntryForAddress
*
* DESCRIPTION
*
* ARGUMENTS
*
* RETURN VALUE
*
* REVISIONS
*
* NOTE
*
* @implemented
*/
NTSTATUS NTAPI
LdrFindEntryForAddress(PVOID Address,
PLDR_DATA_TABLE_ENTRY *Module)
{
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
PLDR_DATA_TABLE_ENTRY ModulePtr;
DPRINT("LdrFindEntryForAddress(Address %p)\n", Address);
if (NtCurrentPeb()->Ldr == NULL)
return(STATUS_NO_MORE_ENTRIES);
RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
Entry = ModuleListHead->Flink;
if (Entry == ModuleListHead)
{
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
return(STATUS_NO_MORE_ENTRIES);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -