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

📄 nagra1.cpp

📁 DVB-S的softcam源代码
💻 CPP
📖 第 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 <unistd.h>
#include <ctype.h>
#include "stdafx.h"
//#include <vdr/tools.h>
#include "asprintf.h"

#include "common.h"
#include "sc.h"
#include "system.h"
#include "misc.h"
#include "opts.h"

#include "debug.h"
#include "nagra.h"
#include "cpu.h"

#include "xnprintf.h"

#include "debug.h"
#include "nagra.h"
#include "cpu.h"

#define SYSTEM_NAME          "Nagra"
#define SYSTEM_PRI           -10

// -- cEmu ---------------------------------------------------------------------

#define MAX_COUNT 200000

class 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) {
        dee(printf("Updating PK keys\n"))
        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 {
        dee(printf("Updating PK keys failed. Used a correct EEPROM image for provider %04x ?\n",((select[0]<<8)|select[1])))
        break;
        }
      }
    }
  return false;
}

bool cEmu::MathMapHandler(void)
{
  dee(printf("Unsupported math call $%02x in ROM %d, please report\n",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=rand();
  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=rand();
  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)
{
  dee(printf("math call: $%02x\n",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: case 0x0f: case 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);
}

#ifndef TESTER

// -- 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);

⌨️ 快捷键说明

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