📄 parse.c
字号:
/* * 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 <stdlib.h>#include <stdio.h>#include <string.h>#include "parse.h"#include "misc.h"#include "log.h"// -----------------------------------------------------------------------------void SetSctLen(unsigned char *data, int len){ data[1]=(len>>8) | 0x70; data[2]=len & 0xFF;}static void SortNanos(unsigned char *dest, const unsigned char *src, int len){ int w=0, c=-1; while(1) { int n=0x100; for(int j=0; j<len;) { int l=src[j+1]+2; if(src[j]==c) { if(w+l>len) { PRINTF(L_GEN_ERROR,"sortnanos: sanity check failed. Exceeding memory area. Probably corrupted nanos!"); memset(dest,0,len); // zero out everything return; } memcpy(&dest[w],&src[j],l); w+=l; } else if(src[j]>c && src[j]<n) n=src[j]; j+=l; } if(n==0x100) break; c=n; }}// -- cProviders ---------------------------------------------------------------void cProviders::AddProv(cProvider *p){ if(p) Add(p);}cProvider *cProviders::FindProv(const unsigned char *data){ cProvider *p=First(); while(p) { if(p->MatchID(data)) break; p=Next(p); } return p;}cProvider *cProviders::MatchProv(const unsigned char *data){ cProvider *p=First(); while(p) { if(p->MatchEMM(data)) break; p=Next(p); } return p;}// -- cAssSct ------------------------------------------------------------------cAssSct::cAssSct(const unsigned char *Data){ data=Data;}// -- cAssembleData ------------------------------------------------------------cAssembleData::cAssembleData(const unsigned char *Data){ data=Data; curr=0;}void cAssembleData::SetAssembled(const unsigned char *Data){ Add(new cAssSct(Data)); curr=First();}const unsigned char *cAssembleData::Assembled(void){ const unsigned char *ret=0; if(First()) { if(curr) { ret=curr->Data(); curr=Next(curr); } } else { ret=data; data=0; } return ret;}// -- cIdSet -------------------------------------------------------------------cIdSet::cIdSet(void){ card=0;}cIdSet::~cIdSet(){ delete card;}void cIdSet::ResetIdSet(void){ delete card; card=0; Clear();}void cIdSet::SetCard(cCard *c){ delete card; card=c;}bool cIdSet::MatchEMM(const unsigned char *data){ return (card && card->MatchEMM(data)) || MatchProv(data);}bool cIdSet::MatchAndAssemble(cAssembleData *ad, int *updtype, cProvider **prov){ const unsigned char *data=ad->Data(); cProvider *p; if(card && card->MatchEMM(data)) { if(updtype) *updtype=card->UpdateType(data); if(prov) *prov=0; if(card->Assemble(ad)>=0) return true; } else if((p=MatchProv(data))) { if(updtype) *updtype=p->UpdateType(data); if(prov) *prov=p; if(p->Assemble(ad)>=0) return true; } return false;}// -- cProviderIrdeto ----------------------------------------------------------cProviderIrdeto::cProviderIrdeto(unsigned char pb, const unsigned char *pi){ provBase=pb; memcpy(provId,pi,sizeof(provId));}bool cProviderIrdeto::MatchID(const unsigned char *data){ const unsigned int mode=cParseIrdeto::AddrBase(data); return (mode<0x10 && mode==provBase);}bool cProviderIrdeto::MatchEMM(const unsigned char *data){ const unsigned int len=cParseIrdeto::AddrLen(data); const unsigned int mode=cParseIrdeto::AddrBase(data); return ( mode<0x10 && len<=sizeof(provId) && mode==provBase && (!len || !memcmp(&data[4],provId,len)));}unsigned long long cProviderIrdeto::ProvId(void){ return (provId[0]<<24)+(provId[1]<<16)+(provId[2]<<8)+provBase;}// -- cCardIrdeto --------------------------------------------------------------cCardIrdeto::cCardIrdeto(unsigned char hb, const unsigned char *hs){ hexBase=hb; memcpy(hexSer,hs,sizeof(hexSer));}bool cCardIrdeto::MatchEMM(const unsigned char *data){ const unsigned int len=cParseIrdeto::AddrLen(data); const unsigned int mode=cParseIrdeto::AddrBase(data); return ( mode>=0x10 && len<=sizeof(hexSer) && mode==hexBase && (!len || !memcmp(&data[4],hexSer,len)));}int cCardIrdeto::UpdateType(const unsigned char *data){ switch(cParseIrdeto::AddrLen(data)) { case 0: return 0; // global case 1: case 2: return 2; // shared default: return 3; // unique }}// -- cParseIrdeto -------------------------------------------------------------unsigned int cParseIrdeto::AddrLen(const unsigned char *data){ return data[3] & 0x07;}unsigned int cParseIrdeto::AddrBase(const unsigned char *data){ return data[3] >> 3;}// -- cProviderSeca ------------------------------------------------------------cProviderSeca::cProviderSeca(const unsigned char *pi, const unsigned char *s){ memcpy(provId,pi,sizeof(provId)); memcpy(sa,s,sizeof(sa));}bool cProviderSeca::MatchID(const unsigned char *data){ const unsigned char *id=cParseSeca::ProvIdPtr(data); return id && !memcmp(id,provId,sizeof(provId));}bool cProviderSeca::MatchEMM(const unsigned char *data){ return TID(data)==0x84 && !memcmp(SID(data),provId,sizeof(provId)) && !memcmp(SA(data),sa,sizeof(sa));}unsigned long long cProviderSeca::ProvId(void){ return (provId[0]<<8)+provId[1];}// -- cCardSeca ----------------------------------------------------------------cCardSeca::cCardSeca(const unsigned char *u){ memcpy(ua,u,sizeof(ua));}bool cCardSeca::MatchEMM(const unsigned char *data){ return TID(data)==0x82 && !memcmp(UA(data),ua,sizeof(ua));}// -- cParseSeca ---------------------------------------------------------------int cParseSeca::CmdLen(const unsigned char *data){ struct SecaCmd *s=(struct SecaCmd *)data; return ((s->cmdLen1&0x0f)<<8) | s->cmdLen2;}int cParseSeca::Payload(const unsigned char *data, const unsigned char **payload){ int l; switch(TID(data)) { case 0x80: case 0x81: l=sizeof(struct SecaEcm); break; case 0x82: l=sizeof(struct SecaEmmUnique); break; case 0x84: l=sizeof(struct SecaEmmShared); break; default: return -1; } if(payload) *payload=&data[l]; return CmdLen(data)-l+sizeof(struct SecaCmd);}int cParseSeca::SysMode(const unsigned char *data){ switch(TID(data)) { case 0x80: case 0x81: return ((struct SecaEcm *)data)->sm; break; case 0x82: return ((struct SecaEmmUnique *)data)->sm; break; case 0x84: return ((struct SecaEmmShared *)data)->sm; break; default: return -1; }}int cParseSeca::KeyNr(const unsigned char *data){ switch(TID(data)) { case 0x80: case 0x81: return ((struct SecaEcm *)data)->keyNr; break; case 0x82: return ((struct SecaEmmUnique *)data)->keyNr; break; case 0x84: return ((struct SecaEmmShared *)data)->keyNr; break; default: return -1; }}const unsigned char *cParseSeca::ProvIdPtr(const unsigned char *data){ switch(TID(data)) { case 0x80: case 0x81: return ((struct SecaEcm *)data)->id; case 0x82: return ((struct SecaEmmUnique *)data)->id; case 0x84: return ((struct SecaEmmShared *)data)->id; } return 0;}int cParseSeca::ProvId(const unsigned char *data){ const unsigned char *id=cParseSeca::ProvIdPtr(data); return id ? (id[0]<<8)+id[1] : -1;}// -- cProviderViaccess --------------------------------------------------------cProviderViaccess::cProviderViaccess(void){ sharedEmm=0; sharedLen=sharedToggle=0;}cProviderViaccess::cProviderViaccess(const unsigned char *id, const unsigned char *s){ sharedEmm=0; sharedLen=sharedToggle=0; memcpy(ident,id,sizeof(ident)); ident[2]&=0xf0; memcpy(sa,s,sizeof(sa));}cProviderViaccess::~cProviderViaccess(){ free(sharedEmm);}bool cProviderViaccess::MatchID(const unsigned char *data){ const unsigned char *id=cParseViaccess::ProvIdPtr(data); return id && id[0]==ident[0] && id[1]==ident[1] && (id[2]&0xf0)==ident[2];}bool cProviderViaccess::MatchEMM(const unsigned char *data){ switch(data[0]) { case 0x8e: if(memcmp(&data[3],sa,sizeof(sa)-1)) break; if((data[6]&2)==0) return sharedEmm && MatchID(sharedEmm); // fall through case 0x8c: case 0x8d: return MatchID(data); } return false;}unsigned long long cProviderViaccess::ProvId(void){ return (ident[0]<<16)+(ident[1]<<8)+ident[2];}int cProviderViaccess::UpdateType(const unsigned char *data){ switch(data[0]) { case 0x8e: return 2; // shared case 0x8c: case 0x8d: default: return 0; // global }}int cProviderViaccess::Assemble(cAssembleData *ad){ const unsigned char *data=ad->Data(); int len=SCT_LEN(data); switch(data[0]) { case 0x8C: case 0x8D: if(data[0]!=sharedToggle) { free(sharedEmm); sharedLen=len; sharedEmm=(unsigned char *)malloc(len); if(sharedEmm) memcpy(sharedEmm,data,sharedLen); sharedToggle=data[0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -