Merge pull request #353 from DrChat/ob_threads
Implement ObLookupThreadByThreadId / ObOpenObjectByPointer
This commit is contained in:
commit
6c5d230f67
|
@ -315,8 +315,7 @@ class Win32Thread : public Win32Handle<Thread> {
|
|||
~Win32Thread() = default;
|
||||
|
||||
void set_name(std::string name) override {
|
||||
AssertCallingThread();
|
||||
xe::threading::set_name(name);
|
||||
xe::threading::set_name(handle_, name);
|
||||
Thread::set_name(name);
|
||||
}
|
||||
|
||||
|
|
|
@ -150,12 +150,15 @@ uint8_t GetFakeCpuNumber(uint8_t proc_mask) {
|
|||
X_STATUS XThread::Create() {
|
||||
// Thread kernel object
|
||||
// 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) {
|
||||
XELOGW("Unable to allocate thread object");
|
||||
return X_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
guest_object->header.type = 6;
|
||||
StashNative(&guest_object->header, this);
|
||||
|
||||
auto module = kernel_state()->GetExecutableModule();
|
||||
|
||||
// Allocate thread scratch.
|
||||
|
@ -268,15 +271,9 @@ X_STATUS XThread::Create() {
|
|||
pcr->current_cpu = GetFakeCpuNumber(proc_mask); // Current CPU(?)
|
||||
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).
|
||||
// TODO: This is actually a KTHREAD object. Use the one from CreateNative
|
||||
// instead.
|
||||
uint8_t* p = memory()->TranslateVirtual(thread_state_address_);
|
||||
xe::store_and_swap<uint32_t>(p + 0x000, 6);
|
||||
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
|
||||
struct X_THREAD {
|
||||
X_DISPATCH_HEADER header;
|
||||
xe::be<uint64_t> cycle_time;
|
||||
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;
|
||||
struct X_KTHREAD {
|
||||
X_DISPATCH_HEADER header; // 0x0
|
||||
char unk_04[0xAA0]; // 0x4
|
||||
|
||||
// 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, 0x000000D9, NetDll_XHttpSetCredentials, 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, 0x000000FC, NetDll_UpnpCleanup, 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, 0x00000497, XamVoiceIsActiveProcess, kFunction),
|
||||
XE_EXPORT(xam, 0x0000049E, XGetVideoCapabilities, kFunction),
|
||||
XE_EXPORT(xam, 0x000004A5, XamUserGetAgeGroup, 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, 0x00000515, XamIsIptvEnabled, 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, 0x00000709, XamGetLiveHiveValueW, kFunction),
|
||||
XE_EXPORT(xam, 0x0000070A, XamGetLiveHiveValueDuringLogonAttemptA, kFunction),
|
||||
XE_EXPORT(xam, 0x0000070C, XamQueryLiveHiveA, kFunction),
|
||||
XE_EXPORT(xam, 0x0000076C, XamDownloadMarketplaceStoresList, kFunction),
|
||||
XE_EXPORT(xam, 0x0000076D, XamGetStoreFront, kFunction),
|
||||
XE_EXPORT(xam, 0x0000076E, XamSetStagingMode, kFunction),
|
||||
|
|
|
@ -49,6 +49,34 @@ SHIM_CALL ObOpenObjectByName_shim(PPCContext* ppc_context,
|
|||
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,
|
||||
KernelState* kernel_state) {
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT(NtClose, ExportTag::kImplemented);
|
||||
|
|
|
@ -273,10 +273,7 @@ void XObject::SetNativePointer(uint32_t native_ptr, bool uninitialized) {
|
|||
|
||||
// Stash pointer in struct.
|
||||
// FIXME: This assumes the object has a dispatch header (some don't!)
|
||||
uint64_t object_ptr = reinterpret_cast<uint64_t>(this);
|
||||
object_ptr |= 0x1;
|
||||
header->wait_list_flink = (uint32_t)(object_ptr >> 32);
|
||||
header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF);
|
||||
StashNative(header, this);
|
||||
|
||||
guest_object_ptr_ = native_ptr;
|
||||
}
|
||||
|
@ -354,10 +351,7 @@ object_ref<XObject> XObject::GetNativeObject(KernelState* kernel_state,
|
|||
|
||||
// Stash pointer in struct.
|
||||
// FIXME: This assumes the object contains a dispatch header (some don't!)
|
||||
uint64_t object_ptr = reinterpret_cast<uint64_t>(object);
|
||||
object_ptr |= 0x1;
|
||||
header->wait_list_flink = (uint32_t)(object_ptr >> 32);
|
||||
header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF);
|
||||
StashNative(header, object);
|
||||
|
||||
// NOTE: we are double-retaining, as the object is implicitly created and
|
||||
// can never be released.
|
||||
|
|
|
@ -156,6 +156,19 @@ class XObject {
|
|||
uint8_t* CreateNative(uint32_t size);
|
||||
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);
|
||||
|
||||
KernelState* kernel_state_;
|
||||
|
|
Loading…
Reference in New Issue