|
SASC-NG
DVBSoftCAM
|
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