⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nagra1.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Softcam plugin to VDR (C++) * * This code is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Or, point your browser to http://www.gnu.org/copyleft/gpl.html */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "system.h"#include "misc.h"#include "opts.h"#include "helper.h"#include "nagra.h"#include "cpu.h"#include "log-nagra.h"#define SYSTEM_NAME          "Nagra"#define SYSTEM_PRI           -10// -- cEmu ---------------------------------------------------------------------#define MAX_COUNT 200000class cEmu : public c6805 {protected:  int romNr, id;  char *romName, *romExtName, *eepromName;  //  int InitStart, InitEnd;  int EmmStart, EmmEnd, EmmKey0, EmmKey1;  int FindKeyStart, FindKeyEnd;  int MapAddr;  int Rc1H, Rc1L;  int EnsIrdChk, Cmd83Chk;  int SoftInt, StackHigh;  //  bool AddRom(unsigned short addr, unsigned short size, const char *name);  bool AddEeprom(unsigned short addr, unsigned short size, unsigned short otpSize, const char *name);  //  virtual bool InitSetup(void) { return true; }  virtual bool UpdateSetup(const unsigned char *emm) { return true; }  virtual bool MathMapHandler(void);public:  cEmu(void);  virtual ~cEmu();  bool Init(int RomNr, int Id);  bool GetOpKeys(const unsigned char *Emm, unsigned char *id, unsigned char *key0, unsigned char *key1);  bool GetPkKeys(const unsigned char *select, unsigned char *pkset);  bool Matches(int RomNr, int Id);  };cEmu::cEmu(void){  romName=romExtName=eepromName=0;}cEmu::~cEmu(){  free(romName);  free(romExtName);  free(eepromName);}bool cEmu::AddRom(unsigned short addr, unsigned short size, const char *name){  cMap *map=new cMapRom(addr,name);  return AddMapper(map,addr,size);}bool cEmu::AddEeprom(unsigned short addr, unsigned short size, unsigned short otpSize, const char *name){  cMap *map=new cMapEeprom(addr,name,otpSize);  return AddMapper(map,addr,size);}bool cEmu::Matches(int RomNr, int Id){  return (romNr==RomNr && id==Id);}bool cEmu::Init(int RomNr, int Id){  romNr=RomNr; id=Id;  asprintf(&romName,"ROM%d.bin",romNr);  asprintf(&romExtName,"ROM%dext.bin",romNr);  asprintf(&eepromName,"eep%i_%02x.bin",romNr,(id&0xff00)>>8);  if(InitSetup()) {    ForceSet(EnsIrdChk, 0x81,true);    ForceSet(Cmd83Chk+0,0x98,true);    ForceSet(Cmd83Chk+1,0x9d,true);    if(SoftInt) {      Set(0x1ffc,SoftInt>>8);      Set(0x1ffd,SoftInt&0xff);      }    SetSp(StackHigh,0);    SetPc(InitStart);    ClearBreakpoints();    AddBreakpoint(InitEnd);    if(!Run(MAX_COUNT)) return true;    }  return false;}bool cEmu::GetOpKeys(const unsigned char *Emm, unsigned char *id, unsigned char *key0, unsigned char *key1){  int keys=0;  if(UpdateSetup(Emm)) {    SetMem(0x0080,&Emm[0],64);    SetMem(0x00F8,&Emm[1],2);    SetPc(EmmStart);    ClearBreakpoints();    AddBreakpoint(EmmEnd);    AddBreakpoint(MapAddr);    AddBreakpoint(EmmKey0);    AddBreakpoint(EmmKey1);    while(!Run(MAX_COUNT)) {      unsigned short pc=GetPc();      if(pc==EmmKey0) {        GetMem(0x82,key0,8);        keys++;        }      if(pc==EmmKey1) {        GetMem(0x82,key1,8);        keys++;        }      if(pc==MapAddr) {        if(!MathMapHandler()) break;        PopPc(); // remove return address from stack        }      if(pc==EmmEnd) {        GetMem(0x00F8,id,2);        break;        }      }    }  return (keys==2);}bool cEmu::GetPkKeys(const unsigned char *select, unsigned char *pkset){  Set(0x0081,select[2]<<7);  SetMem(0x00F8,select,3);  SetPc(FindKeyStart);  ClearBreakpoints();  AddBreakpoint(FindKeyEnd);  while(!Run(MAX_COUNT)) {    unsigned short pc=GetPc();    if(pc==FindKeyEnd) {      if(!cc.c) {        PRINTF(L_SYS_EMU,"Updating PK keys");        unsigned short loc=(Get(Rc1H)<<8)+Get(Rc1L);        for(int i=0; i<45; i+=15) GetMem(loc+4+i,pkset+i,15);        return true;        }      else {        PRINTF(L_SYS_EMU,"Updating PK keys failed. Used a correct EEPROM image for provider %04x ?",((select[0]<<8)|select[1]));        break;        }      }    }  return false;}bool cEmu::MathMapHandler(void){  PRINTF(L_SYS_EMU,"Unsupported math call $%02x in ROM %d, please report",a,romNr);  return false;}// -- cEmuRom3Core -------------------------------------------------------------class cEmuRom3Core : public cEmu {protected:  virtual void Stepper(void);  bool CoreInitSetup(void);  bool DoMaps(bool hasExt);  };void cEmuRom3Core::Stepper(void){  int rnd=random();  unsigned char mem4=Get(0x04);  if(!bitset(mem4,2)) {    Set(0x06,(rnd&0xff00)>>8);    Set(0x07,rnd&0xff);    }}bool cEmuRom3Core::CoreInitSetup(void){  ForceSet(0x0001,1<<3,true);  Set(0x0002,0x03);  Set(0x004e,0x4B);  return true;}bool cEmuRom3Core::DoMaps(bool hasExt){  // Eeprom & ROMext are non-fatal also they are required for some providers  if(hasExt) AddRom(0x2000,0x2000,romExtName);  AddEeprom(0xE000,0x1000,0x20,eepromName);  return AddRom(0x4000,0x4000,romName);}// -- cEmuRom3 -----------------------------------------------------------------class cEmuRom3 : public cEmuRom3Core {protected:  virtual bool InitSetup(void);  virtual bool UpdateSetup(const unsigned char *emm);public:  cEmuRom3(void);  };cEmuRom3::cEmuRom3(void){  InitStart=0x4000;  InitEnd  =0x734b;  EmmStart =0x5a82;  EmmEnd   =0x67db;  EmmKey0  =0x617c;  EmmKey1  =0x6184;  FindKeyStart=0x6133;  FindKeyEnd  =0x6147;  MapAddr  =0x2800;  Rc1H     =0x0024;  Rc1L     =0x0025;  EnsIrdChk=0x6437;  Cmd83Chk =0x6431;  SoftInt  =0x0000;  StackHigh=0x7f;}bool cEmuRom3::InitSetup(void){  return DoMaps(true) && CoreInitSetup();}bool cEmuRom3::UpdateSetup(const unsigned char *emm){  return CoreInitSetup();}// -- cEmuRom7 -----------------------------------------------------------------class cEmuRom7 : public cEmuRom3Core {protected:  virtual bool InitSetup(void);  virtual bool UpdateSetup(const unsigned char *emm);public:  cEmuRom7(void);  };cEmuRom7::cEmuRom7(void){  InitStart=0x4000;  InitEnd  =0x7b68;  EmmStart =0x482b;  EmmEnd   =0x6146;  EmmKey0  =0x4f2a;  EmmKey1  =0x4f32;  FindKeyStart=0x4ee4;  FindKeyEnd  =0x4ef5;  MapAddr  =0x200f;  Rc1H     =0x0028;  Rc1L     =0x0029;  EnsIrdChk=0x51df;  Cmd83Chk =0x51d9;  SoftInt  =0x4008;  StackHigh=0x7f;}bool cEmuRom7::InitSetup(void){  return DoMaps(false) && CoreInitSetup();}bool cEmuRom7::UpdateSetup(const unsigned char *emm){  SetMem(0x01A2,&emm[1],2);  return true;}// -- cEmuRom10Core ------------------------------------------------------------class cEmuRom10Core : public cEmu {protected:  struct Map { unsigned char A[64], B[64], C[64], D[4], opSize; } map;  //  virtual void Stepper(void);  bool DoMaps(bool hasExt, int romSize);  bool CoreInitSetup(void);  bool CoreUpdateSetup(const unsigned char *emm);  };void cEmuRom10Core::Stepper(void){  int rnd=random();  unsigned char mem7=Get(0x07);  if(cc.i) mem7&=0xFD; else mem7|=0x02;  Set(0x07,mem7);  if(bitset(mem7,1) && bitset(mem7,7)) {    Set(0x05,(rnd&0xFF00)>>8);    Set(0x06,rnd&0xFF);    }}bool cEmuRom10Core::DoMaps(bool hasExt, int romSize){  // Eeprom & ROMext are non-fatal also they are required for some providers  if(hasExt) AddRom(0x2000,0x2000,romExtName);  AddEeprom(0xC000,0x2000,0x40,eepromName);  return AddRom(0x4000,romSize,romName);}bool cEmuRom10Core::CoreInitSetup(void){  ForceSet(0x01,0x13,true);  Set(0x02,0x3);  Set(0x07,0xFF);  return true;}bool cEmuRom10Core::CoreUpdateSetup(const unsigned char *emm){  SetMem(0x01A2,&emm[1],2);  SetMem(0x0307,&emm[1],2);  Set(0x0300,emm[5]);  Set(0x0301,emm[2]);  return true;}// -- cEmuRom10 ----------------------------------------------------------------class cEmuRom10 : public cEmuRom10Core {protected:  virtual bool InitSetup(void);  virtual bool UpdateSetup(const unsigned char *emm);  virtual bool MathMapHandler(void);public:  cEmuRom10(void);  };cEmuRom10::cEmuRom10(void){  InitStart=0x4000;  InitEnd  =0x81ca;  EmmStart =0x6a71;  EmmEnd   =0x81f7;  EmmKey0  =0x7172;  EmmKey1  =0x717a;  FindKeyStart=0x712c;  FindKeyEnd  =0x713d;  MapAddr  =0x2020;  Rc1H     =0x004a;  Rc1L     =0x004b;  EnsIrdChk=0x7427;  Cmd83Chk =0x7421;  SoftInt  =0x4004;  StackHigh=0x3ff;}bool cEmuRom10::InitSetup(void){  return DoMaps(false,0x5A00) && CoreInitSetup();}bool cEmuRom10::UpdateSetup(const unsigned char *emm){  Set(0x006e,0x4B);  return CoreUpdateSetup(emm);}bool cEmuRom10::MathMapHandler(void){  PRINTF(L_SYS_EMU,"math call: $%02x",a);  switch(a) {    case 0x02:      switch(Get(0x41)) {        case 0: map.opSize=0x04; break;        case 1: map.opSize=0x20; break;        case 2: map.opSize=0x24; break;        case 3: map.opSize=0x30; break;        case 4: map.opSize=0x34; break;        case 5:        default: map.opSize=0x40; break;        }      return true;    case 0x0e ... 0x10:      {      const unsigned short addr=(Get(0x4d)<<8)|Get(0x4e);      unsigned char tmp[64];      GetMem(addr,tmp,map.opSize);      unsigned char *reg;      switch(a) {        case 0x0e: reg=map.A; break;        case 0x0f: reg=map.B; break;        case 0x10: reg=map.C; break;        default: return false;        }      SetMem(addr,reg,map.opSize);      memcpy(reg,tmp,map.opSize);      Set(0x41,map.opSize);      return true;      }    case 0x29:      Set(0x120,1);      return true;    }  return cEmu::MathMapHandler();}// -- cEmuRom11 ----------------------------------------------------------------class cEmuRom11 : public cEmuRom10Core {protected:  virtual bool InitSetup(void);  virtual bool UpdateSetup(const unsigned char *emm);public:  cEmuRom11(void);  };cEmuRom11::cEmuRom11(void){  InitStart=0x4000;  InitEnd  =0x405b;  EmmStart =0x5865;  EmmEnd   =0x9990;  EmmKey0  =0x5f66;  EmmKey1  =0x5f6e;  FindKeyStart=0x5f20;  FindKeyEnd  =0x5f31;  MapAddr  =0x2020;  Rc1H     =0x004a;  Rc1L     =0x004b;  EnsIrdChk=0x621b;  Cmd83Chk =0x6215;  SoftInt  =0x4004;  StackHigh=0x3ff;}bool cEmuRom11::InitSetup(void){  return DoMaps(false,0x8000) && CoreInitSetup();}bool cEmuRom11::UpdateSetup(const unsigned char *emm){  Set(0x0068,0x4B);  return CoreUpdateSetup(emm);}// -- cNagraDES ----------------------------------------------------------------class cNagraDES {private:  cDes des;protected:  void Decrypt(const unsigned char *data, const unsigned char *key, unsigned char *out, bool desmod=false);  void Crypt(const unsigned char *data, const unsigned char *key, unsigned char *out);  bool SigCheck(const unsigned char *block, const unsigned char *sig, const unsigned char *vkey, const int rounds);};void cNagraDES::Decrypt(const unsigned char *data, const unsigned char *key, unsigned char *out, bool desmod){  unsigned char cardkey[8];  memcpy(cardkey,key,8);  RotateBytes(cardkey,8);  memcpy(out,data,8);  if(!desmod) RotateBytes(out,8);  des.Des(out,cardkey,NAGRA_DES_DECR);  if(!desmod) RotateBytes(out,8);}void cNagraDES::Crypt(const unsigned char *data, const unsigned char *key, unsigned char *out){  unsigned char cardkey[8];  memcpy(cardkey,key,8);  RotateBytes(cardkey,8);  memcpy(out,data,8);  RotateBytes(out,8);  des.Des(out,cardkey,NAGRA_DES_ENCR);  RotateBytes(out,8);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -