diff --git a/inc/version.h b/inc/version.h index b7acf5c..9a5c07c 100644 --- a/inc/version.h +++ b/inc/version.h @@ -28,7 +28,7 @@ #define XB_BIOS_TOOL_VER_MAJOR 0 #define XB_BIOS_TOOL_VER_MINOR 1 #define XB_BIOS_TOOL_VER_PATCH 0 -#define XB_BIOS_TOOL_VER_BUILD 6 +#define XB_BIOS_TOOL_VER_BUILD 7 #define XB_BIOS_TOOL_AUTHOR_STR "tommojphillips" #define XB_BIOS_TOOL_NAME_STR "XbTool" diff --git a/src/Bios.cpp b/src/Bios.cpp index ec1b228..5cfe3b8 100644 --- a/src/Bios.cpp +++ b/src/Bios.cpp @@ -35,7 +35,7 @@ #include "lzx.h" #include "sha1.h" -extern XbTool xbtool; +extern Parameters& params; void Bios::reset() { @@ -114,7 +114,7 @@ void Bios::getOffsets2(const UINT krnlSize, const UINT krnlDataSize) krnl = (krnlData - krnlSize); // calculate the total space available in the rom. - _totalSpaceAvailable = xbtool.params.romsize - BLDR_BLOCK_SIZE - MCPX_BLOCK_SIZE; + _totalSpaceAvailable = params.romsize - BLDR_BLOCK_SIZE - MCPX_BLOCK_SIZE; // calculate the available space in the bios. _availableSpace = _totalSpaceAvailable - krnlSize - krnlDataSize; @@ -148,13 +148,13 @@ int Bios::checkForPreldr() print("\npreldr found\n"); - if (xbtool.params.mcpx.data == NULL) + if (params.mcpx.data == NULL) { error("Error: MCPX v1.1 rom is required to decrypt the preldr ( -mcpx )\n"); return PRELDR_STATUS_ERROR; } - if (xbtool.params.mcpx.version != MCPX_ROM::MCPX_V1_1) + if (params.mcpx.version != MCPX_ROM::MCPX_V1_1) { // user has provided the incorrect mcpx rom. let 'em know. error("Error: decrypting the bldr. MCPX v1.1 was expected but v1.0 was provided.\n"); @@ -163,7 +163,7 @@ int Bios::checkForPreldr() PRELDR_ENTRY* preldrEntry = (PRELDR_ENTRY*)(preldr + (preldrParams->jmpInstr >> 8) + 0x5 - sizeof(PRELDR_ENTRY)); - UCHAR* sbKey = (UCHAR*)(xbtool.params.mcpx.data + MCPX_BLOCK_SIZE - 0x64); + UCHAR* sbKey = (UCHAR*)(params.mcpx.data + MCPX_BLOCK_SIZE - 0x64); #if 0 // decrypt the preldr pubkey @@ -234,8 +234,8 @@ int Bios::load(UCHAR* data, const UINT size) _size = size; // set encryption states based on user input. - _isBldrEncrypted = xbtool.params.encBldr; - _isKernelEncrypted = xbtool.params.encKrnl; + _isBldrEncrypted = params.encBldr; + _isKernelEncrypted = params.encKrnl; getOffsets(); @@ -246,16 +246,16 @@ int Bios::load(UCHAR* data, const UINT size) // only decrypt the bldr if the user has provided a key file or a mcpx rom and the bldr is encrypted. if (_isBldrEncrypted) { - if (xbtool.params.keyBldr != NULL) // bldr key is provided; use it. + if (params.keyBldr != NULL) // bldr key is provided; use it. { - symmetricEncDecBldr(xbtool.params.keyBldr, KEY_SIZE); + symmetricEncDecBldr(params.keyBldr, KEY_SIZE); } - else if (xbtool.params.mcpxFile != NULL) + else if (params.mcpxFile != NULL) { - switch (xbtool.params.mcpx.version) + switch (params.mcpx.version) { case MCPX_ROM::MCPX_V1_0: - symmetricEncDecBldr(xbtool.params.mcpx.data+0x1A5, KEY_SIZE); + symmetricEncDecBldr(params.mcpx.data+0x1A5, KEY_SIZE); break; case MCPX_ROM::MCPX_V1_1: error("Error: decrypting the bldr. MCPX v1.0 was expected but v1.1 was provided.\n"); @@ -329,7 +329,7 @@ int Bios::saveBiosToFile(const char* path) return 1; } - if (xbtool.params.binsize < _size) + if (params.binsize < _size) { error("Error: Desired bin size is less than the total size of the bios\n"); return 1; @@ -337,23 +337,23 @@ int Bios::saveBiosToFile(const char* path) // replicate up to 1Mb - UCHAR* biosData = (UCHAR*)xb_alloc(xbtool.params.binsize); + UCHAR* biosData = (UCHAR*)xb_alloc(params.binsize); xb_cpy(biosData, _bios, _size); // copy the bios data // replicate to 512 KB - if (_size < 0x80000 && xbtool.params.binsize >= 0x80000) + if (_size < 0x80000 && params.binsize >= 0x80000) { xb_cpy(biosData + 0x40000, biosData, _size); } // replicate to 1 MB - if (_size < 0x100000 && xbtool.params.binsize >= 0x100000) + if (_size < 0x100000 && params.binsize >= 0x100000) { xb_cpy(biosData + 0x80000, biosData, 0x80000); } - int result = writeFile(path, biosData, xbtool.params.binsize); + int result = writeFile(path, biosData, params.binsize); xb_free(biosData); @@ -429,7 +429,7 @@ void Bios::symmetricEncDecKernel() if (krnl == NULL) return; - UCHAR* key = xbtool.params.keyKrnl; + UCHAR* key = params.keyKrnl; if (key == NULL) { // key not provided on cli; try get key from bldr block. @@ -490,8 +490,8 @@ void Bios::printBldrInfo() UINT krnlSize = bootParams->krnlSize; UINT krnlDataSize = bootParams->krnlDataSize; - bool isKrnlSizeValid = krnlSize >= 0 && krnlSize <= xbtool.params.romsize; - bool isKrnlDataSizeValid = krnlDataSize >= 0 && krnlDataSize <= xbtool.params.romsize; + bool isKrnlSizeValid = krnlSize >= 0 && krnlSize <= params.romsize; + bool isKrnlDataSizeValid = krnlDataSize >= 0 && krnlDataSize <= params.romsize; print("kernel data size:\t"); print((CON_COL)isKrnlDataSizeValid, "%ld", krnlDataSize); @@ -583,7 +583,7 @@ void Bios::printInitTblInfo() print(" ( %04x )\nRevision:\t\trev %d.%02d\n", initTbl->init_tbl_identifier, initTbl->revision >> 8, initTbl->revision & 0xFF); UINT initTblSize = bootParams->inittblSize; - bool isInitTblSizeValid = initTblSize >= 0 && initTblSize <= xbtool.params.romsize; + bool isInitTblSizeValid = initTblSize >= 0 && initTblSize <= params.romsize; print("Size:\t\t\t"); print((CON_COL)isInitTblSizeValid, "%ld", initTblSize); @@ -729,7 +729,7 @@ int Bios::validateBldr() const UINT krnlDataSize = bootParams->krnlDataSize; const UINT tblSize = bootParams->inittblSize; const UINT availableSpace = _totalSpaceAvailable; - const UINT romSize = xbtool.params.romsize; + const UINT romSize = params.romsize; const bool isKrnlSizeValid = krnlSize >= 0 && krnlSize <= romSize; const bool isDataSizeValid = krnlDataSize >= 0 && krnlDataSize <= romSize; @@ -791,25 +791,25 @@ int Bios::create(UCHAR* in_bl, UINT in_blSize, UCHAR* in_tbl, UINT in_tblSize, U } // check romsize is big enough for the bios. - if (xbtool.params.romsize < in_tblSize + BLDR_BLOCK_SIZE + MCPX_BLOCK_SIZE + in_kSize + in_kDataSize) + if (params.romsize < in_tblSize + BLDR_BLOCK_SIZE + MCPX_BLOCK_SIZE + in_kSize + in_kDataSize) { error("Error: romsize is less than the total size of the bios\n"); return BIOS_LOAD_STATUS_FAILED; } - _bios = (UCHAR*)xb_alloc(xbtool.params.romsize); + _bios = (UCHAR*)xb_alloc(params.romsize); if (_bios == NULL) { error("Error: Failed to allocate memory\n"); return BIOS_LOAD_STATUS_FAILED; } - _size = xbtool.params.romsize; + _size = params.romsize; // set encryption states based on user input. // when building a bios. the bldr file, and kernel file is expected to be passed in UNENCRYPTED. // This is because a bios can't be extracted unless the 2bl is decrypted. - _isBldrEncrypted = !xbtool.params.encBldr; - _isKernelEncrypted = !xbtool.params.encKrnl; + _isBldrEncrypted = !params.encBldr; + _isKernelEncrypted = !params.encKrnl; getOffsets(); @@ -849,15 +849,15 @@ int Bios::create(UCHAR* in_bl, UINT in_blSize, UCHAR* in_tbl, UINT in_tblSize, U { // kernel was encrypted successfully. update the kernel key in the bldr. - if (bldrKeys != NULL && xbtool.params.keyKrnl != NULL) + if (bldrKeys != NULL && params.keyKrnl != NULL) { print("Updating kernel key in bldr..\n"); - xb_cpy(bldrKeys->krnlKey, xbtool.params.keyKrnl, KEY_SIZE); + xb_cpy(bldrKeys->krnlKey, params.keyKrnl, KEY_SIZE); } } } - if ((xbtool.params.sw_flag & SW_BLD_BFM) != 0) // build a bios that boots from media. + if ((params.sw_flag & SW_BLD_BFM) != 0) // build a bios that boots from media. { convertToBootFromMedia(); } @@ -865,16 +865,16 @@ int Bios::create(UCHAR* in_bl, UINT in_blSize, UCHAR* in_tbl, UINT in_tblSize, U // only encrypt the bldr if the user has provided a key file or a mcpx rom and the bldr is not already encrypted. if (!_isBldrEncrypted) { - if (xbtool.params.keyBldr != NULL) + if (params.keyBldr != NULL) { - symmetricEncDecBldr(xbtool.params.keyBldr, KEY_SIZE); + symmetricEncDecBldr(params.keyBldr, KEY_SIZE); } - else if (xbtool.params.mcpxFile != NULL) + else if (params.mcpxFile != NULL) { - switch (xbtool.params.mcpx.version) + switch (params.mcpx.version) { case MCPX_ROM::MCPX_V1_0: - symmetricEncDecBldr(xbtool.params.mcpx.data+0x1A5, KEY_SIZE); + symmetricEncDecBldr(params.mcpx.data+0x1A5, KEY_SIZE); break; case MCPX_ROM::MCPX_V1_1: break; @@ -904,7 +904,7 @@ int Bios::convertToBootFromMedia() // encrypt the bldr with the bfm key. - if (xbtool.params.keyBldr == NULL) + if (params.keyBldr == NULL) { if (bldrKeys == NULL) { @@ -918,7 +918,7 @@ int Bios::convertToBootFromMedia() } else { - if (xb_cmp(xbtool.params.keyBldr, bldrKeys->bfmKey, KEY_SIZE) != 0) + if (xb_cmp(params.keyBldr, bldrKeys->bfmKey, KEY_SIZE) != 0) { error("Error: BFM key does not match the key in the bldr\n"); return 1; @@ -927,7 +927,7 @@ int Bios::convertToBootFromMedia() } // force the bfm bios to be 1Mb in size. - xbtool.params.binsize = 1 * 1024 * 1024; // 1Mb + params.binsize = 1 * 1024 * 1024; // 1Mb return 0; } \ No newline at end of file diff --git a/src/XcodeInterp.cpp b/src/XcodeInterp.cpp index a5740f2..867e333 100644 --- a/src/XcodeInterp.cpp +++ b/src/XcodeInterp.cpp @@ -403,10 +403,58 @@ int XcodeInterp::decodeXcodes() return 0; } +//#define XCODE_SIM_OLD_CODE 0 + int XcodeInterp::simulateXcodes() { // load the inittbl file +#ifndef XCODE_SIM_OLD_CODE + typedef struct X86_INSTR + { + USHORT opcode; + const char* asm_instr; + UINT opcode_len; + UINT instr_len; + bool uses_operand = false; + const char* data_str = NULL; + } X86_INSTR; + + const char* PTR_DATA_STR = ", [0x%08x]"; + const char* NUM_DATA_STR = ", 0x%08x"; + + const X86_INSTR instrs[] = { + { 0x1D8B, "mov ebx", 2, 6, true, PTR_DATA_STR }, + { 0x0D8B, "mov ecx", 2, 6, true, PTR_DATA_STR }, + { 0x158B, "mov edx", 2, 6, true, PTR_DATA_STR }, + + { 0xE0FF, "jmp eax", 2, 2 }, + { 0xE1FF, "jmp ecx", 2, 2 }, + { 0xE2FF, "jmp edx", 2, 2 }, + { 0xE3FF, "jmp ebx", 2, 2 }, + { 0xE4FF, "jmp esp", 2, 2 }, + { 0xE5FF, "jmp ebp", 2, 2 }, + { 0xE6FF, "jmp esi", 2, 2 }, + { 0xE7FF, "jmp edi", 2, 2 }, + + { 0xA5F3, "rep movsd", 2, 2 }, + + { 0xB8, "mov eax", 1, 5, true }, + { 0xB9, "mov ecx", 1, 5, true }, + { 0xBA, "mov edx", 1, 5, true }, + { 0xBB, "mov ebx", 1, 5, true }, + { 0xBC, "mov esp", 1, 5, true }, + { 0xBD, "mov ebp", 1, 5, true }, + { 0xBE, "mov esi", 1, 5, true }, + { 0xBF, "mov edi", 1, 5, true }, + { 0xA1, "mov eax", 1, 5, true, PTR_DATA_STR }, + + { 0xEA, "jmp far", 1, 6, true }, + { 0x90, "nop", 1, 1 }, + { 0xFC, "cld", 1, 1 } + }; + +#else // 6 byte encoding const USHORT MOV_PTR_INSTRS_2_BYTE[] = { 0x1D8B, 0x0D8B, 0x158B }; const char* MOV_PTR_NAMES_2_BYTE[] = { "mov ebx", "mov ecx", "mov edx" }; @@ -438,13 +486,19 @@ int XcodeInterp::simulateXcodes() // 1 byte encoding const UCHAR CLD_INSTR = 0xFC; const char* CLD_NAME = "cld"; +#endif - const UINT DEFAULT_SIM_SIZE = 128; // 32KB + const UINT DEFAULT_SIM_SIZE = 32; // 32KB const UINT SIM_SIZE = (params.simSize > 0) ? params.simSize : DEFAULT_SIM_SIZE; const UINT MAX_INSTR_SIZE = 6; const UCHAR zero_mem[MAX_INSTR_SIZE] = { 0 }; char str_opcode[16] = { 0 }; + char str_operand[16] = { 0 }; + char str_instr[32] = { 0 }; + + UINT operand = 0; + UINT operandLen = 0; int result = 0; @@ -517,6 +571,40 @@ int XcodeInterp::simulateXcodes() if (xb_cmp(mem_sim + i, zero_mem, (i < SIM_SIZE - MAX_INSTR_SIZE ? MAX_INSTR_SIZE : SIM_SIZE - i)) == 0) break; +#ifndef XCODE_SIM_OLD_CODE + // iterate through the x86 instructions + for (j = 0; j < sizeof(instrs) / sizeof(X86_INSTR); j++) + { + if (xb_cmp(mem_sim + i, (UCHAR*)&instrs[j].opcode, instrs[j].opcode_len) == 0) + { + xb_zero(str_instr, sizeof(str_instr)); + format(str_instr, "%04x: %s", i, instrs[j].asm_instr); + + if (instrs[j].uses_operand) + { + operand = 0; + operandLen = instrs[j].instr_len - instrs[j].opcode_len; + if (operandLen > 4) // UINT is 4 bytes + operandLen = 4; + + // to-do: fix jmp far operand. currently only supports 4 byte operand single operand instructions. + + xb_cpy(&operand, (UCHAR*)(mem_sim + i + instrs[j].opcode_len), operandLen); + format(str_operand, instrs[j].data_str == NULL ? NUM_DATA_STR : instrs[j].data_str, operand); + strcat(str_instr, str_operand); + } + strcat(str_instr, "\n"); + + print(str_instr); + + i += instrs[j].instr_len; + found = true; + break; + } + } + if (found) + continue; +#else found = false; // check for 2 byte mov ptr instructions @@ -604,6 +692,7 @@ int XcodeInterp::simulateXcodes() i++; // 1 byte opcode continue; } +#endif // opcode not found error("Error: Unknown instruction at offset %04x, INSTR: %02X\n", i, mem_sim[i]);