Esempio n. 1
0
 public void GvMSIBRegisterIndex()
 {
     code = new Byte[] { 0x8d, 0x04, 0x02 };
     Assert.AreEqual(RegisterName.EDX, SIB.GetBaseRegister(code));
     Assert.AreEqual(RegisterName.EAX, SIB.GetScaledRegister(code));
     Assert.AreEqual(1, SIB.GetScaler(code));
 }
Esempio n. 2
0
 public void GetScalerWhenNoSIBPresent()
 {
     // mov    ebp,esp
     code = new Byte[] { 0x89, 0xe5 };
     Assert.IsFalse(ModRM.HasSIB(code));
     SIB.GetScaler(code);
 }
Esempio n. 3
0
        private static String GetDestinationOperandFor(Byte[] code)
        {
            var destinationOperand            = opcode.GetDestinationRegisterFor(code).ToString().ToLower();
            var destinationIsEffectiveAddress =
                opcode.GetEncodingFor(code).ToString().StartsWith("Ev", StringComparison.Ordinal) ||
                opcode.GetEncodingFor(code).ToString().StartsWith("Eb", StringComparison.Ordinal);

            if (destinationIsEffectiveAddress && ModRM.HasSIB(code))
            {
                var baseRegister = SIB.GetBaseRegister(code).ToString().ToLower();
                var scaled       = SIB.GetScaledRegister(code).ToString().ToLower();
                var scaler       = SIB.GetScaler(code);

                if (SIB.GetScaledRegister(code) == RegisterName.None)
                {
                    destinationOperand = baseRegister;
                }
                else if (scaler == 1)
                {
                    destinationOperand = baseRegister + "+" + scaled;
                }
                else
                {
                    destinationOperand = baseRegister + "+" + scaled + "*" + scaler;
                }

                destinationOperand = Encase(destinationOperand);
            }
            else if (opcode.HasModRM(code) && destinationIsEffectiveAddress)
            {
                if (ModRM.HasIndex(code))
                {
                    destinationOperand += "+" + ModRM.GetIndexFor(code);
                }

                var effectiveAddressIsDereferenced = ModRM.IsEffectiveAddressDereferenced(code);
                if (effectiveAddressIsDereferenced)
                {
                    destinationOperand = Encase(destinationOperand);
                }
            }

            return(destinationOperand);
        }
Esempio n. 4
0
        private static string GetSIBFor(byte[] code)
        {
            string sourceOperand;
            var    baseRegister = SIB.GetBaseRegister(code).ToString().ToLower();
            var    scaled       = SIB.GetScaledRegister(code).ToString().ToLower();
            var    scaler       = SIB.GetScaler(code);

            if (SIB.GetScaledRegister(code) == RegisterName.None)
            {
                sourceOperand = baseRegister;
            }
            else if (scaler == 1)
            {
                sourceOperand = baseRegister + "+" + scaled;
            }
            else
            {
                sourceOperand = baseRegister + "+" + scaled + "*" + scaler;
            }
            return(sourceOperand);
        }
Esempio n. 5
0
 public void EvGvSIBNoIndexToEspFromEax()
 {
     code = new Byte[] { 0x89, 0x04, 0x24 };
     Assert.IsTrue(ModRM.HasSIB(code));
     Assert.AreEqual(RegisterName.ESP, SIB.GetBaseRegister(code));
 }
