Author Topic: my Last Great Idea  (Read 5115 times)

0 Members and 1 Guest are viewing this topic.

Offline bushing

  • Senior Member
  • Needs to get outside.
  • *****
  • Posts: 119
  • props to my peeps
my Last Great Idea
« on: July 21, 2005, 01:15:59 pm »
I would have tried this, but as I mentioned in another thread, my PhatBox seems to have come to an untimely demise :( so I don't know if or when I'll ever get to test this idea.

I believe that now that we've had some success writing to the flash chip on the PhatBox, there is a simple way to patch the bootloader by only changing one bit, which will make it boot from a drive that does not have a valid signature.

One of the properties of flash chips is that when you erase them, they start off as all one bits, and al you can do is set certain bits to zero.  This means you can set any bit in the memory to zero at any time, without having to erase first;  so, we need to find a bit we can set to zero to solve our problem.

There is a routine that is called throughout the bootloader that performs a signature verification ... it returns a 1 to indicate a valid signature, and a 0 otherwise.

If we change the code that calls this verify_sig function on the drive ID signature block to check for a return code of 0 instead of a return code of 1, that should be enough to make it work.

That code is here:
Code: [Select]

ROM:C0005B9C                 LDR     R3, serial_and_model
ROM:C0005BA0                 LDR     R0, [R10,R3]    ; buf
ROM:C0005BA4                 LDR     R1, =drive_signature_buffer ; signature
ROM:C0005BA8                 LDR     R2, =drive_sig_key? ; keyinfo
ROM:C0005BAC                 BL      do_verify_stuff
ROM:C0005BB0                 CMP     R0, #1
ROM:C0005BB4                 LDR     R3, =oBOOT0-2
ROM:C0005BB8                 BNE     verify_sig_failed


We need to change that to a CMP R0, #0.  That means changing 01 00 50 E3 @ offset 0BB0 to 00 00 50 E3.

Here's a code snippet (again, untested) that should do that:
Code: [Select]

volatile unsigned short *bios= mmap(0, 256*1024, PROT_WRITE | PROT_READ, MAP_SHARED, flash->fd_mem, (off_t) 0);

#define WRITE_ADDR(x,y) bios[((x & 0x7FFF)<<1) | ((x & 0x8000) >> 15)]=(y)

// Program command:
WRITE_ADDR(0x555,0xAA);
WRITE_ADDR(0x2AA,0x55);
WRITE_ADDR(0x555,0xA0);

// Clear 16 bit word:
// it's important to use an un-demangled address here because we want to refer to the address the same way the CPU will when booting
bios[0xBB0 >> 1]=0;


Again, haven't even tested that.  It may very well nuke your box as dead as mine is!  (but I think it was static that got to mine...)

An important thing to note there is that by only changing that one byte, it will now boot if your drive signature is bad... but it will now ONLY boot if it's bad, and will not boot if you are using a valid DMS!

If you want to solve that, you need to patch more locations.  Specifically:

* Patch offset 0x1C80 to 00 to make the signature verification routine return 0 for success [mov r0, #1 -> mov r0, #0]

* Patch offset 0xBB0 to 00 to make the loader accept a 0 return code when checking boot sector [cmp r0, #1 -> cmp r0, #0]

* Patch offset 0x350 to 00 to accept 0 code when checking ramdisk [cmp r0, #1 -> cmp r0, #0]

* Patch offset 0x2E0 to 00 to accept 0 code when checking all files except for ramdisk [cmp r0, #1 -> cmp r0, #0]

Try at your own risk, and I guess let me know if it worked... *sigh*

-b
« Last Edit: July 22, 2005, 03:48:02 pm by bushing »

Offline sbingner

  • Administrator
  • Veteran.
  • *****
  • Posts: 1301
Re: my Last Great Idea
« Reply #1 on: July 22, 2005, 09:46:27 am »
that sounds like it should work... I was able to set a non-erased block to zero without any problems.   I'm should look see if there are any other areas that it can be modified by simply changing a bit or two to 0, don't necessarily have to make it 0....