2020-04-03 14:55:44 -07:00
|
|
|
From 338f514f1468d77ae19ac9bbe7ba7d2b018ec83c Mon Sep 17 00:00:00 2001
|
2016-04-28 08:13:03 -07:00
|
|
|
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
|
|
|
Date: Thu, 28 Apr 2016 17:01:16 +0200
|
2020-04-01 16:08:55 -07:00
|
|
|
Subject: [PATCH] libs/wine: Allow to modify reserved LDT entries.
|
2016-04-28 08:13:03 -07:00
|
|
|
|
|
|
|
Some implementation notes:
|
|
|
|
|
|
|
|
1. Some copy protections call NtSetLdtEntries(0x000f) and then with 'retf'
|
|
|
|
instruction jump to that selector expecting that it works (the tests show that
|
|
|
|
NtSetLdtEntries(0x000f,0x001f) should succeed). In order to make this work a
|
|
|
|
limitation to set only selectors > LDT_FIRST_ENTRY (512) in wine_ldt_set_entry()
|
|
|
|
was removed.
|
|
|
|
|
|
|
|
2. wine_ldt_set_entry() was made to always mark modified selector entries as
|
|
|
|
WINE_LDT_FLAGS_ALLOCATED, otherwise get_selector_entry() server call returns
|
|
|
|
entries without that flag set and NtQueryInformationThread(ThreadDescriptorTableEntry)
|
|
|
|
fails.
|
|
|
|
---
|
|
|
|
dlls/kernel32/tests/thread.c | 4 ----
|
2020-04-01 16:08:55 -07:00
|
|
|
dlls/ntdll/signal_i386.c | 2 --
|
2016-04-28 08:13:03 -07:00
|
|
|
libs/wine/ldt.c | 4 +---
|
2020-04-01 16:08:55 -07:00
|
|
|
3 files changed, 1 insertion(+), 9 deletions(-)
|
2016-04-28 08:13:03 -07:00
|
|
|
|
|
|
|
diff --git a/dlls/kernel32/tests/thread.c b/dlls/kernel32/tests/thread.c
|
2020-04-01 16:08:55 -07:00
|
|
|
index 70b22367e18..a454bf118cc 100644
|
2016-04-28 08:13:03 -07:00
|
|
|
--- a/dlls/kernel32/tests/thread.c
|
|
|
|
+++ b/dlls/kernel32/tests/thread.c
|
2020-04-01 16:08:55 -07:00
|
|
|
@@ -1325,16 +1325,12 @@ static void test_NtSetLdtEntries(void)
|
2016-04-28 08:13:03 -07:00
|
|
|
{
|
|
|
|
memset(&sel.entry, 0x9a, sizeof(sel.entry));
|
|
|
|
ret = GetThreadSelectorEntry(GetCurrentThread(), 0x000f, &sel.entry);
|
|
|
|
- todo_wine
|
|
|
|
ok(ret, "GetThreadSelectorEntry failed\n");
|
|
|
|
- todo_wine
|
|
|
|
ok(!memcmp(&ds_entry, &sel.entry, sizeof(ds_entry)), "entries do not match\n");
|
|
|
|
|
|
|
|
memset(&sel.entry, 0x9a, sizeof(sel.entry));
|
|
|
|
ret = GetThreadSelectorEntry(GetCurrentThread(), 0x001f, &sel.entry);
|
|
|
|
- todo_wine
|
|
|
|
ok(ret, "GetThreadSelectorEntry failed\n");
|
|
|
|
- todo_wine
|
|
|
|
ok(!memcmp(&ds_entry, &sel.entry, sizeof(ds_entry)), "entries do not match\n");
|
|
|
|
}
|
|
|
|
}
|
2020-04-01 16:08:55 -07:00
|
|
|
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
|
2020-04-03 14:55:44 -07:00
|
|
|
index 2db76f0e250..fd1a764dacf 100644
|
2020-04-01 16:08:55 -07:00
|
|
|
--- a/dlls/ntdll/signal_i386.c
|
|
|
|
+++ b/dlls/ntdll/signal_i386.c
|
2020-04-03 14:55:44 -07:00
|
|
|
@@ -2614,8 +2614,6 @@ NTSTATUS get_thread_ldt_entry( HANDLE handle, void *data, ULONG len, ULONG *ret_
|
2020-04-01 16:08:55 -07:00
|
|
|
NTSTATUS WINAPI NtSetLdtEntries( ULONG sel1, LDT_ENTRY entry1, ULONG sel2, LDT_ENTRY entry2 )
|
|
|
|
{
|
|
|
|
if (sel1 >> 16 || sel2 >> 16) return STATUS_INVALID_LDT_DESCRIPTOR;
|
|
|
|
- if (sel1 && (sel1 >> 3) < first_ldt_entry) return STATUS_INVALID_LDT_DESCRIPTOR;
|
|
|
|
- if (sel2 && (sel2 >> 3) < first_ldt_entry) return STATUS_INVALID_LDT_DESCRIPTOR;
|
|
|
|
|
|
|
|
ldt_lock();
|
|
|
|
if (sel1) ldt_set_entry( sel1, entry1 );
|
2016-04-28 08:13:03 -07:00
|
|
|
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
|
2020-04-03 14:55:44 -07:00
|
|
|
index a8f4925019b..5e85c1137c8 100644
|
2016-04-28 08:13:03 -07:00
|
|
|
--- a/libs/wine/ldt.c
|
|
|
|
+++ b/libs/wine/ldt.c
|
2020-04-03 14:55:44 -07:00
|
|
|
@@ -225,8 +225,6 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
|
2016-04-28 08:13:03 -07:00
|
|
|
{
|
|
|
|
int ret = 0, index = sel >> 3;
|
|
|
|
|
|
|
|
- if (index < LDT_FIRST_ENTRY) return 0; /* cannot modify reserved entries */
|
|
|
|
-
|
|
|
|
#ifdef linux
|
|
|
|
{
|
|
|
|
struct modify_ldt_s ldt_info;
|
2020-04-03 14:55:44 -07:00
|
|
|
@@ -278,7 +276,7 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
|
|
|
|
wine_ldt_copy_obsolete.limit[index] = wine_ldt_get_limit(entry);
|
|
|
|
wine_ldt_copy_obsolete.flags[index] = (entry->HighWord.Bits.Type |
|
2016-04-28 08:13:03 -07:00
|
|
|
(entry->HighWord.Bits.Default_Big ? WINE_LDT_FLAGS_32BIT : 0) |
|
2020-04-03 14:55:44 -07:00
|
|
|
- (wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_ALLOCATED));
|
2016-04-28 08:13:03 -07:00
|
|
|
+ WINE_LDT_FLAGS_ALLOCATED);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
--
|
2020-04-03 14:55:44 -07:00
|
|
|
2.25.1
|
2016-04-28 08:13:03 -07:00
|
|
|
|