// returns target, source and jump for current command private int TSJ(int Command, out Register Target, out Register Source, out int IPJump) { Target = null; Source = null; IPJump = 1; int TargetType = Command & TT, SourceType = Command & ST, Executable = GetExecutable(Command); int TargetValue = Code[IP + 1]; // target is always first argument switch (Executable) // fill the target { case ADD: case SUB: case MUL: case DIV: case MOD: case XOR: case MOV: case NOT: case LE: case EQ: case IAR: case IARND: case CHI: case RET: case LNK: case GTI: case JF: case JMP: case JFL: case JMPL: case JT: case JTL: case GCRC: case GTC: case AESC: case AESD: case GDAT: case EQAR: switch (TargetType) { case TR: Target = Registers[TargetValue]; break; // register case TV: Target = new Register(this, TargetValue); break; // value (create temp register for manIPulations) } break; } switch (Executable) // fill the source { case ADD: case SUB: case MUL: case DIV: case MOD: case XOR: case MOV: case LE: case EQ: case CHI: case LNK: case GTI: case GTC: case GCRC: case AESC: case AESD: case EQAR: int SourceValue = Code[IP + (Executable != CHI ? 2 : 3)]; switch (SourceType) // source is.. { case SR: Source = Registers[SourceValue]; break; // register case SV: Source = new Register(this, SourceValue); break; // value (create temp register for manipulations) } break; case IAR: case IARND: switch (SourceType) // source is.. { case SR: Source = new Register(this, RegisterType.Link); break; // register case SV: Source = new Register(this, RegisterType.Value); break; // value } break; } switch (Executable) // fill the ip jump { case RET: case NOT: case GDAT: IPJump = 2; break; case ADD: case SUB: case MUL: case DIV: case MOD: case XOR: case MOV: case LE: case EQ: case LNK: case GTI: case GTC: case EQAR: IPJump = 3; break; case IAR: IPJump = 4 + Code[IP + 3]; break; case CHI: case CRE: case AESC: case AESD: IPJump = 4; break; case JF: case JMP: case JFL: case JMPL: case JT: case JTL: IPJump = 2; break; case IARND: case GCRC: IPJump = 5; break; } return Executable; }
private void MakeCipherDecipher(int Executable, Register Target, Register Source, Register Key) { if (Target == null || Source == null || Key == null) throw new Exception("One of the registers is nullable"); if (Target.Type != RegisterType.Array || Source.Type != RegisterType.Array || Key.Type != RegisterType.Array) throw new Exception("One of the registers has invalid type"); byte[] KeyBytes = Cvt.ToByteArray(Key.Value as Int32[]); byte[] SourceBytes = Cvt.ToByteArray(Source.Value as Int32[]); var csp = GetAESCSP(KeyBytes); var transform = Executable == AESC ? csp.CreateEncryptor() : csp.CreateDecryptor(); byte[] TargetBytes = transform.TransformFinalBlock(SourceBytes, 0, SourceBytes.Length); Target.InitArray(0, Cvt.ToIntArray(TargetBytes)); }
/// <summary>source xor target</summary> internal void Xor(Register source) { switch (Type) { case RegisterType.Value: IntValue ^= source.FinalValue; break; case RegisterType.Link: LinkedRegisterValue.Xor(source); break; case RegisterType.Array: ArrayValue[ArrayIndex] ^= source.FinalValue; break; } }
public object Run() { Analyze(); // формируем список меток CheckCode(); IP = 0; while (IP >= 0 && IP < Code.Length) { int Command = Code[IP]; Register Target = null, Source = null; int Jump = 1; Int32 Index, Count, CodeValue, Type, Param1; Int32[] Values; // for arrays int Executable = TSJ(Command, out Target, out Source, out Jump); switch (Executable) // исполяемая команда { case CRE: Index = Code[IP + 1]; Type = Code[IP + 2]; Param1 = Code[IP + 3]; switch (Type) { case 0: Registers[Index] = new Register(this, Param1); break; case 1: Registers[Index] = new Register(this, RegisterType.Array); Registers[Index].CreateArray(Param1); break; case 2: Registers[Index] = new Register(this, RegisterType.Link); if (Param1 > 0) Registers[Index].InitLink(Registers[Param1]); break; default: throw new Exception("Invalid type"); } break; case RET: return Target.Value; case ADD: Target.Add(Source); break; case SUB: Target.Sub(Source); break; case MUL: Target.Mul(Source); break; case DIV: Target.Div(Source); break; case MOD: Target.Mod(Source); break; case XOR: Target.Xor(Source); break; case MOV: Target.FinalValue = Source.FinalValue; break; case NOT: Target.FinalValue = ~Target.FinalValue; break; case LE: Flag = Target.FinalValue < Source.FinalValue; break; case EQ: Flag = Target.FinalValue == Source.FinalValue; break; case IAR: Index = Code[IP + 2]; Count = Code[IP + 3]; Values = new Int32[Count]; for (int i = 0; i < Count; i++) { CodeValue = Code[IP + 4 + i]; Values[i] = Source.Type == RegisterType.Value ? CodeValue : Registers[CodeValue].FinalValue; } Target.InitArray(Index, Values); break; case IARND: Index = Code[IP + 2]; Count = Code[IP + 3]; CodeValue = Code[IP + 4]; int Seed = Source.Type == RegisterType.Value ? CodeValue : Registers[CodeValue].FinalValue; Random Rnd = new Random(Seed); Values = new Int32[Count]; for (int i = 0; i < Count; i++) Values[i] = Rnd.Next(); Target.InitArray(Index, Values); break; case EQAR: if (Target.Type == RegisterType.Array && Source.Type == RegisterType.Array) { int TargetCount = Target.GetArrayCount(), SourceCount = Source.GetArrayCount(); if (TargetCount == SourceCount) { Int32[] TargetArray = (Target.Value as Int32[]), SourceArray = (Source.Value as Int32[]); bool IsEqual = true; for (int i = 0; i < TargetCount; i++) { IsEqual = TargetArray[i] == SourceArray[i]; if (!IsEqual) break; } Flag = IsEqual; } else Flag = false; } else Flag = false; break; case CHI: Target.ChangeArrayIndex(Code[IP + 2], Source.FinalValue); break; case LNK: Target.InitLink(Source); break; case GTI: Target.FinalValue = Source.GetArrayIndex(); break; case GTC: Target.FinalValue = Source.GetArrayCount(); break; case GCRC: if (Source.Type != RegisterType.Array) throw new Exception("Invalid source type"); Index = Code[IP + 3]; Count = Code[IP + 4]; if (Index < 0) Index = 0; if (Count == 0) Count = Source.GetArrayCount(); Values = Source.Value as Int32[]; Int32[] intsForCRC = new Int32[Count]; Array.Copy(Values, Index, intsForCRC, 0, Count); byte[] bytesForCRC = Cvt.ToByteArray(intsForCRC); Target.FinalValue = (int)CheckSum.CalcCRC32(bytesForCRC); break; case AESC: case AESD: MakeCipherDecipher(Executable, Target, Source, Registers[Code[IP + 3]]); break; case GDAT: Target.FinalValue = Cvt.DateToInteger(DateTime.Now); break; // jumps case JMP: Jump = Target.FinalValue; break; case JF: Jump = 0; if (!Flag) IP += Target.FinalValue; else IP += 2; break; case JT: Jump = 0; if (Flag) IP += Target.FinalValue; else IP += 2; break; case JMPL: Jump = 0; IP = Labels[Target.FinalValue]; break; case JFL: Jump = 0; if (!Flag) IP = Labels[Target.FinalValue]; else IP += 2; break; case JTL: Jump = 0; if (Flag) IP = Labels[Target.FinalValue]; else IP += 2; break; default: Jump = 1; break; } IP += Jump; } return -1; }
public void InitLink(Register Link) { Type = RegisterType.Link; LinkedRegisterValue = Link; }