This may help some of you...

I think I follow this mostly - now. Was misreadding before!

However a couple of questions.

The very first instruction, you say:

0081: B6 02 lda $02 ; Load in A
Loads #$01 or 0000 0001 into A from register $02

Where does the $01 come from - how do you know what is in register $02?
We know what the byte should be by looking in the EMM bytes dump of the other EMM.
As we know the answer, we can work out what is needed to EOR the current byte in the EMM bytes dump to get the correct byte (as stored in the other EMM)

Remember, between the 2 EMMs, you can see both keys by comparing the dumps...

Why does the clear bit 1 instruction not actually clear it?
Either the Global Interrupt causes this behaviour and/or the mixture of the Global Interrupt and a total clearing of the Register (ie, disallow 00000000 or disallow 00000000 after Global Interrupt)

So, if I understand correctly - the code in the dbox CAM thinks the keys are the ones in the data part of this EMM, so it just gets them out and attempts to use them, however, these two byte swaps put in the actual keys - correct?
Pretty much, the 8 bytes immediately following the 42 05 and 42 85 bytes in the bytes dump are the keys.
42 = write the key using the index (02 or 85) meaning key 0 or 1. The EMMs (the code starting at $81) modifies the bytes in the keys BEFORE the 42 command is executed.

Alll you need do is modify the EMM code Before it executes. When it does, it mods the keys correctly and the bytes dump commands write the correct key back to the card...

So if I take an EMM that I have captured, I should be able to use the steps above to work out the real key1?

I am capturing the EMM by just grabbing the console output from evocamd - is that the best way to get them?
If you capture BOTH EMM's, you can see in the 1st EMM which 2 bytes are to be altered.
Now look in the 2nd EMM for those 2 byte locations and you'll find the real bytes.

Do the same in the 2nd EMM, the altered bytes are correct in the 1st EMM..

Each EMM must contain 6 correct bytes and 2 false bytes. (for each key)
As each EMM has 2 different sets of false bytes, the both (between them) contain all 8 correct bytes...
 
Last edited:
actually, could you explain that again. where did you get $01 from ?

u said looking in the EMM bytes dump of the "other EMM" , what is the other emm?

what importance is the EMM dump in our coding? what does it represent? is it the decrypted EMM. so all that code that we see from the decrypted emm, is that our own code, right? as in:

DISASSEMBLY OF CODE:
------------------------------

0081: B6 02 lda $02 ; Load in A


emm studio does that right? so if emmstudio does that, we jsut have to identify what the EMM is doing and edit our own source files to work with that, right?

i can see that the EMM dumps both are similar after the 42 05 XX XX , where XX XX are different, im guessing the fake bytes?
 
I just can't seem to get it to work out - any idea where I am going wrong (this is a different EMM, but with the keys X'ed out (hope that is OK on here)?

Code:
You don't have permission to view the code content. Log in or register now.

I am a little confused with the two EMMs - The dbox is displaying two beside each other each time, but they look identical to me.

Reckon I am going to have to pick this up again tomorrow - if you can spot where I am going wrong it would be a great help though!
 
Ah - light bulb moment - I think I have it -

My two EMMs were identical, which means you have to do the process twice - on the second time round, it boils down to

7B xor 10 = 6B (as expected)

and then

DD xor 18 = C5 (as expected)

Sweet - I finally worked something out!

Now for the next thing - how do you patch the dbox with that? Is it a matter of hacking the ROM 7 image on there like with the titanium, or hacking the evocamd emu somehow?
 
Why does the clear bit 1 instruction not actually clear it?

Because its acting on a register, not a memory location. Registers are funny thngs that can be connected to hardware devices like timers and I/O ports etc. As such they can have read only bits (status bits from some hardware device) or write only bits (possibly reseting interrupt flags etc) or read/write bits (turning hardware on/off or setting hardware parameters).

Generally, anything below address $20 is a register.
 
All the info you need to see what's happening is in the 1st post...

2 EMMs are contained in the post (both are commented also)

The Bytes Dump is know as the payload.

