Merge remote-tracking branch 'emoose/import-fixes'

This commit is contained in:
0x8081 2019-08-20 16:21:23 -06:00
commit 974123d9c3
6 changed files with 62 additions and 37 deletions

View File

@ -486,8 +486,6 @@ int XexModule::ReadImage(const void* xex_addr, size_t xex_length,
return 0; return 0;
} }
memory()->LookupHeap(base_address_)->Reset();
aes_decrypt_buffer( aes_decrypt_buffer(
use_dev_key ? xe_xex2_devkit_key : xe_xex2_retail_key, use_dev_key ? xe_xex2_devkit_key : xe_xex2_retail_key,
reinterpret_cast<const uint8_t*>(xex_security_info()->aes_key), 16, reinterpret_cast<const uint8_t*>(xex_security_info()->aes_key), 16,

View File

@ -224,7 +224,9 @@ object_ref<XModule> KernelState::GetModule(const char* name, bool user_only) {
return retain_object(user_module.get()); return retain_object(user_module.get());
} }
} }
return nullptr;
// Module not found, try loading it
return LoadUserModule(name);
} }
object_ref<XThread> KernelState::LaunchModule(object_ref<UserModule> module) { object_ref<XThread> KernelState::LaunchModule(object_ref<UserModule> module) {
@ -232,29 +234,43 @@ object_ref<XThread> KernelState::LaunchModule(object_ref<UserModule> module) {
return nullptr; return nullptr;
} }
SetExecutableModule(module); XELOGI("KernelState: Launching module %s...", module->path().c_str());
XELOGI("KernelState: Launching module...");
// Create a thread to run in. // Create a thread to run in.
// We start suspended so we can run the debugger prep. // We start suspended so we can run the debugger prep.
auto thread = object_ref<XThread>( xe::kernel::object_ref<XThread> thread = nullptr;
new XThread(kernel_state(), module->stack_size(), 0,
module->entry_point(), 0, X_CREATE_SUSPENDED, true, true));
// We know this is the 'main thread'. if (!module->is_dll_module()) {
// Not a DLL module, run entrypoint as normal
thread = object_ref<XThread>(new XThread(
kernel_state(), module->stack_size(), XThread::StartupType::Normal, 0,
module->entry_point(), 0, X_CREATE_SUSPENDED, true, true));
} else {
// Run entrypoint as DllMain, using module handle as start context
thread = object_ref<XThread>(
new XThread(kernel_state(), module->stack_size(),
XThread::StartupType::DllMain, 0, module->entry_point(),
module->handle(), X_CREATE_SUSPENDED, true, true));
}
// We know this is the 'main thread', or '<dllname> thread'
char thread_name[32]; char thread_name[32];
std::snprintf(thread_name, xe::countof(thread_name), "Main XThread%08X", std::snprintf(thread_name, xe::countof(thread_name), "%s XThread%08X",
module->is_dll_module() ? module->name().c_str() : "Main",
thread->handle()); thread->handle());
thread->set_name(thread_name); thread->set_name(thread_name);
X_STATUS result = thread->Create(); X_STATUS result = thread->Create();
if (XFAILED(result)) { if (XFAILED(result)) {
XELOGE("Could not create launch thread: %.8X", result); XELOGE("Could not create launch thread for %s: %.8X",
module->path().c_str(), result);
return nullptr; return nullptr;
} }
// Waits for a debugger client, if desired. // Waits for a debugger client, if desired.
emulator()->processor()->PreLaunch(); if (!module->is_dll_module()) {
emulator()->processor()->PreLaunch();
}
// Resume the thread now. // Resume the thread now.
// If the debugger has requested a suspend this will just decrement the // If the debugger has requested a suspend this will just decrement the
@ -272,9 +288,6 @@ object_ref<UserModule> KernelState::GetExecutableModule() {
} }
void KernelState::SetExecutableModule(object_ref<UserModule> module) { void KernelState::SetExecutableModule(object_ref<UserModule> module) {
if (module.get() == executable_module_.get()) {
return;
}
executable_module_ = std::move(module); executable_module_ = std::move(module);
if (!executable_module_) { if (!executable_module_) {
return; return;
@ -392,16 +405,7 @@ object_ref<UserModule> KernelState::LoadUserModule(const char* raw_name,
module->Dump(); module->Dump();
if (module->is_dll_module() && module->entry_point() && call_entry) { if (module->is_dll_module() && module->entry_point() && call_entry) {
// Call DllMain(DLL_PROCESS_ATTACH): LaunchModule(module);
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs.85%29.aspx
uint64_t args[] = {
module->handle(),
1, // DLL_PROCESS_ATTACH
0, // 0 because always dynamic
};
auto thread_state = XThread::GetCurrentThread()->thread_state();
processor()->Execute(thread_state, module->entry_point(), args,
xe::countof(args));
} }
return module; return module;

View File

@ -248,6 +248,11 @@ X_STATUS UserModule::LoadXexContinue() {
return X_STATUS_SUCCESS; return X_STATUS_SUCCESS;
} }
// Notify kernel that we have an executable if we haven't got one already
if (!kernel_state_->GetExecutableModule()) {
kernel_state_->SetExecutableModule(object_ref<UserModule>(this));
}
// Finish XexModule load (PE sections/imports/symbols...) // Finish XexModule load (PE sections/imports/symbols...)
if (!xex_module()->LoadContinue()) { if (!xex_module()->LoadContinue()) {
return X_STATUS_UNSUCCESSFUL; return X_STATUS_UNSUCCESSFUL;

View File

@ -122,9 +122,11 @@ dword_result_t ExCreateThread(lpdword_t handle_ptr, dword_t stack_size,
std::max((uint32_t)0x4000, ((actual_stack_size + 0xFFF) & 0xFFFFF000)); std::max((uint32_t)0x4000, ((actual_stack_size + 0xFFF) & 0xFFFFF000));
auto thread = object_ref<XThread>( auto thread = object_ref<XThread>(
new XThread(kernel_state(), actual_stack_size, xapi_thread_startup, new XThread(kernel_state(), actual_stack_size,
start_address.guest_address(), start_context.guest_address(), xapi_thread_startup ? XThread::StartupType::XapiThreadStartup
creation_flags, true)); : XThread::StartupType::Normal,
xapi_thread_startup, start_address.guest_address(),
start_context.guest_address(), creation_flags, true));
X_STATUS result = thread->Create(); X_STATUS result = thread->Create();
if (XFAILED(result)) { if (XFAILED(result)) {

View File

@ -50,15 +50,16 @@ XThread::XThread(KernelState* kernel_state)
: XObject(kernel_state, kType), guest_thread_(true) {} : XObject(kernel_state, kType), guest_thread_(true) {}
XThread::XThread(KernelState* kernel_state, uint32_t stack_size, XThread::XThread(KernelState* kernel_state, uint32_t stack_size,
uint32_t xapi_thread_startup, uint32_t start_address, StartupType startup_type, uint32_t xapi_thread_startup,
uint32_t start_context, uint32_t creation_flags, uint32_t start_address, uint32_t start_context,
bool guest_thread, bool main_thread) uint32_t creation_flags, bool guest_thread, bool main_thread)
: XObject(kernel_state, kType), : XObject(kernel_state, kTypeThread),
thread_id_(++next_xthread_id_), thread_id_(++next_xthread_id_),
guest_thread_(guest_thread), guest_thread_(guest_thread),
main_thread_(main_thread), main_thread_(main_thread),
apc_list_(kernel_state->memory()) { apc_list_(kernel_state->memory()) {
creation_params_.stack_size = stack_size; creation_params_.stack_size = stack_size;
creation_params_.startup_type = startup_type;
creation_params_.xapi_thread_startup = xapi_thread_startup; creation_params_.xapi_thread_startup = xapi_thread_startup;
creation_params_.start_address = start_address; creation_params_.start_address = start_address;
creation_params_.start_context = start_context; creation_params_.start_context = start_context;
@ -513,12 +514,23 @@ void XThread::Execute() {
// If a XapiThreadStartup value is present, we use that as a trampoline. // If a XapiThreadStartup value is present, we use that as a trampoline.
// Otherwise, we are a raw thread. // Otherwise, we are a raw thread.
if (creation_params_.xapi_thread_startup) {
if (creation_params_.startup_type == StartupType::XapiThreadStartup) {
uint64_t args[] = {creation_params_.start_address, uint64_t args[] = {creation_params_.start_address,
creation_params_.start_context}; creation_params_.start_context};
kernel_state()->processor()->Execute(thread_state_, kernel_state()->processor()->Execute(thread_state_,
creation_params_.xapi_thread_startup, creation_params_.xapi_thread_startup,
args, xe::countof(args)); args, xe::countof(args));
} else if (creation_params_.startup_type == StartupType::DllMain) {
// Call DllMain(DLL_PROCESS_ATTACH):
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs.85%29.aspx
uint64_t args[] = {
creation_params_.start_context,
1, // DLL_PROCESS_ATTACH
0, // 0 because always dynamic
};
kernel_state()->processor()->Execute(
thread_state_, creation_params_.start_address, args, xe::countof(args));
} else { } else {
// Run user code. // Run user code.
uint64_t args[] = {creation_params_.start_context}; uint64_t args[] = {creation_params_.start_context};
@ -1046,7 +1058,8 @@ object_ref<XThread> XThread::Restore(KernelState* kernel_state,
XHostThread::XHostThread(KernelState* kernel_state, uint32_t stack_size, XHostThread::XHostThread(KernelState* kernel_state, uint32_t stack_size,
uint32_t creation_flags, std::function<int()> host_fn) uint32_t creation_flags, std::function<int()> host_fn)
: XThread(kernel_state, stack_size, 0, 0, 0, creation_flags, false), : XThread(kernel_state, stack_size, XThread::StartupType::Normal, 0, 0, 0,
creation_flags, false),
host_fn_(host_fn) { host_fn_(host_fn) {
// By default host threads are not debugger suspendable. If the thread runs // By default host threads are not debugger suspendable. If the thread runs
// any guest code this must be overridden. // any guest code this must be overridden.

View File

@ -107,8 +107,11 @@ class XThread : public XObject, public cpu::Thread {
public: public:
static const Type kType = kTypeThread; static const Type kType = kTypeThread;
enum StartupType { Normal, XapiThreadStartup, DllMain };
struct CreationParams { struct CreationParams {
uint32_t stack_size; uint32_t stack_size;
StartupType startup_type;
uint32_t xapi_thread_startup; uint32_t xapi_thread_startup;
uint32_t start_address; uint32_t start_address;
uint32_t start_context; uint32_t start_context;
@ -117,9 +120,9 @@ class XThread : public XObject, public cpu::Thread {
XThread(KernelState* kernel_state); XThread(KernelState* kernel_state);
XThread(KernelState* kernel_state, uint32_t stack_size, XThread(KernelState* kernel_state, uint32_t stack_size,
uint32_t xapi_thread_startup, uint32_t start_address, StartupType startup_type, uint32_t xapi_thread_startup,
uint32_t start_context, uint32_t creation_flags, bool guest_thread, uint32_t start_address, uint32_t start_context,
bool main_thread = false); uint32_t creation_flags, bool guest_thread, bool main_thread = false);
~XThread() override; ~XThread() override;
static bool IsInThread(XThread* other); static bool IsInThread(XThread* other);