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

📄 tps.c

📁 VDR softcam plugin 0.9.1
💻 C
📖 第 1 页 / 共 3 页
字号:
  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:          case 0x1:          case 0x2:          case 0x3:          case 0x4:          case 0x5:          case 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:          case 0x9:          case 0xA:          case 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:          case 0xE:          case 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);  if((unsigned int)timestamp>0x7FFFFFFFUL) timestamp=0x7FFFFFFFL;  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;    }}cString cTpsKey::ToString(bool hide){  unsigned char tmp[60];  Put(&tmp[4]);  *((unsigned int *)tmp)=crc32_le(0,&tmp[4],sizeof(tmp)-4);  char str[420];  HexStr(str,tmp,sizeof(tmp));  return str;}// -- cTpsAuHook ---------------------------------------------------------------#ifndef TESTER#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);  };#endif //TESTER// -- cTpsKeys -----------------------------------------------------------------cTpsKeys tpskeys;#define AU_STREAM 0#define AU_TPSBIN 1int tpsAuMode=AU_STREAM;cTpsKeys::cTpsKeys(void):cStructListPlain<cTpsKey>("TPS keys","tps.cache",SL_READWRITE|SL_MISSINGOK|SL_WATCH|SL_NOPURGE),lastLoad(-LOADBIN_TIME),lastAu(-TPSAU_TIME){  first=last=0; algomem=0; loadlist=0;}cTpsKeys::~cTpsKeys(){  free(algomem);  delete loadlist;}const cTpsKey *cTpsKeys::GetKey(time_t t){  ListLock(false);  cTpsKey *k;  for(k=First(); k; k=Next(k)) if(t<k->Timestamp()) break;  ListUnlock();  return k;}const cTpsKey *cTpsKeys::GetV2Key(int id){  unsigned char tmp[56];  memset(tmp,0,sizeof(tmp));  cPlainKey *pk=keys.FindKey('V',id,MBC3('T','P','S'),16,0);  if(pk) {    pk->Get(&tmp[4+2*16]);    tmp[52+2]=1;    tmp[52+3]=0x1C;    cTpsKey *tk=new cTpsKey;    if(tk) {      tk->Set(tmp);      return tk;      }    }  else PRINTF(L_SYS_KEY,"missing %.4x TPS key\n",id);  return 0;}void cTpsKeys::Check(time_t now, int cardnum){  checkMutex.Lock();  if(first==0 && last==0 && Count()>0)    GetFirstLast();  if(now>0 && lastCheck.Elapsed()>CHECK_TIME) {    Purge(now);    lastCheck.Set();    }  bool nokey=now+2*3600>last;  if(tpsAuMode==AU_TPSBIN && lastLoad.Elapsed()>(nokey ? LOADBIN_TIME/60 : LOADBIN_TIME)) {    PRINTF(L_SYS_TPSAU,"loading "TPSBIN" triggered");    LoadBin();    if(now>0) Purge(now);    lastLoad.Set();    }  if(tpsAuMode==AU_STREAM && 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){  PRINTF(L_SYS_TPSAU,"purging TPS keylist");  bool del=false;  ListLock(true);  for(cTpsKey *k=First(); k;) {    cTpsKey *n=Next(k);    if(k->Timestamp()<now-3600) { Del(k); del=true; }    k=n;    }  ListUnlock();  if(del) {    GetFirstLast();    Modified();    }}void cTpsKeys::Join(cSimpleList<cTpsKey> *nlist){  ListLock(true);  cTpsKey *k;  while((k=nlist->First())) {    nlist->Del(k,false);    cTpsKey *p=First();    do {      if(!p) {        Add(k);        Modified();        break;        }      cTpsKey *n=Next(p);      if(k->Timestamp()==p->Timestamp()) {        p->Set(k);        Modified();        delete k;        break;        }      if(k->Timestamp()>p->Timestamp() && (!n || k->Timestamp()<n->Timestamp())) {        Add(k,p);        Modified();        break;        }      p=n;      } while(p);    }  ListUnlock();  delete nlist;  GetFirstLast();}cString cTpsKeys::Time(time_t t){  char str[32];  struct tm tm_r;  strftime(str,sizeof(str),"%b %e %Y %T",localtime_r(&t,&tm_r));  return str;}void cTpsKeys::GetFirstLast(void){  if(Count()>0) {    ListLock(false);    cTpsKey *k=First();    first=last=k->Timestamp();    for(; k; k=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)",Count(),*Time(first),*Time(last));    ListUnlock();    }  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]==0x79 && d[addr+1]==0x00 && d[addr+2]==0x79 && d[addr+3]==0x00)          kd=addr;//XXX this needs proper fix sometime...       else if(d[addr+1]==0x00 && d[addr+3]==0x00 && (d[addr+4]==3||d[addr+4]==2))          kd=addr;//XXX        else if(d[addr]==0x73 && d[addr+1]==0x25 && d[addr+2]==0xFA)          cb1=addr;        else if(d[addr]==0x64 && (d[addr+1]&0xB0)==0xB0 && d[addr+2]==0x24)          cb2=addr;        else if((d[addr]&0x60)==0x60 && (d[addr+1]&0xB0)==0xB0 && (d[addr+2]&0x20)==0x20)          cb3=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(cb1 && !cb2) cb2=addr;        else if(cb1 && cb2 && !cb3) cb3=addr;*/        }      }    }  if(!kd || !cb1 || !cb2 || !cb3) {    PRINTF(L_SYS_TPSAU,"couldn't locate all pointers in data section (%d,%d,%d,%d)",kd,cb1,cb2,cb3);    return false;    }  unsigned int end=(kd>cb1 && kd>cb2 && kd>cb3) ? kd : datahdr->dlen;  unsigned int off=min(cb1,min(cb2,cb3))-2;  PRINTF(L_SYS_TPSAU,"pointers in data section kd=%d cb1=%d cb2=%d cb3=%d - dlen=%d off=%d end=%d - cb1=%d cb2=%d cb3=%d",kd,cb1,cb2,cb3,datahdr->dlen,off,end,cb1-off,cb2-off,cb3-off);  RegisterAlgo3(d+off,cb1-off,cb2-off,cb3-off,end-off);  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;

⌨️ 快捷键说明

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