📄 utils.c
字号:
while (Entry != ModuleListHead)
{
ModulePtr = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
DPRINT("Scanning %wZ at %p\n", &ModulePtr->BaseDllName, ModulePtr->DllBase);
if ((Address >= ModulePtr->DllBase) &&
((ULONG_PTR)Address <= ((ULONG_PTR)ModulePtr->DllBase + ModulePtr->SizeOfImage)))
{
*Module = ModulePtr;
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
return(STATUS_SUCCESS);
}
Entry = Entry->Flink;
}
DPRINT("Failed to find module entry.\n");
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
return(STATUS_NO_MORE_ENTRIES);
}
/***************************************************************************
* NAME LOCAL
* LdrFindEntryForName
*
* DESCRIPTION
*
* ARGUMENTS
*
* RETURN VALUE
*
* REVISIONS
*
* NOTE
*
*/
static NTSTATUS
LdrFindEntryForName(PUNICODE_STRING Name,
PLDR_DATA_TABLE_ENTRY *Module,
BOOLEAN Ref)
{
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
PLDR_DATA_TABLE_ENTRY ModulePtr;
BOOLEAN ContainsPath;
UNICODE_STRING AdjustedName;
unsigned i;
DPRINT("LdrFindEntryForName(Name %wZ)\n", Name);
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);
}
// NULL is the current process
if (Name == NULL)
{
*Module = ExeModule;
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
return(STATUS_SUCCESS);
}
LdrAdjustDllName (&AdjustedName, Name, FALSE);
ContainsPath = (AdjustedName.Length >= 2 * sizeof(WCHAR) && L':' == AdjustedName.Buffer[1]);
for (i = 0; ! ContainsPath && i < AdjustedName.Length / sizeof(WCHAR); i++)
{
ContainsPath = L'\\' == AdjustedName.Buffer[i] ||
L'/' == AdjustedName.Buffer[i];
}
if (LdrpLastModule)
{
if ((! ContainsPath &&
0 == RtlCompareUnicodeString(&LdrpLastModule->BaseDllName, &AdjustedName, TRUE)) ||
(ContainsPath &&
0 == RtlCompareUnicodeString(&LdrpLastModule->FullDllName, &AdjustedName, TRUE)))
{
*Module = LdrpLastModule;
if (Ref && (*Module)->LoadCount != 0xFFFF)
{
(*Module)->LoadCount++;
}
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
RtlFreeUnicodeString(&AdjustedName);
return(STATUS_SUCCESS);
}
}
while (Entry != ModuleListHead)
{
ModulePtr = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
DPRINT("Scanning %wZ %wZ\n", &ModulePtr->BaseDllName, &AdjustedName);
if ((! ContainsPath &&
0 == RtlCompareUnicodeString(&ModulePtr->BaseDllName, &AdjustedName, TRUE)) ||
(ContainsPath &&
0 == RtlCompareUnicodeString(&ModulePtr->FullDllName, &AdjustedName, TRUE)))
{
*Module = LdrpLastModule = ModulePtr;
if (Ref && ModulePtr->LoadCount != 0xFFFF)
{
ModulePtr->LoadCount++;
}
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
RtlFreeUnicodeString(&AdjustedName);
return(STATUS_SUCCESS);
}
Entry = Entry->Flink;
}
DPRINT("Failed to find dll %wZ\n", Name);
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
RtlFreeUnicodeString(&AdjustedName);
return(STATUS_NO_MORE_ENTRIES);
}
/**********************************************************************
* NAME LOCAL
* LdrFixupForward
*
* DESCRIPTION
*
* ARGUMENTS
*
* RETURN VALUE
*
* REVISIONS
*
* NOTE
*
*/
static PVOID
LdrFixupForward(PCHAR ForwardName)
{
CHAR NameBuffer[128];
UNICODE_STRING DllName;
NTSTATUS Status;
PCHAR p;
PLDR_DATA_TABLE_ENTRY Module;
PVOID BaseAddress;
strcpy(NameBuffer, ForwardName);
p = strchr(NameBuffer, '.');
if (p != NULL)
{
*p = 0;
DPRINT("Dll: %s Function: %s\n", NameBuffer, p+1);
RtlCreateUnicodeStringFromAsciiz (&DllName,
NameBuffer);
Status = LdrFindEntryForName (&DllName, &Module, FALSE);
/* FIXME:
* The caller (or the image) is responsible for loading of the dll, where the function is forwarded.
*/
if (!NT_SUCCESS(Status))
{
ULONG Flags = LDRP_PROCESS_CREATION_TIME;
Status = LdrLoadDll(NULL,
&Flags,
&DllName,
&BaseAddress);
if (NT_SUCCESS(Status))
{
Status = LdrFindEntryForName (&DllName, &Module, FALSE);
}
}
RtlFreeUnicodeString (&DllName);
if (!NT_SUCCESS(Status))
{
DPRINT1("LdrFixupForward: failed to load %s\n", NameBuffer);
return NULL;
}
DPRINT("BaseAddress: %p\n", Module->DllBase);
return LdrGetExportByName(Module->DllBase, (PUCHAR)(p+1), -1);
}
return NULL;
}
/**********************************************************************
* NAME LOCAL
* LdrGetExportByOrdinal
*
* DESCRIPTION
*
* ARGUMENTS
*
* RETURN VALUE
*
* REVISIONS
*
* NOTE
*
*/
static PVOID
LdrGetExportByOrdinal (
PVOID BaseAddress,
ULONG Ordinal
)
{
PIMAGE_EXPORT_DIRECTORY ExportDir;
ULONG ExportDirSize;
PDWORD * ExFunctions;
PVOID Function;
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
RtlImageDirectoryEntryToData (BaseAddress,
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&ExportDirSize);
ExFunctions = (PDWORD *)
RVA(
BaseAddress,
ExportDir->AddressOfFunctions
);
DPRINT(
"LdrGetExportByOrdinal(Ordinal %lu) = %p\n",
Ordinal,
RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
);
Function = (0 != ExFunctions[Ordinal - ExportDir->Base]
? RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
: NULL);
if (((ULONG)Function >= (ULONG)ExportDir) &&
((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrFixupForward((PCHAR)Function);
}
return Function;
}
/**********************************************************************
* NAME LOCAL
* LdrGetExportByName
*
* DESCRIPTION
*
* ARGUMENTS
*
* RETURN VALUE
*
* REVISIONS
*
* NOTE
* AddressOfNames and AddressOfNameOrdinals are paralell tables,
* both with NumberOfNames entries.
*
*/
static PVOID
LdrGetExportByName(PVOID BaseAddress,
PUCHAR SymbolName,
WORD Hint)
{
PIMAGE_EXPORT_DIRECTORY ExportDir;
PDWORD * ExFunctions;
PDWORD * ExNames;
USHORT * ExOrdinals;
PVOID ExName;
ULONG Ordinal;
PVOID Function;
LONG minn, maxn;
ULONG ExportDirSize;
DPRINT("LdrGetExportByName %p %s %hu\n", BaseAddress, SymbolName, Hint);
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
RtlImageDirectoryEntryToData(BaseAddress,
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&ExportDirSize);
if (ExportDir == NULL)
{
DPRINT1("LdrGetExportByName(): no export directory, "
"can't lookup %s/%hu!\n", SymbolName, Hint);
return NULL;
}
//The symbol names may be missing entirely
if (ExportDir->AddressOfNames == 0)
{
DPRINT("LdrGetExportByName(): symbol names missing entirely\n");
return NULL;
}
/*
* Get header pointers
*/
ExNames = (PDWORD *)RVA(BaseAddress,
ExportDir->AddressOfNames);
ExOrdinals = (USHORT *)RVA(BaseAddress,
ExportDir->AddressOfNameOrdinals);
ExFunctions = (PDWORD *)RVA(BaseAddress,
ExportDir->AddressOfFunctions);
/*
* Check the hint first
*/
if (Hint < ExportDir->NumberOfNames)
{
ExName = RVA(BaseAddress, ExNames[Hint]);
if (strcmp(ExName, (PCHAR)SymbolName) == 0)
{
Ordinal = ExOrdinals[Hint];
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
if (((ULONG)Function >= (ULONG)ExportDir) &&
((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrFixupForward((PCHAR)Function);
if (Function == NULL)
{
DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
}
return Function;
}
if (Function != NULL)
return Function;
}
}
/*
* Binary search
*/
minn = 0;
maxn = ExportDir->NumberOfNames - 1;
while (minn <= maxn)
{
LONG mid;
LONG res;
mid = (minn + maxn) / 2;
ExName = RVA(BaseAddress, ExNames[mid]);
res = strcmp(ExName, (PCHAR)SymbolName);
if (res == 0)
{
Ordinal = ExOrdinals[mid];
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
if (((ULONG)Function >= (ULONG)ExportDir) &&
((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrFixupForward((PCHAR)Function);
if (Function == NULL)
{
DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
}
return Function;
}
if (Function != NULL)
return Function;
}
else if (minn == maxn)
{
DPRINT("LdrGetExportByName(): binary search failed\n");
break;
}
else if (res > 0)
{
maxn = mid - 1;
}
else
{
minn = mid + 1;
}
}
DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
return (PVOID)NULL;
}
/**********************************************************************
* NAME LOCAL
* LdrPerformRelocations
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -