From f5d20a96e17a500d55c9e26524d9463a62d49a3b Mon Sep 17 00:00:00 2001 From: zoogie Date: Thu, 30 Apr 2020 04:40:41 -0500 Subject: [PATCH] verify mini_b9s_installer in arm9 memory before memcpy safer unsafe mode --- build_payload.py | 7 +- .../usr2arm9ldr/arm9/source/i2c.c | 113 ++++++++++++++++++ .../usr2arm9ldr/arm9/source/i2c.h | 18 +++ .../usr2arm9ldr/arm9/source/main.c | 27 ++++- 4 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 stage3_pre9otherapp/usr2arm9ldr/arm9/source/i2c.c create mode 100644 stage3_pre9otherapp/usr2arm9ldr/arm9/source/i2c.h diff --git a/build_payload.py b/build_payload.py index fda928b..34a578d 100644 --- a/build_payload.py +++ b/build_payload.py @@ -1,4 +1,4 @@ -import os,sys,struct +import os,sys,struct,binascii payload="\x00"*0x20000 @@ -51,6 +51,7 @@ def fix_crc16(path, offset, size, crc_offset, type): if(len(b9s) > 0x10000): print("Error: b9s_installer too large") sys.exit(0) +crc=binascii.crc32(b9s+("\x00"*(0x10000-len(b9s)-4))) & 0xffffffff with open("usm.bin","wb") as f: f.write(payload) @@ -64,5 +65,9 @@ def fix_crc16(path, offset, size, crc_offset, type): f.write(code) f.seek(0x10000) f.write(b9s) + f.seek(0x20000-4) + f.write(struct.pack("> 4) & 1; +} + +static void i2cStop(u8 bus_id, u8 arg0) +{ + *i2cGetCntReg(bus_id) = (arg0 << 5) | 0xC0; + i2cWaitBusy(bus_id); + *i2cGetCntReg(bus_id) = 0xC5; +} + +//----------------------------------------------------------------------------- + +static bool i2cSelectDevice(u8 bus_id, u8 dev_reg) +{ + i2cWaitBusy(bus_id); + *i2cGetDataReg(bus_id) = dev_reg; + *i2cGetCntReg(bus_id) = 0xC2; + + return i2cGetResult(bus_id); +} + +static bool i2cSelectRegister(u8 bus_id, u8 reg) +{ + i2cWaitBusy(bus_id); + *i2cGetDataReg(bus_id) = reg; + *i2cGetCntReg(bus_id) = 0xC0; + + return i2cGetResult(bus_id); +} + +//----------------------------------------------------------------------------- + +bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data) +{ + u8 bus_id = i2cGetDeviceBusId(dev_id), + dev_addr = i2cGetDeviceRegAddr(dev_id); + + for(u32 i = 0; i < 8; i++) + { + if(i2cSelectDevice(bus_id, dev_addr) && i2cSelectRegister(bus_id, reg)) + { + i2cWaitBusy(bus_id); + *i2cGetDataReg(bus_id) = data; + *i2cGetCntReg(bus_id) = 0xC1; + i2cStop(bus_id, 0); + + if(i2cGetResult(bus_id)) return true; + } + *i2cGetCntReg(bus_id) = 0xC5; + i2cWaitBusy(bus_id); + } + + return false; +} \ No newline at end of file diff --git a/stage3_pre9otherapp/usr2arm9ldr/arm9/source/i2c.h b/stage3_pre9otherapp/usr2arm9ldr/arm9/source/i2c.h new file mode 100644 index 0000000..07554f7 --- /dev/null +++ b/stage3_pre9otherapp/usr2arm9ldr/arm9/source/i2c.h @@ -0,0 +1,18 @@ +#pragma once + +#include "types.h" + +#define I2C1_REG_OFF 0x10161000 +#define I2C2_REG_OFF 0x10144000 +#define I2C3_REG_OFF 0x10148000 + +#define I2C_REG_DATA 0 +#define I2C_REG_CNT 1 +#define I2C_REG_CNTEX 2 +#define I2C_REG_SCL 4 + +#define I2C_DEV_MCU 3 +#define I2C_DEV_GYRO 10 +#define I2C_DEV_IR 13 + +bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data); \ No newline at end of file diff --git a/stage3_pre9otherapp/usr2arm9ldr/arm9/source/main.c b/stage3_pre9otherapp/usr2arm9ldr/arm9/source/main.c index 5edf02f..b490890 100644 --- a/stage3_pre9otherapp/usr2arm9ldr/arm9/source/main.c +++ b/stage3_pre9otherapp/usr2arm9ldr/arm9/source/main.c @@ -2,6 +2,7 @@ #include "PXI.h" #include "arm11.h" #include "petitfs/pff.h" +#include "i2c.h" #define CFG11_SHAREDWRAM_32K_DATA(i) (*(vu8 *)(0x10140000 + i)) #define CFG11_SHAREDWRAM_32K_CODE(i) (*(vu8 *)(0x10140008 + i)) @@ -123,9 +124,33 @@ static void patchSvcReplyAndReceive11(void) patch[2] = svcTable[0x7C];; } +u32 crc32(u8 *data, int size) +{ + u32 r = ~0; u8 *end = data + size; + + while(data < end) + { + r ^= *data++; + + for(int i = 0; i < 8; i++) + { + u32 t = ~((r&1) - 1); r = (r>>1) ^ (0xEDB88320 & t); + } + } + + return ~r; +} + void main(void) { - memcpy((void*)0x23F00000, (void*)0x23D45000, 0x10000); + + u8 *minib9s=(void*)0x23D45000; + u32 crc=crc32(minib9s, 0x10000-4); + if(crc != *(u32*)(minib9s+0x10000-4)){ + i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 0); + while(1); + } + memcpy((void*)0x23F00000, minib9s, 0x10000); //patchSvcReplyAndReceive11(); //doFirmlaunch(); //*(u32*)NULL=42;