The instructions start at address $0081

The Bytes Dump starts at $00A0

Think of the Bytes Dump AS THE KEY CHANGE (because it is)

Within the dump are the 2 keys. Key 0 (8 bytes following 42 05) and Key 1 (8 bytes after 42 85)

The EMM alters the bytes in the dump BEFORE the card executes the key update (command 42)

Now if the 1st EMM had 4 incorrect bytes in the dump and only altered 2, the card would never work.
This is why only the 2 bytes that are to be altered by the EMM code are flase.

With this in mind, we now know that the 2 different bytes being altered in the next EMM MUST BE CORRECT if they are different to those being altered in the 1st EMM...

Example: (reading from the right starting at 0, so 88 = byte 0 and 11 = byte 7 and 44 = byte 4)

1st EMM:
Change byte5 to 3 in key 0
Change byte1 to 7 in key 0

Dump
11 22 XX 44 55 66 XX 88 (key 0) After 42 05
11 22 33 44 55 66 77 88 (key 1) After 42 85

----------------------------------------------------------

2nd EMM:
Change byte7 to 1 in key 0
Change byte3 to 5 in key 0

Dump
XX 22 33 44 XX 66 77 88 (key 0) After 42 05
11 22 33 44 55 66 77 88 (key 1) After 42 85


Now you can clearly see that in these EMMs, only key 0 is being played about with...
Key 1 matches in both dumps....

This means that the currently key in use MUST be key 0.....

Now, apply some logic....

The bytes NOT being altered in key 0 MUST be valid...

So if bytes 5 and 1 are fake in the 1st EMM (as they are being altered by the EMM code) you can see that they aren't being altered by the 2nd EMM, hence those must be the correct values.

The same goes for the 2nd EMM.

This time, bytes 7 and 3 are being altered by the code and therefore must be fake.
Look at the same bytes in the 1st EMM as that EMM is NOT altering bytes 7 and 3..These are your real bytes.

So, by comparing which bytes are being altered, you can ascertain the real key.

If the 2nd EMM had the fake bytes from the 1st EMM also, as it only updates 2 bytes, 2 bytes would remain false. This would cause a blackout for all viewers, subs or pirates...

The public opos sw doesn't emulate the rom registers. It didn't handle the call to reg $07 last may and it doesn't emulate the call to register $02 this month.

How do we know the register $02 is #$01 and #$81 when called (loaded into A)

Simple, remember the AND instruction..

This is a mask, the 1st is #$10 and the 2nd is #$18.

& before that instruction you have a nibble swap...

So we know we must have #$01 and #$18 AFTER a nibble swap.

Do another swap and you've got the correct value for the register....

0001 0000 (nibbles are part of a byte) which is #$10
The result of the swap is 0000 0001 (or a logical shift left or right by 4) which = #$01

1000 0001 which is #$81 swapped = 0001 1000 which = #$18

More about the AND command...

It's a masking exercise.

In order to ensure their are no corrupt bits in the register, we AND it with the desired value...

we want 0001 0000 and we can ensure we don't have rogue 1's in it by AND'ing it with 0001 0000

0001 0000 Reg $02
0001 0000 (AND by $10)
-------------
0001 0000 (both the upper and lower lines must conatin a 1 to produce a 1 in the result)

If the register was corrupt, say like this

0101 0101 Reg $02
0001 0000 (AND by $10)
-------------
0001 0000 (you can see we still have the correct answer, even though the bits were corrupt.....)

Ok, anyways, so we've swapped them to read #$10 and #$18...

In the EMM, we have the line 0086: B8 AD eor $AD
So , address $0086 exclusive OR's the contents of address $00AD ( in the bytes dump)

00A8: 01 42 05 ED 74 0E 7A 5F
The 00A8 is the starting address. You read the bytes left to right.
00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF.

So, at address $00AD we have 0E (or 0000 1110)

So we need to EOR this with #$10 (or 0001 0000)

