Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
3a32ea8e
Commit
3a32ea8e
authored
Jul 07, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Add support for LdrSystemDllInitBlock.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
390d71b0
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
187 additions
and
1 deletion
+187
-1
loader.c
dlls/ntdll/loader.c
+14
-0
ntdll.spec
dlls/ntdll/ntdll.spec
+1
-0
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+4
-0
signal_arm64.c
dlls/ntdll/signal_arm64.c
+2
-1
wow64.c
dlls/ntdll/tests/wow64.c
+116
-0
loader.c
dlls/ntdll/unix/loader.c
+28
-0
unix_private.h
dlls/ntdll/unix/unix_private.h
+2
-0
winternl.h
include/winternl.h
+20
-0
No files found.
dlls/ntdll/loader.c
View file @
3a32ea8e
...
...
@@ -74,6 +74,8 @@ void (FASTCALL *pBaseThreadInitThunk)(DWORD,LPTHREAD_START_ROUTINE,void *) = NUL
static
DWORD
(
WINAPI
*
pCtrlRoutine
)(
void
*
);
SYSTEM_DLL_INIT_BLOCK
LdrSystemDllInitBlock
=
{
0xf0
};
const
struct
unix_funcs
*
unix_funcs
=
NULL
;
/* windows directory */
...
...
@@ -3722,6 +3724,18 @@ static void init_wow64(void)
peb64
->
OSBuildNumber
=
peb
->
OSBuildNumber
;
peb64
->
OSPlatformId
=
peb
->
OSPlatformId
;
#define SET_INIT_BLOCK(func) LdrSystemDllInitBlock.p ## func = PtrToUlong( &func )
SET_INIT_BLOCK
(
KiUserApcDispatcher
);
SET_INIT_BLOCK
(
KiUserExceptionDispatcher
);
SET_INIT_BLOCK
(
LdrInitializeThunk
);
SET_INIT_BLOCK
(
LdrSystemDllInitBlock
);
SET_INIT_BLOCK
(
RtlUserThreadStart
);
/* SET_INIT_BLOCK( KiUserCallbackDispatcher ); */
/* SET_INIT_BLOCK( RtlpQueryProcessDebugInformationRemote ); */
/* SET_INIT_BLOCK( RtlpFreezeTimeBias ); */
/* LdrSystemDllInitBlock.ntdll_handle */
#undef SET_INIT_BLOCK
map_wow64cpu
();
}
#endif
...
...
dlls/ntdll/ntdll.spec
View file @
3a32ea8e
...
...
@@ -109,6 +109,7 @@
@ stub LdrSetDllManifestProber
@ stdcall LdrShutdownProcess()
@ stdcall LdrShutdownThread()
@ extern LdrSystemDllInitBlock
@ stub LdrUnloadAlternateResourceModule
@ stdcall LdrUnloadDll(ptr)
@ stdcall LdrUnlockLoaderLock(long long)
...
...
dlls/ntdll/ntdll_misc.h
View file @
3a32ea8e
...
...
@@ -48,6 +48,10 @@ extern LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) DE
extern
void
DECLSPEC_NORETURN
raise_status
(
NTSTATUS
status
,
EXCEPTION_RECORD
*
rec
)
DECLSPEC_HIDDEN
;
extern
LONG
WINAPI
call_unhandled_exception_filter
(
PEXCEPTION_POINTERS
eptr
)
DECLSPEC_HIDDEN
;
extern
void
WINAPI
LdrInitializeThunk
(
CONTEXT
*
,
ULONG_PTR
,
ULONG_PTR
,
ULONG_PTR
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
WINAPI
KiUserExceptionDispatcher
(
EXCEPTION_RECORD
*
,
CONTEXT
*
)
DECLSPEC_HIDDEN
;
extern
void
WINAPI
KiUserApcDispatcher
(
CONTEXT
*
,
ULONG_PTR
,
ULONG_PTR
,
ULONG_PTR
,
PNTAPCFUNC
)
DECLSPEC_HIDDEN
;
#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
extern
RUNTIME_FUNCTION
*
lookup_function_info
(
ULONG_PTR
pc
,
ULONG_PTR
*
base
,
LDR_DATA_TABLE_ENTRY
**
module
)
DECLSPEC_HIDDEN
;
#endif
...
...
dlls/ntdll/signal_arm64.c
View file @
3a32ea8e
...
...
@@ -557,8 +557,9 @@ NTSTATUS WINAPI KiUserExceptionDispatcher( EXCEPTION_RECORD *rec, CONTEXT *conte
* KiUserApcDispatcher (NTDLL.@)
*/
void
WINAPI
KiUserApcDispatcher
(
CONTEXT
*
context
,
ULONG_PTR
arg1
,
ULONG_PTR
arg2
,
ULONG_PTR
arg3
,
void
(
CALLBACK
*
func
)(
ULONG_PTR
,
ULONG_PTR
,
ULONG_PTR
,
CONTEXT
*
)
)
PNTAPCFUNC
apc
)
{
void
(
CALLBACK
*
func
)(
ULONG_PTR
,
ULONG_PTR
,
ULONG_PTR
,
CONTEXT
*
)
=
(
void
*
)
apc
;
func
(
arg1
,
arg2
,
arg3
,
context
);
NtContinue
(
context
,
TRUE
);
}
...
...
dlls/ntdll/tests/wow64.c
View file @
3a32ea8e
...
...
@@ -956,6 +956,121 @@ static void test_nt_wow64(void)
NtClose
(
process
);
}
static
void
test_init_block
(
void
)
{
HMODULE
ntdll
=
GetModuleHandleA
(
"ntdll.dll"
);
ULONG
i
,
size
=
0
,
*
init_block
;
ULONG64
ptr64
,
*
block64
;
void
*
ptr
;
if
(
!
is_wow64
)
return
;
if
((
ptr
=
GetProcAddress
(
ntdll
,
"LdrSystemDllInitBlock"
)))
{
init_block
=
ptr
;
trace
(
"got init block %08x
\n
"
,
init_block
[
0
]
);
#define CHECK_FUNC(val,func) \
ok( (val) == (ULONG_PTR)GetProcAddress( ntdll, func ), \
"got %p for %s %p\n", (void *)(ULONG_PTR)(val), func, GetProcAddress( ntdll, func ))
switch
(
init_block
[
0
])
{
case
0x44
:
/* vistau64 */
CHECK_FUNC
(
init_block
[
1
],
"LdrInitializeThunk"
);
CHECK_FUNC
(
init_block
[
2
],
"KiUserExceptionDispatcher"
);
CHECK_FUNC
(
init_block
[
3
],
"KiUserApcDispatcher"
);
CHECK_FUNC
(
init_block
[
4
],
"KiUserCallbackDispatcher"
);
CHECK_FUNC
(
init_block
[
5
],
"LdrHotPatchRoutine"
);
CHECK_FUNC
(
init_block
[
6
],
"ExpInterlockedPopEntrySListFault"
);
CHECK_FUNC
(
init_block
[
7
],
"ExpInterlockedPopEntrySListResume"
);
CHECK_FUNC
(
init_block
[
8
],
"ExpInterlockedPopEntrySListEnd"
);
CHECK_FUNC
(
init_block
[
9
],
"RtlUserThreadStart"
);
CHECK_FUNC
(
init_block
[
10
],
"RtlpQueryProcessDebugInformationRemote"
);
CHECK_FUNC
(
init_block
[
11
],
"EtwpNotificationThread"
);
ok
(
init_block
[
12
]
==
(
ULONG_PTR
)
ntdll
,
"got %p for ntdll %p
\n
"
,
(
void
*
)(
ULONG_PTR
)
init_block
[
12
],
ntdll
);
size
=
13
*
sizeof
(
*
init_block
);
break
;
case
0x50
:
/* win7 */
CHECK_FUNC
(
init_block
[
4
],
"LdrInitializeThunk"
);
CHECK_FUNC
(
init_block
[
5
],
"KiUserExceptionDispatcher"
);
CHECK_FUNC
(
init_block
[
6
],
"KiUserApcDispatcher"
);
CHECK_FUNC
(
init_block
[
7
],
"KiUserCallbackDispatcher"
);
CHECK_FUNC
(
init_block
[
8
],
"LdrHotPatchRoutine"
);
CHECK_FUNC
(
init_block
[
9
],
"ExpInterlockedPopEntrySListFault"
);
CHECK_FUNC
(
init_block
[
10
],
"ExpInterlockedPopEntrySListResume"
);
CHECK_FUNC
(
init_block
[
11
],
"ExpInterlockedPopEntrySListEnd"
);
CHECK_FUNC
(
init_block
[
12
],
"RtlUserThreadStart"
);
CHECK_FUNC
(
init_block
[
13
],
"RtlpQueryProcessDebugInformationRemote"
);
CHECK_FUNC
(
init_block
[
14
],
"EtwpNotificationThread"
);
ok
(
init_block
[
15
]
==
(
ULONG_PTR
)
ntdll
,
"got %p for ntdll %p
\n
"
,
(
void
*
)(
ULONG_PTR
)
init_block
[
15
],
ntdll
);
CHECK_FUNC
(
init_block
[
16
],
"LdrSystemDllInitBlock"
);
size
=
17
*
sizeof
(
*
init_block
);
break
;
case
0x70
:
/* win8 */
CHECK_FUNC
(
init_block
[
4
],
"LdrInitializeThunk"
);
CHECK_FUNC
(
init_block
[
5
],
"KiUserExceptionDispatcher"
);
CHECK_FUNC
(
init_block
[
6
],
"KiUserApcDispatcher"
);
CHECK_FUNC
(
init_block
[
7
],
"KiUserCallbackDispatcher"
);
CHECK_FUNC
(
init_block
[
8
],
"ExpInterlockedPopEntrySListFault"
);
CHECK_FUNC
(
init_block
[
9
],
"ExpInterlockedPopEntrySListResume"
);
CHECK_FUNC
(
init_block
[
10
],
"ExpInterlockedPopEntrySListEnd"
);
CHECK_FUNC
(
init_block
[
11
],
"RtlUserThreadStart"
);
CHECK_FUNC
(
init_block
[
12
],
"RtlpQueryProcessDebugInformationRemote"
);
ok
(
init_block
[
13
]
==
(
ULONG_PTR
)
ntdll
,
"got %p for ntdll %p
\n
"
,
(
void
*
)(
ULONG_PTR
)
init_block
[
13
],
ntdll
);
CHECK_FUNC
(
init_block
[
14
],
"LdrSystemDllInitBlock"
);
size
=
15
*
sizeof
(
*
init_block
);
break
;
case
0x80
:
/* win10 1507 */
CHECK_FUNC
(
init_block
[
4
],
"LdrInitializeThunk"
);
CHECK_FUNC
(
init_block
[
5
],
"KiUserExceptionDispatcher"
);
CHECK_FUNC
(
init_block
[
6
],
"KiUserApcDispatcher"
);
CHECK_FUNC
(
init_block
[
7
],
"KiUserCallbackDispatcher"
);
CHECK_FUNC
(
init_block
[
8
],
"ExpInterlockedPopEntrySListFault"
);
CHECK_FUNC
(
init_block
[
9
],
"ExpInterlockedPopEntrySListResume"
);
CHECK_FUNC
(
init_block
[
10
],
"ExpInterlockedPopEntrySListEnd"
);
CHECK_FUNC
(
init_block
[
11
],
"RtlUserThreadStart"
);
CHECK_FUNC
(
init_block
[
12
],
"RtlpQueryProcessDebugInformationRemote"
);
ok
(
init_block
[
13
]
==
(
ULONG_PTR
)
ntdll
,
"got %p for ntdll %p
\n
"
,
(
void
*
)(
ULONG_PTR
)
init_block
[
13
],
ntdll
);
CHECK_FUNC
(
init_block
[
14
],
"LdrSystemDllInitBlock"
);
size
=
15
*
sizeof
(
*
init_block
);
break
;
case
0xe0
:
/* win10 1809 */
case
0xf0
:
/* win10 2004 */
block64
=
ptr
;
CHECK_FUNC
(
block64
[
3
],
"LdrInitializeThunk"
);
CHECK_FUNC
(
block64
[
4
],
"KiUserExceptionDispatcher"
);
CHECK_FUNC
(
block64
[
5
],
"KiUserApcDispatcher"
);
todo_wine
CHECK_FUNC
(
block64
[
6
],
"KiUserCallbackDispatcher"
);
CHECK_FUNC
(
block64
[
7
],
"RtlUserThreadStart"
);
CHECK_FUNC
(
block64
[
8
],
"RtlpQueryProcessDebugInformationRemote"
);
todo_wine
ok
(
block64
[
9
]
==
(
ULONG_PTR
)
ntdll
,
"got %p for ntdll %p
\n
"
,
(
void
*
)(
ULONG_PTR
)
block64
[
9
],
ntdll
);
CHECK_FUNC
(
block64
[
10
],
"LdrSystemDllInitBlock"
);
CHECK_FUNC
(
block64
[
11
],
"RtlpFreezeTimeBias"
);
size
=
12
*
sizeof
(
*
block64
);
break
;
default:
ok
(
0
,
"unknown init block %08x
\n
"
,
init_block
[
0
]
);
for
(
i
=
0
;
i
<
32
;
i
++
)
trace
(
"%04x: %08x
\n
"
,
i
,
init_block
[
i
]);
break
;
}
#undef CHECK_FUNC
if
(
size
&&
(
ptr64
=
get_proc_address64
(
ntdll_module
,
"LdrSystemDllInitBlock"
)))
{
DWORD
buffer
[
64
];
HANDLE
process
=
OpenProcess
(
PROCESS_ALL_ACCESS
,
FALSE
,
GetCurrentProcessId
()
);
NTSTATUS
status
=
pNtWow64ReadVirtualMemory64
(
process
,
ptr64
,
buffer
,
size
,
NULL
);
ok
(
!
status
,
"NtWow64ReadVirtualMemory64 failed %x
\n
"
,
status
);
ok
(
!
memcmp
(
buffer
,
init_block
,
size
),
"wrong 64-bit init block
\n
"
);
NtClose
(
process
);
}
}
else
todo_wine
win_skip
(
"LdrSystemDllInitBlock not supported
\n
"
);
}
static
void
test_cpu_area
(
void
)
{
TEB64
*
teb64
=
(
TEB64
*
)
NtCurrentTeb
()
->
GdiBatchCount
;
...
...
@@ -997,6 +1112,7 @@ START_TEST(wow64)
#ifndef _WIN64
test_nt_wow64
();
test_modules
();
test_init_block
();
#endif
test_cpu_area
();
}
dlls/ntdll/unix/loader.c
View file @
3a32ea8e
...
...
@@ -110,6 +110,7 @@ NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*) = NULL
void
(
WINAPI
*
pLdrInitializeThunk
)(
CONTEXT
*
,
void
**
,
ULONG_PTR
,
ULONG_PTR
)
=
NULL
;
void
(
WINAPI
*
pRtlUserThreadStart
)(
PRTL_THREAD_START_ROUTINE
entry
,
void
*
arg
)
=
NULL
;
void
(
WINAPI
*
p__wine_ctrl_routine
)(
void
*
);
SYSTEM_DLL_INIT_BLOCK
*
pLdrSystemDllInitBlock
=
NULL
;
static
NTSTATUS
(
CDECL
*
p__wine_set_unix_funcs
)(
int
version
,
const
struct
unix_funcs
*
funcs
);
...
...
@@ -832,6 +833,7 @@ static void load_ntdll_functions( HMODULE module )
GET_FUNC
(
KiUserExceptionDispatcher
);
GET_FUNC
(
KiUserApcDispatcher
);
GET_FUNC
(
LdrInitializeThunk
);
GET_FUNC
(
LdrSystemDllInitBlock
);
GET_FUNC
(
RtlUserThreadStart
);
GET_FUNC
(
__wine_ctrl_routine
);
GET_FUNC
(
__wine_set_unix_funcs
);
...
...
@@ -847,6 +849,31 @@ static void load_ntdll_functions( HMODULE module )
#undef SET_PTR
}
static
void
load_ntdll_wow64_functions
(
HMODULE
module
)
{
const
IMAGE_EXPORT_DIRECTORY
*
exports
;
exports
=
get_module_data_dir
(
module
,
IMAGE_FILE_EXPORT_DIRECTORY
,
NULL
);
assert
(
exports
);
pLdrSystemDllInitBlock
->
ntdll_handle
=
(
ULONG_PTR
)
module
;
#define GET_FUNC(name) pLdrSystemDllInitBlock->p##name = find_named_export( module, exports, #name )
GET_FUNC
(
KiUserApcDispatcher
);
GET_FUNC
(
KiUserCallbackDispatcher
);
GET_FUNC
(
KiUserExceptionDispatcher
);
GET_FUNC
(
LdrInitializeThunk
);
GET_FUNC
(
LdrSystemDllInitBlock
);
GET_FUNC
(
RtlUserThreadStart
);
GET_FUNC
(
RtlpFreezeTimeBias
);
GET_FUNC
(
RtlpQueryProcessDebugInformationRemote
);
#undef GET_FUNC
/* also set the 32-bit LdrSystemDllInitBlock */
memcpy
(
(
void
*
)(
ULONG_PTR
)
pLdrSystemDllInitBlock
->
pLdrSystemDllInitBlock
,
pLdrSystemDllInitBlock
,
sizeof
(
*
pLdrSystemDllInitBlock
)
);
}
/* reimplementation of LdrProcessRelocationBlock */
static
const
IMAGE_BASE_RELOCATION
*
process_relocation_block
(
void
*
module
,
const
IMAGE_BASE_RELOCATION
*
rel
,
INT_PTR
delta
)
...
...
@@ -1781,6 +1808,7 @@ static void load_wow64_ntdll( USHORT machine )
relocate_ntdll
(
module
);
/* fall through */
case
STATUS_SUCCESS
:
load_ntdll_wow64_functions
(
module
);
TRACE
(
"loaded %s at %p
\n
"
,
debugstr_w
(
path
),
module
);
break
;
default:
...
...
dlls/ntdll/unix/unix_private.h
View file @
3a32ea8e
...
...
@@ -93,6 +93,8 @@ extern NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*)
extern
void
(
WINAPI
*
pLdrInitializeThunk
)(
CONTEXT
*
,
void
**
,
ULONG_PTR
,
ULONG_PTR
)
DECLSPEC_HIDDEN
;
extern
void
(
WINAPI
*
pRtlUserThreadStart
)(
PRTL_THREAD_START_ROUTINE
entry
,
void
*
arg
)
DECLSPEC_HIDDEN
;
extern
void
(
WINAPI
*
p__wine_ctrl_routine
)(
void
*
)
DECLSPEC_HIDDEN
;
extern
SYSTEM_DLL_INIT_BLOCK
*
pLdrSystemDllInitBlock
DECLSPEC_HIDDEN
;
extern
NTSTATUS
CDECL
fast_RtlpWaitForCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
,
int
timeout
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
CDECL
fast_RtlpUnWaitCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
CDECL
fast_RtlDeleteCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
)
DECLSPEC_HIDDEN
;
...
...
include/winternl.h
View file @
3a32ea8e
...
...
@@ -3713,6 +3713,26 @@ typedef struct _WOW64_CPU_AREA_INFO
USHORT
Machine
;
}
WOW64_CPU_AREA_INFO
,
*
PWOW64_CPU_AREA_INFO
;
#ifdef __WINESRC__
/* undocumented layout of LdrSystemDllInitBlock */
/* this varies across Windows version; we are using the win10-2004 layout */
typedef
struct
{
ULONG
version
;
ULONG
unknown1
[
3
];
ULONG64
unknown2
;
ULONG64
pLdrInitializeThunk
;
ULONG64
pKiUserExceptionDispatcher
;
ULONG64
pKiUserApcDispatcher
;
ULONG64
pKiUserCallbackDispatcher
;
ULONG64
pRtlUserThreadStart
;
ULONG64
pRtlpQueryProcessDebugInformationRemote
;
ULONG64
ntdll_handle
;
ULONG64
pLdrSystemDllInitBlock
;
ULONG64
pRtlpFreezeTimeBias
;
}
SYSTEM_DLL_INIT_BLOCK
;
#endif
/***********************************************************************
* Function declarations
*/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment