Merge pull request #353 from DrChat/ob_threads

Implement ObLookupThreadByThreadId / ObOpenObjectByPointer
This commit is contained in:
Ben Vanik 2015-07-18 13:27:25 -07:00
commit 6c5d230f67
7 changed files with 65 additions and 28 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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!
};

View File

@ -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),

View File

@ -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);

View File

@ -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.

View File

@ -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_;