View Single Post
Old 5th April 2007, 20:21   #18  |  Link
arnezami
Registered User
 
Join Date: Sep 2006
Posts: 390
Quote:
Originally Posted by awhitehead View Post
At this point Geremia spent a long time tracking down how the drive is supposed to react to certain CDB commands.
I think I can fill in some gaps here .

At some point Geremia discovered the essential part of the checksum function. At that time it was still unknown what the exact extend was of the whole checksum related issues but this function did seem very promising. He needed an XOR calculator and thats where I could help him.

I also decided to take a shot at the assembly code and after a lot of pm discussion we (well Geremia did most of the tracing ) figured out that the checksum (especially before flashing) was far more complicated than was first assumed. It wasn't just 4 XORs (4 x 32-bit columns) and 1 SUM (of all 32-bit values) and nothing more. There was lots more calculation after that. It was getting a little frustrating because we seemed to find more and more functions all extending these calculations.

So at some point we decided to try to see if it was possible to keep the total SUM and XORs exactly the same while changing just one bit. Basicly avoiding all the difficult checksum calculation issues we encountered. Here is a snippet of what we figured out:

Quote:
Anyway. As far as I understand there are two things done first: SUM and XOR. And only with the endresults of those values is something being calculated.

So if we can make sure the SUM and XORs stay exactly the same then this should work.

Ok how could this be done?

Lets say we want to change 1 bit in 1 column. In order to do that we would have to change two bits in total.

Case 1:

Ok lets say we want to change one bit from 0 to 1. In this case this causes the SUM to go one up. In order to counteract this we would have to change a (very likely) unused part of the fw (in the same column) and find something like FFFFFFFF. We can change the same bit nr (vertically) and change it from 1 to 0. This will have two effects: the XOR of that column is restored AND the SUM is restored!

Case 2:

Ok lets say we want to change one bit from 1 to 0. In this case this causes the SUM to go one down. In order to counteract this we would have to change a (very likely) unused part of the fw (in the same column) and find something like 00000000. We can change the same bit nr (vertically) and change it from 0 to 1. This will have two effects: the XOR of that column is restored AND the SUM is restored!
Geremia tried this and changed one bit. And it flashed! This meant we could change the fw and still flash it (keep in mind all attempts so far had not succeeded in doing this and resulted in flash errors).

Now we realized we could use this same technique to change not just one bit but multiple. There was just one problem: in order for this to work we needed unused space in the flash memory filled with 00s (not just FFs). This was a problem because well there wasn't any: all unused space was filled with FFs.

We both (independently I might add) thought about this but his solution was both brilliant and beautyful . He would change a bunch of FFs (of which we had plenty):

Code:
000DFFB0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
000DFFC0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
000DFFD0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
000DFFE0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
Into this:

Code:
000DFFB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
000DFFC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
000DFFD0 FF FF FF FE FF FF FF FE FF FF FF FE FF FF FF FE 
000DFFE0 FF FF FF FE FF FF FF FE FF FF FF FE FF FF FF FE
And thats just sweet . You may not see this directly but this does three things: (1) each 32-bit column's XOR stays the same (2) the total sum of all 32-bit values stays the same and (3) it creates a bunch of desperately sought for 00s!

Eureka!

From there things did go really quickly. Geremia had already figured out what changes he wanted to try to retrieve the volume ID. He sent me the changes in hex form and the following is what was actually calculated the first time we did multiple bit changes to the fw.

The original code:

Code:
002218C6                 ldi:32  #checks_on_40254, r12
ROM:002218CC                 call:D  @r12            ; some check on 40254, result r4=0 or =1
ROM:002218CE                 ldi:8   #1, r4
ROM:002218D0                 cmp     #0, r4
ROM:002218D2                 bne     loc_2218DE
ROM:002218D4                 ldi:32  #loc_2238E2, r12
ROM:002218DA                 call    @r12            ; seems to go to cdb error
The patched code:

Code:
ROM:002218C6                 ldi:32  #checks_on_40254, r12
ROM:002218CC                 call:D  @r12            ; some check on 40254, result r4=0 or =1
ROM:002218CE                 ldi:8   #1, r4
ROM:002218D0                 nop                     ; patched here
ROM:002218D2                 bra     loc_2218DE    ; patched here
Changes in hex:

from
Code:
000218D0 A8 04 E3 05
to
Code:
000218D0 9F A0 E0 05
The calculation:

Taking A8 04 E3 05 and 9F A0 E0 05 here are the bit changes from 0 to 1:

Code:
17 A0 00 00
And these are the bit changes from 1 to 0.

Code:
20 04 03 00
This means we have to compensate in an FF area the following way:

