mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[NTOS:MM/PS] Remove code duplication between LookupEntryPoint/MiLocateExportName/MiFindExportedRoutineByName. (#4918)
As it turns out, those three functions were duplicating the same code between each other. Reimplement these in terms of a common helper, RtlFindExportedRoutineByName(). Indeed: MiFindExportedRoutineByName() was just MiLocateExportName() but taking a PANSI_STRING instead of a NULL-terminated string. A similar state of affairs also existed in Windows <= 2003, and the MS guys also noticed it. Both routines have been then merged and renamed to MiFindExportedRoutineByName() on Windows 8 (taking a PCSTR instead), and finally renamed and exported as RtlFindExportedRoutineByName() on Windows 10.
This commit is contained in:
parent
d8695eee1e
commit
86e0d5e9b8
4 changed files with 168 additions and 163 deletions
|
@ -1490,16 +1490,15 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MmFreeSectionSegments(PFILE_OBJECT FileObject);
|
MmFreeSectionSegments(PFILE_OBJECT FileObject);
|
||||||
|
|
||||||
/* Exported from NT 6.2 Onward. We keep it internal. */
|
/* Exported from NT 6.2 onward. We keep it internal. */
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MmMapViewInSystemSpaceEx (
|
MmMapViewInSystemSpaceEx(
|
||||||
_In_ PVOID Section,
|
_In_ PVOID Section,
|
||||||
_Outptr_result_bytebuffer_ (*ViewSize) PVOID *MappedBase,
|
_Outptr_result_bytebuffer_ (*ViewSize) PVOID *MappedBase,
|
||||||
_Inout_ PSIZE_T ViewSize,
|
_Inout_ PSIZE_T ViewSize,
|
||||||
_Inout_ PLARGE_INTEGER SectionOffset,
|
_Inout_ PLARGE_INTEGER SectionOffset,
|
||||||
_In_ ULONG_PTR Flags
|
_In_ ULONG_PTR Flags);
|
||||||
);
|
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -1661,6 +1660,23 @@ NTAPI
|
||||||
MmFreeDriverInitialization(
|
MmFreeDriverInitialization(
|
||||||
IN PLDR_DATA_TABLE_ENTRY LdrEntry);
|
IN PLDR_DATA_TABLE_ENTRY LdrEntry);
|
||||||
|
|
||||||
|
/* ReactOS-only, used by psmgr.c PspLookupSystemDllEntryPoint() as well */
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
RtlpFindExportedRoutineByName(
|
||||||
|
_In_ PVOID ImageBase,
|
||||||
|
_In_ PCSTR ExportName,
|
||||||
|
_Out_ PVOID* Function,
|
||||||
|
_Out_opt_ PBOOLEAN IsForwarder,
|
||||||
|
_In_ NTSTATUS NotFoundStatus);
|
||||||
|
|
||||||
|
/* Exported from NT 10.0 onward. We keep it internal. */
|
||||||
|
PVOID
|
||||||
|
NTAPI
|
||||||
|
RtlFindExportedRoutineByName(
|
||||||
|
_In_ PVOID ImageBase,
|
||||||
|
_In_ PCSTR ExportName);
|
||||||
|
|
||||||
/* procsup.c *****************************************************************/
|
/* procsup.c *****************************************************************/
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -134,12 +134,6 @@ PsLocateSystemDll(
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
PspGetSystemDllEntryPoints(
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
PsChangeQuantumTable(
|
PsChangeQuantumTable(
|
||||||
|
|
|
@ -267,60 +267,163 @@ NameToOrdinal(
|
||||||
return OrdinalTable[Mid];
|
return OrdinalTable[Mid];
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID
|
/**
|
||||||
|
* @brief
|
||||||
|
* ReactOS-only helper routine for RtlFindExportedRoutineByName(),
|
||||||
|
* that provides a finer granularity regarding the nature of the
|
||||||
|
* export, and the failure reasons.
|
||||||
|
*
|
||||||
|
* @param[in] ImageBase
|
||||||
|
* The base address of the loaded image.
|
||||||
|
*
|
||||||
|
* @param[in] ExportName
|
||||||
|
* The name of the export, given as an ANSI NULL-terminated string.
|
||||||
|
*
|
||||||
|
* @param[out] Function
|
||||||
|
* The address of the named exported routine, or NULL if not found.
|
||||||
|
* If the export is a forwarder (see @p IsForwarder below), this
|
||||||
|
* address points to the forwarder name.
|
||||||
|
*
|
||||||
|
* @param[out] IsForwarder
|
||||||
|
* An optional pointer to a BOOLEAN variable, that is set to TRUE
|
||||||
|
* if the found export is a forwarder, and FALSE otherwise.
|
||||||
|
*
|
||||||
|
* @param[in] NotFoundStatus
|
||||||
|
* The status code to return in case the export could not be found
|
||||||
|
* (examples: STATUS_ENTRYPOINT_NOT_FOUND, STATUS_PROCEDURE_NOT_FOUND).
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* A status code as follows:
|
||||||
|
* - STATUS_SUCCESS if the named exported routine is found;
|
||||||
|
* - The custom @p NotFoundStatus if the export could not be found;
|
||||||
|
* - STATUS_INVALID_PARAMETER if the image is invalid or does not
|
||||||
|
* contain an Export Directory.
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* See RtlFindExportedRoutineByName() for more remarks.
|
||||||
|
* Used by psmgr.c PspLookupSystemDllEntryPoint() as well.
|
||||||
|
**/
|
||||||
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MiLocateExportName(IN PVOID DllBase,
|
RtlpFindExportedRoutineByName(
|
||||||
IN PCHAR ExportName)
|
_In_ PVOID ImageBase,
|
||||||
|
_In_ PCSTR ExportName,
|
||||||
|
_Out_ PVOID* Function,
|
||||||
|
_Out_opt_ PBOOLEAN IsForwarder,
|
||||||
|
_In_ NTSTATUS NotFoundStatus)
|
||||||
{
|
{
|
||||||
|
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
|
||||||
PULONG NameTable;
|
PULONG NameTable;
|
||||||
PUSHORT OrdinalTable;
|
PUSHORT OrdinalTable;
|
||||||
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
|
|
||||||
USHORT Ordinal;
|
|
||||||
PVOID Function;
|
|
||||||
ULONG ExportSize;
|
ULONG ExportSize;
|
||||||
|
USHORT Ordinal;
|
||||||
PULONG ExportTable;
|
PULONG ExportTable;
|
||||||
|
ULONG_PTR FunctionAddress;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Get the export directory */
|
/* Get the export directory */
|
||||||
ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
|
ExportDirectory = RtlImageDirectoryEntryToData(ImageBase,
|
||||||
TRUE,
|
TRUE,
|
||||||
IMAGE_DIRECTORY_ENTRY_EXPORT,
|
IMAGE_DIRECTORY_ENTRY_EXPORT,
|
||||||
&ExportSize);
|
&ExportSize);
|
||||||
if (!ExportDirectory) return NULL;
|
if (!ExportDirectory)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
/* Setup name tables */
|
/* Setup name tables */
|
||||||
NameTable = (PULONG)((ULONG_PTR)DllBase +
|
NameTable = (PULONG)RVA(ImageBase, ExportDirectory->AddressOfNames);
|
||||||
ExportDirectory->AddressOfNames);
|
OrdinalTable = (PUSHORT)RVA(ImageBase, ExportDirectory->AddressOfNameOrdinals);
|
||||||
OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
|
|
||||||
ExportDirectory->AddressOfNameOrdinals);
|
|
||||||
|
|
||||||
/* Get the ordinal */
|
/* Get the ordinal */
|
||||||
Ordinal = NameToOrdinal(ExportName,
|
Ordinal = NameToOrdinal(ExportName,
|
||||||
DllBase,
|
ImageBase,
|
||||||
ExportDirectory->NumberOfNames,
|
ExportDirectory->NumberOfNames,
|
||||||
NameTable,
|
NameTable,
|
||||||
OrdinalTable);
|
OrdinalTable);
|
||||||
|
|
||||||
/* Check if we couldn't find it */
|
/* Check if we couldn't find it */
|
||||||
if (Ordinal == -1) return NULL;
|
if (Ordinal == -1)
|
||||||
|
return NotFoundStatus;
|
||||||
|
|
||||||
/* Validate the ordinal */
|
/* Validate the ordinal */
|
||||||
if (Ordinal >= ExportDirectory->NumberOfFunctions) return NULL;
|
if (Ordinal >= ExportDirectory->NumberOfFunctions)
|
||||||
|
return NotFoundStatus;
|
||||||
|
|
||||||
/* Resolve the address and write it */
|
/* Resolve the function's address */
|
||||||
ExportTable = (PULONG)((ULONG_PTR)DllBase +
|
ExportTable = (PULONG)RVA(ImageBase, ExportDirectory->AddressOfFunctions);
|
||||||
ExportDirectory->AddressOfFunctions);
|
FunctionAddress = (ULONG_PTR)RVA(ImageBase, ExportTable[Ordinal]);
|
||||||
Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
|
|
||||||
|
|
||||||
/* Check if the function is actually a forwarder */
|
/* Check if the function is actually a forwarder */
|
||||||
if (((ULONG_PTR)Function > (ULONG_PTR)ExportDirectory) &&
|
if (IsForwarder)
|
||||||
((ULONG_PTR)Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
|
|
||||||
{
|
{
|
||||||
/* It is, fail */
|
*IsForwarder = FALSE;
|
||||||
|
if ((FunctionAddress > (ULONG_PTR)ExportDirectory) &&
|
||||||
|
(FunctionAddress < (ULONG_PTR)ExportDirectory + ExportSize))
|
||||||
|
{
|
||||||
|
/* It is, and points to the forwarder name */
|
||||||
|
*IsForwarder = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We've found it */
|
||||||
|
*Function = (PVOID)FunctionAddress;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Finds the address of a given named exported routine in a loaded image.
|
||||||
|
* Note that this function does not support forwarders.
|
||||||
|
*
|
||||||
|
* @param[in] ImageBase
|
||||||
|
* The base address of the loaded image.
|
||||||
|
*
|
||||||
|
* @param[in] ExportName
|
||||||
|
* The name of the export, given as an ANSI NULL-terminated string.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The address of the named exported routine, or NULL if not found.
|
||||||
|
* If the export is a forwarder, this function returns NULL as well.
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* This routine was originally named MiLocateExportName(), with a separate
|
||||||
|
* duplicated MiFindExportedRoutineByName() one (taking a PANSI_STRING)
|
||||||
|
* on Windows <= 2003. Both routines have been then merged and renamed
|
||||||
|
* to MiFindExportedRoutineByName() on Windows 8 (taking a PCSTR instead),
|
||||||
|
* and finally renamed and exported as RtlFindExportedRoutineByName() on
|
||||||
|
* Windows 10.
|
||||||
|
*
|
||||||
|
* @see https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/mm/sysload/mmgetsystemroutineaddress.htm
|
||||||
|
**/
|
||||||
|
PVOID
|
||||||
|
NTAPI
|
||||||
|
RtlFindExportedRoutineByName(
|
||||||
|
_In_ PVOID ImageBase,
|
||||||
|
_In_ PCSTR ExportName)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
BOOLEAN IsForwarder = FALSE;
|
||||||
|
PVOID Function;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Call the internal API */
|
||||||
|
Status = RtlpFindExportedRoutineByName(ImageBase,
|
||||||
|
ExportName,
|
||||||
|
&Function,
|
||||||
|
&IsForwarder,
|
||||||
|
STATUS_ENTRYPOINT_NOT_FOUND);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* If the export is actually a forwarder, log the error and fail */
|
||||||
|
if (IsForwarder)
|
||||||
|
{
|
||||||
|
DPRINT1("RtlFindExportedRoutineByName does not support forwarders!\n", FALSE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We found it */
|
/* We've found the export */
|
||||||
return Function;
|
return Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,8 +443,8 @@ MmCallDllInitialize(
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Try to see if the image exports a DllInitialize routine */
|
/* Try to see if the image exports a DllInitialize routine */
|
||||||
DllInit = (PMM_DLL_INITIALIZE)MiLocateExportName(LdrEntry->DllBase,
|
DllInit = (PMM_DLL_INITIALIZE)
|
||||||
"DllInitialize");
|
RtlFindExportedRoutineByName(LdrEntry->DllBase, "DllInitialize");
|
||||||
if (!DllInit)
|
if (!DllInit)
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
@ -399,7 +502,8 @@ MiCallDllUnloadAndUnloadDll(
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Retrieve the DllUnload routine */
|
/* Retrieve the DllUnload routine */
|
||||||
DllUnload = (PMM_DLL_UNLOAD)MiLocateExportName(LdrEntry->DllBase, "DllUnload");
|
DllUnload = (PMM_DLL_UNLOAD)
|
||||||
|
RtlFindExportedRoutineByName(LdrEntry->DllBase, "DllUnload");
|
||||||
if (!DllUnload)
|
if (!DllUnload)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -512,58 +616,6 @@ MiClearImports(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
|
||||||
LdrEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
|
LdrEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID
|
|
||||||
NTAPI
|
|
||||||
MiFindExportedRoutineByName(IN PVOID DllBase,
|
|
||||||
IN PANSI_STRING ExportName)
|
|
||||||
{
|
|
||||||
PULONG NameTable;
|
|
||||||
PUSHORT OrdinalTable;
|
|
||||||
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
|
|
||||||
USHORT Ordinal;
|
|
||||||
PVOID Function;
|
|
||||||
ULONG ExportSize;
|
|
||||||
PULONG ExportTable;
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
/* Get the export directory */
|
|
||||||
ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
|
|
||||||
TRUE,
|
|
||||||
IMAGE_DIRECTORY_ENTRY_EXPORT,
|
|
||||||
&ExportSize);
|
|
||||||
if (!ExportDirectory) return NULL;
|
|
||||||
|
|
||||||
/* Setup name tables */
|
|
||||||
NameTable = (PULONG)((ULONG_PTR)DllBase +
|
|
||||||
ExportDirectory->AddressOfNames);
|
|
||||||
OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
|
|
||||||
ExportDirectory->AddressOfNameOrdinals);
|
|
||||||
|
|
||||||
/* Get the ordinal */
|
|
||||||
Ordinal = NameToOrdinal(ExportName->Buffer,
|
|
||||||
DllBase,
|
|
||||||
ExportDirectory->NumberOfNames,
|
|
||||||
NameTable,
|
|
||||||
OrdinalTable);
|
|
||||||
|
|
||||||
/* Check if we couldn't find it */
|
|
||||||
if (Ordinal == -1) return NULL;
|
|
||||||
|
|
||||||
/* Validate the ordinal */
|
|
||||||
if (Ordinal >= ExportDirectory->NumberOfFunctions) return NULL;
|
|
||||||
|
|
||||||
/* Resolve the address and write it */
|
|
||||||
ExportTable = (PULONG)((ULONG_PTR)DllBase +
|
|
||||||
ExportDirectory->AddressOfFunctions);
|
|
||||||
Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
|
|
||||||
|
|
||||||
/* We found it! */
|
|
||||||
ASSERT((Function < (PVOID)ExportDirectory) ||
|
|
||||||
(Function > (PVOID)((ULONG_PTR)ExportDirectory + ExportSize)));
|
|
||||||
|
|
||||||
return Function;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MiProcessLoaderEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
|
MiProcessLoaderEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
|
||||||
|
@ -720,6 +772,7 @@ MiSnapThunk(IN PVOID DllBase,
|
||||||
PIMAGE_IMPORT_BY_NAME ForwardName;
|
PIMAGE_IMPORT_BY_NAME ForwardName;
|
||||||
SIZE_T ForwardLength;
|
SIZE_T ForwardLength;
|
||||||
IMAGE_THUNK_DATA ForwardThunk;
|
IMAGE_THUNK_DATA ForwardThunk;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Check if this is an ordinal */
|
/* Check if this is an ordinal */
|
||||||
|
@ -740,7 +793,7 @@ MiSnapThunk(IN PVOID DllBase,
|
||||||
/* Copy the procedure name */
|
/* Copy the procedure name */
|
||||||
RtlStringCbCopyA(*MissingApi,
|
RtlStringCbCopyA(*MissingApi,
|
||||||
MAXIMUM_FILENAME_LENGTH,
|
MAXIMUM_FILENAME_LENGTH,
|
||||||
(PCHAR)&NameImport->Name[0]);
|
(PCHAR)NameImport->Name);
|
||||||
|
|
||||||
/* Setup name tables */
|
/* Setup name tables */
|
||||||
DPRINT("Import name: %s\n", NameImport->Name);
|
DPRINT("Import name: %s\n", NameImport->Name);
|
||||||
|
@ -775,10 +828,10 @@ MiSnapThunk(IN PVOID DllBase,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the ordinal is invalid */
|
/* Check if the ordinal is valid */
|
||||||
if (Ordinal >= ExportDirectory->NumberOfFunctions)
|
if (Ordinal >= ExportDirectory->NumberOfFunctions)
|
||||||
{
|
{
|
||||||
/* Fail */
|
/* It's not, fail */
|
||||||
Status = STATUS_DRIVER_ORDINAL_NOT_FOUND;
|
Status = STATUS_DRIVER_ORDINAL_NOT_FOUND;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -796,7 +849,7 @@ MiSnapThunk(IN PVOID DllBase,
|
||||||
|
|
||||||
/* Check if the function is actually a forwarder */
|
/* Check if the function is actually a forwarder */
|
||||||
if ((Address->u1.Function > (ULONG_PTR)ExportDirectory) &&
|
if ((Address->u1.Function > (ULONG_PTR)ExportDirectory) &&
|
||||||
(Address->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
|
(Address->u1.Function < (ULONG_PTR)ExportDirectory + ExportSize))
|
||||||
{
|
{
|
||||||
/* Now assume failure in case the forwarder doesn't exist */
|
/* Now assume failure in case the forwarder doesn't exist */
|
||||||
Status = STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
|
Status = STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
|
||||||
|
@ -3594,8 +3647,8 @@ MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName)
|
||||||
if (Found)
|
if (Found)
|
||||||
{
|
{
|
||||||
/* Find the procedure name */
|
/* Find the procedure name */
|
||||||
ProcAddress = MiFindExportedRoutineByName(LdrEntry->DllBase,
|
ProcAddress = RtlFindExportedRoutineByName(LdrEntry->DllBase,
|
||||||
&AnsiRoutineName);
|
AnsiRoutineName.Buffer);
|
||||||
|
|
||||||
/* Break out if we found it or if we already tried both modules */
|
/* Break out if we found it or if we already tried both modules */
|
||||||
if (ProcAddress) break;
|
if (ProcAddress) break;
|
||||||
|
|
|
@ -62,80 +62,22 @@ BOOLEAN PspDoingGiveBacks;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
USHORT
|
static CODE_SEG("INIT")
|
||||||
NTAPI
|
|
||||||
NameToOrdinal(
|
|
||||||
_In_ PCSTR ExportName,
|
|
||||||
_In_ PVOID ImageBase,
|
|
||||||
_In_ ULONG NumberOfNames,
|
|
||||||
_In_ PULONG NameTable,
|
|
||||||
_In_ PUSHORT OrdinalTable);
|
|
||||||
|
|
||||||
CODE_SEG("INIT")
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
PspLookupSystemDllEntryPoint(
|
||||||
LookupEntryPoint(IN PVOID DllBase,
|
_In_ PCSTR Name,
|
||||||
IN PCHAR Name,
|
_Out_ PVOID* EntryPoint)
|
||||||
OUT PVOID *EntryPoint)
|
|
||||||
{
|
{
|
||||||
PULONG NameTable;
|
/* Call the internal API */
|
||||||
PUSHORT OrdinalTable;
|
return RtlpFindExportedRoutineByName(PspSystemDllBase,
|
||||||
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
|
Name,
|
||||||
ULONG ExportSize;
|
EntryPoint,
|
||||||
CHAR Buffer[64];
|
NULL,
|
||||||
USHORT Ordinal;
|
STATUS_PROCEDURE_NOT_FOUND);
|
||||||
PULONG ExportTable;
|
|
||||||
|
|
||||||
/* Get the export directory */
|
|
||||||
ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
|
|
||||||
TRUE,
|
|
||||||
IMAGE_DIRECTORY_ENTRY_EXPORT,
|
|
||||||
&ExportSize);
|
|
||||||
|
|
||||||
/* Validate the name and copy it */
|
|
||||||
if (strlen(Name) > sizeof(Buffer) - 2) return STATUS_INVALID_PARAMETER;
|
|
||||||
strcpy(Buffer, Name);
|
|
||||||
|
|
||||||
/* Setup name tables */
|
|
||||||
NameTable = (PULONG)((ULONG_PTR)DllBase +
|
|
||||||
ExportDirectory->AddressOfNames);
|
|
||||||
OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
|
|
||||||
ExportDirectory->AddressOfNameOrdinals);
|
|
||||||
|
|
||||||
/* Get the ordinal */
|
|
||||||
Ordinal = NameToOrdinal(Buffer,
|
|
||||||
DllBase,
|
|
||||||
ExportDirectory->NumberOfNames,
|
|
||||||
NameTable,
|
|
||||||
OrdinalTable);
|
|
||||||
|
|
||||||
/* Make sure the ordinal is valid */
|
|
||||||
if (Ordinal >= ExportDirectory->NumberOfFunctions)
|
|
||||||
{
|
|
||||||
/* It's not, fail */
|
|
||||||
return STATUS_PROCEDURE_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Resolve the address and write it */
|
|
||||||
ExportTable = (PULONG)((ULONG_PTR)DllBase +
|
|
||||||
ExportDirectory->AddressOfFunctions);
|
|
||||||
*EntryPoint = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CODE_SEG("INIT")
|
static CODE_SEG("INIT")
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
|
||||||
PspLookupSystemDllEntryPoint(IN PCHAR Name,
|
|
||||||
IN PVOID *EntryPoint)
|
|
||||||
{
|
|
||||||
/* Call the LDR Routine */
|
|
||||||
return LookupEntryPoint(PspSystemDllBase, Name, EntryPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
CODE_SEG("INIT")
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
PspLookupKernelUserEntryPoints(VOID)
|
PspLookupKernelUserEntryPoints(VOID)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
Loading…
Reference in a new issue