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

📄 tps.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 3 页
字号:
    }  return sections>=6;}bool cOpenTVModule::Decompress(void){  comp_header_t comp;  comp.magic=UINT32_BE(mem);  comp.csize=UINT32_BE(mem+4);  comp.dsize=UINT32_BE(mem+8);  comp.usize=UINT32_BE(mem+12);  comp.end  =UINT8_BE(mem+16);  if((COMP_SECTION_HDR!=comp.magic) || (comp.dsize<=comp.csize) ||      (comp.usize>comp.dsize) || (comp.end>=1) || (comp.csize<=17))    return true;  unsigned char *decomp=MALLOC(unsigned char,comp.dsize);  if(!decomp || !DoDecompress(decomp,mem+17,comp.dsize,comp.csize-17,comp.usize))    return false;  free(mem);  mem=decomp; modlen=comp.dsize;  return true;}#define BYTE() ((odd)?((in_ptr[0]&0x0F)|(in_ptr[1]&0xF0)):in_ptr[0])#define NIBBLE(__v) \  do { \    odd^=1; \    if(odd) __v=in_ptr[0]&0xF0; \    else {  __v=(in_ptr[0]&0xF)<<4; in_ptr++; } \    } while(0)bool cOpenTVModule::DoDecompress(unsigned char *out_ptr, const unsigned char *in_ptr, int dsize, int data_size, int usize){  if(usize==0) return false;  const unsigned char *data_start=in_ptr;  unsigned char *out_start=out_ptr;  unsigned char *out_end=out_ptr+usize;  int odd=0;  while(1) {    unsigned char mask=BYTE(); in_ptr++;    for(int cnt=8; cnt>0; mask<<=1,cnt--) {      if(mask&0x80) {        out_ptr[0]=BYTE(); in_ptr++;        out_ptr++;        }      else {        int off=0, len=0;        unsigned char cmd=BYTE(); in_ptr++;        switch(cmd>>4) {          case 0x0 ... 0x6:            off=((cmd&0xF)<<8)+BYTE(); in_ptr++;            len=((cmd>>4)&0x7)+3;            break;          case 0x7:            {            unsigned char high=BYTE(); in_ptr++;            off=((high&0x7F)<<8)+BYTE(); in_ptr++;            if((cmd==0x7F) && (high&0x80)) {              len=BYTE(); in_ptr++;              if(len==0xFF) {                len=BYTE(); in_ptr++;                len=((len<<8)+BYTE()+0x121)&0xFFFF; in_ptr++;                }              else len+=0x22;              }            else {              len=((cmd&0x0F)<<1)+3; if(high&0x80) len++;              }            break;            }          case 0x8 ... 0xB:            if(cmd&0x20) NIBBLE(off); else off=0;            off=(off<<1)|(cmd&0x1F); len=2;            break;          case 0xC:            off=cmd&0x0F; len=3;            break;          case 0xD ... 0xF:            NIBBLE(off);            off|=cmd&0x0F; len=((cmd>>4)&0x3)+2;            break;          }        const unsigned char *from=out_ptr-(off+1);        if(from<out_start || from>=out_ptr || len>(out_end-out_ptr)) {          PRINTF(L_SYS_TPSAU,"length mismatch in OpenTV decompress");          return false;          }        while(--len>=0) *out_ptr++=*from++;        }      if(out_end<=out_ptr) {        if(out_end!=out_ptr) {          PRINTF(L_SYS_TPSAU,"pointer mismatch in OpenTV decompress");          return false;          }        int len=out_start+dsize-out_ptr;        if(len>0) memmove(out_ptr,data_start+(data_size-(dsize-usize)),len);        return true;        }      }    }}#undef BYTE#undef NIBBLE// -- cTpsKey ------------------------------------------------------------------cTpsKey::cTpsKey(void){  timestamp=0;}void cTpsKey::Set(const cTpsKey *k){  timestamp=k->timestamp;  opmode=k->opmode;  memcpy(step,k->step,sizeof(step));}void cTpsKey::Set(const unsigned char *mem){  timestamp=*((unsigned int *)mem);  opmode=mem[52+3];  for(int i=0; i<3; i++) {    memcpy(step[i].key,&mem[4+i*16],16);    step[i].mode=mem[52+i];    }}void cTpsKey::Put(unsigned char *mem) const{  *((unsigned int *)mem)=timestamp;  mem[52+3]=opmode;  for(int i=0; i<3; i++) {    memcpy(&mem[4+i*16],step[i].key,16);    mem[52+i]=step[i].mode;    }}// -- cTpsAuHook ---------------------------------------------------------------#define BUFF_SIZE 20000class cTpsAuHook : public cLogHook {private:  cOpenTVModule *mod;  int pmtpid, aupid;public:  cTpsAuHook(void);  ~cTpsAuHook();  virtual void Process(int pid, unsigned char *data);  };// -- cTpsKeys -----------------------------------------------------------------cTpsKeys tpskeys;cTpsKeys::cTpsKeys(void):cLoader("TpsAu"),lastLoad(-LOADBIN_TIME),lastAu(-TPSAU_TIME){  list=new cSimpleList<cTpsKey>;  first=last=0; algomem=0;}cTpsKeys::~cTpsKeys(){  delete list;  free(algomem);}const cTpsKey *cTpsKeys::GetKey(time_t t){  cMutexLock lock(this);  for(cTpsKey *k=list->First(); k; k=list->Next(k))    if(t<k->Timestamp()) return k;  return 0;}void cTpsKeys::Check(time_t now, int cardnum){  checkMutex.Lock();  if(first==0 && last==0 && list->Count()>0)    GetFirstLast();  if(now>0 && lastCheck.Elapsed()>CHECK_TIME) {    Purge(now);    lastCheck.Set();    }  bool nokey=now+2*3600>last;/*  if(lastLoad.Elapsed()>(nokey ? LOADBIN_TIME/60 : LOADBIN_TIME)) {    PRINTF(L_SYS_TPSAU,"loading "TPSBIN" triggered");    LoadBin();    if(now>0) Purge(now);    lastLoad.Set();    }*/  if(lastAu.Elapsed()>(nokey ? TPSAU_TIME/60 : TPSAU_TIME)) {    if(ScSetup.AutoUpdate>0) {      PRINTF(L_SYS_TPSAU,"TPS AU triggered");      if(!cSoftCAM::TriggerHook(cardnum,HOOK_TPSAU)) {        cTpsAuHook *hook=new cTpsAuHook;        cSoftCAM::AddHook(cardnum,hook);        PRINTF(L_SYS_TPSAU,"TPS AU hook added");        }      }    lastAu.Set();    }  checkMutex.Unlock();}void cTpsKeys::Purge(time_t now){  cMutexLock lock(this);  PRINTF(L_SYS_TPSAU,"purging TPS keylist");  bool del=false;  for(cTpsKey *k=list->First(); k;) {    cTpsKey *n=list->Next(k);    if(k->Timestamp()<now-3600) { list->Del(k); del=true; }    k=n;    }  if(del) {     GetFirstLast();    Modified();    cLoaders::SaveCache();    }}void cTpsKeys::Join(cSimpleList<cTpsKey> *nlist){  cMutexLock lock(this);  cTpsKey *k;  while((k=nlist->First())) {    nlist->Del(k,false);    cTpsKey *p=list->First();    do {      if(!p) {        list->Add(k);        Modified();        break;        }      cTpsKey *n=list->Next(p);      if(k->Timestamp()==p->Timestamp()) {        p->Set(k);        Modified();        delete k;        break;        }      if(k->Timestamp()>p->Timestamp() && (!n || k->Timestamp()<n->Timestamp())) {        list->Add(k,p);        Modified();        break;        }      p=n;      } while(p);    }  delete nlist;  GetFirstLast();  cLoaders::SaveCache();}cString cTpsKeys::Time(time_t t){  char str[32];  struct tm tm_r;  strftime(str,sizeof(str),"%b %e %T",localtime_r(&t,&tm_r));  return str;}void cTpsKeys::GetFirstLast(void){  if(list->Count()>0) {    cTpsKey *k=list->First();    first=last=k->Timestamp();    for(; k; k=list->Next(k)) {      if(k->Timestamp()<last)        PRINTF(L_SYS_TPSAU,"TPS keys not in accending order!");      last=k->Timestamp();      }    PRINTF(L_SYS_TPS,"%d TPS keys available (from %s to %s)",list->Count(),*Time(first),*Time(last));    }  else {    last=first=0;    PRINTF(L_SYS_TPS,"no TPS keys available");    }}bool cTpsKeys::ProcessAu(const cOpenTVModule *mod){  PRINTF(L_SYS_TPSAU,"processing TPS AU data");  const code_header_t *codehdr=mod->CodeHdr();  const data_header_t *datahdr=mod->DataHdr();  const unsigned char *c=codehdr->code;  const unsigned char *d=datahdr->data;  unsigned int kd=0, cb1=0, cb2=0, cb3=0;  for(unsigned int i=0; i<codehdr->size; i++) {    if(c[i] == 0x81) { // PushEA DS:$xxxx      unsigned int addr=(c[i+1]<<8)|c[i+2];      if(addr<(datahdr->dlen-3)) {        if(d[addr+1]==0x00 && d[addr+3]==0x00 && d[addr+4]==3) kd=addr;        else if(d[addr]==0x73 && d[addr+1]==0x25) {          static const unsigned char scan1[] = { 0x28, 0x20, 0x20, 0xC0 };          for(int j=2; j < 0xC; j++)            if(!memcmp(&d[addr+j],scan1,sizeof(scan1))) { cb1=addr; break; }          }        else if((d[addr]&0xF0)==0x60 && (d[addr+1]&0xF0)==0xB0) {          int vajw = (int)(((~(d[addr]&0x0F))<<4)|(d[addr+1]&0x0F));          unsigned char hits=0;          for(int j=2; j < 0x30; j++) {            int vld = ((d[addr+j]&0x0F)<<4)|(d[addr+j+1]&0x0F);            if((d[addr+j]&0xF0)==0x20 && (d[addr+j+1]&0xF0)==0x70) {              int val=vajw+vld;              if(val==3 || val==4 || val==5) hits++;              }            }          if(hits==3) cb3=addr;          else if(hits==2) cb2=addr;          }        }      }    }  if(!kd || !cb1 || !cb2 || !cb3) {    PRINTF(L_SYS_TPSAU,"couldn't locate all pointers in data section");    return false;    }  RegisterAlgo3(d,cb1,cb2,cb3,kd);  const unsigned char *data=&d[kd];  int seclen, numkeys;  seclen=data[0] | (data[1]<<8);  numkeys=data[2] | (data[3]<<8);  int algo=data[4];  int mkidx=data[5]&7;  unsigned char *sec[7];  sec[0]=(unsigned char *)data+6;  for(int i=1; i<6; i++) sec[i]=sec[i-1]+seclen;  sec[6]=sec[5]+numkeys;  unsigned char key[16];  cPlainKey *pk=keys.FindKey('V',0x7c00,MBC3('M','K',mkidx),16);  if(!pk) {    PRINTF(L_SYS_KEY,"missing V 7C00 TPSMK%d key",mkidx);    return false;    }  pk->Get(key);  if(sec[6]>=d+datahdr->dlen) {    PRINTF(L_SYS_TPSAU,"section 5 exceeds buffer");    return false;    }  int keylen=0;  for(int i=0; i<numkeys; i++) keylen+=sec[5][i];  keylen=(keylen+15)&~15;  if(sec[6]+keylen>=d+datahdr->dlen) {    PRINTF(L_SYS_TPSAU,"section 6 exceeds buffer");    return false;    }  for(int i=0; i<keylen; i+=16) TpsDecrypt(&sec[6][i],algo,key);  cSimpleList<cTpsKey> *nlist=new cSimpleList<cTpsKey>;  for(int i=0; i<seclen; i++) {    static const unsigned char startkey[] = { 0x01,0x01 };    static const unsigned char startaes[] = { 0x09,0x10 };    static const unsigned char startse[] = { 0x0a,0x10 };    unsigned char tmp[56];    tmp[0]=sec[0][i];    tmp[1]=sec[1][i];    tmp[2]=sec[2][i];    tmp[3]=sec[3][i];    if(CheckFF(tmp,4)) continue;    int keyid=sec[4][i];    int keylen=sec[5][keyid];    if(keylen<32) continue;    const unsigned char *tkey=sec[6];    for(int j=0; j<keyid; j++) tkey+=sec[5][j];    unsigned char ke[128];    if(keylen!=45) {      if(!Handle80008003(tkey,keylen,ke)) continue;      tkey=ke;      }    if(memcmp(tkey,startkey,sizeof(startkey))) continue;    tmp[52]=0;    tmp[53]=tkey[5]; //tkey[4];    tmp[54]=1;       //tkey[5];    tmp[55]=0x1c;    tkey+=9;    if(memcmp(tkey,startaes,sizeof(startaes))) continue;    memset(&tmp[4+ 0],0,16);

⌨️ 快捷键说明

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