SASC-NG
DVBSoftCAM

nagra2-0501.c

Go to the documentation of this file.
00001 /*
00002  * Softcam plugin to VDR (C++)
00003  *
00004  * This code is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This code is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
00018  */
00019 
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023 
00024 #include "nagra2.h"
00025 
00026 // -- cMap0501 -----------------------------------------------------------------
00027 
00028 class cMap0501 : public cMapCore {
00029 protected:
00030   virtual bool Map(int f, unsigned char *data, int l);
00031   };
00032 
00033 bool cMap0501::Map(int f, unsigned char *data, int l)
00034 {
00035   l=GetOpSize(l);
00036   switch(f) {
00037     case 0x37:
00038       I.GetLE(data,l<<3);
00039       MonMul(B,I,B);
00040       break;
00041     default:
00042       return false;
00043     }
00044   return true;
00045 }
00046 
00047 // -- cN2Prov0501 --------------------------------------------------------------
00048 
00049 class cN2Prov0501 : public cN2Prov, private cMap0501, public cN2Emu {
00050 private:
00051   cMapMemHW *hwMapper;
00052   bool hasMaprom;
00053   //
00054   bool ProcessMap(int f);
00055   bool RomCallbacks(void);
00056   void AddRomCallbacks(void);
00057 protected:
00058   virtual bool Algo(int algo, const unsigned char *hd, unsigned char *hw);
00059   virtual bool NeedsCwSwap(void) { return true; }
00060   virtual bool RomInit(void);
00061   virtual void TimerHandler(unsigned int num);
00062   virtual void AddMapCycles(unsigned int num) { AddCycles(num); }
00063   virtual unsigned int CpuCycles(void) { return Cycles(); }
00064 public:
00065   cN2Prov0501(int Id, int Flags);
00066   virtual int ProcessBx(unsigned char *data, int len, int pos);
00067   virtual int RunEmu(unsigned char *data, int len, unsigned short load, unsigned short run, unsigned short stop, unsigned short fetch, int fetch_len);
00068   virtual void PostDecrypt(bool ecm) { PostDecryptSetup(ecm); }
00069   };
00070 
00071 static cN2ProvLinkReg<cN2Prov0501,0x0501,(N2FLAG_MECM|N2FLAG_INV|N2FLAG_Bx)> staticPL0501;
00072 
00073 cN2Prov0501::cN2Prov0501(int Id, int Flags)
00074 :cN2Prov(Id,Flags)
00075 {
00076   hwMapper=0; hasMaprom=false;
00077   SetMapIdent(Id);
00078 }
00079 
00080 bool cN2Prov0501::Algo(int algo, const unsigned char *hd, unsigned char *hw)
00081 {
00082   if(algo==0x60) {
00083     hw[0]=hd[0];
00084     hw[1]=hd[1];
00085     hw[2]=hd[2]&0xF8;
00086     ExpandInput(hw);
00087     hw[63]|=0x80;
00088     hw[95]=hw[127]=hw[95]&0x7F;
00089     DoMap(SETSIZE,0,4);
00090     DoMap(IMPORT_J,hw+0x18);
00091     DoMap(IMPORT_D,hw+0x20);
00092     DoMap(IMPORT_B,hw+0x60);
00093     DoMap(0x37,hw+0x40);
00094     DoMap(EXPORT_C,hw);
00095     DoMap(IMPORT_A,hw+0x60);
00096     DoMap(0x3a);
00097     DoMap(EXPORT_C,hw+0x20);
00098     DoMap(0x43);
00099     DoMap(0x44,hw);
00100     memcpy(hw,hw+64,20);
00101     hw[0]&=7;
00102     DoMap(EXPORT_B,hw+3);
00103     memset(hw+3+0x20,0,128-(3+0x20));
00104     return true;
00105     }
00106 
00107   PRINTF(L_SYS_ECM,"%04X: unknown MECM algo %02x",id,algo);
00108   return false;
00109 }
00110 
00111 bool cN2Prov0501::RomInit(void)
00112 {
00113   if(!AddMapper(hwMapper=new cMapMemHW(),HW_OFFSET,HW_REGS,0x00)) return false;
00114   if(   AddMapper(new cMapRom(0x3800,"Rom120_003800-003FFF.bin",0x00000),0x3800,0x0800,0x00)
00115      && AddMapper(new cMapRom(0x8000,"Rom120_408000-40CFFF.bin",0x00000),0x8000,0x5000,0x40)) {
00116     hasMaprom=true;
00117     PRINTF(L_SYS_EMU,"%04x: using native MAP rom",id);
00118     }
00119   return true;
00120 }
00121 
00122 bool cN2Prov0501::ProcessMap(int f)
00123 {
00124   unsigned short addr;
00125   unsigned char tmp[256];
00126   int l=GetOpSize(Get(0x48));
00127   int dl=l<<3;
00128 
00129   switch(f) {
00130     case SETSIZE:
00131       DoMap(f,0,Get(0x48));
00132       break;
00133     case IMPORT_J:
00134     case IMPORT_A:
00135     case IMPORT_B:
00136     case IMPORT_C:
00137     case IMPORT_D:
00138     case IMPORT_LAST:
00139       addr=HILO(0x44);
00140       GetMem(addr,tmp,dl,0); DoMap(f,tmp,l);
00141       break;
00142     case EXPORT_J:
00143     case EXPORT_A:
00144     case EXPORT_B:
00145     case EXPORT_C:
00146     case EXPORT_D:
00147     case EXPORT_LAST:
00148       addr=HILO(0x44);
00149       DoMap(f,tmp,l); SetMem(addr,tmp,dl,0);
00150       break;
00151     case SWAP_A:
00152     case SWAP_B:
00153     case SWAP_C:
00154     case SWAP_D:
00155       addr=HILO(0x44);
00156       GetMem(addr,tmp,dl,0); DoMap(f,tmp,l); SetMem(addr,tmp,dl,0);
00157       break;
00158     case CLEAR_A:
00159     case CLEAR_B:
00160     case CLEAR_C:
00161     case CLEAR_D:
00162     case COPY_A_B:
00163     case COPY_B_A:
00164     case COPY_A_C:
00165     case COPY_C_A:
00166     case COPY_C_D:
00167     case COPY_D_C:
00168       DoMap(f);
00169       break;
00170     case 0x37:
00171       GetMem(HILO(0x44),tmp,dl,0);
00172       DoMap(f,tmp,l);
00173       break;
00174     case 0x3a:
00175       DoMap(f,0,l);
00176       break;
00177     case 0x43:
00178       DoMap(f);
00179       break;
00180     case 0x44:
00181       GetMem(0x400,tmp,64,0);
00182       DoMap(f,tmp);
00183       SetMem(0x440,tmp,20,0);
00184       break;
00185     default:
00186       PRINTF(L_SYS_EMU,"%04x: map call %02x not emulated",id,f);
00187       return false;
00188     }
00189   return true;
00190 }
00191 
00192 bool cN2Prov0501::RomCallbacks(void)
00193 {
00194   unsigned int ea=GetPc();
00195   if(ea&0x8000) ea|=(cr<<16);
00196   switch(ea) {
00197     case 0x3840: //MAP Handler
00198       if(!ProcessMap(a)) return false;
00199       break;
00200     default:
00201       PRINTF(L_SYS_EMU,"%04X: unknown ROM breakpoint %04x",id,ea);
00202       return false;
00203     }
00204   if(ea>=0x8000) PopCr();
00205   PopPc();
00206   return true;
00207 }
00208 
00209 void cN2Prov0501::AddRomCallbacks(void)
00210 {
00211   if(!hasMaprom)
00212     AddBreakpoint(0x3840); // map handler
00213 }
00214 
00215 int cN2Prov0501::ProcessBx(unsigned char *data, int len, int pos)
00216 {
00217   if(data[pos-1]!=0xBC) {
00218     PRINTF(L_SYS_EMU,"%04X: bad nano %02X for ROM 120",id,data[pos-1]);
00219     return -1;
00220     }
00221   if(pos!=(0x93-0x80)) { // maybe exploitable
00222     PRINTF(L_SYS_EMU,"%04X: refuse to execute from %04x",id,0x80+pos);
00223     return -1;
00224     }
00225   if(Init(id,120)) {
00226     SetMem(0x80,data,len);
00227     SetPc(0x80+pos);
00228     SetSp(0x0FFF,0x0FE0);
00229     Set(0x0001,0xFF);
00230     Set(0x000E,0xFF);
00231     Set(0x0000,0x04);
00232     ClearBreakpoints();
00233     AddBreakpoint(0x821f);
00234     AddBreakpoint(0x0000);
00235     AddRomCallbacks();
00236     while(!Run(hasMaprom ? 20000:5000)) {
00237       if(GetPc()==0x821f) {
00238         GetMem(0x80,data,len);
00239         return a;
00240         }
00241       else if(GetPc()==0x0000) break;
00242       else if(!RomCallbacks()) break;
00243       }
00244     }
00245   return -1;
00246 }
00247 
00248 int cN2Prov0501::RunEmu(unsigned char *data, int len, unsigned short load, unsigned short run, unsigned short stop, unsigned short fetch, int fetch_len)
00249 {
00250   if(Init(id,120)) {
00251     SetSp(0x0FFF,0x0EF8);
00252     SetMem(load,data,len);
00253     SetPc(run);
00254     ClearBreakpoints();
00255     AddBreakpoint(stop);
00256     if(stop!=0x0000) AddBreakpoint(0x0000);
00257     AddRomCallbacks();
00258     while(!Run(100000)) {
00259       if(GetPc()==0x0000 || GetPc()==stop) {
00260         GetMem(fetch,data,fetch_len);
00261         return 1;
00262         }
00263       else if(!RomCallbacks()) break;
00264       }
00265     }
00266   return -1;
00267 }
00268 
00269 void cN2Prov0501::TimerHandler(unsigned int num)
00270 {
00271   if(hwMapper) hwMapper->AddCycles(num);
00272 }
00273 
00274 // -- cN2Prov0511 ----------------------------------------------------------------
00275 
00276 static cN2ProvLinkReg<cN2Prov0501,0x0511,(N2FLAG_MECM|N2FLAG_INV)> staticPL0511;
00277 
00278 // -- cN2Prov1101 ----------------------------------------------------------------
00279 
00280 static cN2ProvLinkReg<cN2Prov0501,0x1101,(N2FLAG_MECM|N2FLAG_INV)> staticPL1101;
00281 
00282 // -- cN2Prov3101 ----------------------------------------------------------------
00283 
00284 static cN2ProvLinkReg<cN2Prov0501,0x3101,(N2FLAG_MECM|N2FLAG_INV)> staticPL3101;
00285 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines