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

📄 rar3vm.cpp

📁 7-Zip 是一款号称有着现今最高压缩比的压缩软件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        {
          UInt32 res = GetOperand32(&cmd->Op1) & GetOperand32(&cmd->Op2);
          SetOperand32(&cmd->Op1, res);
          FLAGS_UPDATE_SZ;
        }
        break;
      case CMD_ANDB:
        {
          Byte res = GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2);
          SetOperand8(&cmd->Op1, res);
          FLAGS_UPDATE_SZ_B;
        }
        break;
      case CMD_OR:
        {
          UInt32 res = GetOperand32(&cmd->Op1) | GetOperand32(&cmd->Op2);
          SetOperand32(&cmd->Op1, res);
          FLAGS_UPDATE_SZ;
        }
        break;
      case CMD_ORB:
        {
          Byte res = GetOperand8(&cmd->Op1) | GetOperand8(&cmd->Op2);
          SetOperand8(&cmd->Op1, res);
          FLAGS_UPDATE_SZ_B;
        }
        break;
      case CMD_TEST:
        {
          UInt32 res = GetOperand32(&cmd->Op1) & GetOperand32(&cmd->Op2);
          FLAGS_UPDATE_SZ;
        }
        break;
      case CMD_TESTB:
        {
          Byte res = GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2);
          FLAGS_UPDATE_SZ_B;
        }
        break;
      case CMD_NOT:
        SetOperand(cmd->ByteMode, &cmd->Op1, ~GetOperand(cmd->ByteMode, &cmd->Op1));
        break;
      case CMD_NEG:
        {
          UInt32 res = 0 - GetOperand32(&cmd->Op1);
          SetOperand32(&cmd->Op1, res);
          Flags = res == 0 ? FLAG_Z : FLAG_C | (res & FLAG_S);
        }
        break;
      case CMD_NEGB:
        {
          Byte res = (Byte)(0 - GetOperand8(&cmd->Op1));
          SetOperand8(&cmd->Op1, res);
          Flags = res == 0 ? FLAG_Z : FLAG_C | GET_FLAG_S_B(res);
        }
        break;

      case CMD_SHL:
        {
          UInt32 v1 = GetOperand32(&cmd->Op1);
          int v2 = (int)GetOperand32(&cmd->Op2);
          UInt32 res = v1 << v2;
          SetOperand32(&cmd->Op1, res);
          Flags = (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 << (v2 - 1)) & 0x80000000 ? FLAG_C : 0);
        }
        break;
      case CMD_SHLB:
        {
          Byte v1 = GetOperand8(&cmd->Op1);
          int v2 = (int)GetOperand8(&cmd->Op2);
          Byte res = (Byte)(v1 << v2);
          SetOperand8(&cmd->Op1, res);
          Flags = (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 << (v2 - 1)) & 0x80 ? FLAG_C : 0);
        }
        break;
      case CMD_SHR:
        {
          UInt32 v1 = GetOperand32(&cmd->Op1);
          int v2 = (int)GetOperand32(&cmd->Op2);
          UInt32 res = v1 >> v2;
          SetOperand32(&cmd->Op1, res);
          Flags = (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 >> (v2 - 1)) & FLAG_C);
        }
        break;
      case CMD_SHRB:
        {
          Byte v1 = GetOperand8(&cmd->Op1);
          int v2 = (int)GetOperand8(&cmd->Op2);
          Byte res = (Byte)(v1 >> v2);
          SetOperand8(&cmd->Op1, res);
          Flags = (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 >> (v2 - 1)) & FLAG_C);
        }
        break;
      case CMD_SAR:
        {
          UInt32 v1 = GetOperand32(&cmd->Op1);
          int v2 = (int)GetOperand32(&cmd->Op2);
          UInt32 res = UInt32(((Int32)v1) >> v2);
          SetOperand32(&cmd->Op1, res);
          Flags= (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 >> (v2 - 1)) & FLAG_C);
        }
        break;
      case CMD_SARB:
        {
          Byte v1 = GetOperand8(&cmd->Op1);
          int v2 = (int)GetOperand8(&cmd->Op2);
          Byte res = (Byte)(((signed char)v1) >> v2);
          SetOperand8(&cmd->Op1, res);
          Flags= (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 >> (v2 - 1)) & FLAG_C);
        }
        break;

      case CMD_JMP:
        SET_IP_OP1;
        continue;
      case CMD_JZ:
        if ((Flags & FLAG_Z) != 0)
        {
          SET_IP_OP1;
          continue;
        }
        break;
      case CMD_JNZ:
        if ((Flags & FLAG_Z) == 0)
        {
          SET_IP_OP1;
          continue;
        }
        break;
      case CMD_JS:
        if ((Flags & FLAG_S) != 0)
        {
          SET_IP_OP1;
          continue;
        }
        break;
      case CMD_JNS:
        if ((Flags & FLAG_S) == 0)
        {
          SET_IP_OP1;
          continue;
        }
        break;
      case CMD_JB:
        if ((Flags & FLAG_C) != 0)
        {
          SET_IP_OP1;
          continue;
        }
        break;
      case CMD_JBE:
        if ((Flags & (FLAG_C | FLAG_Z)) != 0)
        {
          SET_IP_OP1;
          continue;
        }
        break;
      case CMD_JA:
        if ((Flags & (FLAG_C | FLAG_Z)) == 0)
        {
          SET_IP_OP1;
          continue;
        }
        break;
      case CMD_JAE:
        if ((Flags & FLAG_C) == 0)
        {
          SET_IP_OP1;
          continue;
        }
        break;
      
      case CMD_PUSH:
        R[kStackRegIndex] -= 4;
        SetValue32(&Mem[R[kStackRegIndex] & kSpaceMask], GetOperand32(&cmd->Op1));
        break;
      case CMD_POP:
        SetOperand32(&cmd->Op1, GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]));
        R[kStackRegIndex] += 4;
        break;
      case CMD_CALL:
        R[kStackRegIndex] -= 4;
        SetValue32(&Mem[R[kStackRegIndex] & kSpaceMask], (UInt32)(cmd - commands + 1));
        SET_IP_OP1;
        continue;

      case CMD_PUSHA:
        {
          for (UInt32 i = 0, SP = R[kStackRegIndex] - 4; i < kNumRegs; i++, SP -= 4)
            SetValue32(&Mem[SP & kSpaceMask], R[i]);
          R[kStackRegIndex] -= kNumRegs * 4;
        }
        break;
      case CMD_POPA:
        {
          for (UInt32 i = 0, SP = R[kStackRegIndex]; i < kNumRegs; i++, SP += 4)
            R[kStackRegIndex - i] = GetValue32(&Mem[SP & kSpaceMask]);
        }
        break;
      case CMD_PUSHF:
        R[kStackRegIndex] -= 4;
        SetValue32(&Mem[R[kStackRegIndex]&kSpaceMask], Flags);
        break;
      case CMD_POPF:
        Flags = GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]);
        R[kStackRegIndex] += 4;
        break;
      
      case CMD_MOVZX:
        SetOperand32(&cmd->Op1, GetOperand8(&cmd->Op2));
        break;
      case CMD_MOVSX:
        SetOperand32(&cmd->Op1, (UInt32)(Int32)(signed char)GetOperand8(&cmd->Op2));
        break;
      case CMD_XCHG:
        {
          UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1);
          SetOperand(cmd->ByteMode, &cmd->Op1, GetOperand(cmd->ByteMode, &cmd->Op2));
          SetOperand(cmd->ByteMode, &cmd->Op2, v1);
        }
        break;
      case CMD_MUL:
        {
          UInt32 res = GetOperand32(&cmd->Op1) * GetOperand32(&cmd->Op2);
          SetOperand32(&cmd->Op1, res);
        }
        break;
      case CMD_MULB:
        {
          Byte res = GetOperand8(&cmd->Op1) * GetOperand8(&cmd->Op2);
          SetOperand8(&cmd->Op1, res);
        }
        break;
      case CMD_DIV:
        {
          UInt32 divider = GetOperand(cmd->ByteMode, &cmd->Op2);
          if (divider != 0)
          {
            UInt32 res = GetOperand(cmd->ByteMode, &cmd->Op1) / divider;
            SetOperand(cmd->ByteMode, &cmd->Op1, res);
          }
        }
        break;
      
      #endif
      
      case CMD_RET:
        {
          if (R[kStackRegIndex] >= kSpaceSize)
            return true;
          UInt32 ip = GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]);
          SET_IP(ip);
          R[kStackRegIndex] += 4;
          continue;
        }
      case CMD_PRINT:
        break;
    }
    cmd++;
    --maxOpCount;
  }
}


