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; ULONG Flags;
PVOID EntryPoint; PVOID EntryPoint;
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
UNICODE_STRING Name; UNICODE_STRING FullName;
UNICODE_STRING BaseName;
union union
{ {
struct struct

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -62,4 +62,21 @@ NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord,
UNIMPLEMENTED; UNIMPLEMENTED;
} }
VOID STDCALL
RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
{
}
VOID STDCALL
RtlUnwind(ULONG Unknown1,
ULONG Unknown2,
ULONG Unknown3,
ULONG Unknown4)
{
}
/* EOF */ /* EOF */

View file

@ -74,7 +74,7 @@ print_address(PVOID address)
if (address >= current->Base && if (address >= current->Base &&
address < (current->Base + current->Length)) address < (current->Base + current->Length))
{ {
DbgPrint("<%wZ: %x>", &current->Name, DbgPrint("<%wZ: %x>", &current->FullName,
address - current->Base); address - current->Base);
return(TRUE); 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -56,17 +56,17 @@ static NTSTATUS LdrCreateModule(PVOID ObjectBody,
PVOID Parent, PVOID Parent,
PWSTR RemainingPath, PWSTR RemainingPath,
POBJECT_ATTRIBUTES ObjectAttributes); POBJECT_ATTRIBUTES ObjectAttributes);
static VOID LdrpBuildModuleBaseName(PUNICODE_STRING BaseName,
PUNICODE_STRING FullName);
/* PE Driver load support */ /* PE Driver load support */
static PMODULE_OBJECT LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING FileName); static PMODULE_OBJECT LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING FileName);
static PVOID LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject, static PVOID LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
char *Name, char *Name,
unsigned short Hint); unsigned short Hint);
#if 0 static PMODULE_OBJECT LdrPEGetModuleObject(PUNICODE_STRING ModuleName);
static unsigned int LdrGetKernelSymbolAddr(char *Name); static PVOID LdrPEFixupForward(PCHAR ForwardName);
#endif
static PIMAGE_SECTION_HEADER LdrPEGetEnclosingSectionHeader(DWORD RVA,
PMODULE_OBJECT ModuleObject);
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -133,14 +133,18 @@ VOID LdrInitModuleManagement(VOID)
IoDriverObjectType); IoDriverObjectType);
assert(ModuleObject != NULL); assert(ModuleObject != NULL);
InitializeListHead(&ModuleListHead); InitializeListHead(&ModuleListHead);
/* Initialize ModuleObject data */
ModuleObject->Base = (PVOID) KERNEL_BASE;
ModuleObject->Flags = MODULE_FLAG_PE;
InsertTailList(&ModuleListHead,
&ModuleObject->ListEntry);
RtlCreateUnicodeString(&ModuleObject->FullName,
L"ntoskrnl.exe");
LdrpBuildModuleBaseName(&ModuleObject->BaseName,
&ModuleObject->FullName);
/* Initialize ModuleObject data */
ModuleObject->Base = (PVOID) KERNEL_BASE;
ModuleObject->Flags = MODULE_FLAG_PE;
InsertTailList(&ModuleListHead, &ModuleObject->ListEntry);
RtlCreateUnicodeString(&ModuleObject->Name,
L"ntoskrnl.exe");
DosHeader = (PIMAGE_DOS_HEADER) KERNEL_BASE; DosHeader = (PIMAGE_DOS_HEADER) KERNEL_BASE;
ModuleObject->Image.PE.FileHeader = ModuleObject->Image.PE.FileHeader =
(PIMAGE_FILE_HEADER) ((DWORD) ModuleObject->Base + (PIMAGE_FILE_HEADER) ((DWORD) ModuleObject->Base +
@ -519,7 +523,7 @@ LdrpQueryModuleInformation(PVOID Buffer,
AnsiName.MaximumLength = 256; AnsiName.MaximumLength = 256;
AnsiName.Buffer = Smi->Module[ModuleCount].Name; AnsiName.Buffer = Smi->Module[ModuleCount].Name;
RtlUnicodeStringToAnsiString(&AnsiName, RtlUnicodeStringToAnsiString(&AnsiName,
&current->Name, &current->FullName,
FALSE); FALSE);
p = strrchr (AnsiName.Buffer, '\\'); p = strrchr (AnsiName.Buffer, '\\');
@ -544,6 +548,45 @@ LdrpQueryModuleInformation(PVOID Buffer,
return STATUS_SUCCESS; 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 */ /* ---------------------------------------------- PE Module support */
PMODULE_OBJECT PMODULE_OBJECT
@ -855,11 +898,15 @@ LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING FileName)
&ObjectAttributes, &ObjectAttributes,
IoDriverObjectType); IoDriverObjectType);
/* Initialize ModuleObject data */ /* Initialize ModuleObject data */
ModuleObject->Base = DriverBase; ModuleObject->Base = DriverBase;
ModuleObject->Flags = MODULE_FLAG_PE; ModuleObject->Flags = MODULE_FLAG_PE;
InsertTailList(&ModuleListHead, &ModuleObject->ListEntry); InsertTailList(&ModuleListHead,
RtlCreateUnicodeString(&ModuleObject->Name, FileName->Buffer); &ModuleObject->ListEntry);
RtlCreateUnicodeString(&ModuleObject->FullName,
FileName->Buffer);
LdrpBuildModuleBaseName(&ModuleObject->BaseName,
&ModuleObject->FullName);
ModuleObject->EntryPoint = (PVOID) ((DWORD)DriverBase + ModuleObject->EntryPoint = (PVOID) ((DWORD)DriverBase +
PEOptionalHeader->AddressOfEntryPoint); PEOptionalHeader->AddressOfEntryPoint);
@ -888,41 +935,33 @@ LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
unsigned short Hint) unsigned short Hint)
{ {
WORD Idx; WORD Idx;
DWORD ExportsStartRVA, ExportsEndRVA;
PVOID ExportAddress; PVOID ExportAddress;
PWORD OrdinalList; PWORD OrdinalList;
PDWORD FunctionList, NameList; PDWORD FunctionList, NameList;
PIMAGE_SECTION_HEADER SectionHeader; PIMAGE_EXPORT_DIRECTORY ExportDir;
PIMAGE_EXPORT_DIRECTORY ExportDirectory; ULONG ExportDirSize;
ExportsStartRVA = ModuleObject->Image.PE.OptionalHeader->DataDirectory ExportDir = (PIMAGE_EXPORT_DIRECTORY)
[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; RtlImageDirectoryEntryToData(ModuleObject->Base,
ExportsEndRVA = ExportsStartRVA + TRUE,
ModuleObject->Image.PE.OptionalHeader->DataDirectory IMAGE_DIRECTORY_ENTRY_EXPORT,
[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; &ExportDirSize);
DPRINT("ExportDir %p ExportDirSize %lx\n", ExportDir, ExportDirSize);
if (ExportDir == NULL)
{
return NULL;
}
/* 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) FunctionList = (PDWORD)((DWORD)ExportDir->AddressOfFunctions + ModuleObject->Base);
{ NameList = (PDWORD)((DWORD)ExportDir->AddressOfNames + ModuleObject->Base);
return 0; OrdinalList = (PWORD)((DWORD)ExportDir->AddressOfNameOrdinals + ModuleObject->Base);
}
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);
ExportAddress = 0; ExportAddress = 0;
if (Name != NULL) if (Name != NULL)
{ {
for (Idx = 0; Idx < ExportDirectory->NumberOfNames; Idx++) for (Idx = 0; Idx < ExportDir->NumberOfNames; Idx++)
{ {
#if 0 #if 0
DPRINT(" Name:%s NameList[%d]:%s\n", DPRINT(" Name:%s NameList[%d]:%s\n",
@ -935,6 +974,14 @@ LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
{ {
ExportAddress = (PVOID) ((DWORD)ModuleObject->Base + ExportAddress = (PVOID) ((DWORD)ModuleObject->Base +
FunctionList[OrdinalList[Idx]]); 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; break;
} }
} }
@ -942,37 +989,91 @@ LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
else /* use hint */ else /* use hint */
{ {
ExportAddress = (PVOID) ((DWORD)ModuleObject->Base + 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,
Name != NULL ? Name : "(Ordinal)");
KeBugCheck(0);
} }
return ExportAddress; if (ExportAddress == 0)
{
DbgPrint("Export not found for %d:%s\n",
Hint,
Name != NULL ? Name : "(Ordinal)");
KeBugCheck(0);
}
return ExportAddress;
} }
static PIMAGE_SECTION_HEADER
LdrPEGetEnclosingSectionHeader(DWORD RVA, static PMODULE_OBJECT
PMODULE_OBJECT ModuleObject) LdrPEGetModuleObject(PUNICODE_STRING ModuleName)
{ {
PIMAGE_SECTION_HEADER SectionHeader = SECHDROFFSET(ModuleObject->Base); PLIST_ENTRY Entry;
unsigned i; PMODULE_OBJECT Module;
for (i = 0; i < ModuleObject->Image.PE.FileHeader->NumberOfSections; DPRINT("LdrPEGetModuleObject (ModuleName %wZ)\n",
i++, SectionHeader++) ModuleName);
{
/* Is the RVA within this section? */
if ((RVA >= SectionHeader->VirtualAddress) &&
(RVA < (SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize)))
{
return SectionHeader;
}
}
return 0; Entry = ModuleListHead.Flink;
while (Entry != &ModuleListHead)
{
Module = CONTAINING_RECORD(Entry, MODULE_OBJECT, ListEntry);
DPRINT("Comparing %wZ and %wZ\n",
&Module->BaseName,
ModuleName);
if (!RtlCompareUnicodeString(&Module->BaseName, ModuleName, TRUE))
{
DPRINT("Module %x\n", Module);
return Module;
}
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 */ /* 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 ; reactos/ntoskrnl/ntoskrnl.def
; ;
@ -752,7 +752,7 @@ RtlPrefixUnicodeString@12
;RtlQueryAtomInAtomTable ;RtlQueryAtomInAtomTable
RtlQueryRegistryValues@20 RtlQueryRegistryValues@20
;RtlQueryTimeZoneInformation ;RtlQueryTimeZoneInformation
;RtlRaiseException RtlRaiseException@4
;RtlRandom ;RtlRandom
;RtlRemoveUnicodePrefix ;RtlRemoveUnicodePrefix
;RtlReserveChunk ;RtlReserveChunk
@ -782,7 +782,7 @@ RtlUnicodeToCustomCPN@24
RtlUnicodeToMultiByteN@20 RtlUnicodeToMultiByteN@20
RtlUnicodeToMultiByteSize@12 RtlUnicodeToMultiByteSize@12
RtlUnicodeToOemN@20 RtlUnicodeToOemN@20
;RtlUnwind RtlUnwind@16
RtlUpcaseUnicodeChar@4 RtlUpcaseUnicodeChar@4
RtlUpcaseUnicodeString@12 RtlUpcaseUnicodeString@12
RtlUpcaseUnicodeStringToAnsiString@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 ; reactos/ntoskrnl/ntoskrnl.def
; ;
@ -750,7 +750,7 @@ RtlPrefixUnicodeString=RtlPrefixUnicodeString@12
;RtlQueryAtomInAtomTable ;RtlQueryAtomInAtomTable
RtlQueryRegistryValues=RtlQueryRegistryValues@20 RtlQueryRegistryValues=RtlQueryRegistryValues@20
;RtlQueryTimeZoneInformation ;RtlQueryTimeZoneInformation
;RtlRaiseException RtlRaiseException=RtlRaiseException@4
;RtlRandom ;RtlRandom
;RtlRemoveUnicodePrefix ;RtlRemoveUnicodePrefix
;RtlReserveChunk ;RtlReserveChunk
@ -780,7 +780,7 @@ RtlUnicodeToCustomCPN=RtlUnicodeToCustomCPN@24
RtlUnicodeToMultiByteN=RtlUnicodeToMultiByteN@20 RtlUnicodeToMultiByteN=RtlUnicodeToMultiByteN@20
RtlUnicodeToMultiByteSize=RtlUnicodeToMultiByteSize@12 RtlUnicodeToMultiByteSize=RtlUnicodeToMultiByteSize@12
RtlUnicodeToOemN=RtlUnicodeToOemN@20 RtlUnicodeToOemN=RtlUnicodeToOemN@20
;RtlUnwind RtlUnwind=RtlUnwind@16
RtlUpcaseUnicodeChar=RtlUpcaseUnicodeChar@4 RtlUpcaseUnicodeChar=RtlUpcaseUnicodeChar@4
RtlUpcaseUnicodeString=RtlUpcaseUnicodeString@12 RtlUpcaseUnicodeString=RtlUpcaseUnicodeString@12
RtlUpcaseUnicodeStringToAnsiString=RtlUpcaseUnicodeStringToAnsiString@12 RtlUpcaseUnicodeStringToAnsiString=RtlUpcaseUnicodeStringToAnsiString@12