Advertisement
Guest User

XOSC.cpp

a guest
Jul 31st, 2017
721
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.67 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "xosc.h"
  3.  
  4. /*
  5.     Reversed by: Medaka
  6.  
  7.     This is the entire XOSC module in C code.
  8.     Please give credit where it's due, don't just copy and paste, please.
  9.     I've worked really hard on this trying to perfect evey last bit of this.
  10. */
  11.  
  12. byte* xamAllocatedData;
  13.  
  14. extern "C" {
  15.     NTSTATUS XamAlloc(int size, int size2, byte* data);
  16.     void XamFree(PBYTE allocatedData);
  17.     NTSTATUS IoSynchronousDeviceIoControlRequest(int io_request, void** deviceObject, void* bufferInput, int length, int r7, int r8, void* output);
  18.     void HalReadWritePCISpace(int r3, int r4, int r5, int r6, void* buffer, int length, bool WritePCISpace);
  19. }
  20.  
  21. NTSTATUS SysChall_GetStorageDeviceSize(char* path, int* outSize) {
  22.     *outSize = 0;
  23.  
  24.     HANDLE file = 0;
  25.     NTSTATUS status = STATUS_SUCCESS;
  26.  
  27.     ANSI_STRING deviceName = { 0 };
  28.     OBJECT_ATTRIBUTES objAttr = { 0 };
  29.     IO_STATUS_BLOCK statusBlock = { 0 };
  30.     FILE_FS_SIZE_INFORMATION sizeInfo = { 0 };
  31.  
  32.     RtlInitAnsiString(&deviceName, path);
  33.     InitializeObjectAttributes(&objAttr, &deviceName, OBJ_CASE_INSENSITIVE, 0);
  34.  
  35.     if (NT_SUCCESS(NtOpenFile(&file, (SYNCHRONIZE | 1), &objAttr, &statusBlock, FILE_SHARE_READ, XOSC_DEVICESIZE_OPEN_OPTIONS)))
  36.         if (NT_SUCCESS(status = NtQueryVolumeInformationFile(file, &statusBlock, &sizeInfo, 0x18, FileFsSizeInformation)))
  37.             *outSize = sizeInfo.TotalAllocationUnits.LowPart;
  38.  
  39.     NtClose(file);
  40.     return status;
  41. }
  42.  
  43. NTSTATUS SysChall_GetStorageDeviceSizes(xoscResponse* chalResp) {
  44.     chalResp->operations |= 0x10;
  45.  
  46.     SysChall_GetStorageDeviceSize("\\Device\\Mu0\\", &chalResp->memoryUnit0);
  47.     SysChall_GetStorageDeviceSize("\\Device\\Mu1\\", &chalResp->memoryUnit1);
  48.     SysChall_GetStorageDeviceSize("\\Device\\BuiltInMuSfc\\", &chalResp->memoryUnitIntFlash);
  49.     SysChall_GetStorageDeviceSize("\\Device\\BuiltInMuUsb\\Storage\\", &chalResp->memoryUnitIntUSB);
  50.     SysChall_GetStorageDeviceSize("\\Device\\Mass0PartitionFile\\Storage\\", &chalResp->mass0PartitionFileSize);
  51.     SysChall_GetStorageDeviceSize("\\Device\\Mass1PartitionFile\\Storage\\", &chalResp->mass1PartitionFileSize);
  52.     SysChall_GetStorageDeviceSize("\\Device\\Mass2PartitionFile\\Storage\\", &chalResp->mass2PartitionFileSize);
  53.  
  54.     return STATUS_SUCCESS;
  55. }
  56.  
  57. NTSTATUS SysChall_GetConsoleKVCertificate(xoscResponse* chalResp) {
  58.     NTSTATUS keyStatus = STATUS_SUCCESS;
  59.     WORD certificateDataLength = 0;
  60.     XE_CONSOLE_CERTIFICATE certData = { 0 };
  61.  
  62.     if (NT_SUCCESS(keyStatus = XeKeysGetKey(XEKEY_XEIKA_CERTIFICATE, (PVOID)&certData, (PDWORD)&certificateDataLength))) {
  63.         if (certificateDataLength > 0x110 || certData.signature[0x64] == 0x4F534947 || *(short*)certData.signature[0x68] >= 1) {
  64.             chalResp->operations |= 2;
  65.             memcpy((byte*)(chalResp + 0xB4), &certData.signature[0x6C], 0x24);
  66.             *(int*)((int)chalResp + 0x80) = *(byte*)((int)&certData + 0x117);
  67.         } else keyStatus = STATUS_INVALID_PARAMETER_1;
  68.     }
  69.  
  70.     return chalResp->keyResultCert = keyStatus;
  71. }
  72.  
  73. NTSTATUS SysChall_GetDeviceControlRequest(xoscResponse* chalResp) {
  74.     chalResp->operations |= 1;
  75.  
  76.     PVOID deviceObject = NULL;
  77.     BYTE partitionInfo[0x24] = { 0 };
  78.     NTSTATUS status = STATUS_SUCCESS;
  79.     STRING objectPath = { 0xE, 0xF, "\\Device\\Cdrom0" };
  80.  
  81.     if (!NT_SUCCESS(status = ObReferenceObjectByName(&objectPath, 0, 0, 0, &deviceObject)))
  82.         return chalResp->ioCtlResult = status;
  83.  
  84.     *(long long*)((int)chalResp + 0xF0) = -1;
  85.     *(long long*)((int)chalResp + 0xF8) = -1;
  86.     *(long long*)((int)chalResp + 0x100) = -1;
  87.     *(long long*)((int)chalResp + 0x108) = -1;
  88.     *(long long*)((int)chalResp + 0x110) = -1;
  89.  
  90.     *(short*)((int)deviceObject + 0x20) = *(short*)((int)chalResp + 0xF0);
  91.  
  92.     *(char*)partitionInfo = 0x24;
  93.     *(char*)(partitionInfo + 0x7) = 1;
  94.     *(int*)(partitionInfo + 0x8) = 0x24;
  95.     *(char*)(partitionInfo + 0x14) = 0x12;
  96.     *(char*)(partitionInfo + 0x18) = 0x24;
  97.     *(char*)(partitionInfo + 0x19) = 0xC0;
  98.  
  99.     status = IoSynchronousDeviceIoControlRequest(IOCTL_DISK_VERIFY, &deviceObject, partitionInfo, 0x24, 0, 0, 0);
  100.     ObDereferenceObject(deviceObject);
  101.  
  102.     return chalResp->ioCtlResult = status;
  103. }
  104.  
  105. NTSTATUS SysChall_SetupSataDiskHash(xoscResponse* chalResp) {
  106.     XECRYPT_RSA rsa = { 0 };
  107.     byte outDigest[0x14] = { 0 };
  108.     int rsaSecuritySize = 0x110;
  109.  
  110.     chalResp->operations |= 0x80;
  111.  
  112.     memset((int*)((int)chalResp + 0x1D4), 0, 4);
  113.     memset((int*)((int)chalResp + 0x1D8), 0, 4);
  114.     memset((int*)((int)chalResp + 0x1DC), 0, 4);
  115.     memset((int*)((int)chalResp + 0x1E0), 0, 4);
  116.     memset((int*)((int)chalResp + 0x1E4), 0, 4);
  117.  
  118.     memset((long long*)((int)chalResp + 0x1E8), 0, 8);
  119.     memset((long long*)((int)chalResp + 0x1F0), 0, 8);
  120.     memset((long long*)((int)chalResp + 0x1F8), 0, 8);
  121.     memset((long long*)((int)chalResp + 0x200), 0, 8);
  122.     memset((long long*)((int)chalResp + 0x208), 0, 8);
  123.     memset((long long*)((int)chalResp + 0x210), 0, 8);
  124.  
  125.     memset((int*)((int)chalResp + 0x218), 0, 4);
  126.     memset((int*)((int)chalResp + 0x1D0), XboxHardwareInfo->Flags, 4);
  127.  
  128.     if ((XboxHardwareInfo->Flags & 0x20) == 0)
  129.         return STATUS_SUCCESS;
  130.  
  131.     for (int i = 0; i < 5; i++) {
  132.         memcpy(xamAllocatedData, (byte*)0x8E038400, 0x15C);
  133.         XeCryptSha(xamAllocatedData, 0x5C, 0, 0, 0, 0, outDigest, XECRYPT_SHA_DIGEST_SIZE);
  134.    
  135.         if (!NT_SUCCESS(XeKeysGetKey(XEKEY_CONSTANT_SATA_DISK_SECURITY_KEY, &rsa, (PDWORD)&rsaSecuritySize)))
  136.             continue;
  137.  
  138.         if (rsaSecuritySize != 0x110 || rsa.cqw != 0x20)
  139.             continue;
  140.  
  141.         byte* signature = (byte*)(xamAllocatedData + 0x5C);
  142.  
  143.         XeCryptBnQw_SwapDwQwLeBe((PQWORD)signature, (PQWORD)signature, 0x20);
  144.         if (XeCryptBnQwNeRsaPubCrypt((PQWORD)signature, (PQWORD)signature, &rsa))
  145.             continue;
  146.  
  147.         XeCryptBnQw_SwapDwQwLeBe((PQWORD)signature, (PQWORD)signature, 0x20);
  148.         if (XeCryptBnDwLePkcs1Verify(outDigest, signature, 0x100))
  149.             break;
  150.     }
  151.  
  152.     if (xamAllocatedData == 0)
  153.         return STATUS_SUCCESS;
  154.  
  155.     memcpy((int*)(chalResp + 0x1D4), xamAllocatedData, 0x14);
  156.     memcpy((int*)(*(int*)(chalResp + 0x1E8)), (int*)(xamAllocatedData + 0x14), 4);
  157.     memcpy((int*)(*(int*)(chalResp + 0x1E8) + 0x4), (int*)(xamAllocatedData + 0x18), 4);
  158.  
  159.     return STATUS_SUCCESS;
  160. }
  161.  
  162. NTSTATUS SysChall_SetupDiskVerificationHash(xoscResponse* chalResp) {
  163.     BYTE pageData[0xA0] = { 0 };
  164.     BYTE outDigest[0x14] = { 0 };
  165.  
  166.     for (int i = 0; i < 5; i++) {
  167.         memcpy(pageData, (int*)0x8E038780, 0xA0);
  168.         XeCryptSha((PBYTE)(pageData + 0x14), 0x8C, 0, 0, 0, 0, outDigest, XECRYPT_SHA_DIGEST_SIZE);
  169.  
  170.         if (memcmp((PBYTE)(pageData + 0x14), outDigest, 0x14) != 0)
  171.             continue;
  172.  
  173.         goto nextSequence;
  174.     }
  175.  
  176.     chalResp->sataResult = STATUS_KEY_RESULT_FAILED;
  177.     return STATUS_SUCCESS;
  178.  
  179. nextSequence:
  180.     chalResp->operations = 0;
  181.  
  182.     memcpy((byte*)((int)chalResp + 0x21C), (byte*)0x8E038680, 0x80);
  183.  
  184.     memcpy((int*)((int)chalResp + 0x24), (int*)(pageData + 0x14), 4);
  185.     memcpy((int*)((int)chalResp + 0x28), (int*)(pageData + 0x18), 4);
  186.     memcpy((int*)((int)chalResp + 0x2C), (int*)(pageData + 0x1C), 4);
  187.     memcpy((int*)((int)chalResp + 0x30), (int*)(pageData + 0x90), 4);
  188.     memcpy((long long*)((int)chalResp + 0xD0), (int*)(pageData + 0x70), 4);
  189.     memcpy((int*)((int)chalResp + 0x2A4), (int*)(pageData + 0x9C), 4);
  190.     memcpy((long long*)((int)chalResp + 0x2C8), (int*)(pageData + 0x34), 4);
  191.     memcpy((long long*)((int)chalResp + 0x2D0), (int*)(pageData + 0x38), 4);
  192.  
  193.     memcpy((byte*)(pageData + 0x3C), (byte*)(pageData + 0x1F), 0x11);
  194.     memcpy((byte*)((int)chalResp + 0x9D), (byte*)(pageData + 0x40), 0x20);
  195.     memcpy((byte*)((int)chalResp + 0xBD), (byte*)(pageData + 0x60), 0x10);
  196.  
  197.     memcpy((long long*)((int)chalResp + 0xD8), (long long*)(pageData + 0x78), 8);
  198.     memcpy((long long*)((int)chalResp + 0xE0), (long long*)(pageData + 0x80), 8);
  199.     memcpy((long long*)((int)chalResp + 0xE8), (long long*)((pageData + 0x80) + 0x8), 8);
  200.     memcpy((long long*)((int)chalResp + 0x29C), (long long*)(pageData + 0x94), 8);
  201.  
  202.     return chalResp->sataResult = STATUS_SUCCESS;
  203. }
  204.  
  205. NTSTATUS SysChall_SetupSerialNumberHash(xoscResponse* chalResp) {
  206.     byte outDigest[0x14] = { 0 };
  207.     byte serialNumber[0xC] = { 0 };
  208.  
  209.     WORD keyProperty = XeKeysGetKeyProperties(XEKEY_CONSOLE_SERIAL_NUMBER);
  210.  
  211.     for (int i = 0; i < 5; i++) {
  212.         memcpy(xamAllocatedData, (byte*)0x8E038000, 0x400);
  213.         XeCryptSha((PBYTE)(xamAllocatedData + 0x14), 0x3EC, 0, 0, 0, 0, outDigest, XECRYPT_SHA_DIGEST_SIZE);
  214.        
  215.         if (memcmp(xamAllocatedData, outDigest, 0x14) != 0)
  216.             continue;
  217.  
  218.         goto nextSequence;
  219.     }
  220.  
  221.     chalResp->keyResultSerial = STATUS_KEY_RESULT_FAILED;
  222.     return STATUS_SUCCESS;
  223.  
  224. nextSequence:
  225.     if (xamAllocatedData == 0) {
  226.         chalResp->keyResultSerial = STATUS_KEY_RESULT_FAILED;
  227.         return STATUS_SUCCESS;
  228.     }
  229.  
  230.     if (*(int*)(xamAllocatedData + 0x14) < 1) {
  231.         chalResp->keyResultSerial = 0xC8003005;
  232.         return STATUS_SUCCESS;
  233.     }
  234.  
  235.     if (keyProperty < 0xC) {
  236.         chalResp->keyResultSerial = STATUS_INVALID_PARAMETER_1;
  237.         return STATUS_SUCCESS;
  238.     }
  239.  
  240.     NTSTATUS keyStatus = XeKeysGetKey(XEKEY_CONSOLE_SERIAL_NUMBER, serialNumber, (PDWORD)&keyProperty);
  241.  
  242.     if (!NT_SUCCESS(keyStatus)) {
  243.         chalResp->keyResultSerial = keyStatus;
  244.         return STATUS_SUCCESS;
  245.     }
  246.  
  247.     chalResp->operations |= 0x20;
  248.  
  249.     int size = (*(int*)(xamAllocatedData + 0x14) - 1);
  250.  
  251.     memcpy(&chalResp->consoleId, (long long*)(xamAllocatedData + 0x1A0), 8);
  252.     memcpy((long long*)(*(int*)(xamAllocatedData + 0x1A0) + 0x8),
  253.         (int*)(xamAllocatedData + 0x10),
  254.         size = size <= 5 ? size : 5
  255.     );
  256.  
  257.     if (size < 5 && (size - 5) != 0)
  258.         memcpy((long long*)((int)xamAllocatedData + ((size + 0x35) * 8)), 0, (size - 5));
  259.  
  260.     memcpy((byte*)(xamAllocatedData + 0x138), serialNumber, 0xC);
  261.  
  262.     *(byte*)(xamAllocatedData + 0x144) = 0;
  263.     return chalResp->keyResultSerial = STATUS_SUCCESS;
  264. }
  265.  
  266. void SysChall_SetupModuleHashes(xoscResponse* chalResp) {
  267.     chalResp->operations |= 0x8;
  268.  
  269.     DWORD flags = 0;
  270.     SHORT settingSize = 6;
  271.     byte unknownBuffer[0x10] = { 0 };
  272.     byte securityDigest[0x14];
  273.     byte macAddress[0x6];
  274.     byte smcOut[0x5];
  275.     byte smcMsg[0x5];
  276.  
  277.     memcpy(&chalResp->bootloaderVersion, (short*)0x8E038600, 2);
  278.     memcpy(&chalResp->xamRegion, (short*)0x8E038602, 2);
  279.     memcpy(&chalResp->xamOdd, (short*)0x8E038604, 2);
  280.  
  281.     memcpy(&chalResp->_unk3, (int*)0x8E03861C, 4);
  282.     memcpy(&chalResp->flashSize, (int*)0x8E038618, 4);
  283.     memcpy(&chalResp->xoscRegion, (int*)0x8E038614, 4);
  284.     memcpy(&chalResp->hvFlags, (int*)0x8E038610, 4);
  285.  
  286.     memcpy(&chalResp->_unk10, (long long*)0x8E038630, 8);
  287.     memcpy(&chalResp->_unk11, (long long*)0x8E038638, 8);
  288.     memcpy(&chalResp->_unk12, (long long*)0x8E038640, 8);
  289.     memcpy(&chalResp->hvProtectionFlags, (long long*)0x8E038678, 8);
  290.     memcpy(&chalResp->_unk5, (long long*)0x8E038704, 8);
  291.  
  292.     memcpy(&chalResp->_unk6, (int*)0x8E038708, 4);
  293.     memcpy(&chalResp->_unk8, (int*)0x8E03870C, 4);
  294.     memcpy(&chalResp->_unk9, (int*)0x8E038710, 4);
  295.     memcpy(&chalResp->crlVersion, (int*)0x8E000154, 4);
  296.  
  297.     PLDR_DATA_TABLE_ENTRY hXam = (PLDR_DATA_TABLE_ENTRY)GetModuleHandleA(MODULE_XAM);
  298.     PLDR_DATA_TABLE_ENTRY hKernel = (PLDR_DATA_TABLE_ENTRY)GetModuleHandleA(MODULE_KERNEL);
  299.     PLDR_DATA_TABLE_ENTRY hCurrTitle = (PLDR_DATA_TABLE_ENTRY)GetModuleHandleA(MODULE_TITLE);
  300.  
  301.     memcpy(securityDigest, (byte*)0x8E03AA40, 0x14);
  302.     unknownBuffer[0xE] &= 0xF8;
  303.  
  304.     if (hXam || hKernel || hCurrTitle) {
  305.         IMAGE_XEX_HEADER* xamHeader = (IMAGE_XEX_HEADER*)(hXam->XexHeaderBase);
  306.  
  307.         if (xamHeader) {
  308.             XEX_SECURITY_INFO* securityInfo = (XEX_SECURITY_INFO*)(xamHeader->SecurityInfo);
  309.  
  310.             int size = ((xamHeader->SizeOfHeaders - ((int)xamHeader->SecurityInfo + 0x17C)) + (int)xamHeader);
  311.             XeCryptSha((PBYTE)&securityInfo->AllowedMediaTypes, size, securityDigest, 0x14, unknownBuffer, 0x10, securityDigest, 0x14);
  312.         }
  313.  
  314.         IMAGE_XEX_HEADER* krnlHeader = (IMAGE_XEX_HEADER*)(hKernel->XexHeaderBase);
  315.         if (krnlHeader) {
  316.             if (NT_SUCCESS(ExGetXConfigSetting(XCONFIG_SECURED_CATEGORY, XCONFIG_SECURED_MAC_ADDRESS, macAddress, 0x6, (PWORD)settingSize))) {
  317.                 XEX_SECURITY_INFO* securityInfo = (XEX_SECURITY_INFO*)(krnlHeader->SecurityInfo);
  318.  
  319.                 int size = ((krnlHeader->SizeOfHeaders - ((int)krnlHeader->SecurityInfo + 0x17C)) + (int)krnlHeader);
  320.                 XeCryptSha((PBYTE)&securityInfo->AllowedMediaTypes, size, securityDigest, 0x14, macAddress, 0x6, securityDigest, 0x14);
  321.             }
  322.         }
  323.  
  324.         IMAGE_XEX_HEADER* currModuleHeader = (IMAGE_XEX_HEADER*)(hCurrTitle->XexHeaderBase);
  325.         if (currModuleHeader) {
  326.             smcMsg[0] = REQUEST_SMC_VERSION;
  327.             HalSendSMCMessage(smcMsg, smcOut);
  328.  
  329.             XEX_SECURITY_INFO* securityInfo = (XEX_SECURITY_INFO*)(currModuleHeader->SecurityInfo);
  330.  
  331.             int size = ((currModuleHeader->SizeOfHeaders - (DWORD)&securityInfo->AllowedMediaTypes) + (int)currModuleHeader);
  332.             XeCryptSha((PBYTE)&securityInfo->AllowedMediaTypes, size, securityDigest, 0x14, smcOut, 0x5, securityDigest, 0x14);
  333.         }
  334.     }
  335.  
  336.     XeCryptSha((PBYTE)0x900101A3, 0x8E59, securityDigest, 0x14, 0, 0, securityDigest, 0x14);
  337.     securityDigest[0] = 7;
  338.  
  339.     memcpy(chalResp->kvDigest, securityDigest, 0x10);
  340.     memcpy(chalResp->fuseDigest, (byte*)0x8E03AA50, 0x10);
  341. }
  342.  
  343. NTSTATUS SysChall_GetPCIEDriveConnectionStatus(xoscResponse* chalResp) {
  344.     byte data[0x100] = { 0 };
  345.     HalReadWritePCISpace(0, 2, 0, 0, data, 0x100, 0);
  346.  
  347.     QWORD r9 = (((*(byte*)(data + 0x8) & ~0xFFFF00) | ((*(short*)(data + 0x2) << 8) & 0xFFFF00) << 8) & 0xFFFFFFFFFFFFFFFF);
  348.     QWORD r10 = (((*(byte*)(data + 0xB) & ~0xFFFF00) | ((*(short*)(data + 0x4) << 8) & 0xFFFF00) << 8) & 0xFFFFFFFFFFFFFFFF);
  349.  
  350.     chalResp->daeResult = 0x40000012;
  351.     chalResp->operations |= 0x100;
  352.     chalResp->pcieHardwareInfo = ((((r9 | XboxHardwareInfo->PCIBridgeRevisionID) << 32) | r10) | *(byte*)(data + 0xA));
  353.  
  354.     return STATUS_SUCCESS;
  355. }
  356.  
  357. NTSTATUS SysChall_Init(int task, char* tableName, int tableSize, xoscResponse* chalResp, int bufferSize) {
  358.     if (chalResp == 0 || bufferSize == 0 || bufferSize < 0x2E0) {
  359.         printf("[SysChall_Execute] failed\n");
  360.         return E_INVALIDARG;
  361.     }
  362.  
  363.     NTSTATUS exeIdStatus = STATUS_SUCCESS;
  364.     PXEX_EXECUTION_ID executionId;
  365.  
  366.     memset(chalResp, 0, bufferSize);
  367.     memset(chalResp, 0xAA, 0x2E0);
  368.  
  369.     chalResp->operations = 0;
  370.     chalResp->xoscMajor = 9;
  371.     chalResp->xoscFooterMagic = 0x5F534750;
  372.  
  373.     if (NT_SUCCESS(XamAlloc(0x200000, 0x8000, xamAllocatedData))) {
  374.         SysChall_GetDeviceControlRequest(chalResp);
  375.         SysChall_GetConsoleKVCertificate(chalResp);
  376.         SysChall_SetupModuleHashes(chalResp);
  377.         SysChall_GetStorageDeviceSizes(chalResp);
  378.         SysChall_GetPCIEDriveConnectionStatus(chalResp);
  379.     }
  380.  
  381.     if (NT_SUCCESS(exeIdStatus = XamGetExecutionId(&executionId))) {
  382.         chalResp->executionResult = exeIdStatus;
  383.  
  384.         memcpy(&chalResp->xexExecutionId, &executionId, sizeof(XEX_EXECUTION_ID));
  385.         XamLoaderGetMediaInfo(&chalResp->mediaInfo, &chalResp->titleId);
  386.  
  387.         chalResp->operations |= 0x4;
  388.     }
  389.  
  390.     if (XamLoaderIsTitleTerminatePending())
  391.         chalResp->operations |= XOSC_FLAG_STATUS_FLAG_TITLE_TERMINATED;
  392.  
  393.     if (XamTaskShouldExit())
  394.         chalResp->operations |= XOSC_FLAG_STATUS_TASK_SHOULD_EXIT;
  395.  
  396.     if (xamAllocatedData != 0)
  397.         XamFree(xamAllocatedData);
  398.  
  399.     return chalResp->result = STATUS_SUCCESS;
  400. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement