[PATCH] server: Make sure pids/tids are multiples of four.
Rémi Bernon
rbernon at codeweavers.com
Fri Apr 24 08:16:34 CDT 2020
See: https://devblogs.microsoft.com/oldnewthing/?p=23283
Street Fighter V unpacker relies on it when validating other processes
for its anti-debug checks, it uses (PID&0xfffffffc)>>2 as an array index
and then checks back indexes against PIDs, and terminates early if some
PIDs do not match.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
server/process.c | 31 ++++++++++++++++++-------------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/server/process.c b/server/process.c
index 73984f363f59..211207ed03b6 100644
--- a/server/process.c
+++ b/server/process.c
@@ -339,21 +339,24 @@ static void kill_all_processes(void);
#define PTID_OFFSET 8 /* offset for first ptid value */
+static unsigned int index_from_ptid(unsigned int id) { return id / 4; }
+static unsigned int ptid_from_index(unsigned int index) { return index * 4; }
+
/* allocate a new process or thread id */
unsigned int alloc_ptid( void *ptr )
{
struct ptid_entry *entry;
- unsigned int id;
+ unsigned int index;
if (used_ptid_entries < alloc_ptid_entries)
{
- id = used_ptid_entries + PTID_OFFSET;
+ index = used_ptid_entries + PTID_OFFSET;
entry = &ptid_entries[used_ptid_entries++];
}
else if (next_free_ptid && num_free_ptids >= 256)
{
- id = next_free_ptid;
- entry = &ptid_entries[id - PTID_OFFSET];
+ index = next_free_ptid;
+ entry = &ptid_entries[index - PTID_OFFSET];
if (!(next_free_ptid = entry->next)) last_free_ptid = 0;
num_free_ptids--;
}
@@ -368,35 +371,37 @@ unsigned int alloc_ptid( void *ptr )
}
ptid_entries = entry;
alloc_ptid_entries = count;
- id = used_ptid_entries + PTID_OFFSET;
+ index = used_ptid_entries + PTID_OFFSET;
entry = &ptid_entries[used_ptid_entries++];
}
entry->ptr = ptr;
- return id;
+ return ptid_from_index( index );
}
/* free a process or thread id */
void free_ptid( unsigned int id )
{
- struct ptid_entry *entry = &ptid_entries[id - PTID_OFFSET];
+ unsigned int index = index_from_ptid( id );
+ struct ptid_entry *entry = &ptid_entries[index - PTID_OFFSET];
entry->ptr = NULL;
entry->next = 0;
/* append to end of free list so that we don't reuse it too early */
- if (last_free_ptid) ptid_entries[last_free_ptid - PTID_OFFSET].next = id;
- else next_free_ptid = id;
- last_free_ptid = id;
+ if (last_free_ptid) ptid_entries[last_free_ptid - PTID_OFFSET].next = index;
+ else next_free_ptid = index;
+ last_free_ptid = index;
num_free_ptids++;
}
/* retrieve the pointer corresponding to a process or thread id */
void *get_ptid_entry( unsigned int id )
{
- if (id < PTID_OFFSET) return NULL;
- if (id - PTID_OFFSET >= used_ptid_entries) return NULL;
- return ptid_entries[id - PTID_OFFSET].ptr;
+ unsigned int index = index_from_ptid( id );
+ if (index < PTID_OFFSET) return NULL;
+ if (index - PTID_OFFSET >= used_ptid_entries) return NULL;
+ return ptid_entries[index - PTID_OFFSET].ptr;
}
/* return the main thread of the process */
--
2.26.1
More information about the wine-devel
mailing list