From 54d322a3313729189eebd8ec8556372b6a830c8a Mon Sep 17 00:00:00 2001 From: leslie Date: Sat, 5 Jan 2008 11:52:15 +0100 Subject: [PATCH] improve testing code --- testing/Makefile | 2 +- testing/compat.c | 7 +++ testing/testN2Emu.c | 131 +++++++++++++++++++++++++++++--------------- 3 files changed, 95 insertions(+), 45 deletions(-) diff --git a/testing/Makefile b/testing/Makefile index 3118328..8ef82ce 100644 --- a/testing/Makefile +++ b/testing/Makefile @@ -54,7 +54,7 @@ testN1Emu.o: testN1Emu.c ../systems/nagra/nagra.c ../systems/nagra/nagra1.c ../s testN1Emu: testN1Emu.o $(SHAREDOBJS) $(NOBJS) $(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@ -testN2Emu.o: testN2Emu.c +testN2Emu.o: testN2Emu.c compat.h testN2Emu: testN2Emu.o $(SHAREDOBJS) $(NOBJS) $(CXX) $(CXXFLAGS) $^ $(LIBS) -L../systems/nagra -lsc-nagra -o $@ diff --git a/testing/compat.c b/testing/compat.c index ef9d7ce..373cc15 100644 --- a/testing/compat.c +++ b/testing/compat.c @@ -82,6 +82,13 @@ int ReadRaw(const char *name, unsigned char *buff, int maxlen) if(strstr(line,"dump: n=")) continue; char *p=index(line,'#'); if(p) *p=0; + p=index(line,'['); + if(p) { + p=index(p,']'); + if(p) { + strcpy(line,p+1); + } + } p=index(line,':'); if(p) p++; else p=line; while(1) { diff --git a/testing/testN2Emu.c b/testing/testN2Emu.c index f5ea4d4..5e85ce6 100644 --- a/testing/testN2Emu.c +++ b/testing/testN2Emu.c @@ -11,56 +11,70 @@ static const unsigned char key3des[16] = { }; +static cN2Prov *emmP=0; + void Emm(unsigned char *emmdata, int cmdLen, int id) { - cN2Prov *emmP=cN2Providers::GetProv(id,N2FLAG_NONE); - if(emmP) printf("provider %04x capabilities%s%s%s%s\n",id, - emmP->HasFlags(N2FLAG_MECM) ?" MECM":"", - emmP->HasFlags(N2FLAG_Bx) ?" Bx":"", - emmP->HasFlags(N2FLAG_POSTAU) ?" POSTPROCAU":"", - emmP->HasFlags(N2FLAG_INV) ?" INVCW":""); + if(!emmP || (emmP && !emmP->CanHandle(id))) { + delete emmP; + emmP=cN2Providers::GetProv(id,N2FLAG_NONE); + if(emmP) emmP->PrintCaps(L_SYS_EMM); + } + HEXDUMP(L_SYS_RAWEMM,emmdata,cmdLen,"Nagra2 RAWEMM"); + id=(emmdata[8]<<8)+emmdata[9]; + LBSTARTF(L_SYS_EMM); + bool contFail=false; for(int i=8+2+4+4; iPostProcAU(id,&emmdata[i])) { - printf("key%02x: ",(emmdata[i+3]&0x40)>>6); - SDump(&emmdata[i+7],16); + if((((emmdata[i+3]|0xF3)+1)&0xFF) != 0) { + int len=emmdata[i+2]; + int off=emmdata[i+5]; + int ulen=emmdata[i+6]; + if(len>0 && ulen>0 && off+ulen<=len) { + int ks=emmdata[i+3], kn; + if(ks==0x06 || ks==0x46) kn=(ks>>6)&1; else kn=MBC(N2_MAGIC,ks); + unsigned char key[256]; + memset(key,0,sizeof(key)); + bool ok=false; + if((emmdata[i+1]&0x7F)==0) ok=true; + else { + if(emmP && emmP->HasFlags(N2FLAG_POSTAU)) { + if(emmP->PostProcAU(id,&emmdata[i])) ok=true; + } + else PRINTF(L_SYS_EMM,"POSTAU for provider %04x not supported",id); + } + if(ok) { + printf("key %x: off=%x ulen=%x ",kn,off,ulen); + SDump(&emmdata[i+7],ulen); + } + i+=ulen; } + else PRINTF(L_SYS_EMM,"nano42 key size mismatch len=%d off=%d ulen=%d",len,off,ulen); } - i+=23; + else PRINTF(L_SYS_EMM,"nano42 0xf3 status exceeded"); + i+=7; break; case 0xE0: // DN key update if(emmdata[i+1]==0x25) { printf("key%02x: ",(emmdata[i+16]&0x40)>>6); SDump(&emmdata[i+23],16); } - i+=39; + i+=emmdata[i+1]+2; break; case 0x83: // change data prov. id id=(emmdata[i+1]<<8)|emmdata[i+2]; - printf("keyid: %04x\n",id); i+=3; break; - case 0xA4: // conditional (always no match assumed for now) - i+=emmdata[i+1]+2+4; - break; - case 0xA6: - i+=emmdata[i+1]+1; - break; - case 0x13: - case 0x14: - case 0x15: - i+=4; - break; - case 0xB0 ... 0xBF: // Update with ROM CPU code + case 0xB0: case 0xB1: case 0xB2: case 0xB3: // Update with ROM CPU code + case 0xB4: case 0xB5: case 0xB6: case 0xB7: + case 0xB8: case 0xB9: case 0xBA: case 0xBB: + case 0xBC: case 0xBD: case 0xBE: case 0xBF: { int bx=emmdata[i]&15; if(!emmP || !emmP->HasFlags(N2FLAG_Bx)) { - printf("B%X for provider %04x not supported\n",bx,id); + PRINTF(L_SYS_EMM,"B%X for provider %04x not supported",bx,id); i=cmdLen; break; } @@ -68,24 +82,50 @@ printf("%02x: nano %02x\n",i,emmdata[i]); if((r=emmP->ProcessBx(emmdata,cmdLen,i+1))>0) i+=r; else { - printf("B%X executing failed for %04x\n",bx,id); + PRINTF(L_SYS_EMM,"B%X executing failed for %04x",bx,id); i=cmdLen; } break; } - case 0xE3: // Eeprom update - i+=emmdata[i+4]+4; + case 0xA4: i+=emmdata[i+1]+2+4; break; // conditional (always no match assumed for now) + case 0xA6: i+=15; break; + case 0xAA: i+=emmdata[i+1]+5; break; + case 0xAD: i+=emmdata[i+1]+2; break; + case 0xA2: + case 0xAE: i+=11;break; + case 0x12: i+=emmdata[i+1]+2; break; // create tier + case 0x20: i+=19; break; // modify tier + case 0x9F: i+=6; break; + case 0xE3: // Eeprom update + { + int ex=emmdata[i]&15; + if(!emmP || !emmP->HasFlags(N2FLAG_Ex)) { + i+=emmdata[i+4]+5; + PRINTF(L_SYS_EMM,"E%X for provider %04x not supported",ex,id); + break; + } + int r; + if((r=emmP->ProcessEx(emmdata,cmdLen,i+1))>0) + i+=r; + else { + PRINTF(L_SYS_EMM,"E%X executing failed for %04x",ex,id); + i=cmdLen; + } break; + } case 0xE1: case 0xE2: - case 0x00: // end of processing - i=cmdLen; - break; + case 0x00: i=cmdLen; break; // end of processing default: + if(!contFail) LBPUT("unknown EMM nano"); + LBPUT(" %02x",emmdata[i]); + contFail=true; i++; continue; } + LBFLUSH(); contFail=false; } + LBEND(); } bool Ecm(unsigned char *buff, int cmdLen, int id) @@ -140,8 +180,8 @@ static unsigned char odata[15] = { 0x80,0x30,0x47,0x07,0x45,0xec,0xc1,0xee,0xc5, int main(int argc, char *argv[]) { - if(argc<4) { - printf("usage: %s \n",argv[0]); + if(argc<5) { + printf("usage: %s [ [..]]\n",argv[0]); return 1; } @@ -156,14 +196,17 @@ int main(int argc, char *argv[]) InitAll(argv[1]); LogAll(); cLogging::SetModuleOption(LCLASS(L_SYS,L_SYS_DISASM),false); - unsigned char data[256]; - int len=ReadRaw(argv[4],data,sizeof(data)); - if((mode==1 && len!=64) || (mode==2 && len!=96)) { - printf("bad raw file format\n"); - return 1; - } int id=strtol(argv[2],0,0); - if(mode==1) Ecm(data,len,id); - else if(mode==2) Emm(data,len,id); + int dlen=(mode==1) ? 64 : 96; + unsigned char data[4096]; + for(int pos=4; pos