Merge pull request #353 from DrChat/ob_threads
Implement ObLookupThreadByThreadId / ObOpenObjectByPointer
This commit is contained in:
@@ -315,8 +315,7 @@ class Win32Thread : public Win32Handle<Thread> {
|
|||||||
~Win32Thread() = default;
|
~Win32Thread() = default;
|
||||||
|
|
||||||
void set_name(std::string name) override {
|
void set_name(std::string name) override {
|
||||||
AssertCallingThread();
|
xe::threading::set_name(handle_, name);
|
||||||
xe::threading::set_name(name);
|
|
||||||
Thread::set_name(name);
|
Thread::set_name(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -150,12 +150,15 @@ uint8_t GetFakeCpuNumber(uint8_t proc_mask) {
|
|||||||
X_STATUS XThread::Create() {
|
X_STATUS XThread::Create() {
|
||||||
// Thread kernel object
|
// Thread kernel object
|
||||||
// This call will also setup the native pointer for us.
|
// This call will also setup the native pointer for us.
|
||||||
uint8_t* guest_object = CreateNative(sizeof(X_THREAD));
|
auto guest_object = CreateNative<X_KTHREAD>(sizeof(X_KTHREAD));
|
||||||
if (!guest_object) {
|
if (!guest_object) {
|
||||||
XELOGW("Unable to allocate thread object");
|
XELOGW("Unable to allocate thread object");
|
||||||
return X_STATUS_NO_MEMORY;
|
return X_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guest_object->header.type = 6;
|
||||||
|
StashNative(&guest_object->header, this);
|
||||||
|
|
||||||
auto module = kernel_state()->GetExecutableModule();
|
auto module = kernel_state()->GetExecutableModule();
|
||||||
|
|
||||||
// Allocate thread scratch.
|
// Allocate thread scratch.
|
||||||
@@ -268,15 +271,9 @@ X_STATUS XThread::Create() {
|
|||||||
pcr->current_cpu = GetFakeCpuNumber(proc_mask); // Current CPU(?)
|
pcr->current_cpu = GetFakeCpuNumber(proc_mask); // Current CPU(?)
|
||||||
pcr->dpc_active = 0; // DPC active bool?
|
pcr->dpc_active = 0; // DPC active bool?
|
||||||
|
|
||||||
// Thread state block
|
|
||||||
struct XTEB {
|
|
||||||
xe::be<uint32_t> unk_00; // 0x0
|
|
||||||
xe::be<uint32_t> unk_04; // 0x4
|
|
||||||
X_LIST_ENTRY unk_08; // 0x8
|
|
||||||
X_LIST_ENTRY unk_10; // 0x10
|
|
||||||
};
|
|
||||||
|
|
||||||
// Setup the thread state block (last error/etc).
|
// Setup the thread state block (last error/etc).
|
||||||
|
// TODO: This is actually a KTHREAD object. Use the one from CreateNative
|
||||||
|
// instead.
|
||||||
uint8_t* p = memory()->TranslateVirtual(thread_state_address_);
|
uint8_t* p = memory()->TranslateVirtual(thread_state_address_);
|
||||||
xe::store_and_swap<uint32_t>(p + 0x000, 6);
|
xe::store_and_swap<uint32_t>(p + 0x000, 6);
|
||||||
xe::store_and_swap<uint32_t>(p + 0x008, thread_state_address_ + 0x008);
|
xe::store_and_swap<uint32_t>(p + 0x008, thread_state_address_ + 0x008);
|
||||||
|
|||||||
@@ -66,14 +66,9 @@ struct XAPC {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// http://www.nirsoft.net/kernel_struct/vista/KTHREAD.html
|
// http://www.nirsoft.net/kernel_struct/vista/KTHREAD.html
|
||||||
struct X_THREAD {
|
struct X_KTHREAD {
|
||||||
X_DISPATCH_HEADER header;
|
X_DISPATCH_HEADER header; // 0x0
|
||||||
xe::be<uint64_t> cycle_time;
|
char unk_04[0xAA0]; // 0x4
|
||||||
xe::be<uint32_t> high_cycle_time; // FIXME: Needed?
|
|
||||||
xe::be<uint64_t> quantum_target;
|
|
||||||
xe::be<uint32_t> initial_stack_ptr;
|
|
||||||
xe::be<uint32_t> stack_limit_ptr;
|
|
||||||
xe::be<uint32_t> kernel_stack_ptr;
|
|
||||||
|
|
||||||
// This struct is actually quite long... so uh, not filling this out!
|
// This struct is actually quite long... so uh, not filling this out!
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -150,7 +150,10 @@ XE_EXPORT(xam, 0x000000D7, NetDll_XHttpSetOption,
|
|||||||
XE_EXPORT(xam, 0x000000D8, NetDll_XHttpDoWork, kFunction),
|
XE_EXPORT(xam, 0x000000D8, NetDll_XHttpDoWork, kFunction),
|
||||||
XE_EXPORT(xam, 0x000000D9, NetDll_XHttpSetCredentials, kFunction),
|
XE_EXPORT(xam, 0x000000D9, NetDll_XHttpSetCredentials, kFunction),
|
||||||
XE_EXPORT(xam, 0x000000DA, NetDll_XHttpQueryAuthSchemes, kFunction),
|
XE_EXPORT(xam, 0x000000DA, NetDll_XHttpQueryAuthSchemes, kFunction),
|
||||||
XE_EXPORT(xam, 0x000000DB, NetDll_XHttpCrackUrl, kFunction),
|
XE_EXPORT(xam, 0x000000DB, NetDll_XHttpCrackUrlW, kFunction),
|
||||||
|
XE_EXPORT(xam, 0x000000DC, NetDll_XHttpCrackUrl, kFunction),
|
||||||
|
XE_EXPORT(xam, 0x000000DD, NetDll_XHttpCreateUrl, kFunction),
|
||||||
|
XE_EXPORT(xam, 0x000000DE, NetDll_XHttpCreateUrlW, kFunction),
|
||||||
XE_EXPORT(xam, 0x000000FB, NetDll_UpnpStartup, kFunction),
|
XE_EXPORT(xam, 0x000000FB, NetDll_UpnpStartup, kFunction),
|
||||||
XE_EXPORT(xam, 0x000000FC, NetDll_UpnpCleanup, kFunction),
|
XE_EXPORT(xam, 0x000000FC, NetDll_UpnpCleanup, kFunction),
|
||||||
XE_EXPORT(xam, 0x000000FD, NetDll_UpnpSearchCreate, kFunction),
|
XE_EXPORT(xam, 0x000000FD, NetDll_UpnpSearchCreate, kFunction),
|
||||||
@@ -957,7 +960,13 @@ XE_EXPORT(xam, 0x00000490, XamVoiceGetMicArrayAudioEx,
|
|||||||
XE_EXPORT(xam, 0x00000491, XamVoiceDisableMicArray, kFunction),
|
XE_EXPORT(xam, 0x00000491, XamVoiceDisableMicArray, kFunction),
|
||||||
XE_EXPORT(xam, 0x00000497, XamVoiceIsActiveProcess, kFunction),
|
XE_EXPORT(xam, 0x00000497, XamVoiceIsActiveProcess, kFunction),
|
||||||
XE_EXPORT(xam, 0x0000049E, XGetVideoCapabilities, kFunction),
|
XE_EXPORT(xam, 0x0000049E, XGetVideoCapabilities, kFunction),
|
||||||
|
XE_EXPORT(xam, 0x000004A5, XamUserGetAgeGroup, kFunction),
|
||||||
XE_EXPORT(xam, 0x000004B0, XMPRegisterCodec, kFunction),
|
XE_EXPORT(xam, 0x000004B0, XMPRegisterCodec, kFunction),
|
||||||
|
XE_EXPORT(xam, 0x000004BC, XampXAuthStartup, kFunction),
|
||||||
|
XE_EXPORT(xam, 0x000004BD, XampXAuthShutdown, kFunction),
|
||||||
|
XE_EXPORT(xam, 0x000004BE, XamGetToken, kFunction),
|
||||||
|
XE_EXPORT(xam, 0x000004BF, XamFreeToken, kFunction),
|
||||||
|
XE_EXPORT(xam, 0x000004EE, XampXAuthGetTitleBuffer, kFunction),
|
||||||
XE_EXPORT(xam, 0x00000514, XamIsCurrentTitleIptv, kFunction),
|
XE_EXPORT(xam, 0x00000514, XamIsCurrentTitleIptv, kFunction),
|
||||||
XE_EXPORT(xam, 0x00000515, XamIsIptvEnabled, kFunction),
|
XE_EXPORT(xam, 0x00000515, XamIsIptvEnabled, kFunction),
|
||||||
XE_EXPORT(xam, 0x00000516, XamIsDvrRecording, kFunction),
|
XE_EXPORT(xam, 0x00000516, XamIsDvrRecording, kFunction),
|
||||||
@@ -1046,6 +1055,7 @@ XE_EXPORT(xam, 0x000006A8, XamShowPaymentOptionsUI,
|
|||||||
XE_EXPORT(xam, 0x00000708, XamGetLiveHiveValueA, kFunction),
|
XE_EXPORT(xam, 0x00000708, XamGetLiveHiveValueA, kFunction),
|
||||||
XE_EXPORT(xam, 0x00000709, XamGetLiveHiveValueW, kFunction),
|
XE_EXPORT(xam, 0x00000709, XamGetLiveHiveValueW, kFunction),
|
||||||
XE_EXPORT(xam, 0x0000070A, XamGetLiveHiveValueDuringLogonAttemptA, kFunction),
|
XE_EXPORT(xam, 0x0000070A, XamGetLiveHiveValueDuringLogonAttemptA, kFunction),
|
||||||
|
XE_EXPORT(xam, 0x0000070C, XamQueryLiveHiveA, kFunction),
|
||||||
XE_EXPORT(xam, 0x0000076C, XamDownloadMarketplaceStoresList, kFunction),
|
XE_EXPORT(xam, 0x0000076C, XamDownloadMarketplaceStoresList, kFunction),
|
||||||
XE_EXPORT(xam, 0x0000076D, XamGetStoreFront, kFunction),
|
XE_EXPORT(xam, 0x0000076D, XamGetStoreFront, kFunction),
|
||||||
XE_EXPORT(xam, 0x0000076E, XamSetStagingMode, kFunction),
|
XE_EXPORT(xam, 0x0000076E, XamSetStagingMode, kFunction),
|
||||||
|
|||||||
@@ -49,6 +49,34 @@ SHIM_CALL ObOpenObjectByName_shim(PPCContext* ppc_context,
|
|||||||
SHIM_SET_RETURN_32(result);
|
SHIM_SET_RETURN_32(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dword_result_t ObOpenObjectByPointer(lpvoid_t object_ptr,
|
||||||
|
lpdword_t out_handle_ptr) {
|
||||||
|
auto object = XObject::GetNativeObject<XObject>(kernel_state(), object_ptr);
|
||||||
|
if (!object) {
|
||||||
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retain the handle. Will be released in NtClose.
|
||||||
|
object->RetainHandle();
|
||||||
|
*out_handle_ptr = object->handle();
|
||||||
|
return X_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(ObOpenObjectByPointer, ExportTag::kImplemented);
|
||||||
|
|
||||||
|
dword_result_t ObLookupThreadByThreadId(dword_t thread_id,
|
||||||
|
lpdword_t out_object_ptr) {
|
||||||
|
auto thread = kernel_state()->GetThreadByID(thread_id);
|
||||||
|
if (!thread) {
|
||||||
|
return X_STATUS_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retain the object. Will be released in ObDereferenceObject.
|
||||||
|
thread->Retain();
|
||||||
|
*out_object_ptr = thread->guest_object();
|
||||||
|
return X_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(ObLookupThreadByThreadId, ExportTag::kImplemented);
|
||||||
|
|
||||||
SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context,
|
SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context,
|
||||||
KernelState* kernel_state) {
|
KernelState* kernel_state) {
|
||||||
uint32_t handle = SHIM_GET_ARG_32(0);
|
uint32_t handle = SHIM_GET_ARG_32(0);
|
||||||
@@ -162,6 +190,7 @@ dword_result_t NtDuplicateObject(dword_t handle, lpdword_t new_handle_ptr,
|
|||||||
DECLARE_XBOXKRNL_EXPORT(NtDuplicateObject, ExportTag::kImplemented);
|
DECLARE_XBOXKRNL_EXPORT(NtDuplicateObject, ExportTag::kImplemented);
|
||||||
|
|
||||||
dword_result_t NtClose(dword_t handle) {
|
dword_result_t NtClose(dword_t handle) {
|
||||||
|
// FIXME: This needs to be removed once handle count reaches 0!
|
||||||
return kernel_state()->object_table()->RemoveHandle(handle);
|
return kernel_state()->object_table()->RemoveHandle(handle);
|
||||||
}
|
}
|
||||||
DECLARE_XBOXKRNL_EXPORT(NtClose, ExportTag::kImplemented);
|
DECLARE_XBOXKRNL_EXPORT(NtClose, ExportTag::kImplemented);
|
||||||
|
|||||||
@@ -273,10 +273,7 @@ void XObject::SetNativePointer(uint32_t native_ptr, bool uninitialized) {
|
|||||||
|
|
||||||
// Stash pointer in struct.
|
// Stash pointer in struct.
|
||||||
// FIXME: This assumes the object has a dispatch header (some don't!)
|
// FIXME: This assumes the object has a dispatch header (some don't!)
|
||||||
uint64_t object_ptr = reinterpret_cast<uint64_t>(this);
|
StashNative(header, this);
|
||||||
object_ptr |= 0x1;
|
|
||||||
header->wait_list_flink = (uint32_t)(object_ptr >> 32);
|
|
||||||
header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF);
|
|
||||||
|
|
||||||
guest_object_ptr_ = native_ptr;
|
guest_object_ptr_ = native_ptr;
|
||||||
}
|
}
|
||||||
@@ -354,10 +351,7 @@ object_ref<XObject> XObject::GetNativeObject(KernelState* kernel_state,
|
|||||||
|
|
||||||
// Stash pointer in struct.
|
// Stash pointer in struct.
|
||||||
// FIXME: This assumes the object contains a dispatch header (some don't!)
|
// FIXME: This assumes the object contains a dispatch header (some don't!)
|
||||||
uint64_t object_ptr = reinterpret_cast<uint64_t>(object);
|
StashNative(header, object);
|
||||||
object_ptr |= 0x1;
|
|
||||||
header->wait_list_flink = (uint32_t)(object_ptr >> 32);
|
|
||||||
header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF);
|
|
||||||
|
|
||||||
// NOTE: we are double-retaining, as the object is implicitly created and
|
// NOTE: we are double-retaining, as the object is implicitly created and
|
||||||
// can never be released.
|
// can never be released.
|
||||||
|
|||||||
@@ -156,6 +156,19 @@ class XObject {
|
|||||||
uint8_t* CreateNative(uint32_t size);
|
uint8_t* CreateNative(uint32_t size);
|
||||||
void SetNativePointer(uint32_t native_ptr, bool uninitialized = false);
|
void SetNativePointer(uint32_t native_ptr, bool uninitialized = false);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T* CreateNative(uint32_t size) {
|
||||||
|
return reinterpret_cast<T*>(CreateNative(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stash native pointer into X_DISPATCH_HEADER
|
||||||
|
static void StashNative(X_DISPATCH_HEADER* header, void* native_ptr) {
|
||||||
|
uint64_t object_ptr = reinterpret_cast<uint64_t>(native_ptr);
|
||||||
|
object_ptr |= 0x1;
|
||||||
|
header->wait_list_flink = (uint32_t)(object_ptr >> 32);
|
||||||
|
header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t TimeoutTicksToMs(int64_t timeout_ticks);
|
static uint32_t TimeoutTicksToMs(int64_t timeout_ticks);
|
||||||
|
|
||||||
KernelState* kernel_state_;
|
KernelState* kernel_state_;
|
||||||
|
|||||||
Reference in New Issue
Block a user