//////////////////////////////////////////////////////
// Read program

UInt32 ReadEncodedUInt32(CMemBitDecoder &inp)
{
  switch(inp.ReadBits(2))
  {
    case 0:
      return inp.ReadBits(4);
    case 1:
    {
      UInt32 v = inp.ReadBits(4);
      if (v == 0)
        return 0xFFFFFF00 | inp.ReadBits(8);
      else
        return (v << 4) | inp.ReadBits(4);
    }
    case 2:
      return inp.ReadBits(16);
    default:
      return inp.ReadBits(32);
  }
}

void CVm::DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode)
{
  if (inp.ReadBit())
  {
    op.Type = OP_TYPE_REG;
    op.Data = inp.ReadBits(kNumRegBits);
  }
  else if (inp.ReadBit() == 0)
  {
    op.Type = OP_TYPE_INT;
    if (byteMode)
      op.Data = inp.ReadBits(8);
    else
      op.Data = ReadEncodedUInt32(inp);
  }
  else
  {
    op.Type = OP_TYPE_REGMEM;
    if (inp.ReadBit() == 0)
    {
      op.Data = inp.ReadBits(kNumRegBits);
      op.Base = 0;
    }
    else
    {
      if (inp.ReadBit() == 0)
        op.Data = inp.ReadBits(kNumRegBits);
      else
        op.Data = kNumRegs;
      op.Base = ReadEncodedUInt32(inp);
    }
  }
}