Esempio n. 6
0
        private static MachineState EmulateOpcode(ICollection <ReportItem> reportItems,
                                                  MachineState machineState,
                                                  Byte[] code)
        {
            var           state = machineState;
            RegisterName  sourceRegister, destinationRegister;
            AbstractValue sourceValue;
            Int32         index;

            var encoding = opcode.GetEncodingFor(code);
            var op = opcode.GetOperatorEffectFor(code);

            switch (encoding)
            {
            case OpcodeEncoding.rAxIv:
            case OpcodeEncoding.rAxIz:
            {
                destinationRegister = opcode.GetDestinationRegisterFor(code);
                var immediate = opcode.GetImmediateFor(code);
                state = state.DoOperation(destinationRegister, op, new AbstractValue(immediate));
                return(state);
            }

            case OpcodeEncoding.rAxOv:
            {
                state.Registers[RegisterName.EAX] = state.DataSegment[BitMath.BytesToDword(code, 1)];
                return(state);
            }

            case OpcodeEncoding.rBP:
            case OpcodeEncoding.rSI:
            case OpcodeEncoding.rSP:
            case OpcodeEncoding.rAX:
            case OpcodeEncoding.rBX:
            case OpcodeEncoding.rCX:
            case OpcodeEncoding.rDX:
            case OpcodeEncoding.Iz:
            {
                return(emulateStackEffectFor(code, state));
            }

            case OpcodeEncoding.EvIz:
            case OpcodeEncoding.EvIb:
            case OpcodeEncoding.EbIb:
            case OpcodeEncoding.EvGv:
            case OpcodeEncoding.EbGb:
            {
                destinationRegister = opcode.GetDestinationRegisterFor(code);
                index = 0;

                if (ModRM.HasIndex(code))
                {
                    index = ModRM.GetIndexFor(code);
                }

                if (opcode.HasImmediate(code))
                {
                    sourceValue = new AbstractValue(opcode.GetImmediateFor(code));
                }
                else
                {
                    sourceRegister = ModRM.GetGvFor(code);
                    sourceValue    = state.Registers[sourceRegister];
                }

                ////if (ModRM.HasOffset(code))
                ////{
                ////    UInt32 offset = ModRM.GetOffsetFor(code);
                ////    state.DataSegment[offset] = sourceValue;
                ////    return state;
                ////}

                if (ModRM.IsEffectiveAddressDereferenced(code))
                {
                    if (!state.Registers[destinationRegister].IsPointer)
                    {
                        throw new InvalidOperationException(
                                  "Trying to dereference non-pointer in register " + destinationRegister
                                  );
                    }

                    state = state.DoOperation(destinationRegister, index, op, sourceValue);
                    if (state.Registers[destinationRegister].PointsTo[index].IsOutOfBounds)
                    {
                        reportItems.Add(new ReportItem(state.InstructionPointer, sourceValue.IsTainted));
                    }
                }
                else
                {
                    state = state.DoOperation(destinationRegister, op, sourceValue);
                    if (state.Registers[destinationRegister].IsOutOfBounds)
                    {
                        reportItems.Add(new ReportItem(state.InstructionPointer, sourceValue.IsTainted));
                    }
                }

                return(state);
            }

            case OpcodeEncoding.GvEv:
            case OpcodeEncoding.GvEb:
            {
                sourceRegister      = ModRM.GetEvFor(code);
                destinationRegister = ModRM.GetGvFor(code);
                sourceValue         = state.Registers[sourceRegister];

                if (ModRM.HasOffset(code))
                {
                    var offset = ModRM.GetOffsetFor(code);
                    sourceValue = state.DataSegment[offset];
                }
                else if (ModRM.IsEffectiveAddressDereferenced(code))
                {
                    if (!sourceValue.IsPointer)
                    {
                        throw new InvalidOperationException(
                                  String.Format("Trying to dereference null pointer in register {0}.", sourceRegister));
                    }

                    index = 0;

                    if (ModRM.HasIndex(code))
                    {
                        index = ModRM.GetIndexFor(code);
                    }

                    sourceValue = sourceValue.PointsTo[index];

                    if (sourceValue.IsOutOfBounds)
                    {
                        reportItems.Add(new ReportItem(state.InstructionPointer, sourceValue.IsTainted));
                    }
                }

                state = state.DoOperation(destinationRegister, op, sourceValue);
                return(state);
            }

            case OpcodeEncoding.GvM:
            {
                // GvM, M may refer to [base register + offset]
                if (!ModRM.IsEffectiveAddressDereferenced(code))
                {
                    throw new InvalidOperationException("GvM must be dereferenced");
                }

                destinationRegister = opcode.GetDestinationRegisterFor(code);
                AbstractValue baseRegisterValue;
                index = 0;

                // TODO: handle the [dword] special case
                if (ModRM.HasSIB(code))
                {
                    var scaledRegisterValue = state.Registers[SIB.GetScaledRegister(code)].Value;
                    var scaler = SIB.GetScaler(code);
                    baseRegisterValue = state.Registers[SIB.GetBaseRegister(code)];
                    index             = (Int32)(scaledRegisterValue * scaler);
                }
                else
                {
                    sourceRegister = ModRM.GetEvFor(code);
                    if (ModRM.HasIndex(code))
                    {
                        index = ModRM.GetIndexFor(code);
                    }

                    baseRegisterValue = state.Registers[sourceRegister];
                }

                // TODO: review these casts of index for possible elimination
                sourceValue = new AbstractValue(
                    baseRegisterValue.PointsTo.DoOperation(
                        OperatorEffect.Add,
                        new AbstractValue((UInt32)index)
                        )
                    );

                state = state.DoOperation(destinationRegister, OperatorEffect.Assignment, sourceValue);
                if (state.Registers[destinationRegister].IsOutOfBounds)
                {
                    var reportItem = new ReportItem(state.InstructionPointer, sourceValue.IsTainted);
                    reportItems.Add(reportItem);
                }

                return(state);
            }

            case OpcodeEncoding.ObAL:
            {
                var dwordValue = state.Registers[RegisterName.EAX];
                var byteValue  = dwordValue.TruncateValueToByte();
                var offset     = BitMath.BytesToDword(code, 1);

                if (!state.DataSegment.ContainsKey(offset))
                {
                    state.DataSegment[offset] = new AbstractValue();
                }

                state = state.DoOperation(offset, op, byteValue);
                return(state);
            }

            case OpcodeEncoding.Jz:
            {
                // TODO: should push EIP + code.Length onto stack
                var contractSatisfied      = false;
                var mallocContract         = new MallocContract();
                var glibcStartMainContract = new GLibcStartMainContract();
                var contracts = new List <Contract>
                {
                    mallocContract,
                    glibcStartMainContract
                };

                foreach (var contract in contracts)
                {
                    if (contract.IsSatisfiedBy(state, code))
                    {
                        contractSatisfied = true;
                        state             = contract.Execute(state);
                    }
                }

                if (!contractSatisfied)
                {
                    var returnAddress = state.InstructionPointer + (UInt32)code.Length;
                    state = state.PushOntoStack(new AbstractValue(returnAddress));
                    state.InstructionPointer = opcode.GetEffectiveAddress(code, state.InstructionPointer);
                }

                return(state);
            }

            case OpcodeEncoding.Jb:
            {
                var offset = code[1];

                state = state.DoOperation(op, new AbstractValue(offset));
                state.InstructionPointer += opcode.GetInstructionLengthFor(code);

                return(state);
            }

            case OpcodeEncoding.None:
            {
                return(state);
            }

            default:
            {
                throw new InvalidOpcodeException(code);
            }
            }
        }
