📄 rarvm.java
字号:
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.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];
}
}
}
}
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -