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

📄 st20.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 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 <unistd.h>#include <string.h>#include <vdr/tools.h>#include "log-viaccess.h"#include "st20.h"#include "helper.h"#include "misc.h"//#define SAVE_DEBUG // add some (slow) failsafe checks and stricter emulation#define INVALID_VALUE 	0xCCCCCCCC#define ERRORVAL	0xDEADBEEF#define MININT		0x7FFFFFFF#define MOSTPOS		0x7FFFFFFF#define MOSTNEG		0x80000000#ifndef SAVE_DEBUG#define POP() stack[(sptr++)&STACKMASK]#else#define POP() ({ int __t=stack[sptr&STACKMASK]; stack[(sptr++)&STACKMASK]=INVALID_VALUE; __t; })#endif#define PUSH(v) do { int __v=(v); stack[(--sptr)&STACKMASK]=__v; } while(0)#define DROP(n) sptr+=n#define AAA stack[sptr&STACKMASK]#define BBB stack[(sptr+1)&STACKMASK]#define CCC stack[(sptr+2)&STACKMASK]#define GET_OP()        operand|=op1&0x0F#define CLEAR_OP()      operand=0#define JUMP(x)         Iptr+=(x)#define POP64()         ({ unsigned int __b=POP(); ((unsigned long long)POP()<<32)|__b; })#define PUSHPOP(op,val) do { int __a=val; AAA op##= (__a); } while(0)#ifndef SAVE_DEBUG#define RB(off) UINT8_LE(Addr(off))#define RW(off) UINT32_LE(Addr(off))#define WW(off,val) BYTE4_LE(Addr(off),val)#else#define RB(off) ReadByte(off)#define RW(off) ReadWord(off)#define WW(off,val) WriteWord(off,val)#endif#define LOG_OP(op) do { if(v) LogOp(op); } while(0)// -- cST20 --------------------------------------------------------------------cST20::cST20(void){  flash=ram=0;  loglb=new cLineBuff(128);}cST20::~cST20(){  free(flash);  free(ram);  delete loglb;}void cST20::SetFlash(unsigned char *m, int len){  free(flash);  flash=MALLOC(unsigned char,len);  if(flash && m) memcpy(flash,m,len);  else memset(flash,0,len);  flashSize=len;}void cST20::SetRam(unsigned char *m, int len){  free(ram);  ram=MALLOC(unsigned char,len);  if(ram && m) memcpy(ram,m,len);  else memset(ram,0,len);  ramSize=len;}void cST20::Init(unsigned int IPtr, unsigned int WPtr){  Wptr=WPtr; Iptr=IPtr;  memset(stack,INVALID_VALUE,sizeof(stack)); sptr=STACKMAX-3;  memset(iram,0,sizeof(iram));  verbose=LOG(L_SYS_DISASM);}void cST20::SetCallFrame(unsigned int raddr, int p1, int p2, int p3){  Wptr-=16;  WriteWord(Wptr,raddr); // RET  WriteWord(Wptr+4,0);  WriteWord(Wptr+8,0);  WriteWord(Wptr+12,p1);  WriteWord(Wptr+16,p2);  WriteWord(Wptr+20,p3);  SetReg(AREG,raddr);    // RET}unsigned int cST20::GetReg(int reg) const{  switch(reg) {    case IPTR: return Iptr;    case WPTR: return Wptr;    case AREG: return AAA;    case BREG: return BBB;    case CREG: return CCC;    default:   PRINTF(L_SYS_ST20,"getreg: unknown reg"); return ERRORVAL;    }}void cST20::SetReg(int reg, unsigned int val){  switch(reg) {    case IPTR: Iptr=val; return;    case WPTR: Wptr=val; return;    case AREG: AAA=val; return;    case BREG: BBB=val; return;    case CREG: CCC=val; return;    default:   PRINTF(L_SYS_ST20,"setreg: unknown reg"); return;    }}unsigned char *cST20::Addr(unsigned int off){  switch(off) {    case FLASHS ... FLASHE:#ifndef SAVE_DEBUG      return &flash[off-FLASHS];#else      off-=FLASHS; if(off<flashSize && flash) return &flash[off]; break;#endif    case RAMS ... RAME:#ifndef SAVE_DEBUG      return &ram[off-RAMS];#else      off-=RAMS; if(off<ramSize && ram) return &ram[off]; break;#endif    case IRAMS ... IRAME:      return &iram[off-IRAMS];    }#ifndef SAVE_DEBUG  invalid=ERRORVAL; return (unsigned char *)&invalid;#else  return 0;#endif}unsigned int cST20::ReadWord(unsigned int off){#ifndef SAVE_DEBUG  return UINT32_LE(Addr(off));#else  unsigned char *addr=Addr(off);  return addr ? UINT32_LE(addr) : ERRORVAL;#endif}unsigned short cST20::ReadShort(unsigned int off){#ifndef SAVE_DEBUG  return UINT16_LE(Addr(off));#else  unsigned char *addr=Addr(off);  return addr ? UINT16_LE(addr) : ERRORVAL>>16;#endif}unsigned char cST20::ReadByte(unsigned int off){#ifndef SAVE_DEBUG  return UINT8_LE(Addr(off));#else  unsigned char *addr=Addr(off);  return addr ? UINT8_LE(addr) : ERRORVAL>>24;#endif}void cST20::WriteWord(unsigned int off, unsigned int val){#ifndef SAVE_DEBUG  BYTE4_LE(Addr(off),val);#else  unsigned char *addr=Addr(off);  if(addr) BYTE4_LE(addr,val);#endif}void cST20::WriteShort(unsigned int off, unsigned short val){#ifndef SAVE_DEBUG  BYTE2_LE(Addr(off),val);#else  unsigned char *addr=Addr(off);  if(addr) BYTE2_LE(addr,val);#endif}void cST20::WriteByte(unsigned int off, unsigned char val){#ifndef SAVE_DEBUG  BYTE1_LE(Addr(off),val);#else  unsigned char *addr=Addr(off);  if(addr) BYTE1_LE(addr,val);#endif}#define OP_COL 20void cST20::LogOpOper(int op, int oper){  const static char *cmds[] = { "j","ldlp",0,"ldnl","ldc","ldnlp",0,"ldl","adc","call","cj","ajw","eqc","stl","stnl",0 };  const static char flags[] = {  3,  0,    0, 0,     1,    0,     0, 0,    1,    3,     3,   0,    1,    0,    0,    0 };  if(oper==0) loglb->Printf("%08X %02X",Iptr-1,op);  else        loglb->Printf("%02X",op);  oper|=op&0xF; op>>=4;  if(!cmds[op]) return;  int n=loglb->Length();  if(flags[op]&2) oper+=Iptr;  if(flags[op]&1) loglb->Printf("%*s%-5s $%-8X ",max(OP_COL-n,1)," ",cmds[op],oper);  else            loglb->Printf("%*s%-5s  %-8d ",max(OP_COL-n,1)," ",cmds[op],oper);}void cST20::LogOp(char *op){  int n=loglb->Length();  loglb->Printf("%*s%-15s ",max(OP_COL-n,1)," ",op);}int cST20::Decode(int count){  int operand;  bool v=verbose;  CLEAR_OP();  while(Iptr!=0) {    int a, op1=RB(Iptr++);    if(v) LogOpOper(op1,operand);    GET_OP();    switch(op1>>4) {      case 0x0: // j / jump#ifdef SAVE_DEBUG        POP(); POP(); POP();#endif        JUMP(operand);        CLEAR_OP();        break;      case 0x1: // ldlp        PUSH(Wptr+(operand*4));        CLEAR_OP();        break;      case 0x2: // positive prefix        operand<<=4;        break;      case 0x3: // ldnl        AAA=RW(AAA+(operand*4));        CLEAR_OP();        break;      case 0x4: // ldc        PUSH(operand);        CLEAR_OP();        break;      case 0x5: // ldnlp        PUSHPOP(+,operand*4);        CLEAR_OP();        break;      case 0x6: // negative prefix        operand=(~operand)<<4;        break;      case 0x7: // ldl        PUSH(RW(Wptr+(operand*4)));        CLEAR_OP();        break;      case 0x8: // adc        PUSHPOP(+,operand);        CLEAR_OP();        break;      case 0x9: // call        Wptr-=16;        WW(Wptr,Iptr); WW(Wptr+4,POP()); WW(Wptr+8,POP()); WW(Wptr+12,POP());        PUSH(Iptr);        JUMP(operand);        CLEAR_OP();        break;      case 0xA: // cj / conditional jump        if(AAA) DROP(1); else JUMP(operand);        CLEAR_OP();        break;      case 0xB: // ajw / adjust workspace        Wptr+=operand*4;        CLEAR_OP();        break;      case 0xC: // eqc / equals constant        AAA=(operand==AAA ? 1 : 0);        CLEAR_OP();        break;      case 0xD: // stl        WW(Wptr+(operand*4),POP());        CLEAR_OP();        break;      case 0xE: // stnl        a=POP(); WW(a+(operand*4),POP());        CLEAR_OP();        break;      case 0xF: // opr (secondary ins)        switch(operand) {	  case  0x00: LOG_OP("rev");   a=AAA; AAA=BBB; BBB=a; break;	  case  0x01: LOG_OP("lb");    AAA=RB(AAA); break;	  case  0x02: LOG_OP("bsub");  PUSHPOP(+,POP()); break;	  case  0x04: LOG_OP("diff");  PUSHPOP(-,POP()); break;	  case  0x05: LOG_OP("add");   PUSHPOP(+,POP()); break;	  case  0x06: LOG_OP("gcall"); a=AAA; AAA=Iptr; Iptr=a; break;	  case  0x08: LOG_OP("prod");  PUSHPOP(*,POP()); break;	  case  0x09: LOG_OP("gt");    a=POP(); AAA=(AAA>a); break;	  case  0x0A: LOG_OP("wsub");  a=POP(); AAA=a+(AAA*4); break;	  case  0x0C: LOG_OP("sub");   PUSHPOP(-,POP()); break;          case  0x1B: LOG_OP("ldpi");  PUSHPOP(+,Iptr); break;          case  0x20: LOG_OP("ret");   Iptr=RW(Wptr); Wptr=Wptr+16; break;          case  0x2C: LOG_OP("div");   PUSHPOP(/,POP()); break;          case  0x32: LOG_OP("not");   AAA=~AAA; break;          case  0x33: LOG_OP("xor");   PUSHPOP(^,POP()); break;          case  0x34: LOG_OP("bcnt");  PUSHPOP(*,4); break;          case  0x3B: LOG_OP("sb");    a=POP(); WriteByte(a,POP()); break;          case  0x3F: LOG_OP("wcnt");  a=POP(); PUSH(a&3); PUSH((unsigned int)a>>2); break;          case  0x40: LOG_OP("shr");   a=POP(); AAA=(unsigned int)AAA>>a; break;          case  0x41: LOG_OP("shl");   a=POP(); AAA=(unsigned int)AAA<<a; break;          case  0x42: LOG_OP("mint");  PUSH(MOSTNEG); break;          case  0x46: LOG_OP("and");   PUSHPOP(&,POP()); break;          case  0x4A: LOG_OP("move");  { a=POP(); int b=POP(); int c=POP(); while(a--) WriteByte(b++,ReadByte(c++)); } break;          case  0x4B: LOG_OP("or");    PUSHPOP(|,POP()); break;          case  0x53: LOG_OP("mul");   PUSHPOP(*,POP()); break;          case  0x5A: LOG_OP("dup");   PUSH(AAA); break;          case  0x5F: LOG_OP("gtu");   a=POP(); AAA=((unsigned int)AAA>(unsigned int)a); break;          case  0x1D: LOG_OP("xdble"); CCC=BBB; BBB=(AAA>=0 ? 0:-1); break;          case  0x1A: LOG_OP("ldiv");  { a=POP(); unsigned long long ll=POP64(); PUSH(ll%(unsigned int)a); PUSH(ll/(unsigned int)a); } break;          case  0x1F: LOG_OP("rem");   PUSHPOP(%,POP()); break;          case  0x35: LOG_OP("lshr");  { a=POP(); unsigned long long ll=POP64()>>a; PUSH((ll>>32)&0xFFFFFFFF); PUSH(ll&0xFFFFFFFF); } break;          case  0xCA: LOG_OP("ls");    AAA=ReadShort(AAA); break;          case  0xCD: LOG_OP("gintdis"); break;          case  0xCE: LOG_OP("gintenb"); break;          case -0x40: LOG_OP("nop");   break;	  default:             if(verbose) PUTLB(L_SYS_DISASM,loglb);            PRINTF(L_SYS_ST20,"unknown opcode %X",operand);            return ERR_ILL_OP;	  }        CLEAR_OP();        break;      }    if(v && operand==0) {      loglb->Printf("%08X %08X %08X W:%08X",AAA,BBB,CCC,Wptr);      PUTLB(L_SYS_DISASM,loglb);      }    if(--count<=0 && operand==0) {      PRINTF(L_SYS_ST20,"instruction counter exceeded");      return ERR_CNT;      }    }  return 0;}

⌨️ 快捷键说明

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