Skip to content

Commit

Permalink
General refactoring, kernel updates, performance improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Ernegien committed Apr 25, 2023
1 parent 88d02de commit 509f4a6
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 208 deletions.
31 changes: 0 additions & 31 deletions src/OGXbdmDumper/CallResult.cs

This file was deleted.

8 changes: 8 additions & 0 deletions src/OGXbdmDumper/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,14 @@ public void ClearReceiveBuffer(int size)
}
}

/// <summary>
/// Clears all existing data from the receive buffer.
/// </summary>
public void ClearReceiveBuffer()
{
ClearReceiveBuffer(_client.Available);
}

/// <summary>
/// Sends a command to the xbox without waiting for a response.
/// </summary>
Expand Down
65 changes: 32 additions & 33 deletions src/OGXbdmDumper/Kernel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using Iced.Intel;
using System.Text;
using PeNet;

namespace OGXbdmDumper
{
Expand All @@ -21,11 +20,6 @@ public class Kernel
/// </summary>
public const string Name = "xboxkrnl.exe";

/// <summary>
/// Indicates whether this is a DVT3 beta kernel or not.
/// </summary>
public bool IsBeta { get; private set; }

/// <summary>
/// The kernel module information. Note: Internally caches result for future use.
/// </summary>
Expand Down Expand Up @@ -68,29 +62,14 @@ public Kernel(Xbox xbox)
Module = xbox.Modules.Find(m => m.Name == Name) ??
throw new NullReferenceException(string.Format("Failed to load {0} module information!", Name));

// gets export table of offsets relative to kernel base address
long peBase = xbox.Memory.ReadUInt32(Address + 0x3C);
long dataDirectory = xbox.Memory.ReadUInt32(Address + peBase + 0x78);
int exportCount = xbox.Memory.ReadInt32(Address + dataDirectory + 0x14);
long exportAddress = Address + xbox.Memory.ReadUInt32(Address + dataDirectory + 0x1C);
byte[] exportBytes = xbox.Memory.ReadBytes(exportAddress, exportCount * sizeof(uint));

// converts them to absolute addresses
long[] addresses = new long[exportCount + 1];
for (int i = 0; i < exportCount; i++)
{
long offset = BitConverter.ToUInt32(exportBytes, i * 4);
if (offset != 0)
{
addresses[i + 1] = Address + offset;
}
}

// TODO: guestimate, dvt4/retail seemed to have at least 366 whereas dvt3/beta around 345
IsBeta = exportCount < 360;
// TODO: remove 3rd-party dependency with proper PE parsing logic
// grab enough of the kernel in memory to allow parsing it (possibly only need through the data section)
var initSection = Module.Sections.Find(m => m.Name == "INIT");
int size = (int)(initSection.Base - Address);
var pe = new PeFile(_xbox.Memory.ReadBytes(Address, size));

// generate exports
Exports = new KernelExports(addresses, IsBeta);
// resolve exports
Exports = new KernelExports(Address, pe.ExportedFunctions);

// get the version
Version = xbox.Memory.ReadInt32(Exports.XboxKrnlVersion).ToVersion();
Expand All @@ -113,13 +92,13 @@ public Kernel(Xbox xbox)

public void HalReadSMBusValue(int address, int command, bool writeWord, uint valuePtr)
{
if (_xbox.Call(Exports.HalReadSMBusValue, address, command, writeWord, valuePtr).Eax != 0)
if (_xbox.Call(Exports.HalReadSMBusValue, address, command, writeWord, valuePtr) != 0)
throw new Exception();
}

public uint NtOpenFile(uint fileHandlePtr, uint desiredAccess, uint objectAttributesPtr, uint ioStatusBlockPtr, uint shareAccess, uint openOptions)
{
int status = (int)_xbox.Call(Exports.NtOpenFile, fileHandlePtr, desiredAccess, objectAttributesPtr, ioStatusBlockPtr, shareAccess, openOptions).Eax;
int status = (int)_xbox.Call(Exports.NtOpenFile, fileHandlePtr, desiredAccess, objectAttributesPtr, ioStatusBlockPtr, shareAccess, openOptions);
if (status != 0)
throw new Win32Exception(status);

Expand All @@ -128,18 +107,38 @@ public uint NtOpenFile(uint fileHandlePtr, uint desiredAccess, uint objectAttrib

public void NtReadFile(uint fileHandlePtr, uint eventPtr, uint apcRoutinePtr, uint apcContextPtr, uint ioStatusBlockPtr, uint bufferPtr, uint length, uint byteOffsetPtr)
{
int status = (int)_xbox.Call(Exports.NtReadFile, fileHandlePtr, eventPtr, apcRoutinePtr, apcContextPtr, ioStatusBlockPtr, bufferPtr, length, byteOffsetPtr).Eax;
int status = (int)_xbox.Call(Exports.NtReadFile, fileHandlePtr, eventPtr, apcRoutinePtr, apcContextPtr, ioStatusBlockPtr, bufferPtr, length, byteOffsetPtr);
if (status != 0)
throw new Win32Exception(status);
}

public void NtClose(uint fileHandlePtr)
{
int status = (int)_xbox.Call(Exports.NtClose, fileHandlePtr).Eax;
int status = (int)_xbox.Call(Exports.NtClose, fileHandlePtr);
if (status != 0)
throw new Win32Exception(status);
}

/// <summary>
/// Allocates physical memory.
/// </summary>
/// <param name="size">The allocation size.</param>
/// <returns>Returns the allocation address, or zero if unsuccessful.</returns>
public long MmAllocateContiguousMemory(int size)
{
return _xbox.Call(_xbox.Kernel.Exports.MmAllocateContiguousMemory, size);
}

/// <summary>
/// Frees physical memory on the xbox.
/// </summary>
/// <param name="address">Memory address.</param>
/// <returns>Returns true if successful.</returns>
public bool MmFreeContiguousMemory(long address)
{
return _xbox.Call(_xbox.Kernel.Exports.MmFreeContiguousMemory, address) != 0;
}

#endregion
}
}
56 changes: 45 additions & 11 deletions src/OGXbdmDumper/KernelExports.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
namespace OGXbdmDumper
using PeNet.Header.Pe;

namespace OGXbdmDumper
{
/// <summary>
/// TODO: description
/// </summary>
public class KernelExports
{
private ExportFunction[] _functions;
private readonly long _kernelBase;

#region Exports

/// <summary>
Expand Down Expand Up @@ -47,22 +52,51 @@ public class KernelExports
/// </summary>
public long XboxKrnlVersion { get; }

/// <summary>
///
/// </summary>
public long MmAllocateContiguousMemory { get; }

/// <summary>
///
/// </summary>
public long MmFreeContiguousMemory { get; }

#endregion

/// <summary>
/// Index signifies ordinal number.
/// </summary>
/// <param name="addresses"></param>
public KernelExports(long[] addresses, bool isBeta = false)
/// <param name="kernelBase"></param>
/// <param name="functions"></param>
public KernelExports(long kernelBase, ExportFunction[] functions)
{
_kernelBase = kernelBase;
_functions = functions;

// TODO: guestimate, dvt4/retail seemed to have at least 366 whereas dvt3/beta around 345
bool isBeta = functions.Length < 360;

HalReadSMBusValue = Resolve(isBeta ? 339 : 45);
NtClose = Resolve(isBeta ? 183 : 187);
NtDeviceIoControlFile = Resolve(isBeta ? 192 : 196);
NtOpenFile = Resolve(isBeta ? 199 : 202);
NtReadFile = Resolve(isBeta ? 216 : 219);
RtlFreeAnsiString = Resolve(isBeta ? 282 : 286);
RtlInitAnsiString = Resolve(isBeta ? 285 : 289);
XboxKrnlVersion = Resolve(isBeta ? 316 : 324);
MmAllocateContiguousMemory = Resolve(isBeta ? 161 : 165);
MmFreeContiguousMemory = Resolve(isBeta ? 166 : 171);
}

private long Resolve(int ordinal)
{
HalReadSMBusValue = addresses[isBeta ? 339 : 45];
NtClose = addresses[isBeta ? 183 : 187];
NtDeviceIoControlFile = addresses[isBeta ? 192 : 196];
NtOpenFile = addresses[isBeta ? 199 : 202];
NtReadFile = addresses[isBeta ? 216 : 219];
RtlFreeAnsiString = addresses[isBeta ? 282 : 286];
RtlInitAnsiString = addresses[isBeta ? 285 : 289];
XboxKrnlVersion = addresses[isBeta ? 316 : 324];
foreach (var function in _functions)
{
if (function.Ordinal == ordinal)
return _kernelBase + function.Address;
}
return 0;
}
}
}
1 change: 1 addition & 0 deletions src/OGXbdmDumper/OGXbdmDumper.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<PackageReference Include="ConsoleTools" Version="1.1.1" />
<PackageReference Include="Iced" Version="1.18.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
<PackageReference Include="PeNet" Version="3.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
Expand Down
Loading

0 comments on commit 509f4a6

Please sign in to comment.