Code:
E8 5F FF FF
And in a 00 area the following way (this is simple):

Code:
20 04 03 00
This meant we knew exactly what to change in the original fw. If it flashed correctly it would be a confirmation that this technique actually worked. If it also would give the volume ID it would confirm the change was enough as a working VID hack.

And it flashed. While the change in code did not change the Volume ID behaviour it did mean we were on the right track. Geremia did some more changes (mostly concerning the skipping of AGID stuff I believe) and finally made the drive give the Volume ID .

This is the last info (I have) on the actual patch needed for Volume ID retrieval:

Code:
ROM:002218B2                 .type ATAPI_AD_AACS_READ_VOLUMEID, @function
ROM:002218B2 ATAPI_AD_AACS_READ_VOLUMEID:
ROM:002218B2                 stm1    (r8, r9, r10, r11)
ROM:002218B4                 st      rp, @-r15
ROM:002218B6                 enter   #0x14
ROM:002218B8                 mov     r4, r9          ; AGID, from 0 to 3
ROM:002218BA                 ldi:32  #off_2F0010, r10
ROM:002218C0                 ldi:32  #0x405BB, r11
ROM:002218C6                 ldi:32  #checks_on_40254, r12
ROM:002218CC                 call:D  @r12            ; some check on 40254, result r4=0 or =1
ROM:002218CE                 ldi:8   #1, r4
ROM:002218D0                 cmp     #0, r4          ; patch here does not work
ROM:002218D2                 bne     loc_2218DE
ROM:002218D4                 ldi:32  #loc_2238E2, r12
ROM:002218DA                 call    @r12            ; seems to go to cdb error
ROM:002218DC                 bra     loc_2219A8
ROM:002218DE ; ---------------------------------------------------------------------------
ROM:002218DE
ROM:002218DE loc_2218DE:                             ; CODE XREF: ATAPI_AD_AACS_READ_VOLUMEID+20j
ROM:002218DE                 ldi:20  #0x164, r0
ROM:002218E2                 mul     r0, r9          ; AGID, from 0 to 3
ROM:002218E4                 mov     mdl, r0
ROM:002218E6                 ldi:32  #0x60C1C8, r8   ; seems AGID related data stored in internal ram
ROM:002218EC                 add     r0, r8
ROM:002218EE                 ldi:8   #4, r13
ROM:002218F0                 ld      @(r13, r8), r0
ROM:002218F2                 cmp     #0, r4          ; patched here, substituted r0 with r4, which is always 4
ROM:002218F4                 bne     loc_22191C      ; patched here, branch a little more forward, skipping checks on AGID
ROM:002218F6                 ldi:32  #CDB_field_error, r12
ROM:002218FC                 call:D  @r12
ROM:002218FE                 ldi:8   #0xA, r4
ROM:00221900                 bra     loc_2219A8
ROM:00221902 ; ---------------------------------------------------------------------------
ROM:00221902                 ld      @r8, r0
ROM:00221904                 cmp     #5, r0
ROM:00221906                 beq:D   loc_22191C
ROM:00221908                 mov     r9, r4
ROM:0022190A                 ldi:32  #sub_224208, r12
ROM:00221910                 call    @r12
ROM:00221912                 ldi:32  #loc_22383C, r12
ROM:00221918                 call    @r12
ROM:0022191A                 bra     loc_2219A8
ROM:0022191C ; ---------------------------------------------------------------------------
ROM:0022191C
ROM:0022191C loc_22191C:                             ; CODE XREF: ATAPI_AD_AACS_READ_VOLUMEID+42j
ROM:0022191C                                         ; ATAPI_AD_AACS_READ_VOLUMEID+54j
ROM:0022191C                 ldi:32  #sub_224208, r12 ; seems to clear AGID validity, so next time need auth again
ROM:00221922                 call    @r12
ROM:00221924                 ldi:32  #0x6010F0, r4
ROM:0022192A                 st      r4, @(r14, 0xF8)
ROM:0022192C                 ldi:32  #0x60ABB8, r5
I would like to thank Geremia for letting me participate (and hopefully encourage and/or inspire him) in his effort (or should I say: quest ) of opening a so called "closed system". He has done the bulk of the work and I enjoyed helping him where I could and where I felt it was needed.

Its another victory for those who enjoy their fair use rights...

Regards,

arnezami


PS. I would also like to add that for all this to happen sacrifices were made. Both by me and by Geremia (and probably others too). Lets just say we (at the very least) lost quite a lot of sleep lately. I hope when asking about information or improvements or whatever you will always keep this in mind.

Last edited by arnezami; 6th April 2007 at 08:13.
arnezami is offline