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

📄 rarvm.cpp

📁 source code for unrar3.3.4,uppack the .rar files,for multi-os
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "rar.hpp"#include "rarvmtbl.cpp"RarVM::RarVM(){  Mem=NULL;}RarVM::~RarVM(){  delete Mem;}void RarVM::Init(){  if (Mem==NULL)    Mem=new byte[VM_MEMSIZE+4];}inline uint RarVM::GetValue(bool ByteMode,uint *Addr){  if (ByteMode)    return(*(byte *)Addr);  else  {#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT)    byte *B=(byte *)Addr;    return UINT32((uint)B[0]|((uint)B[1]<<8)|((uint)B[2]<<16)|((uint)B[3]<<24));#else    return UINT32(*Addr);#endif  }}#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT)  #define GET_VALUE(ByteMode,Addr) GetValue(ByteMode,(uint *)Addr)#else  #define GET_VALUE(ByteMode,Addr) ((ByteMode) ? (*(byte *)(Addr)):UINT32(*(uint *)(Addr)))#endifinline void RarVM::SetValue(bool ByteMode,uint *Addr,uint Value){  if (ByteMode)    *(byte *)Addr=Value;  else  {#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT) || !defined(PRESENT_INT32)    ((byte *)Addr)[0]=(byte)Value;    ((byte *)Addr)[1]=(byte)(Value>>8);    ((byte *)Addr)[2]=(byte)(Value>>16);    ((byte *)Addr)[3]=(byte)(Value>>24);#else    *(uint32 *)Addr=Value;#endif  }}#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT) || !defined(PRESENT_INT32)  #define SET_VALUE(ByteMode,Addr,Value) SetValue(ByteMode,(uint *)Addr,Value)#else  #define SET_VALUE(ByteMode,Addr,Value) ((ByteMode) ? (*(byte *)(Addr)=(Value)):(*(uint32 *)(Addr)=((uint32)(Value))))#endifvoid RarVM::SetValue(uint *Addr,uint Value){  SetValue(false,Addr,Value);}inline uint* RarVM::GetOperand(VM_PreparedOperand *CmdOp){  if (CmdOp->Type==VM_OPREGMEM)    return((uint *)&Mem[(*CmdOp->Addr+CmdOp->Base)&VM_MEMMASK]);  else    return(CmdOp->Addr);}void RarVM::Execute(VM_PreparedProgram *Prg){  memcpy(R,Prg->InitR,sizeof(Prg->InitR));  unsigned int GlobalSize=Min(Prg->GlobalData.Size(),VM_GLOBALMEMSIZE);  if (GlobalSize)    memcpy(Mem+VM_GLOBALMEMADDR,&Prg->GlobalData[0],GlobalSize);  unsigned int StaticSize=Min(Prg->StaticData.Size(),VM_GLOBALMEMSIZE-GlobalSize);  if (StaticSize)    memcpy(Mem+VM_GLOBALMEMADDR+GlobalSize,&Prg->StaticData[0],StaticSize);  R[7]=VM_MEMSIZE;  Flags=0;  VM_PreparedCommand *PreparedCode=Prg->AltCmd ? Prg->AltCmd:&Prg->Cmd[0];  if (!ExecuteCode(PreparedCode,Prg->CmdCount))    PreparedCode[0].OpCode=VM_RET;  uint NewBlockPos=GET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20])&VM_MEMMASK;  uint NewBlockSize=GET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x1c])&VM_MEMMASK;  if (NewBlockPos+NewBlockSize>=VM_MEMSIZE)    NewBlockPos=NewBlockSize=0;  Prg->FilteredData=Mem+NewBlockPos;  Prg->FilteredDataSize=NewBlockSize;  Prg->GlobalData.Reset();  uint DataSize=Min(GET_VALUE(false,(uint*)&Mem[VM_GLOBALMEMADDR+0x30]),VM_GLOBALMEMSIZE);  if (DataSize!=0)  {    Prg->GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE);    memcpy(&Prg->GlobalData[0],&Mem[VM_GLOBALMEMADDR],DataSize+VM_FIXEDGLOBALSIZE);  }}#define SET_IP(IP)                      \  if ((IP)>=CodeSize)                   \    return(true);                       \  if (--MaxOpCount<=0)                  \    return(false);                      \  Cmd=PreparedCode+(IP);bool RarVM::ExecuteCode(VM_PreparedCommand *PreparedCode,int CodeSize){  int MaxOpCount=25000000;  VM_PreparedCommand *Cmd=PreparedCode;  while (1)  {    uint *Op1=GetOperand(&Cmd->Op1);    uint *Op2=GetOperand(&Cmd->Op2);    switch(Cmd->OpCode)    {#ifndef NORARVM      case VM_MOV:        SET_VALUE(Cmd->ByteMode,Op1,GET_VALUE(Cmd->ByteMode,Op2));        break;#ifdef VM_OPTIMIZE      case VM_MOVB:        SET_VALUE(true,Op1,GET_VALUE(true,Op2));        break;      case VM_MOVD:        SET_VALUE(false,Op1,GET_VALUE(false,Op2));        break;#endif      case VM_CMP:        {          uint Value1=GET_VALUE(Cmd->ByteMode,Op1);          uint Result=UINT32(Value1-GET_VALUE(Cmd->ByteMode,Op2));          Flags=Result==0 ? VM_FZ:(Result>Value1)|(Result&VM_FS);        }        break;#ifdef VM_OPTIMIZE      case VM_CMPB:        {          uint Value1=GET_VALUE(true,Op1);          uint Result=UINT32(Value1-GET_VALUE(true,Op2));          Flags=Result==0 ? VM_FZ:(Result>Value1)|(Result&VM_FS);        }        break;      case VM_CMPD:        {          uint Value1=GET_VALUE(false,Op1);          uint Result=UINT32(Value1-GET_VALUE(false,Op2));          Flags=Result==0 ? VM_FZ:(Result>Value1)|(Result&VM_FS);        }        break;#endif      case VM_ADD:        {          uint Value1=GET_VALUE(Cmd->ByteMode,Op1);          uint Result=UINT32(Value1+GET_VALUE(Cmd->ByteMode,Op2));          Flags=Result==0 ? VM_FZ:(Result<Value1)|(Result&VM_FS);          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;#ifdef VM_OPTIMIZE      case VM_ADDB:        SET_VALUE(true,Op1,GET_VALUE(true,Op1)+GET_VALUE(true,Op2));        break;      case VM_ADDD:        SET_VALUE(false,Op1,GET_VALUE(false,Op1)+GET_VALUE(false,Op2));        break;#endif      case VM_SUB:        {          uint Value1=GET_VALUE(Cmd->ByteMode,Op1);          uint Result=UINT32(Value1-GET_VALUE(Cmd->ByteMode,Op2));          Flags=Result==0 ? VM_FZ:(Result>Value1)|(Result&VM_FS);          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;#ifdef VM_OPTIMIZE      case VM_SUBB:        SET_VALUE(true,Op1,GET_VALUE(true,Op1)-GET_VALUE(true,Op2));        break;      case VM_SUBD:        SET_VALUE(false,Op1,GET_VALUE(false,Op1)-GET_VALUE(false,Op2));        break;#endif      case VM_JZ:        if ((Flags & VM_FZ)!=0)        {          SET_IP(GET_VALUE(false,Op1));          continue;        }        break;      case VM_JNZ:        if ((Flags & VM_FZ)==0)        {          SET_IP(GET_VALUE(false,Op1));          continue;        }        break;      case VM_INC:        {          uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)+1);          SET_VALUE(Cmd->ByteMode,Op1,Result);          Flags=Result==0 ? VM_FZ:Result&VM_FS;        }        break;#ifdef VM_OPTIMIZE      case VM_INCB:        SET_VALUE(true,Op1,GET_VALUE(true,Op1)+1);        break;      case VM_INCD:        SET_VALUE(false,Op1,GET_VALUE(false,Op1)+1);        break;#endif      case VM_DEC:        {          uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)-1);          SET_VALUE(Cmd->ByteMode,Op1,Result);          Flags=Result==0 ? VM_FZ:Result&VM_FS;        }        break;#ifdef VM_OPTIMIZE      case VM_DECB:        SET_VALUE(true,Op1,GET_VALUE(true,Op1)-1);        break;      case VM_DECD:        SET_VALUE(false,Op1,GET_VALUE(false,Op1)-1);        break;#endif      case VM_JMP:        SET_IP(GET_VALUE(false,Op1));        continue;      case VM_XOR:        {          uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)^GET_VALUE(Cmd->ByteMode,Op2));          Flags=Result==0 ? VM_FZ:Result&VM_FS;          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;      case VM_AND:        {          uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)&GET_VALUE(Cmd->ByteMode,Op2));          Flags=Result==0 ? VM_FZ:Result&VM_FS;          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;      case VM_OR:        {          uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)|GET_VALUE(Cmd->ByteMode,Op2));          Flags=Result==0 ? VM_FZ:Result&VM_FS;          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;      case VM_TEST:        {          uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)&GET_VALUE(Cmd->ByteMode,Op2));          Flags=Result==0 ? VM_FZ:Result&VM_FS;        }        break;      case VM_JS:        if ((Flags & VM_FS)!=0)        {          SET_IP(GET_VALUE(false,Op1));          continue;        }        break;      case VM_JNS:        if ((Flags & VM_FS)==0)        {          SET_IP(GET_VALUE(false,Op1));          continue;        }        break;      case VM_JB:        if ((Flags & VM_FC)!=0)        {          SET_IP(GET_VALUE(false,Op1));          continue;        }        break;      case VM_JBE:        if ((Flags & (VM_FC|VM_FZ))!=0)        {          SET_IP(GET_VALUE(false,Op1));          continue;        }        break;      case VM_JA:        if ((Flags & (VM_FC|VM_FZ))==0)        {          SET_IP(GET_VALUE(false,Op1));          continue;        }        break;      case VM_JAE:        if ((Flags & VM_FC)==0)        {          SET_IP(GET_VALUE(false,Op1));          continue;        }        break;      case VM_PUSH:        R[7]-=4;        SET_VALUE(false,(uint *)&Mem[R[7]&VM_MEMMASK],GET_VALUE(false,Op1));        break;      case VM_POP:        SET_VALUE(false,Op1,GET_VALUE(false,(uint *)&Mem[R[7] & VM_MEMMASK]));        R[7]+=4;        break;      case VM_CALL:        R[7]-=4;        SET_VALUE(false,(uint *)&Mem[R[7]&VM_MEMMASK],Cmd-PreparedCode+1);        SET_IP(GET_VALUE(false,Op1));        continue;      case VM_NOT:        SET_VALUE(Cmd->ByteMode,Op1,~GET_VALUE(Cmd->ByteMode,Op1));        break;      case VM_SHL:        {          uint Value1=GET_VALUE(Cmd->ByteMode,Op1);          uint Value2=GET_VALUE(Cmd->ByteMode,Op2);          uint Result=UINT32(Value1<<Value2);          Flags=(Result==0 ? VM_FZ:(Result&VM_FS))|((Value1<<(Value2-1))&0x80000000 ? VM_FC:0);          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;      case VM_SHR:        {          uint Value1=GET_VALUE(Cmd->ByteMode,Op1);          uint Value2=GET_VALUE(Cmd->ByteMode,Op2);          uint Result=UINT32(Value1>>Value2);          Flags=(Result==0 ? VM_FZ:(Result&VM_FS))|((Value1>>(Value2-1))&VM_FC);          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;      case VM_SAR:        {          uint Value1=GET_VALUE(Cmd->ByteMode,Op1);          uint Value2=GET_VALUE(Cmd->ByteMode,Op2);          uint Result=UINT32(((int)Value1)>>Value2);          Flags=(Result==0 ? VM_FZ:(Result&VM_FS))|((Value1>>(Value2-1))&VM_FC);          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;      case VM_NEG:        {          uint Result=UINT32(-GET_VALUE(Cmd->ByteMode,Op1));          Flags=Result==0 ? VM_FZ:VM_FC|(Result&VM_FS);          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;#ifdef VM_OPTIMIZE      case VM_NEGB:        SET_VALUE(true,Op1,-GET_VALUE(true,Op1));        break;      case VM_NEGD:        SET_VALUE(false,Op1,-GET_VALUE(false,Op1));        break;#endif      case VM_PUSHA:        {          const int RegCount=sizeof(R)/sizeof(R[0]);          for (int I=0,SP=R[7]-4;I<RegCount;I++,SP-=4)            SET_VALUE(false,(uint *)&Mem[SP & VM_MEMMASK],R[I]);          R[7]-=RegCount*4;        }        break;      case VM_POPA:        {          const int RegCount=sizeof(R)/sizeof(R[0]);          for (uint I=0,SP=R[7];I<RegCount;I++,SP+=4)            R[7-I]=GET_VALUE(false,(uint *)&Mem[SP & VM_MEMMASK]);        }        break;      case VM_PUSHF:        R[7]-=4;        SET_VALUE(false,(uint *)&Mem[R[7]&VM_MEMMASK],Flags);        break;      case VM_POPF:        Flags=GET_VALUE(false,(uint *)&Mem[R[7] & VM_MEMMASK]);        R[7]+=4;        break;      case VM_MOVZX:        SET_VALUE(false,Op1,GET_VALUE(true,Op2));        break;      case VM_MOVSX:        SET_VALUE(false,Op1,(signed char)GET_VALUE(true,Op2));        break;      case VM_XCHG:        {          uint Value1=GET_VALUE(Cmd->ByteMode,Op1);          SET_VALUE(Cmd->ByteMode,Op1,GET_VALUE(Cmd->ByteMode,Op2));          SET_VALUE(Cmd->ByteMode,Op2,Value1);        }        break;      case VM_MUL:        {          uint Result=GET_VALUE(Cmd->ByteMode,Op1)*GET_VALUE(Cmd->ByteMode,Op2);          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;      case VM_DIV:        {          uint Divider=GET_VALUE(Cmd->ByteMode,Op2);          if (Divider!=0)          {            uint Result=GET_VALUE(Cmd->ByteMode,Op1)/Divider;            SET_VALUE(Cmd->ByteMode,Op1,Result);          }        }        break;      case VM_ADC:        {          uint Value1=GET_VALUE(Cmd->ByteMode,Op1);          uint FC=(Flags&VM_FC);          uint Result=UINT32(Value1+GET_VALUE(Cmd->ByteMode,Op2)+FC);          Flags=Result==0 ? VM_FZ:(Result<Value1 || Result==Value1 && FC)|(Result&VM_FS);          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;      case VM_SBB:        {          uint Value1=GET_VALUE(Cmd->ByteMode,Op1);          uint FC=(Flags&VM_FC);          uint Result=UINT32(Value1-GET_VALUE(Cmd->ByteMode,Op2)-FC);          Flags=Result==0 ? VM_FZ:(Result>Value1 || Result==Value1 && FC)|(Result&VM_FS);          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;#endif      case VM_RET:        if (R[7]>=VM_MEMSIZE)          return(true);        SET_IP(GET_VALUE(false,(uint *)&Mem[R[7] & VM_MEMMASK]));        R[7]+=4;        continue;#ifdef VM_STANDARDFILTERS      case VM_STANDARD:        ExecuteStandardFilter((VM_StandardFilters)Cmd->Op1.Data);        break;#endif      case VM_PRINT:#ifdef DEBUG        PrintState(Cmd-PreparedCode);#endif        break;    }    Cmd++;    --MaxOpCount;  }}void RarVM::PrintState(uint IP){#if defined(DEBUG) && !defined(GUI) && !defined(SILENT)  mprintf("\n");  for (int I=0;I<sizeof(R)/sizeof(R[0]);I++)    mprintf("R%d=%08X\t%s",I,R[I],I==3 ? "\n":"");  mprintf("\nIP=%08X\tFlags: C=%d S=%d",IP,(Flags & VM_FC)!=0,(Flags & VM_FS)!=0);  mprintf("\n");#endif}void RarVM::Prepare(byte *Code,int CodeSize,VM_PreparedProgram *Prg){  InitBitInput();  memcpy(InBuf,Code,Min(CodeSize,BitInput::MAX_SIZE));  byte XorSum=0;  for (int I=1;I<CodeSize;I++)    XorSum^=Code[I];  faddbits(8);  Prg->CmdCount=0;  if (XorSum==Code[0])  {#ifdef VM_STANDARDFILTERS    VM_StandardFilters FilterType=IsStandardFilter(Code,CodeSize);    if (FilterType!=VMSF_NONE)    {      Prg->Cmd.Add(1);      VM_PreparedCommand *CurCmd=&Prg->Cmd[Prg->CmdCount++];      CurCmd->OpCode=VM_STANDARD;      CurCmd->Op1.Data=FilterType;      CurCmd->Op1.Addr=&CurCmd->Op1.Data;      CurCmd->Op2.Addr=&CurCmd->Op2.Data;      CodeSize=0;    }#endif      uint DataFlag=fgetbits();    faddbits(1);    if (DataFlag&0x8000)    {      int DataSize=ReadData(*this)+1;      for (int I=0;InAddr<CodeSize && I<DataSize;I++)      {        Prg->StaticData.Add(1);        Prg->StaticData[I]=fgetbits()>>8;        faddbits(8);      }    }    while (InAddr<CodeSize)    {      Prg->Cmd.Add(1);      VM_PreparedCommand *CurCmd=&Prg->Cmd[Prg->CmdCount];

⌨️ 快捷键说明

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