XObject::GetObject->GetNativeObject

This commit is contained in:
Ben Vanik 2015-05-24 21:01:57 -07:00
parent d746743d20
commit 120e09f8e7
4 changed files with 48 additions and 45 deletions

View File

@ -118,7 +118,7 @@ SHIM_CALL ObDereferenceObject_shim(PPCContext* ppc_state, KernelState* state) {
} }
void* object_ptr = SHIM_MEM_ADDR(native_ptr); void* object_ptr = SHIM_MEM_ADDR(native_ptr);
XObject* object = XObject::GetObject(state, object_ptr); auto object = XObject::GetNativeObject<XObject>(state, object_ptr);
if (object) { if (object) {
object->Release(); object->Release();
} }

View File

@ -176,8 +176,8 @@ SHIM_CALL KeResumeThread_shim(PPCContext* ppc_state, KernelState* state) {
XELOGD("KeResumeThread(%.8X)", thread_ptr); XELOGD("KeResumeThread(%.8X)", thread_ptr);
X_STATUS result; X_STATUS result;
XThread* thread = auto thread =
(XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); XObject::GetNativeObject<XThread>(state, SHIM_MEM_ADDR(thread_ptr));
if (thread) { if (thread) {
result = thread->Resume(); result = thread->Resume();
} }
@ -215,8 +215,8 @@ SHIM_CALL KeSetAffinityThread_shim(PPCContext* ppc_state, KernelState* state) {
XELOGD("KeSetAffinityThread(%.8X, %.8X)", thread_ptr, affinity); XELOGD("KeSetAffinityThread(%.8X, %.8X)", thread_ptr, affinity);
XThread* thread = auto thread =
(XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); XObject::GetNativeObject<XThread>(state, SHIM_MEM_ADDR(thread_ptr));
if (thread) { if (thread) {
thread->SetAffinity(affinity); thread->SetAffinity(affinity);
} }
@ -232,8 +232,8 @@ SHIM_CALL KeQueryBasePriorityThread_shim(PPCContext* ppc_state,
int32_t priority = 0; int32_t priority = 0;
XThread* thread = auto thread =
(XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); XObject::GetNativeObject<XThread>(state, SHIM_MEM_ADDR(thread_ptr));
if (thread) { if (thread) {
priority = thread->QueryPriority(); priority = thread->QueryPriority();
} }
@ -259,8 +259,7 @@ SHIM_CALL KeSetBasePriorityThread_shim(PPCContext* ppc_state,
// Log it in case this is the source of any problems in the future // Log it in case this is the source of any problems in the future
XELOGD("KeSetBasePriorityThread - Interpreting thread ptr as handle!"); XELOGD("KeSetBasePriorityThread - Interpreting thread ptr as handle!");
} else { } else {
thread = (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); thread = XObject::GetNativeObject<XThread>(state, SHIM_MEM_ADDR(thread_ptr)).release();
thread->Retain();
} }
if (thread) { if (thread) {
@ -279,8 +278,8 @@ SHIM_CALL KeSetDisableBoostThread_shim(PPCContext* ppc_state,
XELOGD("KeSetDisableBoostThread(%.8X, %.8X)", thread_ptr, disabled); XELOGD("KeSetDisableBoostThread(%.8X, %.8X)", thread_ptr, disabled);
XThread* thread = auto thread =
(XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); XObject::GetNativeObject<XThread>(state, SHIM_MEM_ADDR(thread_ptr));
if (thread) { if (thread) {
// Uhm? // Uhm?
} }
@ -490,8 +489,7 @@ SHIM_CALL KeSetEvent_shim(PPCContext* ppc_state, KernelState* state) {
void* event_ptr = SHIM_MEM_ADDR(event_ref); void* event_ptr = SHIM_MEM_ADDR(event_ref);
XEvent* ev = (XEvent*)XObject::GetObject(state, event_ptr); auto ev = XObject::GetNativeObject<XEvent>(state, event_ptr);
assert_not_null(ev);
if (!ev) { if (!ev) {
SHIM_SET_RETURN_64(0); SHIM_SET_RETURN_64(0);
return; return;
@ -533,8 +531,7 @@ SHIM_CALL KePulseEvent_shim(PPCContext* ppc_state, KernelState* state) {
int32_t result = 0; int32_t result = 0;
void* event_ptr = SHIM_MEM_ADDR(event_ref); void* event_ptr = SHIM_MEM_ADDR(event_ref);
XEvent* ev = (XEvent*)XObject::GetObject(state, event_ptr); auto ev = XObject::GetNativeObject<XEvent>(state, event_ptr);
assert_not_null(ev);
if (ev) { if (ev) {
result = ev->Pulse(increment, !!wait); result = ev->Pulse(increment, !!wait);
} }
@ -570,8 +567,7 @@ SHIM_CALL KeResetEvent_shim(PPCContext* ppc_state, KernelState* state) {
XELOGD("KeResetEvent(%.8X)", event_ref); XELOGD("KeResetEvent(%.8X)", event_ref);
void* event_ptr = SHIM_MEM_ADDR(event_ref); void* event_ptr = SHIM_MEM_ADDR(event_ref);
XEvent* ev = (XEvent*)XEvent::GetObject(state, event_ptr); auto ev = XObject::GetNativeObject<XEvent>(state, event_ptr);
assert_not_null(ev);
if (!ev) { if (!ev) {
SHIM_SET_RETURN_64(0); SHIM_SET_RETURN_64(0);
return; return;
@ -613,7 +609,7 @@ SHIM_CALL NtCreateSemaphore_shim(PPCContext* ppc_state, KernelState* state) {
AssertNoNameCollision(state, obj_attributes_ptr); AssertNoNameCollision(state, obj_attributes_ptr);
} }
XSemaphore* sem = new XSemaphore(state); auto sem = object_ref<XSemaphore>(new XSemaphore(state));
sem->Initialize(count, limit); sem->Initialize(count, limit);
// obj_attributes may have a name inside of it, if != NULL. // obj_attributes may have a name inside of it, if != NULL.
@ -637,9 +633,8 @@ SHIM_CALL KeInitializeSemaphore_shim(PPCContext* ppc_state,
XELOGD("KeInitializeSemaphore(%.8X, %d, %d)", semaphore_ref, count, limit); XELOGD("KeInitializeSemaphore(%.8X, %d, %d)", semaphore_ref, count, limit);
void* semaphore_ptr = SHIM_MEM_ADDR(semaphore_ref); void* semaphore_ptr = SHIM_MEM_ADDR(semaphore_ref);
XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject(state, semaphore_ptr, auto sem = XObject::GetNativeObject<XSemaphore>(state, semaphore_ptr,
5 /* SemaphoreObject */); 5 /* SemaphoreObject */);
assert_not_null(sem);
if (!sem) { if (!sem) {
return; return;
} }
@ -657,8 +652,7 @@ SHIM_CALL KeReleaseSemaphore_shim(PPCContext* ppc_state, KernelState* state) {
adjustment, wait); adjustment, wait);
void* semaphore_ptr = SHIM_MEM_ADDR(semaphore_ref); void* semaphore_ptr = SHIM_MEM_ADDR(semaphore_ref);
XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject(state, semaphore_ptr); auto sem = XObject::GetNativeObject<XSemaphore>(state, semaphore_ptr);
assert_not_null(sem);
if (!sem) { if (!sem) {
SHIM_SET_RETURN_64(0); SHIM_SET_RETURN_64(0);
return; return;
@ -848,7 +842,8 @@ SHIM_CALL KeWaitForSingleObject_shim(PPCContext* ppc_state,
XELOGD("KeWaitForSingleObject(%.8X, %.8X, %.8X, %.1X, %.8X)", object_ptr, XELOGD("KeWaitForSingleObject(%.8X, %.8X, %.8X, %.1X, %.8X)", object_ptr,
wait_reason, processor_mode, alertable, timeout_ptr); wait_reason, processor_mode, alertable, timeout_ptr);
XObject* object = XObject::GetObject(state, SHIM_MEM_ADDR(object_ptr)); auto object =
XObject::GetNativeObject<XObject>(state, SHIM_MEM_ADDR(object_ptr));
if (!object) { if (!object) {
// The only kind-of failure code. // The only kind-of failure code.
SHIM_SET_RETURN_32(X_STATUS_ABANDONED_WAIT_0); SHIM_SET_RETURN_32(X_STATUS_ABANDONED_WAIT_0);
@ -906,11 +901,11 @@ SHIM_CALL KeWaitForMultipleObjects_shim(PPCContext* ppc_state,
X_STATUS result = X_STATUS_SUCCESS; X_STATUS result = X_STATUS_SUCCESS;
XObject** objects = (XObject**)alloca(sizeof(XObject*) * count); std::vector<object_ref<XObject>> objects(count);
for (uint32_t n = 0; n < count; n++) { for (uint32_t n = 0; n < count; n++) {
uint32_t object_ptr_ptr = SHIM_MEM_32(objects_ptr + n * 4); uint32_t object_ptr_ptr = SHIM_MEM_32(objects_ptr + n * 4);
void* object_ptr = SHIM_MEM_ADDR(object_ptr_ptr); void* object_ptr = SHIM_MEM_ADDR(object_ptr_ptr);
objects[n] = XObject::GetObject(state, object_ptr); objects[n] = XObject::GetNativeObject<XObject>(state, object_ptr);
if (!objects[n]) { if (!objects[n]) {
SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER); SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER);
return; return;
@ -918,9 +913,9 @@ SHIM_CALL KeWaitForMultipleObjects_shim(PPCContext* ppc_state,
} }
uint64_t timeout = timeout_ptr ? SHIM_MEM_64(timeout_ptr) : 0; uint64_t timeout = timeout_ptr ? SHIM_MEM_64(timeout_ptr) : 0;
result = XObject::WaitMultiple(count, objects, wait_type, wait_reason, result = XObject::WaitMultiple(
processor_mode, alertable, count, reinterpret_cast<XObject**>(objects.data()), wait_type,
timeout_ptr ? &timeout : NULL); wait_reason, processor_mode, alertable, timeout_ptr ? &timeout : nullptr);
SHIM_SET_RETURN_32(result); SHIM_SET_RETURN_32(result);
} }
@ -1150,8 +1145,8 @@ SHIM_CALL KeInsertQueueApc_shim(PPCContext* ppc_state, KernelState* state) {
priority_increment); priority_increment);
uint32_t thread_ptr = SHIM_MEM_32(apc_ptr + 4); uint32_t thread_ptr = SHIM_MEM_32(apc_ptr + 4);
XThread* thread = auto thread =
(XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); XObject::GetNativeObject<XThread>(state, SHIM_MEM_ADDR(thread_ptr));
if (!thread) { if (!thread) {
SHIM_SET_RETURN_64(0); SHIM_SET_RETURN_64(0);
return; return;
@ -1192,8 +1187,8 @@ SHIM_CALL KeRemoveQueueApc_shim(PPCContext* ppc_state, KernelState* state) {
bool result = false; bool result = false;
uint32_t thread_ptr = SHIM_MEM_32(apc_ptr + 4); uint32_t thread_ptr = SHIM_MEM_32(apc_ptr + 4);
XThread* thread = auto thread =
(XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); XObject::GetNativeObject<XThread>(state, SHIM_MEM_ADDR(thread_ptr));
if (!thread) { if (!thread) {
SHIM_SET_RETURN_64(0); SHIM_SET_RETURN_64(0);
return; return;

View File

@ -175,10 +175,9 @@ void XObject::SetNativePointer(uint32_t native_ptr, bool uninitialized) {
header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF); header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF);
} }
XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, object_ref<XObject> XObject::GetNativeObject(KernelState* kernel_state,
void* native_ptr,
int32_t as_type) { int32_t as_type) {
assert_not_null(native_ptr);
// Unfortunately the XDK seems to inline some KeInitialize calls, meaning // Unfortunately the XDK seems to inline some KeInitialize calls, meaning
// we never see it and just randomly start getting passed events/timers/etc. // we never see it and just randomly start getting passed events/timers/etc.
// Luckily it seems like all other calls (Set/Reset/Wait/etc) are used and // Luckily it seems like all other calls (Set/Reset/Wait/etc) are used and
@ -202,28 +201,28 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
((header->wait_list_blink) & ~0x1); ((header->wait_list_blink) & ~0x1);
XObject* object = reinterpret_cast<XObject*>(object_ptr); XObject* object = reinterpret_cast<XObject*>(object_ptr);
// TODO(benvanik): assert nothing has been changed in the struct. // TODO(benvanik): assert nothing has been changed in the struct.
return object; return retain_object<XObject>(object);
} else { } else {
// First use, create new. // First use, create new.
// http://www.nirsoft.net/kernel_struct/vista/KOBJECTS.html // http://www.nirsoft.net/kernel_struct/vista/KOBJECTS.html
XObject* object = NULL; XObject* object = nullptr;
switch (as_type) { switch (as_type) {
case 0: // EventNotificationObject case 0: // EventNotificationObject
case 1: // EventSynchronizationObject case 1: // EventSynchronizationObject
{ {
XEvent* ev = new XEvent(kernel_state); auto ev = new XEvent(kernel_state);
ev->InitializeNative(native_ptr, *header); ev->InitializeNative(native_ptr, *header);
object = ev; object = ev;
} break; } break;
case 2: // MutantObject case 2: // MutantObject
{ {
XMutant* mutant = new XMutant(kernel_state); auto mutant = new XMutant(kernel_state);
mutant->InitializeNative(native_ptr, *header); mutant->InitializeNative(native_ptr, *header);
object = mutant; object = mutant;
} break; } break;
case 5: // SemaphoreObject case 5: // SemaphoreObject
{ {
XSemaphore* sem = new XSemaphore(kernel_state); auto sem = new XSemaphore(kernel_state);
sem->InitializeNative(native_ptr, *header); sem->InitializeNative(native_ptr, *header);
object = sem; object = sem;
} break; } break;
@ -251,7 +250,9 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
header->wait_list_flink = (uint32_t)(object_ptr >> 32); header->wait_list_flink = (uint32_t)(object_ptr >> 32);
header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF); header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF);
return object; // NOTE: we are double-retaining, as the object is implicitly created and
// can never be released.
return retain_object<XObject>(object);
} }
} }

View File

@ -81,8 +81,15 @@ class XObject {
uint32_t processor_mode, uint32_t alertable, uint32_t processor_mode, uint32_t alertable,
uint64_t* opt_timeout); uint64_t* opt_timeout);
static XObject* GetObject(KernelState* kernel_state, void* native_ptr, static object_ref<XObject> GetNativeObject(KernelState* kernel_state,
void* native_ptr,
int32_t as_type = -1); int32_t as_type = -1);
template <typename T>
static object_ref<T> GetNativeObject(KernelState* kernel_state,
void* native_ptr, int32_t as_type = -1) {
return object_ref<T>(reinterpret_cast<T*>(
GetNativeObject(kernel_state, native_ptr, as_type).release()));
}
virtual void* GetWaitHandle() { return 0; } virtual void* GetWaitHandle() { return 0; }