void CVm::ReadVmProgram(const Byte *code, UInt32 codeSize, CProgram *prg)
{
  CMemBitDecoder inp;
  inp.Init(code, codeSize);

  prg->StaticData.Clear();
  if (inp.ReadBit())
  {
    UInt32 dataSize = ReadEncodedUInt32(inp) + 1;
    for (UInt32 i = 0; inp.Avail() && i < dataSize; i++)
      prg->StaticData.Add((Byte)inp.ReadBits(8));
  }
  while (inp.Avail())
  {
    prg->Commands.Add(CCommand());
    CCommand *cmd = &prg->Commands.Back();
    if (inp.ReadBit() == 0)
      cmd->OpCode = (ECommand)inp.ReadBits(3);
    else
      cmd->OpCode = (ECommand)(8 + inp.ReadBits(5));
    if (kCmdFlags[cmd->OpCode] & CF_BYTEMODE)
      cmd->ByteMode = (inp.ReadBit()) ? true : false;
    else
      cmd->ByteMode = 0;
    int opNum = (kCmdFlags[cmd->OpCode] & CF_OPMASK);
    if (opNum > 0)
    {
      DecodeArg(inp, cmd->Op1, cmd->ByteMode);
      if (opNum == 2)
        DecodeArg(inp, cmd->Op2, cmd->ByteMode);
      else
      {
        if (cmd->Op1.Type == OP_TYPE_INT && (kCmdFlags[cmd->OpCode] & (CF_JUMP | CF_PROC)))
        {
          int Distance = cmd->Op1.Data;
          if (Distance >= 256)
            Distance -= 256;
          else
          {
            if (Distance >= 136)
              Distance -= 264;
            else if (Distance >= 16)
              Distance -= 8;

⌨️ 快捷键说明

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