summaryrefslogtreecommitdiff
path: root/src/com/github/junrar/unpack/vm/RarVM.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/github/junrar/unpack/vm/RarVM.java')
-rw-r--r--src/com/github/junrar/unpack/vm/RarVM.java1221
1 files changed, 0 insertions, 1221 deletions
diff --git a/src/com/github/junrar/unpack/vm/RarVM.java b/src/com/github/junrar/unpack/vm/RarVM.java
deleted file mode 100644
index e6e6a01..0000000
--- a/src/com/github/junrar/unpack/vm/RarVM.java
+++ /dev/null
@@ -1,1221 +0,0 @@
-/*
- * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
- * Original author: Edmund Wagner
- * Creation date: 31.05.2007
- *
- * Source: $HeadURL$
- * Last changed: $LastChangedDate$
- *
- * the unrar licence applies to all junrar source and binary distributions
- * you are not allowed to use this source to re-create the RAR compression algorithm
- *
- * Here some html entities which can be used for escaping javadoc tags:
- * "&": "&" or "&"
- * "<": "&#060;" or "&lt;"
- * ">": "&#062;" or "&gt;"
- * "@": "&#064;"
- */
-package com.github.junrar.unpack.vm;
-
-import java.util.List;
-import java.util.Vector;
-
-import com.github.junrar.crc.RarCRC;
-import com.github.junrar.io.Raw;
-
-
-/**
- * DOCUMENT ME
- *
- * @author $LastChangedBy$
- * @version $LastChangedRevision$
- */
-public class RarVM extends BitInput {
-
- public static final int VM_MEMSIZE = 0x40000;
-
- public static final int VM_MEMMASK = (VM_MEMSIZE - 1);
-
- public static final int VM_GLOBALMEMADDR = 0x3C000;
-
- public static final int VM_GLOBALMEMSIZE = 0x2000;
-
- public static final int VM_FIXEDGLOBALSIZE = 64;
-
- private static final int regCount = 8;
-
- private static final long UINT_MASK = 0xffffFFFF;//((long)2*(long)Integer.MAX_VALUE);
-
- private byte[] mem;
-
- private int[] R = new int[regCount];
-
- private int flags;
-
- private int maxOpCount = 25000000;
-
- private int codeSize;
-
- private int IP;
-
- public RarVM() {
- mem = null;
- }
-
- public void init() {
- if (mem == null) {
- mem = new byte[VM_MEMSIZE + 4];
- }
- }
-
- private boolean isVMMem(byte[] mem) {
- return this.mem == mem;
- }
-
- private int getValue(boolean byteMode, byte[] mem, int offset) {
- if (byteMode) {
- if (isVMMem(mem)) {
- return (mem[offset]);
- } else {
- return (mem[offset] & 0xff);
- }
- } else {
- if (isVMMem(mem)) {
- //little
- return Raw.readIntLittleEndian(mem, offset);
- } else
- //big endian
- return Raw.readIntBigEndian(mem, offset);
- }
- }
-
- private void setValue(boolean byteMode, byte[] mem, int offset, int value) {
- if (byteMode) {
- if (isVMMem(mem)) {
- mem[offset] = (byte) value;
- } else {
- mem[offset] = (byte) ((mem[offset] & 0x00) | (byte) (value & 0xff));
- }
- } else {
- if (isVMMem(mem)) {
- Raw.writeIntLittleEndian(mem, offset, value);
-// mem[offset + 0] = (byte) value;
-// mem[offset + 1] = (byte) (value >>> 8);
-// mem[offset + 2] = (byte) (value >>> 16);
-// mem[offset + 3] = (byte) (value >>> 24);
- } else {
- Raw.writeIntBigEndian(mem, offset, value);
-// mem[offset + 3] = (byte) value;
-// mem[offset + 2] = (byte) (value >>> 8);
-// mem[offset + 1] = (byte) (value >>> 16);
-// mem[offset + 0] = (byte) (value >>> 24);
- }
-
- }
- // #define SET_VALUE(ByteMode,Addr,Value) SetValue(ByteMode,(uint
- // *)Addr,Value)
- }
-
- public void setLowEndianValue(byte[] mem, int offset, int value) {
- Raw.writeIntLittleEndian(mem, offset, value);
-// mem[offset + 0] = (byte) (value&0xff);
-// mem[offset + 1] = (byte) ((value >>> 8)&0xff);
-// mem[offset + 2] = (byte) ((value >>> 16)&0xff);
-// mem[offset + 3] = (byte) ((value >>> 24)&0xff);
- }
- public void setLowEndianValue(Vector<Byte> mem, int offset, int value) {
- mem.set(offset + 0, Byte.valueOf((byte) (value&0xff))) ;
- mem.set(offset + 1, Byte.valueOf((byte) ((value >>> 8)&0xff)));
- mem.set(offset + 2, Byte.valueOf((byte) ((value >>> 16)&0xff) ));
- mem.set(offset + 3, Byte.valueOf((byte) ((value >>> 24)&0xff))) ;
- }
- private int getOperand(VMPreparedOperand cmdOp) {
- int ret = 0;
- if (cmdOp.getType() == VMOpType.VM_OPREGMEM) {
- int pos = (cmdOp.getOffset() + cmdOp.getBase()) & VM_MEMMASK;
- ret = Raw.readIntLittleEndian(mem, pos);
- } else {
- int pos = cmdOp.getOffset();
- ret = Raw.readIntLittleEndian(mem, pos);
- }
- return ret;
- }
-
- public void execute(VMPreparedProgram prg) {
- for (int i = 0; i < prg.getInitR().length; i++) // memcpy(R,Prg->InitR,sizeof(Prg->InitR));
- {
- R[i] = prg.getInitR()[i];
- }
-
- long globalSize = Math
- .min(prg.getGlobalData().size(), VM_GLOBALMEMSIZE) & 0xffFFffFF;
- if (globalSize != 0) {
- for (int i = 0; i < globalSize; i++) // memcpy(Mem+VM_GLOBALMEMADDR,&Prg->GlobalData[0],GlobalSize);
- {
- mem[VM_GLOBALMEMADDR + i] = prg.getGlobalData().get(i);
- }
-
- }
- long staticSize = Math.min(prg.getStaticData().size(), VM_GLOBALMEMSIZE
- - globalSize) & 0xffFFffFF;
- if (staticSize != 0) {
- for (int i = 0; i < staticSize; i++) // memcpy(Mem+VM_GLOBALMEMADDR+GlobalSize,&Prg->StaticData[0],StaticSize);
- {
- mem[VM_GLOBALMEMADDR + (int) globalSize + i] = prg
- .getStaticData().get(i);
- }
-
- }
- R[7] = VM_MEMSIZE;
- flags = 0;
-
- List<VMPreparedCommand> preparedCode = prg.getAltCmd().size() != 0 ? prg
- .getAltCmd()
- : prg.getCmd();
-
- if (!ExecuteCode(preparedCode, prg.getCmdCount())) {
- preparedCode.get(0).setOpCode(VMCommands.VM_RET);
- }
- int newBlockPos = getValue(false, mem, VM_GLOBALMEMADDR + 0x20)
- & VM_MEMMASK;
- int newBlockSize = getValue(false, mem, VM_GLOBALMEMADDR + 0x1c)
- & VM_MEMMASK;
- if ((newBlockPos + newBlockSize) >= VM_MEMSIZE) {
- newBlockPos = 0;
- newBlockSize = 0;
- }
-
- prg.setFilteredDataOffset(newBlockPos);
- prg.setFilteredDataSize(newBlockSize);
-
- prg.getGlobalData().clear();
-
- int dataSize = Math.min(getValue(false, mem, VM_GLOBALMEMADDR + 0x30),
- VM_GLOBALMEMSIZE - VM_FIXEDGLOBALSIZE);
- if (dataSize != 0) {
- prg.getGlobalData().setSize(dataSize + VM_FIXEDGLOBALSIZE);
- // ->GlobalData.Add(dataSize+VM_FIXEDGLOBALSIZE);
-
- for (int i = 0; i < dataSize + VM_FIXEDGLOBALSIZE; i++) // memcpy(&Prg->GlobalData[0],&Mem[VM_GLOBALMEMADDR],DataSize+VM_FIXEDGLOBALSIZE);
- {
- prg.getGlobalData().set(i, mem[VM_GLOBALMEMADDR + i]);
- }
- }
- }
-
- public byte[] getMem()
- {
- return mem;
- }
-
- private boolean setIP(int ip) {
- if ((ip) >= codeSize) {
- return (true);
- }
-
- if (--maxOpCount <= 0) {
- return (false);
- }
-
- IP = ip;
- return true;
- }
-
- private boolean ExecuteCode(List<VMPreparedCommand> preparedCode,
- int cmdCount) {
-
- maxOpCount = 25000000;
- this.codeSize = cmdCount;
- this.IP = 0;
-
- while (true) {
- VMPreparedCommand cmd = preparedCode.get(IP);
- int op1 = getOperand(cmd.getOp1());
- int op2 = getOperand(cmd.getOp2());
- switch (cmd.getOpCode()) {
- case VM_MOV:
- setValue(cmd.isByteMode(), mem, op1, getValue(cmd.isByteMode(),
- mem, op2)); // SET_VALUE(Cmd->ByteMode,Op1,GET_VALUE(Cmd->ByteMode,Op2));
- break;
- case VM_MOVB:
- setValue(true, mem, op1, getValue(true, mem, op2));
- break;
- case VM_MOVD:
- setValue(false, mem, op1, getValue(false, mem, op2));
- break;
-
- case VM_CMP: {
- int value1 = getValue(cmd.isByteMode(), mem, op1);
- int result = value1 - getValue(cmd.isByteMode(), mem, op2);
-
- if (result == 0) {
- flags = VMFlags.VM_FZ.getFlag();
- } else {
- flags = (result > value1) ? 1 : 0 | (result & VMFlags.VM_FS
- .getFlag());
- }
- }
- break;
-
- case VM_CMPB: {
- int value1 = getValue(true, mem, op1);
- int result = value1 - getValue(true, mem, op2);
- if (result == 0) {
- flags = VMFlags.VM_FZ.getFlag();
- } else {
- flags = (result > value1) ? 1 : 0 | (result & VMFlags.VM_FS
- .getFlag());
- }
- }
- break;
- case VM_CMPD: {
- int value1 = getValue(false, mem, op1);
- int result = value1 - getValue(false, mem, op2);
- if (result == 0) {
- flags = VMFlags.VM_FZ.getFlag();
- } else {
- flags = (result > value1) ? 1 : 0 | (result & VMFlags.VM_FS
- .getFlag());
- }
- }
- break;
-
- case VM_ADD: {
- int value1 = getValue(cmd.isByteMode(), mem, op1);
- int result = (int) ((((long) value1 + (long) getValue(cmd
- .isByteMode(), mem, op2))) & 0xffffffff);
- if (cmd.isByteMode()) {
- result &= 0xff;
- flags = (result < value1) ? 1
- : 0 | (result == 0 ? VMFlags.VM_FZ.getFlag()
- : ((result & 0x80) != 0) ? VMFlags.VM_FS
- .getFlag() : 0);
- // Flags=(Result<Value1)|(Result==0 ? VM_FZ:((Result&0x80) ?
- // VM_FS:0));
- } else
- flags = (result < value1) ? 1
- : 0 | (result == 0 ? VMFlags.VM_FZ.getFlag()
- : (result & VMFlags.VM_FS.getFlag()));
- setValue(cmd.isByteMode(), mem, op1, result);
- }
- break;
-
- case VM_ADDB:
- setValue(true, mem, op1,
- (int) ((long) getValue(true, mem, op1) & 0xFFffFFff
- + (long) getValue(true, mem, op2) & 0xFFffFFff));
- break;
- case VM_ADDD:
- setValue(
- false,
- mem,
- op1,
- (int) ((long) getValue(false, mem, op1) & 0xFFffFFff
- + (long) getValue(false, mem, op2) & 0xFFffFFff));
- break;
-
- case VM_SUB: {
- int value1 = getValue(cmd.isByteMode(), mem, op1);
- int result = (int) ((long) value1 & 0xffFFffFF
- - (long) getValue(cmd.isByteMode(), mem, op2) & 0xFFffFFff);
- flags = (result == 0) ? VMFlags.VM_FZ.getFlag()
- : (result > value1) ? 1 : 0 | (result & VMFlags.VM_FS
- .getFlag());
- setValue(cmd.isByteMode(), mem, op1, result);// (Cmd->ByteMode,Op1,Result);
- }
- break;
-
- case VM_SUBB:
- setValue(true, mem, op1,
- (int) ((long) getValue(true, mem, op1) & 0xFFffFFff
- - (long) getValue(true, mem, op2) & 0xFFffFFff));
- break;
- case VM_SUBD:
- setValue(
- false,
- mem,
- op1,
- (int) ((long) getValue(false, mem, op1) & 0xFFffFFff
- - (long) getValue(false, mem, op2) & 0xFFffFFff));
- break;
-
- case VM_JZ:
- if ((flags & VMFlags.VM_FZ.getFlag()) != 0) {
- setIP(getValue(false, mem, op1));
- continue;
- }
- break;
- case VM_JNZ:
- if ((flags & VMFlags.VM_FZ.getFlag()) == 0) {
- setIP(getValue(false, mem, op1));
- continue;
- }
- break;
- case VM_INC: {
- int result = (int) ((long) getValue(cmd.isByteMode(), mem, op1) & 0xFFffFFff + 1);
- if (cmd.isByteMode()) {
- result &= 0xff;
- }
-
- setValue(cmd.isByteMode(), mem, op1, result);
- flags = result == 0 ? VMFlags.VM_FZ.getFlag() : result
- & VMFlags.VM_FS.getFlag();
- }
- break;
-
- case VM_INCB:
- setValue(
- true,
- mem,
- op1,
- (int) ((long) getValue(true, mem, op1) & 0xFFffFFff + 1));
- break;
- case VM_INCD:
- setValue(false, mem, op1, (int) ((long) getValue(false, mem,
- op1) & 0xFFffFFff + 1));
- break;
-
- case VM_DEC: {
- int result = (int) ((long) getValue(cmd.isByteMode(), mem, op1) & 0xFFffFFff - 1);
- setValue(cmd.isByteMode(), mem, op1, result);
- flags = result == 0 ? VMFlags.VM_FZ.getFlag() : result
- & VMFlags.VM_FS.getFlag();
- }
- break;
-
- case VM_DECB:
- setValue(
- true,
- mem,
- op1,
- (int) ((long) getValue(true, mem, op1) & 0xFFffFFff - 1));
- break;
- case VM_DECD:
- setValue(false, mem, op1, (int) ((long) getValue(false, mem,
- op1) & 0xFFffFFff - 1));
- break;
-
- case VM_JMP:
- setIP(getValue(false, mem, op1));
- continue;
- case VM_XOR: {
- int result = getValue(cmd.isByteMode(), mem, op1)
- ^ getValue(cmd.isByteMode(), mem, op2);
- flags = result == 0 ? VMFlags.VM_FZ.getFlag() : result
- & VMFlags.VM_FS.getFlag();
- setValue(cmd.isByteMode(), mem, op1, result);
- }
- break;
- case VM_AND: {
- int result = getValue(cmd.isByteMode(), mem, op1)
- & getValue(cmd.isByteMode(), mem, op2);
- flags = result == 0 ? VMFlags.VM_FZ.getFlag() : result
- & VMFlags.VM_FS.getFlag();
- setValue(cmd.isByteMode(), mem, op1, result);
- }
- break;
- case VM_OR: {
- int result = getValue(cmd.isByteMode(), mem, op1)
- | getValue(cmd.isByteMode(), mem, op2);
- flags = result == 0 ? VMFlags.VM_FZ.getFlag() : result
- & VMFlags.VM_FS.getFlag();
- setValue(cmd.isByteMode(), mem, op1, result);
- }
- break;
- case VM_TEST: {
- int result = getValue(cmd.isByteMode(), mem, op1)
- & getValue(cmd.isByteMode(), mem, op2);
- flags = result == 0 ? VMFlags.VM_FZ.getFlag() : result
- & VMFlags.VM_FS.getFlag();
- }
- break;
- case VM_JS:
- if ((flags & VMFlags.VM_FS.getFlag()) != 0) {
- setIP(getValue(false, mem, op1));
- continue;
- }
- break;
- case VM_JNS:
- if ((flags & VMFlags.VM_FS.getFlag()) == 0) {
- setIP(getValue(false, mem, op1));
- continue;
- }
- break;
- case VM_JB:
- if ((flags & VMFlags.VM_FC.getFlag()) != 0) {
- setIP(getValue(false, mem, op1));
- continue;
- }
- break;
- case VM_JBE:
- if ((flags & (VMFlags.VM_FC.getFlag() | VMFlags.VM_FZ.getFlag())) != 0) {
- setIP(getValue(false, mem, op1));
- continue;
- }
- break;
- case VM_JA:
- if ((flags & (VMFlags.VM_FC.getFlag() | VMFlags.VM_FZ.getFlag())) == 0) {
- setIP(getValue(false, mem, op1));
- continue;
- }
- break;
- case VM_JAE:
- if ((flags & VMFlags.VM_FC.getFlag()) == 0) {
- setIP(getValue(false, mem, op1));
- continue;
- }
- break;
- case VM_PUSH:
- R[7] -= 4;
- setValue(false, mem, R[7] & VM_MEMMASK, getValue(false, mem,
- op1));
- break;
- case VM_POP:
- setValue(false, mem, op1, getValue(false, mem, R[7]
- & VM_MEMMASK));
- R[7] += 4;
- break;
- case VM_CALL:
- R[7] -= 4;
- setValue(false, mem, R[7] & VM_MEMMASK, IP + 1);
- setIP(getValue(false, mem, op1));
- continue;
- case VM_NOT:
- setValue(cmd.isByteMode(), mem, op1, ~getValue(
- cmd.isByteMode(), mem, op1));
- break;
- case VM_SHL: {
- int value1 = getValue(cmd.isByteMode(), mem, op1);
- int value2 = getValue(cmd.isByteMode(), mem, op2);
- int result = value1 << value2;
- flags = (result == 0 ? VMFlags.VM_FZ.getFlag()
- : (result & VMFlags.VM_FS.getFlag()))
- | (((value1 << (value2 - 1)) & 0x80000000) != 0 ? VMFlags.VM_FC
- .getFlag()
- : 0);
- setValue(cmd.isByteMode(), mem, op1, result);
- }
- break;
- case VM_SHR: {
- int value1 = getValue(cmd.isByteMode(), mem, op1);
- int value2 = getValue(cmd.isByteMode(), mem, op2);
- int result = value1 >>> value2;
- flags = (result == 0 ? VMFlags.VM_FZ.getFlag()
- : (result & VMFlags.VM_FS.getFlag()))
- | ((value1 >>> (value2 - 1)) & VMFlags.VM_FC.getFlag());
- setValue(cmd.isByteMode(), mem, op1, result);
- }
- break;
- case VM_SAR: {
- int value1 = getValue(cmd.isByteMode(), mem, op1);
- int value2 = getValue(cmd.isByteMode(), mem, op2);
- int result = ((int) value1) >> value2;
- flags = (result == 0 ? VMFlags.VM_FZ.getFlag()
- : (result & VMFlags.VM_FS.getFlag()))
- | ((value1 >> (value2 - 1)) & VMFlags.VM_FC.getFlag());
- setValue(cmd.isByteMode(), mem, op1, result);
- }
- break;
- case VM_NEG: {
- int result = -getValue(cmd.isByteMode(), mem, op1);
- flags = result == 0 ? VMFlags.VM_FZ.getFlag() : VMFlags.VM_FC
- .getFlag()
- | (result & VMFlags.VM_FS.getFlag());
- setValue(cmd.isByteMode(), mem, op1, result);
- }
- break;
-
- case VM_NEGB:
- setValue(true, mem, op1, -getValue(true, mem, op1));
- break;
- case VM_NEGD:
- setValue(false, mem, op1, -getValue(false, mem, op1));
- break;
- case VM_PUSHA: {
- for (int i = 0, SP = R[7] - 4; i < regCount; i++, SP -= 4) {
- setValue(false, mem, SP & VM_MEMMASK, R[i]);
- }
- R[7] -= regCount * 4;
- }
- break;
- case VM_POPA: {
- for (int i = 0, SP = R[7]; i < regCount; i++, SP += 4)
- R[7 - i] = getValue(false, mem, SP & VM_MEMMASK);
- }
- break;
- case VM_PUSHF:
- R[7] -= 4;
- setValue(false, mem, R[7] & VM_MEMMASK, flags);
- break;
- case VM_POPF:
- flags = getValue(false, mem, R[7] & VM_MEMMASK);
- R[7] += 4;
- break;
- case VM_MOVZX:
- setValue(false, mem, op1, getValue(true, mem, op2));
- break;
- case VM_MOVSX:
- setValue(false, mem, op1, (byte) getValue(true, mem, op2));
- break;
- case VM_XCHG: {
- int value1 = getValue(cmd.isByteMode(), mem, op1);
- setValue(cmd.isByteMode(), mem, op1, getValue(cmd.isByteMode(),
- mem, op2));
- setValue(cmd.isByteMode(), mem, op2, value1);
- }
- break;
- case VM_MUL: {
- int result = (int) (((long) getValue(cmd.isByteMode(), mem, op1)
- & 0xFFffFFff
- * (long) getValue(cmd.isByteMode(), mem, op2) & 0xFFffFFff) & 0xFFffFFff);
- setValue(cmd.isByteMode(), mem, op1, result);
- }
- break;
- case VM_DIV: {
- int divider = getValue(cmd.isByteMode(), mem, op2);
- if (divider != 0) {
- int result = getValue(cmd.isByteMode(), mem, op1) / divider;
- setValue(cmd.isByteMode(), mem, op1, result);
- }
- }
- break;
- case VM_ADC: {
- int value1 = getValue(cmd.isByteMode(), mem, op1);
- int FC = (flags & VMFlags.VM_FC.getFlag());
- int result = (int) ((long) value1 & 0xFFffFFff
- + (long) getValue(cmd.isByteMode(), mem, op2)
- & 0xFFffFFff + (long) FC & 0xFFffFFff);
- if (cmd.isByteMode()) {
- result &= 0xff;
- }
-
- flags = (result < value1 || result == value1 && FC != 0) ? 1
- : 0 | (result == 0 ? VMFlags.VM_FZ.getFlag()
- : (result & VMFlags.VM_FS.getFlag()));
- setValue(cmd.isByteMode(), mem, op1, result);
- }
- break;
- case VM_SBB: {
- int value1 = getValue(cmd.isByteMode(), mem, op1);
- int FC = (flags & VMFlags.VM_FC.getFlag());
- int result = (int) ((long) value1 & 0xFFffFFff
- - (long) getValue(cmd.isByteMode(), mem, op2)
- & 0xFFffFFff - (long) FC & 0xFFffFFff);
- if (cmd.isByteMode()) {
- result &= 0xff;
- }
- flags = (result > value1 || result == value1 && FC != 0) ? 1
- : 0 | (result == 0 ? VMFlags.VM_FZ.getFlag()
- : (result & VMFlags.VM_FS.getFlag()));
- setValue(cmd.isByteMode(), mem, op1, result);
- }
- break;
-
- case VM_RET:
- if (R[7] >= VM_MEMSIZE) {
- return (true);
- }
- setIP(getValue(false, mem, R[7] & VM_MEMMASK));
- R[7] += 4;
- continue;
-
- case VM_STANDARD:
- ExecuteStandardFilter(VMStandardFilters.findFilter(cmd.getOp1()
- .getData()));
- break;
- case VM_PRINT:
- break;
- }
- IP++;
- --maxOpCount;
- }
- }
-
- public void prepare(byte[] code, int codeSize, VMPreparedProgram prg) {
- InitBitInput();
- int cpLength = Math.min(MAX_SIZE, codeSize);
- for (int i = 0; i < cpLength; i++) // memcpy(inBuf,Code,Min(CodeSize,BitInput::MAX_SIZE));
- {
- inBuf[i] |= code[i];
- }
-
- byte xorSum = 0;
- for (int i = 1; i < codeSize; i++) {
- xorSum ^= code[i];
- }
-
- faddbits(8);
-
- prg.setCmdCount(0);
- if (xorSum == code[0]) {
- VMStandardFilters filterType = IsStandardFilter(code, codeSize);
- if (filterType != VMStandardFilters.VMSF_NONE) {
-
- VMPreparedCommand curCmd = new VMPreparedCommand();
- curCmd.setOpCode(VMCommands.VM_STANDARD);
- curCmd.getOp1().setData(filterType.getFilter());
- curCmd.getOp1().setType(VMOpType.VM_OPNONE);
- curCmd.getOp2().setType(VMOpType.VM_OPNONE);
- codeSize = 0;
- prg.getCmd().add(curCmd);
- prg.setCmdCount(prg.getCmdCount()+1);
- // TODO
- // curCmd->Op1.Data=FilterType;
- // >>>>>> CurCmd->Op1.Addr=&CurCmd->Op1.Data; <<<<<<<<<< not set
- // do i need to ?
- // >>>>>> CurCmd->Op2.Addr=&CurCmd->Op2.Data; <<<<<<<<<< "
- // CurCmd->Op1.Type=CurCmd->Op2.Type=VM_OPNONE;
- // CodeSize=0;
- }
- int dataFlag = fgetbits();
- faddbits(1);
-
- // Read static data contained in DB operators. This data cannot be
- // changed,
- // it is a part of VM code, not a filter parameter.
-
- if ((dataFlag & 0x8000) != 0) {
- long dataSize = (long) ((long) ReadData(this) & 0xffFFffFF + 1);
- for (int i = 0; inAddr < codeSize && i < dataSize; i++) {
- prg.getStaticData().add(
- Byte.valueOf((byte) (fgetbits() >> 8)));
- faddbits(8);
- }
- }
-
- while (inAddr < codeSize) {
- VMPreparedCommand curCmd = new VMPreparedCommand();
- int data = fgetbits();
- if ((data & 0x8000) == 0) {
- curCmd.setOpCode(VMCommands.findVMCommand((data >> 12)));
- faddbits(4);
- } else {
- curCmd.setOpCode(VMCommands
- .findVMCommand((data >> 10) - 24));
- faddbits(6);
- }
- if ((VMCmdFlags.VM_CmdFlags[curCmd.getOpCode().getVMCommand()] & VMCmdFlags.VMCF_BYTEMODE) != 0) {
- curCmd.setByteMode((fgetbits() >> 15) == 1 ? true : false);
- faddbits(1);
- } else {
- curCmd.setByteMode(false);
- }
- curCmd.getOp1().setType(VMOpType.VM_OPNONE);
- curCmd.getOp2().setType(VMOpType.VM_OPNONE);
-
- int opNum = (VMCmdFlags.VM_CmdFlags[curCmd.getOpCode()
- .getVMCommand()] & VMCmdFlags.VMCF_OPMASK);
- // TODO >>> CurCmd->Op1.Addr=CurCmd->Op2.Addr=NULL; <<<???
- if (opNum > 0) {
- decodeArg(curCmd.getOp1(), curCmd.isByteMode());
- if (opNum == 2)
- decodeArg(curCmd.getOp2(), curCmd.isByteMode());
- else {
- if (curCmd.getOp1().getType() == VMOpType.VM_OPINT
- && (VMCmdFlags.VM_CmdFlags[curCmd.getOpCode()
- .getVMCommand()] & (VMCmdFlags.VMCF_JUMP | VMCmdFlags.VMCF_PROC)) != 0) {
- int distance = curCmd.getOp1().getData();
- if (distance >= 256)
- distance -= 256;
- else {
- if (distance >= 136) {
- distance -= 264;
- } else {
- if (distance >= 16) {
- distance -= 8;
- } else {
- if (distance >= 8) {
- distance -= 16;
- }
- }
- }
- distance += prg.getCmdCount();
- }
- curCmd.getOp1().setData(distance);
- }
- }
- }
- prg.setCmdCount(prg.getCmdCount() + 1);
- prg.getCmd().add(curCmd);
- }
- }
- VMPreparedCommand curCmd = new VMPreparedCommand();
- curCmd.setOpCode(VMCommands.VM_RET);
- // TODO CurCmd->Op1.Addr=&CurCmd->Op1.Data;
- // CurCmd->Op2.Addr=&CurCmd->Op2.Data;
- curCmd.getOp1().setType(VMOpType.VM_OPNONE);
- curCmd.getOp2().setType(VMOpType.VM_OPNONE);
-
- // for (int i=0;i<prg.getCmdCount();i++)
- // {
- // VM_PreparedCommand *Cmd=&Prg->Cmd[I];
- // if (Cmd->Op1.Addr==NULL)
- // Cmd->Op1.Addr=&Cmd->Op1.Data;
- // if (Cmd->Op2.Addr==NULL)
- // Cmd->Op2.Addr=&Cmd->Op2.Data;
- // }
-
- prg.getCmd().add(curCmd);
- prg.setCmdCount(prg.getCmdCount()+1);
- // #ifdef VM_OPTIMIZE
- if (codeSize != 0) {
- optimize(prg);
- }
- }
-
- private void decodeArg(VMPreparedOperand op, boolean byteMode) {
- int data = fgetbits();
- if ((data & 0x8000) != 0) {
- op.setType(VMOpType.VM_OPREG);
- op.setData((data >> 12) & 7);
- op.setOffset(op.getData());
- faddbits(4);
- } else {
- if ((data & 0xc000) == 0) {
- op.setType(VMOpType.VM_OPINT);
- if (byteMode) {
- op.setData((data >> 6) & 0xff);
- faddbits(10);
- } else {
- faddbits(2);
- op.setData(ReadData(this));
- }
- } else {
- op.setType(VMOpType.VM_OPREGMEM);
- if ((data & 0x2000) == 0) {
- op.setData((data >> 10) & 7);
- op.setOffset(op.getData());
- op.setBase(0);
- faddbits(6);
- } else {
- if ((data & 0x1000) == 0) {
- op.setData((data >> 9) & 7);
- op.setOffset(op.getData());
- faddbits(7);
- } else {
- op.setData(0);
- faddbits(4);
- }
- op.setBase(ReadData(this));
- }
- }
- }
-
- }
-
- private void optimize(VMPreparedProgram prg) {
- List<VMPreparedCommand> commands = prg.getCmd();
-
- for (VMPreparedCommand cmd : commands) {
- switch (cmd.getOpCode()) {
- case VM_MOV:
- cmd.setOpCode(cmd.isByteMode() ? VMCommands.VM_MOVB
- : VMCommands.VM_MOVD);
- continue;
- case VM_CMP:
- cmd.setOpCode(cmd.isByteMode() ? VMCommands.VM_CMPB
- : VMCommands.VM_CMPD);
- continue;
- }
- if ((VMCmdFlags.VM_CmdFlags[cmd.getOpCode().getVMCommand()] & VMCmdFlags.VMCF_CHFLAGS) == 0) {
- continue;
- }
- boolean flagsRequired = false;
-
- for (int i = commands.indexOf(cmd) + 1; i < commands.size(); i++) {
- int flags = VMCmdFlags.VM_CmdFlags[commands.get(i).getOpCode()
- .getVMCommand()];
- if ((flags & (VMCmdFlags.VMCF_JUMP | VMCmdFlags.VMCF_PROC | VMCmdFlags.VMCF_USEFLAGS)) != 0) {
- flagsRequired = true;
- break;
- }
- if ((flags & VMCmdFlags.VMCF_CHFLAGS) != 0) {
- break;
- }
- }
- if (flagsRequired) {
- continue;
- }
- switch (cmd.getOpCode()) {
- case VM_ADD:
- cmd.setOpCode(cmd.isByteMode() ? VMCommands.VM_ADDB
- : VMCommands.VM_ADDD);
- continue;
- case VM_SUB:
- cmd.setOpCode(cmd.isByteMode() ? VMCommands.VM_SUBB
- : VMCommands.VM_SUBD);
- continue;
- case VM_INC:
- cmd.setOpCode(cmd.isByteMode() ? VMCommands.VM_INCB
- : VMCommands.VM_INCD);
- continue;
- case VM_DEC:
- cmd.setOpCode(cmd.isByteMode() ? VMCommands.VM_DECB
- : VMCommands.VM_DECD);
- continue;
- case VM_NEG:
- cmd.setOpCode(cmd.isByteMode() ? VMCommands.VM_NEGB
- : VMCommands.VM_NEGD);
- continue;
- }
- }
-
- }
-
- public static int ReadData(BitInput rarVM) {
- int data = rarVM.fgetbits();
- switch (data & 0xc000) {
- case 0:
- rarVM.faddbits(6);
- return ((data >> 10) & 0xf);
- case 0x4000:
- if ((data & 0x3c00) == 0) {
- data = 0xffffff00 | ((data >> 2) & 0xff);
- rarVM.faddbits(14);
- } else {
- data = (data >> 6) & 0xff;
- rarVM.faddbits(10);
- }
- return (data);
- case 0x8000:
- rarVM.faddbits(2);
- data = rarVM.fgetbits();
- rarVM.faddbits(16);
- return (data);
- default:
- rarVM.faddbits(2);
- data = (rarVM.fgetbits() << 16);
- rarVM.faddbits(16);
- data |= rarVM.fgetbits();
- rarVM.faddbits(16);
- return (data);
- }
- }
-
- private VMStandardFilters IsStandardFilter(byte[] code, int codeSize) {
- VMStandardFilterSignature stdList[]={
- new VMStandardFilterSignature(53, 0xad576887, VMStandardFilters.VMSF_E8),
- new VMStandardFilterSignature(57, 0x3cd7e57e, VMStandardFilters.VMSF_E8E9),
- new VMStandardFilterSignature(120, 0x3769893f, VMStandardFilters.VMSF_ITANIUM),
- new VMStandardFilterSignature(29, 0x0e06077d, VMStandardFilters.VMSF_DELTA),
- new VMStandardFilterSignature(149, 0x1c2c5dc8, VMStandardFilters.VMSF_RGB),
- new VMStandardFilterSignature(216, 0xbc85e701, VMStandardFilters.VMSF_AUDIO),
- new VMStandardFilterSignature(40, 0x46b9c560, VMStandardFilters.VMSF_UPCASE)
- };
- int CodeCRC = RarCRC.checkCrc(0xffffffff,code,0,code.length)^0xffffffff;
- for (int i=0;i<stdList.length;i++){
- if (stdList[i].getCRC()==CodeCRC && stdList[i].getLength()==code.length){
- return(stdList[i].getType());
- }
-
- }
- return(VMStandardFilters.VMSF_NONE);
- }
-
- private void ExecuteStandardFilter(VMStandardFilters filterType) {
- switch(filterType)
- {
- case VMSF_E8:
- case VMSF_E8E9:
- {
- int dataSize=R[4];
- long fileOffset=R[6]&0xFFffFFff;
-
- if (dataSize>=VM_GLOBALMEMADDR){
- break;
- }
- int fileSize=0x1000000;
- byte cmpByte2=(byte) ((filterType==VMStandardFilters.VMSF_E8E9) ? 0xe9:0xe8);
- for (int curPos=0;curPos<dataSize-4;)
- {
- byte curByte=mem[curPos++];
- if (curByte==0xe8 || curByte==cmpByte2)
- {
-// #ifdef PRESENT_INT32
-// sint32 Offset=CurPos+FileOffset;
-// sint32 Addr=GET_VALUE(false,Data);
-// if (Addr<0)
-// {
-// if (Addr+Offset>=0)
-// SET_VALUE(false,Data,Addr+FileSize);
-// }
-// else
-// if (Addr<FileSize)
-// SET_VALUE(false,Data,Addr-Offset);
-// #else
- long offset=curPos+fileOffset;
- long Addr=getValue(false,mem,curPos);
- if ((Addr & 0x80000000)!=0)
- {
- if (((Addr+offset) & 0x80000000)==0)
- setValue(false,mem,curPos,(int)Addr+fileSize);
- }
- else {
- if (((Addr-fileSize) & 0x80000000)!=0){
- setValue(false,mem,curPos,(int)(Addr-offset));
- }
- }
-// #endif
- curPos+=4;
- }
- }
- }
- break;
- case VMSF_ITANIUM:
- {
-
- int dataSize=R[4];
- long fileOffset=R[6]&0xFFffFFff;
-
- if (dataSize>=VM_GLOBALMEMADDR){
- break;
- }
- int curPos=0;
- final byte Masks[]={4,4,6,6,0,0,7,7,4,4,0,0,4,4,0,0};
- fileOffset>>>=4;
-
- while (curPos<dataSize-21)
- {
- int Byte=(mem[curPos]&0x1f)-0x10;
- if (Byte>=0)
- {
-
- byte cmdMask=Masks[Byte];
- if (cmdMask!=0)
- for (int i=0;i<=2;i++)
- if ((cmdMask & (1<<i))!=0)
- {
- int startPos=i*41+5;
- int opType=filterItanium_GetBits(curPos,startPos+37,4);
- if (opType==5)
- {
- int offset=filterItanium_GetBits(curPos,startPos+13,20);
- filterItanium_SetBits(curPos,(int)(offset-fileOffset)&0xfffff,startPos+13,20);
- }
- }
- }
- curPos+=16;
- fileOffset++;
- }
- }
- break;
- case VMSF_DELTA:
- {
- int dataSize=R[4]&0xFFffFFff;
- int channels=R[0]&0xFFffFFff;
- int srcPos=0;
- int border=(dataSize*2) &0xFFffFFff;
- setValue(false,mem,VM_GLOBALMEMADDR+0x20,(int)dataSize);
- if (dataSize>=VM_GLOBALMEMADDR/2){
- break;
- }
-// bytes from same channels are grouped to continual data blocks,
-// so we need to place them back to their interleaving positions
-
- for (int curChannel=0;curChannel<channels;curChannel++)
- {
- byte PrevByte=0;
- for (int destPos=dataSize+curChannel;destPos<border;destPos+=channels){
- mem[destPos]=(PrevByte-=mem[srcPos++]);
- }
-
- }
- }
- break;
- case VMSF_RGB:
- {
- // byte *SrcData=Mem,*DestData=SrcData+DataSize;
- int dataSize=R[4],width=R[0]-3,posR=R[1];
- int channels=3;
- int srcPos = 0;
- int destDataPos = dataSize;
- setValue(false,mem,VM_GLOBALMEMADDR+0x20,dataSize);
- if (dataSize>=VM_GLOBALMEMADDR/2 || posR<0){
- break;
- }
- for (int curChannel=0;curChannel<channels;curChannel++)
- {
- long prevByte=0;
-
- for (int i=curChannel;i<dataSize;i+=channels)
- {
- long predicted;
- int upperPos=i-width;
- if (upperPos>=3)
- {
- int upperDataPos=destDataPos+upperPos;
- int upperByte=mem[(int)upperDataPos]&0xff;
- int upperLeftByte=mem[upperDataPos-3]&0xff;
- predicted=prevByte+upperByte-upperLeftByte;
- int pa=Math.abs((int)(predicted-prevByte));
- int pb=Math.abs((int)(predicted-upperByte));
- int pc=Math.abs((int)(predicted-upperLeftByte));
- if (pa<=pb && pa<=pc){
- predicted=prevByte;
- }
- else{
- if (pb<=pc){
- predicted=upperByte;
- }
- else{
- predicted=upperLeftByte;
- }
- }
- }
- else{
- predicted=prevByte;
- }
-
- prevByte=(predicted-mem[srcPos++]&0xff)&0xff;
- mem[destDataPos+i]=(byte)(prevByte&0xff);
-
- }
- }
- for (int i=posR,border=dataSize-2;i<border;i+=3)
- {
- byte G=mem[destDataPos+i+1];
- mem[destDataPos+i]+=G;
- mem[destDataPos+i+2]+=G;
- }
- }
- break;
- case VMSF_AUDIO:
- {
- int dataSize=R[4],channels=R[0];
- int srcPos = 0;
- int destDataPos = dataSize;
- //byte *SrcData=Mem,*DestData=SrcData+DataSize;
- setValue(false,mem,VM_GLOBALMEMADDR+0x20,dataSize);
- if (dataSize>=VM_GLOBALMEMADDR/2){
- break;
- }
- for (int curChannel=0;curChannel<channels;curChannel++)
- {
- long prevByte=0;
- long prevDelta=0;
- long Dif[] = new long[7];
- int D1=0,D2=0,D3;
- int K1=0,K2=0,K3=0;
-
- for (int i=curChannel,byteCount=0;i<dataSize;i+=channels,byteCount++)
- {
- D3=D2;
- D2=(int)prevDelta-D1;
- D1=(int)prevDelta;
-
- long predicted=8*prevByte+K1*D1+K2*D2+K3*D3;
- predicted=(predicted>>>3) & 0xff;
-
- long curByte=mem[srcPos++]&0xff;
-
- predicted = (predicted - curByte)&UINT_MASK;
- mem[destDataPos+i]=(byte)predicted;
- prevDelta=(byte)(predicted-prevByte);
- prevByte=predicted;
-
- int D=((byte)curByte)<<3;
-
- Dif[0]+=Math.abs(D);
- Dif[1]+=Math.abs(D-D1);
- Dif[2]+=Math.abs(D+D1);
- Dif[3]+=Math.abs(D-D2);
- Dif[4]+=Math.abs(D+D2);
- Dif[5]+=Math.abs(D-D3);
- Dif[6]+=Math.abs(D+D3);
-
- if ((byteCount & 0x1f)==0)
- {
- long minDif=Dif[0], numMinDif=0;
- Dif[0]=0;
- for (int j=1;j<Dif.length;j++)
- {
- if (Dif[j]<minDif)
- {
- minDif=Dif[j];
- numMinDif=j;
- }
- Dif[j]=0;
- }
- switch((int)numMinDif)
- {
- case 1: if (K1>=-16) K1--; break;
- case 2: if (K1 < 16) K1++; break;
- case 3: if (K2>=-16) K2--; break;
- case 4: if (K2 < 16) K2++; break;
- case 5: if (K3>=-16) K3--; break;
- case 6: if (K3 < 16) K3++; break;
- }
- }
- }
- }
- }
- break;
- case VMSF_UPCASE:
- {
- int dataSize=R[4],srcPos=0,destPos=dataSize;
- if (dataSize>=VM_GLOBALMEMADDR/2){
- break;
- }
- while (srcPos<dataSize)
- {
- byte curByte=mem[srcPos++];
- if (curByte==2 && (curByte=mem[srcPos++])!=2){
- curByte-=32;
- }
- mem[destPos++]=curByte;
- }
- setValue(false,mem,VM_GLOBALMEMADDR+0x1c,destPos-dataSize);
- setValue(false,mem,VM_GLOBALMEMADDR+0x20,dataSize);
- }
- break;
- }
-
- }
-
- private void filterItanium_SetBits(int curPos, int bitField, int bitPos, int bitCount) {
- int inAddr=bitPos/8;
- int inBit=bitPos&7;
- int andMask=0xffffffff>>>(32-bitCount);
- andMask=~(andMask<<inBit);
-
- bitField<<=inBit;
-
- for (int i=0;i<4;i++)
- {
- mem[curPos+inAddr+i]&=andMask;
- mem[curPos+inAddr+i]|=bitField;
- andMask=(andMask>>>8)|0xff000000;
- bitField>>>=8;
- }
-
- }
-
- private int filterItanium_GetBits(int curPos, int bitPos, int bitCount) {
- int inAddr=bitPos/8;
- int inBit=bitPos&7;
- int bitField=(int)(mem[curPos+inAddr++]&0xff);
- bitField|=(int) ((mem[curPos+inAddr++]&0xff) << 8);
- bitField|=(int) ((mem[curPos+inAddr++]&0xff) << 16);
- bitField|=(int) ((mem[curPos+inAddr]&0xff) << 24);
- bitField >>>= inBit;
- return(bitField & (0xffffffff>>>(32-bitCount)));
- }
-
-
- public void setMemory(int pos,byte[] data,int offset,int dataSize)
- {
- if (pos<VM_MEMSIZE){ //&& data!=Mem+Pos)
- //memmove(Mem+Pos,Data,Min(DataSize,VM_MEMSIZE-Pos));
- for (int i = 0; i < Math.min(data.length-offset,dataSize); i++) {
- if((VM_MEMSIZE-pos)<i){
- break;
- }
- mem[pos+i] = data[offset+i];
- }
- }
- }
-
-
-}
-
-// \ No newline at end of file