Implemented forwarded exports in kernel-mode

svn path=/trunk/; revision=1646
This commit is contained in:
Eric Kohl 2001-02-21 18:19:19 +00:00
parent c1c75ffd5e
commit 3121974d42
6 changed files with 195 additions and 76 deletions

View file

@ -14,7 +14,8 @@ typedef struct _MODULE_OBJECT
ULONG Flags;
PVOID EntryPoint;
LIST_ENTRY ListEntry;
UNICODE_STRING Name;
UNICODE_STRING FullName;
UNICODE_STRING BaseName;
union
{
struct

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: catch.c,v 1.8 2000/12/23 02:37:40 dwelch Exp $
/* $Id: catch.c,v 1.9 2001/02/21 18:17:57 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -62,4 +62,21 @@ NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord,
UNIMPLEMENTED;
}
VOID STDCALL
RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
{
}
VOID STDCALL
RtlUnwind(ULONG Unknown1,
ULONG Unknown2,
ULONG Unknown3,
ULONG Unknown4)
{
}
/* EOF */

View file

@ -74,7 +74,7 @@ print_address(PVOID address)
if (address >= current->Base &&
address < (current->Base + current->Length))
{
DbgPrint("<%wZ: %x>", &current->Name,
DbgPrint("<%wZ: %x>", &current->FullName,
address - current->Base);
return(TRUE);
}

View file

@ -1,4 +1,4 @@
/* $Id: loader.c,v 1.66 2001/01/18 16:55:00 ekohl Exp $
/* $Id: loader.c,v 1.67 2001/02/21 18:18:31 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -56,17 +56,17 @@ static NTSTATUS LdrCreateModule(PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
POBJECT_ATTRIBUTES ObjectAttributes);
static VOID LdrpBuildModuleBaseName(PUNICODE_STRING BaseName,
PUNICODE_STRING FullName);
/* PE Driver load support */
static PMODULE_OBJECT LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING FileName);
static PVOID LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
char *Name,
unsigned short Hint);
#if 0
static unsigned int LdrGetKernelSymbolAddr(char *Name);
#endif
static PIMAGE_SECTION_HEADER LdrPEGetEnclosingSectionHeader(DWORD RVA,
PMODULE_OBJECT ModuleObject);
static PMODULE_OBJECT LdrPEGetModuleObject(PUNICODE_STRING ModuleName);
static PVOID LdrPEFixupForward(PCHAR ForwardName);
/* FUNCTIONS *****************************************************************/
@ -138,9 +138,13 @@ VOID LdrInitModuleManagement(VOID)
/* Initialize ModuleObject data */
ModuleObject->Base = (PVOID) KERNEL_BASE;
ModuleObject->Flags = MODULE_FLAG_PE;
InsertTailList(&ModuleListHead, &ModuleObject->ListEntry);
RtlCreateUnicodeString(&ModuleObject->Name,
InsertTailList(&ModuleListHead,
&ModuleObject->ListEntry);
RtlCreateUnicodeString(&ModuleObject->FullName,
L"ntoskrnl.exe");
LdrpBuildModuleBaseName(&ModuleObject->BaseName,
&ModuleObject->FullName);
DosHeader = (PIMAGE_DOS_HEADER) KERNEL_BASE;
ModuleObject->Image.PE.FileHeader =
(PIMAGE_FILE_HEADER) ((DWORD) ModuleObject->Base +
@ -519,7 +523,7 @@ LdrpQueryModuleInformation(PVOID Buffer,
AnsiName.MaximumLength = 256;
AnsiName.Buffer = Smi->Module[ModuleCount].Name;
RtlUnicodeStringToAnsiString(&AnsiName,
&current->Name,
&current->FullName,
FALSE);
p = strrchr (AnsiName.Buffer, '\\');
@ -544,6 +548,45 @@ LdrpQueryModuleInformation(PVOID Buffer,
return STATUS_SUCCESS;
}
static VOID
LdrpBuildModuleBaseName(PUNICODE_STRING BaseName,
PUNICODE_STRING FullName)
{
UNICODE_STRING Name;
PWCHAR p;
PWCHAR q;
DPRINT("LdrpBuildModuleBaseName()\n");
DPRINT("FullName %wZ\n", FullName);
p = wcsrchr(FullName->Buffer, '\\');
if (p == NULL)
{
p = FullName->Buffer;
}
else
{
p++;
}
DPRINT("p %S\n", p);
RtlCreateUnicodeString(&Name, p);
q = wcschr(p, '.');
if (q != NULL)
{
*q = (WCHAR)0;
}
DPRINT("p %S\n", p);
RtlCreateUnicodeString(BaseName, p);
RtlFreeUnicodeString(&Name);
}
/* ---------------------------------------------- PE Module support */
PMODULE_OBJECT
@ -858,8 +901,12 @@ LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING FileName)
/* Initialize ModuleObject data */
ModuleObject->Base = DriverBase;
ModuleObject->Flags = MODULE_FLAG_PE;
InsertTailList(&ModuleListHead, &ModuleObject->ListEntry);
RtlCreateUnicodeString(&ModuleObject->Name, FileName->Buffer);
InsertTailList(&ModuleListHead,
&ModuleObject->ListEntry);
RtlCreateUnicodeString(&ModuleObject->FullName,
FileName->Buffer);
LdrpBuildModuleBaseName(&ModuleObject->BaseName,
&ModuleObject->FullName);
ModuleObject->EntryPoint = (PVOID) ((DWORD)DriverBase +
PEOptionalHeader->AddressOfEntryPoint);
@ -888,41 +935,33 @@ LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
unsigned short Hint)
{
WORD Idx;
DWORD ExportsStartRVA, ExportsEndRVA;
PVOID ExportAddress;
PWORD OrdinalList;
PDWORD FunctionList, NameList;
PIMAGE_SECTION_HEADER SectionHeader;
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
PIMAGE_EXPORT_DIRECTORY ExportDir;
ULONG ExportDirSize;
ExportsStartRVA = ModuleObject->Image.PE.OptionalHeader->DataDirectory
[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
ExportsEndRVA = ExportsStartRVA +
ModuleObject->Image.PE.OptionalHeader->DataDirectory
[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
/* Get the IMAGE_SECTION_HEADER that contains the exports. This is
usually the .edata section, but doesn't have to be. */
SectionHeader = LdrPEGetEnclosingSectionHeader(ExportsStartRVA, ModuleObject);
if (!SectionHeader)
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
RtlImageDirectoryEntryToData(ModuleObject->Base,
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&ExportDirSize);
DPRINT("ExportDir %p ExportDirSize %lx\n", ExportDir, ExportDirSize);
if (ExportDir == NULL)
{
return 0;
return NULL;
}
ExportDirectory = MakePtr(PIMAGE_EXPORT_DIRECTORY,
ModuleObject->Base,
SectionHeader->VirtualAddress);
FunctionList = (PDWORD)((DWORD)ExportDirectory->AddressOfFunctions + ModuleObject->Base);
NameList = (PDWORD)((DWORD)ExportDirectory->AddressOfNames + ModuleObject->Base);
OrdinalList = (PWORD)((DWORD)ExportDirectory->AddressOfNameOrdinals + ModuleObject->Base);
FunctionList = (PDWORD)((DWORD)ExportDir->AddressOfFunctions + ModuleObject->Base);
NameList = (PDWORD)((DWORD)ExportDir->AddressOfNames + ModuleObject->Base);
OrdinalList = (PWORD)((DWORD)ExportDir->AddressOfNameOrdinals + ModuleObject->Base);
ExportAddress = 0;
if (Name != NULL)
{
for (Idx = 0; Idx < ExportDirectory->NumberOfNames; Idx++)
for (Idx = 0; Idx < ExportDir->NumberOfNames; Idx++)
{
#if 0
DPRINT(" Name:%s NameList[%d]:%s\n",
@ -935,6 +974,14 @@ LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
{
ExportAddress = (PVOID) ((DWORD)ModuleObject->Base +
FunctionList[OrdinalList[Idx]]);
if (((ULONG)ExportAddress >= (ULONG)ExportDir) &&
((ULONG)ExportAddress < (ULONG)ExportDir + ExportDirSize))
{
DPRINT("Forward: %s\n", (PCHAR)ExportAddress);
ExportAddress = LdrPEFixupForward((PCHAR)ExportAddress);
DPRINT("ExportAddress: %p\n", ExportAddress);
}
break;
}
}
@ -942,11 +989,13 @@ LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
else /* use hint */
{
ExportAddress = (PVOID) ((DWORD)ModuleObject->Base +
FunctionList[Hint - ExportDirectory->Base]);
FunctionList[Hint - ExportDir->Base]);
}
if (ExportAddress == 0)
{
DbgPrint("Export not found for %d:%s\n", Hint,
DbgPrint("Export not found for %d:%s\n",
Hint,
Name != NULL ? Name : "(Ordinal)");
KeBugCheck(0);
}
@ -954,25 +1003,77 @@ LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
return ExportAddress;
}
static PIMAGE_SECTION_HEADER
LdrPEGetEnclosingSectionHeader(DWORD RVA,
PMODULE_OBJECT ModuleObject)
static PMODULE_OBJECT
LdrPEGetModuleObject(PUNICODE_STRING ModuleName)
{
PIMAGE_SECTION_HEADER SectionHeader = SECHDROFFSET(ModuleObject->Base);
unsigned i;
PLIST_ENTRY Entry;
PMODULE_OBJECT Module;
for (i = 0; i < ModuleObject->Image.PE.FileHeader->NumberOfSections;
i++, SectionHeader++)
DPRINT("LdrPEGetModuleObject (ModuleName %wZ)\n",
ModuleName);
Entry = ModuleListHead.Flink;
while (Entry != &ModuleListHead)
{
/* Is the RVA within this section? */
if ((RVA >= SectionHeader->VirtualAddress) &&
(RVA < (SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize)))
Module = CONTAINING_RECORD(Entry, MODULE_OBJECT, ListEntry);
DPRINT("Comparing %wZ and %wZ\n",
&Module->BaseName,
ModuleName);
if (!RtlCompareUnicodeString(&Module->BaseName, ModuleName, TRUE))
{
return SectionHeader;
}
DPRINT("Module %x\n", Module);
return Module;
}
return 0;
Entry = Entry->Flink;
}
DbgPrint("LdrPEGetModuleObject: Failed to find dll %wZ\n", ModuleName);
return NULL;
}
static PVOID
LdrPEFixupForward(PCHAR ForwardName)
{
CHAR NameBuffer[128];
UNICODE_STRING ModuleName;
PCHAR p;
PMODULE_OBJECT ModuleObject;
DPRINT("LdrPEFixupForward (%s)\n", ForwardName);
strcpy(NameBuffer, ForwardName);
p = strchr(NameBuffer, '.');
if (p == NULL)
{
return NULL;
}
*p = 0;
DPRINT("Driver: %s Function: %s\n", NameBuffer, p+1);
RtlCreateUnicodeStringFromAsciiz(&ModuleName,
NameBuffer);
ModuleObject = LdrPEGetModuleObject(&ModuleName);
RtlFreeUnicodeString(&ModuleName);
DPRINT("ModuleObject: %p\n", ModuleObject);
if (ModuleObject == NULL)
{
DbgPrint("LdrPEFixupForward: failed to find module %s\n", NameBuffer);
return NULL;
}
return LdrPEGetExportAddress(ModuleObject, p+1, 0);
}
/* EOF */

View file

@ -1,4 +1,4 @@
; $Id: ntoskrnl.def,v 1.97 2001/02/18 19:43:14 phreak Exp $
; $Id: ntoskrnl.def,v 1.98 2001/02/21 18:19:19 ekohl Exp $
;
; reactos/ntoskrnl/ntoskrnl.def
;
@ -752,7 +752,7 @@ RtlPrefixUnicodeString@12
;RtlQueryAtomInAtomTable
RtlQueryRegistryValues@20
;RtlQueryTimeZoneInformation
;RtlRaiseException
RtlRaiseException@4
;RtlRandom
;RtlRemoveUnicodePrefix
;RtlReserveChunk
@ -782,7 +782,7 @@ RtlUnicodeToCustomCPN@24
RtlUnicodeToMultiByteN@20
RtlUnicodeToMultiByteSize@12
RtlUnicodeToOemN@20
;RtlUnwind
RtlUnwind@16
RtlUpcaseUnicodeChar@4
RtlUpcaseUnicodeString@12
RtlUpcaseUnicodeStringToAnsiString@12

View file

@ -1,4 +1,4 @@
; $Id: ntoskrnl.edf,v 1.84 2001/02/18 19:43:14 phreak Exp $
; $Id: ntoskrnl.edf,v 1.85 2001/02/21 18:19:19 ekohl Exp $
;
; reactos/ntoskrnl/ntoskrnl.def
;
@ -750,7 +750,7 @@ RtlPrefixUnicodeString=RtlPrefixUnicodeString@12
;RtlQueryAtomInAtomTable
RtlQueryRegistryValues=RtlQueryRegistryValues@20
;RtlQueryTimeZoneInformation
;RtlRaiseException
RtlRaiseException=RtlRaiseException@4
;RtlRandom
;RtlRemoveUnicodePrefix
;RtlReserveChunk
@ -780,7 +780,7 @@ RtlUnicodeToCustomCPN=RtlUnicodeToCustomCPN@24
RtlUnicodeToMultiByteN=RtlUnicodeToMultiByteN@20
RtlUnicodeToMultiByteSize=RtlUnicodeToMultiByteSize@12
RtlUnicodeToOemN=RtlUnicodeToOemN@20
;RtlUnwind
RtlUnwind=RtlUnwind@16
RtlUpcaseUnicodeChar=RtlUpcaseUnicodeChar@4
RtlUpcaseUnicodeString=RtlUpcaseUnicodeString@12
RtlUpcaseUnicodeStringToAnsiString=RtlUpcaseUnicodeStringToAnsiString@12