Esempio n. 7
0
        public RegisterName GetDestinationRegisterFor(Byte[] code)
        {
            var opcodeEncoding = GetEncodingFor(code);

            if (GetStackEffectFor(code) ==
                StackEffect.Pop)
            {
                switch (opcodeEncoding)
                {
                case OpcodeEncoding.rBP:
                {
                    return(RegisterName.EBP);
                }

                case OpcodeEncoding.rSI:
                {
                    return(RegisterName.ESI);
                }

                case OpcodeEncoding.rSP:
                {
                    return(RegisterName.ESP);
                }

                case OpcodeEncoding.rAX:
                {
                    return(RegisterName.EAX);
                }

                case OpcodeEncoding.rBX:
                {
                    return(RegisterName.EBX);
                }

                case OpcodeEncoding.rCX:
                {
                    return(RegisterName.ECX);
                }

                case OpcodeEncoding.rDX:
                {
                    return(RegisterName.EDX);
                }
                }
            }

            switch (opcodeEncoding)
            {
            case OpcodeEncoding.GvM:
            case OpcodeEncoding.GvEv:
            case OpcodeEncoding.GvEb:
            {
                return(ModRM.GetGvFor(code));
            }

            case OpcodeEncoding.rAxIv:
            case OpcodeEncoding.rAxIz:
            {
                return(RegisterName.EAX);
            }

            case OpcodeEncoding.EbGb:
            case OpcodeEncoding.EbIb:
            case OpcodeEncoding.EvGv:
            case OpcodeEncoding.EvIb:
            case OpcodeEncoding.EvIz:
            {
                if (ModRM.HasSIB(code))
                {
                    return(SIB.GetBaseRegister(code));
                }

                return(ModRM.GetEvFor(code));
            }

            default:
            {
                return(RegisterName.None);
            }
            }
        }