Ejemplo n.º 1
0
 public void EsiEbp8()
 {
     // mov    esi,DWORD PTR [ebp-8]
     code = new Byte[] { 0x8b, 0x75, 0xf8 };
     Assert.AreEqual(RegisterName.EBP, ModRM.GetEvFor(code));
     Assert.AreEqual(RegisterName.ESI, ModRM.GetGvFor(code));
     Assert.AreEqual(0xf8, ModRM.GetIndexFor(code));
 }
Ejemplo n.º 2
0
 public void EaxEbx4()
 {
     // mov    eax,DWORD PTR [ebx-4]
     code = new Byte[] { 0x8b, 0x43, 0xfc };
     Assert.AreEqual(RegisterName.EBX, ModRM.GetEvFor(code));
     Assert.AreEqual(RegisterName.EAX, ModRM.GetGvFor(code));
     Assert.AreEqual(0xfc, ModRM.GetIndexFor(code));
 }
Ejemplo n.º 3
0
 public void EdiEbp4()
 {
     // mov    edi,DWORD PTR [ebp-4]
     code = new Byte[] { 0x8b, 0x7d, 0xfc };
     Assert.AreEqual(RegisterName.EBP, ModRM.GetEvFor(code));
     Assert.AreEqual(RegisterName.EDI, ModRM.GetGvFor(code));
     Assert.AreEqual(0xfc, ModRM.GetIndexFor(code));
 }
Ejemplo n.º 4
0
 public void EbxEbp12()
 {
     // mov    ebx,DWORD PTR [ebp-12]
     code = new Byte[] { 0x8b, 0x5d, 0xf4 };
     Assert.AreEqual(RegisterName.EBP, ModRM.GetEvFor(code));
     Assert.AreEqual(RegisterName.EBX, ModRM.GetGvFor(code));
     Assert.IsFalse(ModRM.HasSIB(code));
     Assert.AreEqual(0xf4, ModRM.GetIndexFor(code));
 }
Ejemplo n.º 5
0
 public void TwoByteWithModRMWithIndex()
 {
     // movzx  eax,BYTE PTR [ebp-5]
     code = new Byte[] { 0x0f, 0xb6, 0x45, 0xfb };
     Assert.AreEqual(RegisterName.EBP, ModRM.GetEvFor(code));
     Assert.AreEqual(RegisterName.EAX, ModRM.GetGvFor(code));
     Assert.AreEqual(0xfb, ModRM.GetIndexFor(code));
     Assert.IsTrue(ModRM.IsEffectiveAddressDereferenced(code));
 }
Ejemplo n.º 6
0
 public void TwoByteWithModRMNoIndex()
 {
     // movzx  ebx,BYTE PTR [eax]
     code = new Byte[] { 0x0f, 0xb6, 0x18 };
     Assert.AreEqual(RegisterName.EAX, ModRM.GetEvFor(code));
     Assert.AreEqual(RegisterName.EBX, ModRM.GetGvFor(code));
     Assert.IsFalse(ModRM.HasIndex(code));
     Assert.IsTrue(ModRM.IsEffectiveAddressDereferenced(code));
 }
Ejemplo n.º 7
0
 public void EaxEaxNoIndex()
 {
     // mov    eax,DWORD PTR [eax]
     code = new Byte[] { 0x8b, 0x00 };
     Assert.AreEqual(RegisterName.EAX, ModRM.GetEvFor(code));
     Assert.AreEqual(RegisterName.EAX, ModRM.GetGvFor(code));
     Assert.IsFalse(ModRM.HasIndex(code));
     Assert.IsTrue(ModRM.IsEffectiveAddressDereferenced(code));
 }
Ejemplo n.º 8
0
 public void MovEbpEsp()
 {
     // mov    ebp,esp
     code = new Byte[] { 0x89, 0xe5 };
     Assert.AreEqual(RegisterName.EBP, ModRM.GetEvFor(code));
     Assert.AreEqual(RegisterName.ESP, ModRM.GetGvFor(code));
     Assert.IsFalse(ModRM.HasIndex(code));
     Assert.IsFalse(ModRM.IsEffectiveAddressDereferenced(code));
 }
Ejemplo n.º 9
0
        public void EaxEbpPlusSByte12()
        {
            // mov    eax,DWORD PTR [ebp+index]
            const int INDEX = 0x0c;

            code = new Byte[] { 0x8b, 0x45, INDEX };
            Assert.AreEqual(RegisterName.EBP, ModRM.GetEvFor(code));
            Assert.AreEqual(RegisterName.EAX, ModRM.GetGvFor(code));
            Assert.AreEqual(INDEX, ModRM.GetIndexFor(code));
        }
Ejemplo n.º 10
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);
            }
            }
        }
Ejemplo n.º 11
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);
            }
            }
        }
Ejemplo n.º 12
0
        public RegisterName GetSourceRegisterFor(Byte[] code)
        {
            var opcodeEncoding = GetEncodingFor(code);

            if (GetStackEffectFor(code) ==
                StackEffect.Push)
            {
                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.EbGb:
            case OpcodeEncoding.EvGv:
            {
                return(ModRM.GetGvFor(code));
            }

            case OpcodeEncoding.GvEb:
            case OpcodeEncoding.GvEv:
            case OpcodeEncoding.GvM:
            {
                if (ModRM.HasSIB(code))
                {
                    // MOV EAX,DWORD PTR DS:[EDX+EAX*4]
                    // Since SIB does not have a single source register
                    // it currently returns RegisterName.None
                    return(RegisterName.None);
                }

                if (ModRM.IsEvDword(code))
                {
                    return(RegisterName.None);
                }

                return(ModRM.GetEvFor(code));
            }

            default:
            {
                return(RegisterName.None);
            }
            }
        }
Ejemplo n.º 13
0
 public void GetEvWithSIB()
 {
     code = new Byte[] { 0xc7, 0x04, 0x24, 0x10, 0x00, 0x00, 0x00 };
     Assert.IsTrue(ModRM.HasSIB(code));
     ModRM.GetEvFor(code);
 }