mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Implemented forwarded exports in kernel-mode
svn path=/trunk/; revision=1646
This commit is contained in:
parent
c1c75ffd5e
commit
3121974d42
6 changed files with 195 additions and 76 deletions
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -74,7 +74,7 @@ print_address(PVOID address)
|
|||
if (address >= current->Base &&
|
||||
address < (current->Base + current->Length))
|
||||
{
|
||||
DbgPrint("<%wZ: %x>", ¤t->Name,
|
||||
DbgPrint("<%wZ: %x>", ¤t->FullName,
|
||||
address - current->Base);
|
||||
return(TRUE);
|
||||
}
|
||||
|
|
|
@ -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 *****************************************************************/
|
||||
|
||||
|
@ -133,14 +133,18 @@ VOID LdrInitModuleManagement(VOID)
|
|||
IoDriverObjectType);
|
||||
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;
|
||||
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,
|
||||
¤t->Name,
|
||||
¤t->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
|
||||
|
@ -855,11 +898,15 @@ LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING FileName)
|
|||
&ObjectAttributes,
|
||||
IoDriverObjectType);
|
||||
|
||||
/* Initialize ModuleObject data */
|
||||
ModuleObject->Base = DriverBase;
|
||||
ModuleObject->Flags = MODULE_FLAG_PE;
|
||||
InsertTailList(&ModuleListHead, &ModuleObject->ListEntry);
|
||||
RtlCreateUnicodeString(&ModuleObject->Name, FileName->Buffer);
|
||||
/* Initialize ModuleObject data */
|
||||
ModuleObject->Base = DriverBase;
|
||||
ModuleObject->Flags = MODULE_FLAG_PE;
|
||||
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;
|
||||
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 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)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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,37 +989,91 @@ LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
|
|||
else /* use hint */
|
||||
{
|
||||
ExportAddress = (PVOID) ((DWORD)ModuleObject->Base +
|
||||
FunctionList[Hint - ExportDirectory->Base]);
|
||||
}
|
||||
if (ExportAddress == 0)
|
||||
{
|
||||
DbgPrint("Export not found for %d:%s\n", Hint,
|
||||
Name != NULL ? Name : "(Ordinal)");
|
||||
KeBugCheck(0);
|
||||
FunctionList[Hint - ExportDir->Base]);
|
||||
}
|
||||
|
||||
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,
|
||||
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++)
|
||||
{
|
||||
/* Is the RVA within this section? */
|
||||
if ((RVA >= SectionHeader->VirtualAddress) &&
|
||||
(RVA < (SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize)))
|
||||
{
|
||||
return SectionHeader;
|
||||
}
|
||||
}
|
||||
DPRINT("LdrPEGetModuleObject (ModuleName %wZ)\n",
|
||||
ModuleName);
|
||||
|
||||
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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue