Commit 40601653 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Redirect PE function pointers through the ARM64EC redirection map.

parent 56409f2c
......@@ -1820,6 +1820,55 @@ static void load_ntdll_wow64_functions( HMODULE module )
/***********************************************************************
* redirect_arm64ec_ptr
*
* Redirect a function pointer through the arm64ec redirection table.
*/
static void *redirect_arm64ec_ptr( void *module, void *ptr,
const IMAGE_ARM64EC_REDIRECTION_ENTRY *map, ULONG map_count )
{
int min = 0, max = map_count - 1;
ULONG_PTR rva = (char *)ptr - (char *)module;
while (min <= max)
{
int pos = (min + max) / 2;
if (map[pos].Source == rva) return get_rva( module, map[pos].Destination );
if (map[pos].Source < rva) min = pos + 1;
else max = pos - 1;
}
return ptr;
}
/***********************************************************************
* redirect_ntdll_functions
*
* Redirect ntdll functions on arm64ec.
*/
static void redirect_ntdll_functions( HMODULE module )
{
const IMAGE_LOAD_CONFIG_DIRECTORY *loadcfg;
const IMAGE_ARM64EC_METADATA *metadata;
const IMAGE_ARM64EC_REDIRECTION_ENTRY *map;
if (!(loadcfg = get_module_data_dir( module, IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, NULL ))) return;
if (!(metadata = (void *)loadcfg->CHPEMetadataPointer)) return;
if (!(map = get_rva( module, metadata->RedirectionMetadata ))) return;
#define REDIRECT(name) \
p##name = redirect_arm64ec_ptr( module, p##name, map, metadata->RedirectionMetadataCount )
REDIRECT( DbgUiRemoteBreakin );
REDIRECT( KiRaiseUserExceptionDispatcher );
REDIRECT( KiUserExceptionDispatcher );
REDIRECT( KiUserApcDispatcher );
REDIRECT( KiUserCallbackDispatcher );
REDIRECT( LdrInitializeThunk );
REDIRECT( RtlUserThreadStart );
#undef REDIRECT
}
/***********************************************************************
* load_ntdll
*/
static void load_ntdll(void)
......@@ -1851,6 +1900,7 @@ static void load_ntdll(void)
if (status) fatal_error( "failed to load %s error %x\n", name, status );
free( name );
load_ntdll_functions( module );
if (is_arm64ec()) redirect_ntdll_functions( module );
}
......
......@@ -64,6 +64,7 @@ static inline TEB64 *NtCurrentTeb64(void) { return (TEB64 *)NtCurrentTeb()->GdiB
extern WOW_PEB *wow_peb DECLSPEC_HIDDEN;
extern ULONG_PTR user_space_wow_limit DECLSPEC_HIDDEN;
extern SECTION_IMAGE_INFORMATION main_image_info DECLSPEC_HIDDEN;
static inline WOW_TEB *get_wow_teb( TEB *teb )
{
......@@ -81,6 +82,12 @@ static inline BOOL is_old_wow64(void)
return !is_win64 && wow_peb;
}
static inline BOOL is_arm64ec(void)
{
return (current_machine == IMAGE_FILE_MACHINE_ARM64 &&
main_image_info.Machine == IMAGE_FILE_MACHINE_AMD64);
}
/* thread private data, stored in NtCurrentTeb()->GdiTebBatch */
struct ntdll_thread_data
{
......@@ -152,7 +159,6 @@ extern USHORT *uctable DECLSPEC_HIDDEN;
extern USHORT *lctable DECLSPEC_HIDDEN;
extern SIZE_T startup_info_size DECLSPEC_HIDDEN;
extern BOOL is_prefix_bootstrap DECLSPEC_HIDDEN;
extern SECTION_IMAGE_INFORMATION main_image_info DECLSPEC_HIDDEN;
extern int main_argc DECLSPEC_HIDDEN;
extern char **main_argv DECLSPEC_HIDDEN;
extern char **main_envp DECLSPEC_HIDDEN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment