Files
XBDM/xbdm/hvx.c
2025-11-06 15:36:24 -05:00

214 lines
5.5 KiB
C

// This wasn't written by me
// You know who you are
#include "dmincludes.h"
// I need to clean this up ;_;
// Sorry
const BYTE HvPeekPokeExp[] = {
0x00, 0x00, 0x00, 0x00
};
// Sorry
const BYTE HvPeekPokeExp2[] = { // Encrypted
0x00, 0x00, 0x00, 0x00
};
#define HvxCall QWORD _declspec(naked)
static HvxCall HvxExpansionInstall(DWORD PhysicalAddress, DWORD CodeSize) {
if(XboxKrnlVersion->Build == 9199) {
__asm { li r0, 0x76 }
} else if(XboxKrnlVersion->Build == 12611 || XboxKrnlVersion->Build == 12625) {
__asm { li r0, 0x70 }
} else if(XboxKrnlVersion->Build >= 13110) {
__asm { li r0, 0x6F }
}
__asm {
sc
blr
}
}
static HvxCall HvxExpansionCall(DWORD ExpansionId, QWORD Param1, QWORD Param2, QWORD Param3, QWORD Param4) {
if(XboxKrnlVersion->Build == 9199) {
__asm { li r0, 0x77 }
} else if(XboxKrnlVersion->Build == 12611 || XboxKrnlVersion->Build == 12625) {
__asm { li r0, 0x71 }
} else if(XboxKrnlVersion->Build >= 13110) {
__asm { li r0, 0x70 }
}
__asm {
sc
blr
}
}
HRESULT HvInitialize() {
// Allocate physcial memory for this expansion
VOID* pPhysExp = XPhysicalAlloc(0x1000, MAXULONG_PTR, 0, PAGE_READWRITE);
DWORD physExpAdd = MmGetPhysicalAddress(pPhysExp);
HRESULT result;
// Copy over our expansion data
ZeroMemory(pPhysExp, 0x1000);
memcpy(pPhysExp, HvPeekPokeExp, sizeof(HvPeekPokeExp));
if(XboxKrnlVersion->Build >= 13110)
*(LPDWORD)pPhysExp = 'HXPR';
// Now we can install our expansion
result = (HRESULT)HvxExpansionInstall(physExpAdd, 0x1000);
// Free our allocated data
XPhysicalFree(pPhysExp);
if(FAILED(result))
DbgPrint("[hvx] failed to install (0x%08x)\n", result);
// Return our install result
return result;
}
BYTE HvPeekBYTE(QWORD Address) {
return (BYTE)HvxExpansionCall(HvPeekPokeExpID, PEEK_BYTE, Address, 0, 0);
}
WORD HvPeekWORD(QWORD Address) {
return (WORD)HvxExpansionCall(HvPeekPokeExpID, PEEK_WORD, Address, 0, 0);
}
DWORD HvPeekDWORD(QWORD Address) {
return (DWORD)HvxExpansionCall(HvPeekPokeExpID, PEEK_DWORD, Address, 0, 0);
}
QWORD HvPeekQWORD(QWORD Address) {
return HvxExpansionCall(HvPeekPokeExpID, PEEK_QWORD, Address, 0, 0);
}
HRESULT HvPeekBytes(QWORD Address, PVOID Buffer, DWORD Size) {
// Create a physical buffer to peek into
VOID* data = XPhysicalAlloc(Size, MAXULONG_PTR, 0, PAGE_READWRITE);
HRESULT result;
ZeroMemory(data, Size);
result = (HRESULT)HvxExpansionCall(HvPeekPokeExpID,
PEEK_BYTES, Address, MmGetPhysicalAddress(data), Size);
// If its successful copy it bacl
if(result == S_OK) memcpy(Buffer, data, Size);
// Free our physical data and return our result
XPhysicalFree(data);
return result;
}
HRESULT HvPokeBYTE(QWORD Address, BYTE Value) {
return (HRESULT)HvxExpansionCall(HvPeekPokeExpID, POKE_BYTE, Address, Value, 0);
}
HRESULT HvPokeWORD(QWORD Address, WORD Value) {
return (HRESULT)HvxExpansionCall(HvPeekPokeExpID, POKE_WORD, Address, Value, 0);
}
HRESULT HvPokeDWORD(QWORD Address, DWORD Value) {
return (HRESULT)HvxExpansionCall(HvPeekPokeExpID, POKE_DWORD, Address, Value, 0);
}
HRESULT HvPokeQWORD(QWORD Address, QWORD Value) {
return (HRESULT)HvxExpansionCall(HvPeekPokeExpID, POKE_QWORD, Address, Value, 0);
}
HRESULT HvPokeBytes(QWORD Address, const void* Buffer, DWORD Size) {
// Create a physical buffer to poke from
VOID* data = XPhysicalAlloc(Size, MAXULONG_PTR, 0, PAGE_READWRITE);
HRESULT result;
memcpy(data, Buffer, Size);
result = (HRESULT)HvxExpansionCall(HvPeekPokeExpID,
POKE_BYTES, Address, MmGetPhysicalAddress(data), Size);
// Free our physical data and return our result
XPhysicalFree(data);
return result;
}
QWORD HvPeekSPR(SOC_SPRS SPR) {
return HvxExpansionCall(HvPeekPokeExpID, PEEK_SPR, SPR, 0, 0);
}
QWORD HvPokeSPR(SOC_SPRS SPR, QWORD Value) {
return HvxExpansionCall(HvPeekPokeExpID, POKE_SPR, SPR, Value, 0);
}
VOID HvGetFuses(QWORD *Out)
{
int x;
for (x = 0; x < 12; x++)
{
Out[x] = HvPeekQWORD(0x8000020000020000 + (x * 0x200));
}
}
VOID HvDumpFromMemory(CHAR* FilePath) {
// Create our output file
HANDLE fHandle = CreateFile(FilePath, GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
// Read our our HV from memory
BYTE hvPart[0x10000]; DWORD pageSize = 0x10000;DWORD x;
QWORD address = 0;
QWORD rtoc = 0x0000000200000000;
for(x = 0; x < 4; x++) {
DWORD bytesWritten = 0;
// Read our section from our HV
ZeroMemory(hvPart, pageSize);
HvPeekBytes(address, hvPart, pageSize);
// Write out the section
WriteFile(fHandle, hvPart, pageSize, &bytesWritten, NULL);
// Now increase our address
address += (rtoc + pageSize);
}
// Close our output file
CloseHandle(fHandle);
}
VOID HvDumpFuses(CHAR* FilePath) {
// Create our output file
HANDLE fHandle = CreateFile(FilePath, GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
// Read each fuse set and dump it
QWORD fuseSet = 0; DWORD bytesWritten = 0;DWORD x;
for (x = 0; x < 12; x++) {
fuseSet = HvPeekQWORD(0x8000020000020000 + (x * 0x200));
WriteFile(fHandle, &fuseSet, 8, &bytesWritten, NULL);
}
// Close our output file
CloseHandle(fHandle);
}
VOID HvDump1Bl(CHAR* FilePath) {
// Create our output file
HANDLE fHandle = CreateFile(FilePath, GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD bytesWritten = 0;
BYTE bl1[0x8000];
ZeroMemory(bl1, 0x8000);
HvPeekBytes(0x8000020000000000, bl1, 0x8000);
WriteFile(fHandle, bl1, 0x8000, &bytesWritten, NULL);
// Close our output file
CloseHandle(fHandle);
}