[Kernel] More TranslateVirtual/HostToGuestVirtual usage

This commit is contained in:
Triang3l 2019-08-14 08:28:30 +03:00
parent 2152c79965
commit 0067f5561d
6 changed files with 14 additions and 37 deletions

View File

@ -33,8 +33,8 @@ using PPCContext = xe::cpu::ppc::PPCContext;
library_name, ordinals::export_name, \ library_name, ordinals::export_name, \
(xe::cpu::xe_kernel_export_shim_fn)export_name##_shim); (xe::cpu::xe_kernel_export_shim_fn)export_name##_shim);
#define SHIM_MEM_BASE ppc_context->virtual_membase #define SHIM_MEM_ADDR(a) \
#define SHIM_MEM_ADDR(a) (a ? (ppc_context->virtual_membase + a) : nullptr) ((a) ? ppc_context->kernel_state->memory()->TranslateVirtual(a) : nullptr)
#define SHIM_MEM_8(a) xe::load_and_swap<uint8_t>(SHIM_MEM_ADDR(a)) #define SHIM_MEM_8(a) xe::load_and_swap<uint8_t>(SHIM_MEM_ADDR(a))
#define SHIM_MEM_16(a) xe::load_and_swap<uint16_t>(SHIM_MEM_ADDR(a)) #define SHIM_MEM_16(a) xe::load_and_swap<uint16_t>(SHIM_MEM_ADDR(a))

View File

@ -243,8 +243,8 @@ dword_result_t XexGetProcedureAddress(lpvoid_t hmodule, dword_t ordinal,
assert_not_zero(ordinal); assert_not_zero(ordinal);
bool is_string_name = (ordinal & 0xFFFF0000) != 0; bool is_string_name = (ordinal & 0xFFFF0000) != 0;
auto string_name = reinterpret_cast<const char*>( auto string_name =
kernel_memory()->virtual_membase() + ordinal); reinterpret_cast<const char*>(kernel_memory()->TranslateVirtual(ordinal));
X_STATUS result = X_STATUS_INVALID_HANDLE; X_STATUS result = X_STATUS_INVALID_HANDLE;

View File

@ -166,7 +166,7 @@ dword_result_t ObDereferenceObject(dword_t native_ptr) {
} }
auto object = XObject::GetNativeObject<XObject>( auto object = XObject::GetNativeObject<XObject>(
kernel_state(), kernel_memory()->virtual_membase() + native_ptr); kernel_state(), kernel_memory()->TranslateVirtual(native_ptr));
if (object) { if (object) {
object->Release(); object->Release();
} }

View File

