mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Implemented handling of forwarded exports
svn path=/trunk/; revision=1610
This commit is contained in:
parent
c87bd2d365
commit
41280eeeb5
1 changed files with 170 additions and 81 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: utils.c,v 1.38 2001/02/06 05:50:50 dwelch Exp $
|
/* $Id: utils.c,v 1.39 2001/02/10 10:04:39 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -45,9 +45,9 @@ STDCALL
|
||||||
LPVOID lpReserved
|
LPVOID lpReserved
|
||||||
);
|
);
|
||||||
|
|
||||||
static
|
static NTSTATUS LdrFindDll(PLDR_MODULE *Dll,PUNICODE_STRING Name);
|
||||||
NTSTATUS
|
static PVOID LdrFixupForward(PCHAR ForwardName);
|
||||||
LdrFindDll (PLDR_MODULE *Dll,PUNICODE_STRING Name);
|
static PVOID LdrGetExportByName(PVOID BaseAddress, PUCHAR SymbolName, USHORT Hint);
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
@ -571,6 +571,66 @@ NTSTATUS LdrMapSections(HANDLE ProcessHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* NAME LOCAL
|
||||||
|
* LdrFixupForward
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* ARGUMENTS
|
||||||
|
*
|
||||||
|
* RETURN VALUE
|
||||||
|
*
|
||||||
|
* REVISIONS
|
||||||
|
*
|
||||||
|
* NOTE
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static PVOID
|
||||||
|
LdrFixupForward(PCHAR ForwardName)
|
||||||
|
{
|
||||||
|
CHAR NameBuffer[128];
|
||||||
|
UNICODE_STRING DllName;
|
||||||
|
UNICODE_STRING FunctionName;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PCHAR p;
|
||||||
|
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 = LdrGetDllHandle (0, 0, &DllName, &BaseAddress);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Status = LdrLoadDll(NULL,
|
||||||
|
0,
|
||||||
|
&DllName,
|
||||||
|
&BaseAddress);
|
||||||
|
RtlFreeUnicodeString (&DllName);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("LdrFixupForward: failed to load %wZ\n", &DllName);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlFreeUnicodeString (&DllName);
|
||||||
|
DPRINT("BaseAddress: %p\n", BaseAddress);
|
||||||
|
|
||||||
|
return LdrGetExportByName(BaseAddress, p+1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* NAME LOCAL
|
* NAME LOCAL
|
||||||
* LdrGetExportByOrdinal
|
* LdrGetExportByOrdinal
|
||||||
|
@ -638,89 +698,119 @@ LdrGetExportByOrdinal (
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static PVOID
|
static PVOID
|
||||||
LdrGetExportByName (PVOID BaseAddress, PUCHAR SymbolName, WORD Hint)
|
LdrGetExportByName(PVOID BaseAddress,
|
||||||
|
PUCHAR SymbolName,
|
||||||
|
WORD Hint)
|
||||||
{
|
{
|
||||||
PIMAGE_EXPORT_DIRECTORY ExportDir;
|
PIMAGE_EXPORT_DIRECTORY ExportDir;
|
||||||
PDWORD * ExFunctions;
|
PDWORD * ExFunctions;
|
||||||
PDWORD * ExNames;
|
PDWORD * ExNames;
|
||||||
USHORT * ExOrdinals;
|
USHORT * ExOrdinals;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
PVOID ExName;
|
PVOID ExName;
|
||||||
ULONG Ordinal;
|
ULONG Ordinal;
|
||||||
ULONG minn, maxn;
|
PVOID Function;
|
||||||
|
ULONG minn, maxn;
|
||||||
|
ULONG ExportDirSize;
|
||||||
|
|
||||||
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
|
DPRINT("LdrGetExportByName %x %s %hu\n", BaseAddress, SymbolName, Hint);
|
||||||
RtlImageDirectoryEntryToData (BaseAddress,
|
|
||||||
|
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
|
||||||
|
RtlImageDirectoryEntryToData(BaseAddress,
|
||||||
TRUE,
|
TRUE,
|
||||||
IMAGE_DIRECTORY_ENTRY_EXPORT,
|
IMAGE_DIRECTORY_ENTRY_EXPORT,
|
||||||
NULL);
|
&ExportDirSize);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get header pointers
|
* Get header pointers
|
||||||
*/
|
*/
|
||||||
ExNames = (PDWORD *)RVA(BaseAddress,
|
ExNames = (PDWORD *)RVA(BaseAddress,
|
||||||
ExportDir->AddressOfNames);
|
ExportDir->AddressOfNames);
|
||||||
ExOrdinals = (USHORT *)RVA(BaseAddress,
|
ExOrdinals = (USHORT *)RVA(BaseAddress,
|
||||||
ExportDir->AddressOfNameOrdinals);
|
ExportDir->AddressOfNameOrdinals);
|
||||||
ExFunctions = (PDWORD *)RVA(BaseAddress,
|
ExFunctions = (PDWORD *)RVA(BaseAddress,
|
||||||
ExportDir->AddressOfFunctions);
|
ExportDir->AddressOfFunctions);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the hint first
|
* Check the hint first
|
||||||
*/
|
*/
|
||||||
if (Hint < ExportDir->NumberOfFunctions)
|
if (Hint < ExportDir->NumberOfFunctions)
|
||||||
{
|
{
|
||||||
ExName = RVA(BaseAddress, ExNames[Hint]);
|
ExName = RVA(BaseAddress, ExNames[Hint]);
|
||||||
if (strcmp(ExName, SymbolName) == 0)
|
if (strcmp(ExName, SymbolName) == 0)
|
||||||
{
|
{
|
||||||
Ordinal = ExOrdinals[Hint];
|
Ordinal = ExOrdinals[Hint];
|
||||||
return(RVA(BaseAddress, ExFunctions[Ordinal]));
|
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)
|
||||||
|
return Function;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try a binary search first
|
* Try a binary search first
|
||||||
*/
|
*/
|
||||||
minn = 0, maxn = ExportDir->NumberOfFunctions;
|
minn = 0, maxn = ExportDir->NumberOfFunctions;
|
||||||
while (minn <= maxn)
|
while (minn <= maxn)
|
||||||
{
|
{
|
||||||
ULONG mid;
|
ULONG mid;
|
||||||
LONG res;
|
LONG res;
|
||||||
|
|
||||||
mid = (minn + maxn) / 2;
|
mid = (minn + maxn) / 2;
|
||||||
|
|
||||||
ExName = RVA(BaseAddress, ExNames[mid]);
|
ExName = RVA(BaseAddress, ExNames[mid]);
|
||||||
res = strcmp(ExName, SymbolName);
|
res = strcmp(ExName, SymbolName);
|
||||||
if (res == 0)
|
if (res == 0)
|
||||||
{
|
{
|
||||||
Ordinal = ExOrdinals[mid];
|
Ordinal = ExOrdinals[mid];
|
||||||
return(RVA(BaseAddress, ExFunctions[Ordinal]));
|
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
|
||||||
}
|
if (((ULONG)Function >= (ULONG)ExportDir) &&
|
||||||
else if (res > 0)
|
((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
|
||||||
{
|
{
|
||||||
maxn = mid - 1;
|
DPRINT("Forward: %s\n", (PCHAR)Function);
|
||||||
}
|
Function = LdrFixupForward((PCHAR)Function);
|
||||||
else
|
}
|
||||||
{
|
if (Function != NULL)
|
||||||
minn = mid + 1;
|
return Function;
|
||||||
}
|
}
|
||||||
}
|
else if (res > 0)
|
||||||
/*
|
{
|
||||||
* Fall back on a linear search
|
maxn = mid - 1;
|
||||||
*/
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
minn = mid + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Fall back on a linear search
|
||||||
|
*/
|
||||||
|
|
||||||
DbgPrint("LDR: Falling back on a linear search of export table\n");
|
DbgPrint("LDR: Falling back on a linear search of export table\n");
|
||||||
for (i = 0; i < ExportDir->NumberOfFunctions; i++)
|
for (i = 0; i < ExportDir->NumberOfFunctions; i++)
|
||||||
{
|
{
|
||||||
ExName = RVA(BaseAddress, ExNames[i]);
|
ExName = RVA(BaseAddress, ExNames[i]);
|
||||||
if (strcmp(ExName,SymbolName) == 0)
|
if (strcmp(ExName,SymbolName) == 0)
|
||||||
{
|
{
|
||||||
Ordinal = ExOrdinals[i];
|
Ordinal = ExOrdinals[i];
|
||||||
return(RVA(BaseAddress, ExFunctions[Ordinal]));
|
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
|
||||||
}
|
DPRINT("%x %x %x\n", Function, ExportDir, ExportDir + ExportDirSize);
|
||||||
}
|
if (((ULONG)Function >= (ULONG)ExportDir) &&
|
||||||
DbgPrint("LdrGetExportByName() = failed to find %s\n",SymbolName);
|
((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
|
||||||
return NULL;
|
{
|
||||||
|
DPRINT("Forward: %s\n", (PCHAR)Function);
|
||||||
|
Function = LdrFixupForward((PCHAR)Function);
|
||||||
|
}
|
||||||
|
return Function;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DbgPrint("LdrGetExportByName() = failed to find %s\n",SymbolName);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1474,9 +1564,8 @@ LdrGetDllHandle (IN ULONG Unknown1,
|
||||||
{
|
{
|
||||||
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
|
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
|
||||||
|
|
||||||
DPRINT("EntryPoint %lu\n", Module->EntryPoint);
|
DPRINT("EntryPoint %x\n", Module->EntryPoint);
|
||||||
|
DPRINT("Comparing %wZ and %wZ\n",
|
||||||
DPRINT("Scanning %wZ %wZ\n",
|
|
||||||
&Module->BaseDllName,
|
&Module->BaseDllName,
|
||||||
&FullDllName);
|
&FullDllName);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue