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

📄 shl.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 2 页
字号:
  for(int i=0; i<n; i+=8)    DES_ecb_encrypt((DES_cblock *)&data[i],(DES_cblock *)&data[i],&sched,DES_DECRYPT);  if(r) { // possible last incomplete block    DES_cblock out;    DES_ecb_encrypt((DES_cblock *)&data[n],&out,&sched,DES_DECRYPT);    memcpy(&data[n],out,r);    }}// -- SHL provider -------------------------------------------------------------struct ShlProv {  const char *name;  unsigned short id;  bool hasXor;  int filters, pidRange;  const unsigned short pids[128];  const unsigned char xorTab[16];  };static const struct ShlProv prov[] = {/*  { "FreeX",0x4A90,false,40,0x1300,    { 0x1389,0x138a,0x138b,0x138c,0x138d,0x138e,0x138f,0x1390,      0x1391,0x1392,0x1393,0x1394,0x1395,0x1396,0x1397,0x1398,      0x1399,0x139a,0x139b,0x139c,0x13a4,0x13a5,0x13a6,0x13a7,      0x13a8,0x13a9,0x13bf,0x13c0,0x13c1,0x13c2,0x13c3,0x13c4,      0x13c5,0x13c6,0x13c7,0x13c8,0x13c9,0x13ca,0x13cb,0x13cc },    {} },*/  { "FullX-2",0x4A90,false,128,0x0000,    { 0x0bb9,0x0bba,0x0bbc,0x0bbf,0x0bc0,0x0bc2,0x0bc3,0x0bc4,      0x0bc7,0x0bc8,0x0bc9,0x0bcc,0x0bcd,0x0bce,0x0bcf,0x0bd0,      0x0bd3,0x0bd5,0x0bd6,0x0bd7,0x0bd8,0x0bd9,0x0bdb,0x0bdd,      0x0bdf,0x0be0,0x0be1,0x0be2,0x0be3,0x0be4,0x0be5,0x0be6,      0x0be7,0x0be8,0x0be9,0x0bea,0x1784,0x177c,0x178a,0x1796,      0x1774,0x1772,0x17a2,0x1783,0x1792,0x177b,0x1775,0x179b,      0x1794,0x1789,0x1778,0x1799,0x1793,0x1797,0x1782,0x1779,      0x179e,0x1787,0x178d,0x177d,0x1771,0x1791,0x1776,0x1788,      0x178f,0x179c,0x177e,0x178b,0x1785,0x1781,0x0bc5,0x17a1,      0x0bbe,0x179f,0x0bdc,0x1780,0x0bca,0x0bd2,0x0bbd,0x179a,      0x1773,0x178e,0x1795 },    {} },  { "FullX",0x6997,true,60,0x1700,    { 0x178e,0x178f,0x1783,0x1780,0x1776,0x177b,0x1772,0x1779,      0x1785,0x179e,0x1791,0x1771,0x177e,0x1793,0x1778,0x179a,      0x17a2,0x17a1,0x178d,0x1787,0x1797,0x1796,0x177d,0x1781,      0x1799,0x1794,0x179b,0x1784,0x1795,0x177c,0x1782,0x179c,      0x1773,0x1788,0x1789,0x178b,0x179f,0x1775,0x1792,0x1774,      0x178a },    { 0x4E,0x9E,0x5C,0xFA,0x62,0x80,0x4C,0x86,0x56,0xDF,0x7E,0x03,0x9B,0x05,0xB2,0xE7 } },  { "DP",0x6996,true,48,0x1300,    { 0x1389,0x138a,0x138b,0x138c,0x138d,0x138e,0x138f,0x1390,      0x1391,0x1392,0x1393,0x1394,0x1395,0x1396,0x1397,0x1398,      0x1399,0x139a,0x139b,0x139c,0x13a4,0x13a5,0x13a6,0x13a7,      0x13a8,0x13a9,0x13bf,0x13c0,0x13c1,0x13c2,0x13c3,0x13c4,      0x13c5,0x13c6,0x13c7,0x13c8,0x13c9,0x13ca,0x13cb,0x13cc },    { 0x30,0x61,0xD7,0xC0,0x8E,0x41,0x2C,0xB9,0xAA,0x50,0xB2,0xF4,0x5B,0x2E,0x84,0xCF } }  };static const struct ShlProv *FindProv(unsigned short id){  for(unsigned int i=0; i<(sizeof(prov)/sizeof(struct ShlProv)); i++)    if(prov[i].id==id) return &prov[i];  return 0;}// -- cSystemShl ---------------------------------------------------------------#define ENC_OFF 12 // encrypted bytes offset#define ENC_LEN 24 // encrypted bytes length#define KEY_OFF   7#define PID_OFF   15#define EMASK_OFF 8#define OMASK_OFF 12#define CW_OFF    17class cSystemShl : public cSystem, private cShl {private:  cPidHopper *ph;  int prvId;  bool hasPrvId;  cMutex mutex;  cCondVar wait;  //  void ProcessCw(const unsigned char *data, int prvId, const unsigned char *xorTable);public:  cSystemShl(void);  virtual ~cSystemShl();  virtual bool ProcessECM(const cEcmInfo *ecm, unsigned char *source);  virtual void ProcessEMM(int pid, int caid, unsigned char *buffer);  };cSystemShl::cSystemShl(void):cSystem(SYSTEM_NAME,SYSTEM_PRI){  ph=0; hasPrvId=false;  hasLogger=needsLogger=true; maxEcmTry=20;}cSystemShl::~cSystemShl(){  delete ph;}bool cSystemShl::ProcessECM(const cEcmInfo *ecm, unsigned char *source){  static const unsigned char tester[] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF };  // in old SHL algo ECM starts with 12 0xFF  if(SCT_LEN(source)<(ENC_OFF+ENC_LEN+3)) {    PRINTF(L_SYS_VERBOSE,"short ecm");    return false;    }  if(memcmp(tester,&source[3],sizeof(tester))) { // new SHL    mutex.Lock();    if(!hasPrvId) {      wait.TimedWait(mutex,500); // wait for provider ID      if(!hasPrvId) {        PRINTF(L_SYS_ECM,"no provider ID (logger enabled?)");        mutex.Unlock();        return false;        }      }    const struct ShlProv *prv=FindProv(prvId);    if(!prv) {      PRINTF(L_SYS_ECM,"provider %04x not supported",prvId);      mutex.Unlock();      return false;      }    mutex.Unlock();    if(!ph) {      PRINTF(L_SYS_ECM,"using card %d",CardNum());      ph=new cPidHopper(CardNum(),prv->filters);      if(!ph) {        PRINTF(L_SYS_ECM,"no pid hopper");        return false;        }#if 1      unsigned int l=min((int)(sizeof(prv->pids)/sizeof(unsigned short)),prv->filters);      for(unsigned int i=0; i<l; i++) {        if(prv->pids[i]<=0) break;        ph->AddPid(prv->pids[i]);        }#endif      }    int pid=ecm->ecm_pid;    int now=time_ms();    unsigned char buff[4096];    unsigned char emask=0, omask=0;    memcpy(buff+1,source,SCT_LEN(source)); buff[0]=0;    LBSTARTF(L_SYS_VERBOSE);    LBPUT("chain 0x%04x [%d] ",pid,SCT_LEN(source)+1);    while(1) {      unsigned char *ptr=buff;      if(ptr[0]!=0) { // decrypt whole payload        LBPUT("PES");        unsigned char test[8];        memcpy(test,ptr,sizeof(test)); Decode(test,sizeof(test));        if(test[0]!=source[0] && (ptr[0]==0x11 || ptr[0]==0x12)) {     // Section is available at section_pointer offset.          SetKey(&ptr[KEY_OFF+1]);             // Use the same key and pid offsets which you use          Decode(&ptr[PID_OFF+1],183-PID_OFF); // for normal SHL section data decoding.          ptr+=ptr[0]+1;          if(ptr[0]==0x91 && SCT_LEN(ptr)==11) ptr+=11;          LBPUT("s");          }        else if(test[0]!=source[0] && ptr[0]==0x0a) {          SetKey(&ptr[1]);          Decode(&ptr[9],183-9);          ptr+=ptr[0]+1;          LBPUT("a");          }        else {          Decode(ptr,184);          LBPUT("n");          }        LBPUT(" ");        }      else {          // decrypt data only        LBPUT("SCT ");        ptr++;        SetKey(&ptr[KEY_OFF]);        Decode(&ptr[PID_OFF],SCT_LEN(ptr)-PID_OFF);        }      if(ptr[0]!=source[0]) {        LBPUT("wrong section %02x != %02x",ptr[0],source[0]);        return false;        }      pid=(ptr[PID_OFF]<<8)+ptr[PID_OFF+1];      if(pid==0x1FFF) {     // finished        if(prv->hasXor) ProcessCw(ptr,prv->id,prv->xorTab);        else {          for(int i=0; i<8; i++) {            const int m=1<<(7-i);            if(!(emask & m)) cw[i  ]=ptr[CW_OFF+i];            if(!(omask & m)) cw[i+8]=ptr[CW_OFF+i+8];            }          }        LBPUT("done");        ph->CutOff(now);        return true;        }      else {                // next hop        if(prv->hasXor) ProcessCw(ptr,prv->id,prv->xorTab);        else {          emask=ptr[EMASK_OFF];          omask=ptr[OMASK_OFF];          memcpy(cw,&ptr[CW_OFF],16);          }        LBPUT("0x%04x ",pid);#if 1        if(prv->pidRange && (pid&0xFF00)!=prv->pidRange) {          LBPUT("wrong pid range");          return false;          }#endif        int n=ph->Read(pid,now,buff,sizeof(buff),1000);        if(n<CW_OFF+16+1) {          LBPUT("read failed");          return false;          }        LBPUT("[%d] ",n);        }      }    LBEND();    }  else { // old SHL    static const unsigned char signature[] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF };    source+=ENC_OFF+3; // here's the DES crypto content    cPlainKey *pk=0;    cKeySnoop ks(this,'Z',ecm->provId,0x00);    unsigned char key[8];    while((pk=keys.FindKey('Z',ecm->provId,0x00,sizeof(key),pk))) {      pk->Get(key);      SetKey(key);      Decode(source,ENC_LEN);      unsigned char sigbuf[8];      memcpy(&sigbuf[0],&source[0],2);      memcpy(&sigbuf[2],&source[18],6);      if(!memcmp(sigbuf,signature,sizeof(sigbuf))) {        memcpy(cw,&source[2],16);        ks.OK(pk);        return true;        }      }    }  return false;}void cSystemShl::ProcessCw(const unsigned char *data, int prvId, const unsigned char *xorTable){  if(SCT_LEN(data)<150) {    PRINTF(L_SYS_VERBOSE,"data is too short");    return;    }  const unsigned int dataStart=data[33];  if((dataStart+35)>184) {    PRINTF(L_SYS_VERBOSE,"data broken (%d)",dataStart);    return;    }  const unsigned int xorVal=data[dataStart+35];  const unsigned int emask =data[dataStart+34];  const unsigned int omask =data[dataStart+33];  for(int i=0; i<8; i++) {    const unsigned int m=1<<i;    if(emask & m) cw[i  ]=data[CW_OFF+i  ]^xorVal^xorTable[i  ];    if(omask & m) cw[i+8]=data[CW_OFF+8+i]^xorVal^xorTable[i+8];    }}void cSystemShl::ProcessEMM(int pid, int caid, unsigned char *buffer){  int n=SCT_LEN(buffer)-3;  buffer+=3;  for(int i=0; i<n;) {    switch(buffer[i]) {      case 0x0a:        mutex.Lock();        prvId=WORD(buffer,i+2,0xFFFF);        if(!hasPrvId) {          const struct ShlProv *prv=FindProv(prvId);          PRINTF(L_SYS_EMM,"provider id %04x (%s)\n",prvId,prv ? prv->name:"unknown");          wait.Broadcast();          }        hasPrvId=true;        mutex.Unlock();        break;      case 0x08:      case 0x0b:      case 0x09:      case 0x06:      case 0x02:      case 0x30:      case 0x07:        break;      default:        HEXDUMP(L_SYS_EMM,&buffer[i+2],buffer[i+1],"unknown nano: %02x:",buffer[i]);        break;      }    i+=buffer[i+1]+2;    }}// -- cSystemLinkShl -----------------------------------------------------------class cSystemLinkShl : public cSystemLink {public:  cSystemLinkShl(void);  virtual bool CanHandle(unsigned short SysId);  virtual cSystem *Create(void) { return new cSystemShl; }  };static cSystemLinkShl staticInit;cSystemLinkShl::cSystemLinkShl(void):cSystemLink(SYSTEM_NAME,SYSTEM_PRI){  Feature.NeedsKeyFile();}bool cSystemLinkShl::CanHandle(unsigned short SysId){  SysId&=0xFFF0;  return SYSTEM_CAN_HANDLE(SysId);}

⌨️ 快捷键说明

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