Example #1
0
		public static void AddOpCode(IList<short> instrs, Code code) {
			if ((uint)code <= 0xFF)
				instrs.Add((byte)code);
			else if (((uint)code >> 8) == 0xFE) {
				instrs.Add((byte)((uint)code >> 8));
				instrs.Add(unchecked((byte)code));
			}
			else if (code == Code.UNKNOWN1)
				instrs.AddUnknownByte();
			else if (code == Code.UNKNOWN2)
				instrs.AddUnknownInt16();
			else
				throw new InvalidOperationException();
		}
Example #2
0
        public static void AddOperand(IList<short> instrs, ModuleDefMD module, uint offset, OpCode opCode, object operand)
        {
            Instruction target;
            IVariable variable;
            switch (opCode.OperandType) {
            case OperandType.InlineBrTarget:
                target = operand as Instruction;
                if (target == null)
                    instrs.AddUnknownInt32();
                else
                    instrs.AddInt32(unchecked((int)target.Offset - (int)(offset + 4)));
                break;

            case OperandType.InlineField:
            case OperandType.InlineMethod:
            case OperandType.InlineTok:
            case OperandType.InlineType:
                var tok = operand as ITokenOperand;
                instrs.AddToken(module, tok == null ? 0 : tok.MDToken.Raw);
                break;

            case OperandType.InlineSig:
                var msig = operand as MethodSig;
                instrs.AddToken(module, msig == null ? 0 : msig.OriginalToken);
                break;

            case OperandType.InlineString:
                instrs.AddUnknownInt32();
                break;

            case OperandType.InlineI:
                if (operand is int)
                    instrs.AddInt32((int)operand);
                else
                    instrs.AddUnknownInt32();
                break;

            case OperandType.InlineI8:
                if (operand is long)
                    instrs.AddInt64((long)operand);
                else
                    instrs.AddUnknownInt64();
                break;

            case OperandType.InlineR:
                if (operand is double)
                    instrs.AddDouble((double)operand);
                else
                    instrs.AddUnknownInt64();
                break;

            case OperandType.ShortInlineR:
                if (operand is float)
                    instrs.AddSingle((float)operand);
                else
                    instrs.AddUnknownInt32();
                break;

            case OperandType.InlineSwitch:
                var targets = operand as IList<Instruction>;
                if (targets == null)
                    instrs.AddUnknownInt32();
                else {
                    uint offsetAfter = offset + 4 + (uint)targets.Count * 4;
                    instrs.AddInt32(targets.Count);
                    foreach (var instr in targets) {
                        if (instr == null)
                            instrs.AddUnknownInt32();
                        else
                            instrs.AddInt32(unchecked((int)instr.Offset - (int)offsetAfter));
                    }
                }
                break;

            case OperandType.InlineVar:
                variable = operand as IVariable;
                if (variable == null)
                    instrs.AddUnknownInt16();
                else if (ushort.MinValue <= variable.Index && variable.Index <= ushort.MaxValue)
                    instrs.AddInt16(unchecked((short)variable.Index));
                else
                    instrs.AddUnknownInt16();
                break;

            case OperandType.ShortInlineVar:
                variable = operand as IVariable;
                if (variable == null)
                    instrs.AddUnknownByte();
                else if (byte.MinValue <= variable.Index && variable.Index <= byte.MaxValue)
                    instrs.Add((byte)variable.Index);
                else
                    instrs.AddUnknownByte();
                break;

            case OperandType.ShortInlineBrTarget:
                target = operand as Instruction;
                if (target == null)
                    instrs.AddUnknownByte();
                else {
                    int displ = unchecked((int)target.Offset - (int)(offset + 1));
                    if (sbyte.MinValue <= displ && displ <= sbyte.MaxValue)
                        instrs.Add((short)(displ & 0xFF));
                    else
                        instrs.AddUnknownByte();
                }
                break;

            case OperandType.ShortInlineI:
                if (operand is sbyte)
                    instrs.Add((short)((sbyte)operand & 0xFF));
                else if (operand is byte)
                    instrs.Add((short)((byte)operand & 0xFF));
                else
                    instrs.AddUnknownByte();
                break;

            case OperandType.InlineNone:
            case OperandType.InlinePhi:
                break;

            default: throw new InvalidOperationException();
            }
        }