@ -241,7 +241,7 @@ dword_result_t RtlUnicodeStringToAnsiString(
uint32_t buffer_ptr = uint32_t buffer_ptr =
kernel_memory()->SystemHeapAlloc(uint32_t(ansi_str.size() + 1)); kernel_memory()->SystemHeapAlloc(uint32_t(ansi_str.size() + 1));
memcpy(kernel_memory()->virtual_membase() + buffer_ptr, ansi_str.data(), memcpy(kernel_memory()->TranslateVirtual(buffer_ptr), ansi_str.data(),
ansi_str.size() + 1); ansi_str.size() + 1);
destination_ptr->length = static_cast<uint16_t>(ansi_str.size()); destination_ptr->length = static_cast<uint16_t>(ansi_str.size());
destination_ptr->maximum_length = destination_ptr->maximum_length =
@ -250,7 +250,7 @@ dword_result_t RtlUnicodeStringToAnsiString(
} else { } else {
uint32_t buffer_capacity = destination_ptr->maximum_length; uint32_t buffer_capacity = destination_ptr->maximum_length;
auto buffer_ptr = auto buffer_ptr =
kernel_memory()->virtual_membase() + destination_ptr->pointer; kernel_memory()->TranslateVirtual(destination_ptr->pointer);
if (buffer_capacity < ansi_str.size() + 1) { if (buffer_capacity < ansi_str.size() + 1) {
// Too large - we just write what we can. // Too large - we just write what we can.
result = X_STATUS_BUFFER_OVERFLOW; result = X_STATUS_BUFFER_OVERFLOW;
@ -332,7 +332,7 @@ pointer_result_t RtlImageNtHeader(lpvoid_t module) {
if (nt_magic != 0x4550) { // 'PE' if (nt_magic != 0x4550) { // 'PE'
return 0; return 0;
} }
return static_cast<uint32_t>(nt_header - kernel_memory()->virtual_membase()); return kernel_memory()->HostToGuestVirtual(nt_header);
} }
DECLARE_XBOXKRNL_EXPORT1(RtlImageNtHeader, kNone, kImplemented); DECLARE_XBOXKRNL_EXPORT1(RtlImageNtHeader, kNone, kImplemented);

View File

@ -430,7 +430,6 @@ bool Memory::AccessViolationCallback(void* host_address, bool is_write) {
// TODO(Triang3l): Handle GPU readback. // TODO(Triang3l): Handle GPU readback.
return false; return false;
} }
// Access via physical_membase_ is special, when need to bypass everything, // Access via physical_membase_ is special, when need to bypass everything,
// so only watching virtual memory regions. // so only watching virtual memory regions.
if (reinterpret_cast<size_t>(host_address) < if (reinterpret_cast<size_t>(host_address) <
@ -439,29 +438,14 @@ bool Memory::AccessViolationCallback(void* host_address, bool is_write) {
reinterpret_cast<size_t>(physical_membase_)) { reinterpret_cast<size_t>(physical_membase_)) {
return false; return false;
} }
uint32_t virtual_address = HostToGuestVirtual(host_address);
uint32_t virtual_address =
uint32_t(reinterpret_cast<uint8_t*>(host_address) - virtual_membase_);
// If the 4 KB page offset in 0xE0000000 cannot be applied via memory mapping,
// it will be added by CPU load/store implementations, so the host virtual
// addresses (relative to virtual_membase_) where access violations occur do
// not match guest virtual addresses. Revert what CPU memory accesses are
// doing.
// TODO(Triang3l): Move this to a host->guest address conversion function.
if (virtual_address >= 0xE0000000) {
uint32_t host_address_offset = heaps_.vE0000000.host_address_offset();
if (virtual_address < 0xE0000000 + host_address_offset) {
return false;
}
virtual_address -= host_address_offset;
}
BaseHeap* heap = LookupHeap(virtual_address); BaseHeap* heap = LookupHeap(virtual_address);
if (heap == &heaps_.vA0000000 || heap == &heaps_.vC0000000 || if (heap == &heaps_.vA0000000 || heap == &heaps_.vC0000000 ||
heap == &heaps_.vE0000000) { heap == &heaps_.vE0000000) {
return static_cast<PhysicalHeap*>(heap)->TriggerWatches( // Will be rounded to physical page boundaries internally, so just pass 1 as
virtual_address / system_page_size_ * system_page_size_, // the length - guranteed not to cross page boundaries also.
system_page_size_, is_write, false); return static_cast<PhysicalHeap*>(heap)->TriggerWatches(virtual_address, 1,
is_write, false);
} }
return false; return false;

View File

@ -344,17 +344,10 @@ struct X_VIDEO_MODE {
}; };
static_assert_size(X_VIDEO_MODE, 48); static_assert_size(X_VIDEO_MODE, 48);
// https://docs.microsoft.com/en-us/windows/win32/api/ntdef/ns-ntdef-list_entry
struct X_LIST_ENTRY { struct X_LIST_ENTRY {
be<uint32_t> flink_ptr; // next entry / head be<uint32_t> flink_ptr; // next entry / head
be<uint32_t> blink_ptr; // previous entry / head be<uint32_t> blink_ptr; // previous entry / head
// Assumes X_LIST_ENTRY is within guest memory!
void initialize(uint8_t* virtual_membase) {
flink_ptr = static_cast<uint32_t>(reinterpret_cast<uint8_t*>(this) -
virtual_membase);
blink_ptr = static_cast<uint32_t>(reinterpret_cast<uint8_t*>(this) -
virtual_membase);
}
}; };
static_assert_size(X_LIST_ENTRY, 8); static_assert_size(X_LIST_ENTRY, 8);