0001 0000
0000 1110
-------------
0001 1110 (or #$1E)

You can verify this by looking in the other EMM's byte dump

00A8: 01 42 05 FD 74 1E 7A 5F

No, looking at the 2nd part of the EMM.

it sets bit 7 of the Register.

It was last 0000 0001

008B: 11 02 bclr0 $02

This should clear bit0 (or the bit furthest on the right). The register should now = 0000 0000

BUT it doesn't....

We know this as we know (from above) the Register MUST = #$81 and #$81 is 1000 0001

We know bit7 is set (to 1) with the next instruction 008D: 1E 02 bset7 $02
bit7 is furthest to the left... (remember, you count right to left starting at 0)

So if bit0 was cleared and bit7 was set, we'd have 1000 0000 or #$80, which we know is wrong...

That's what b0rks the opos...

This is probably because the Register cannot be cleared after a Global Interrupt is set..
008A: 9B sei

So, we now EOR the data held at address $00B2 (in the bytes dump) with #$18 (or 0001 1000)
00B0: 6B 60 58 42 85 FF 6C C6

0001 1000
0101 1000
-------------
0100 0000 = #$40

Again, we can check the result from the other EMM

00B0: 6B 78 40 42 85 FF 6C C6

Apply this logic to each EMM that comes down the line, they will change the bytes read and the bytes stored in them (in the dump) but if you **** off the call to the registers

0081: B6 02 lda $02
008F: B6 02 lda $02

and replace them with
0081: A6 01 lda #$01
008F: A6 81 lda #$81

The rest of the EMM, the swap, the AND, the EOR and the key writing will all work fine :)

All you need to do is patch the opos s/w in order to execute your code that writes out those 2 register calls above and you've solved it....

The easiest way to do it is to log active comms between a card and the STB and work out which routine is called BEFORE executing the code stored at address $0081 (the EMM)

Once you know that, you can jump from their code to some free space in the ROM, check for the EMM (look for 42 in the bytes dump and 4E in the EMM) and if true, write over thier code with the above....

When the key update executes (command $42) (remember, your patch needs to run before the instructions are executed in the bytes dump) it will write the correct keys to your dataspace (eeprom image, what you see in Nagra Edit)

I hope this has helped a little

Code:
You don't have permission to view the code content. Log in or register now.
 
Last edited:
BTW, could someone please move this to the main cable section. ta :)
 
has this worked guys?

Why are people asking if this is working or not...

The above IS the correct info about the EMMs and the suggested patch WILL sort an opos card out..

Take my word on it (& consider my last patch lasted 11 months...)
 
Hmmm, time for a hint..

If you wanted to break out of the regular subroutines just prior to your EMM being executed, why not take a peek at $74EC..

Instead of following the jsr instruction, jump to some free space, run all your patches (you can even include the previous keyroll method patch here instead of jumping from $823D...)

If you do include the previous keyroll, you won't need to duplicate the code that was at $823D in your free space, which therefore reduces the patch size allowing more space for future patches :)

Anyways, once you've jumped from $74EC, don't forget you need to return to it (and if you jump from within your patch to the end, you'll require 2 returns :))

Simply use the same opcodes you see in the EMMs posted here to construct a patch, add it to your ROM, encrypt it and bingo :cool:


OH & CAN SOMEONE PLEASE MOVE THIS TO THE MAIN FORUM :)
 
Last edited:
Just a copy of titaiumhack I found as the one posted doesn't seem to download properly.
I hope this is the right one.
 
can i mod this to work on a tit2 card ? rom10 ?

Ive noticed each time the card AU's the keys are out slightly on two on the bytes. I in no way understand anything written in this thread but if im right that it will sort out the wrong bytes then i shall try and learn, although never done any of this before. I have no understanding of codeing or hexdecimal what so ever :(
 
Lets just say that exactly the same fix has the potential to fix quite a few of the different platforms affected including certain linux based boxes
 
Hi I was just wondering what you were using as a disassember. I used to know some coding (mainly 088 chips) but haven't done it for many years so I was looking for pointers as to where to look to relearn. ie exactly what the language is. If anyone could point me in the right direction that would be great. Cheers
 
Back
Top