Esempio n. 1
0
        public static void SetFlag(this Win64.CONTEXT ctx, NIContextFlag i, bool value)
        {
            ctx.EFlags -= ctx.GetFlag(i) ? (uint)i : 0;

            ctx.EFlags ^= (value) ? (uint)i : 0;
        }
Esempio n. 2
0
        /// <summary>
        /// Performs a SingleStep operation, that is to stay it resumes the process and pauses at the very next instruction.
        /// Jumps are followed, conditional jumps are evaluated, Calls are either stepped into or over depending on StepIntoCalls value.
        /// </summary>
        /// <returns></returns>
        public NIDebugger64 SingleStep()
        {
            getContext(getCurrentThreadId());
            ulong address = Context.Rip;

            if (address == 0x7ffa79b6660e)
            {
                int i = 0;
            }
            byte[] data;
            ReadData(address, 16, out data);

            if (breakpoints.ContainsKey(address) == true)
            {
                Array.Copy(breakpoints[address].originalBytes, data, 2);
                ClearBreakpoint(address);
            }

            ldasm_data ldata = lde.ldasm(data, 0, false);

            uint  size        = ldata.size;
            ulong nextAddress = Context.Rip + size;

            if (ldata.opcd_size == 1 && (data[ldata.opcd_offset] == 0xEB))
            {
                // we have a 1 byte JMP here
                sbyte offset = (sbyte)data[ldata.imm_offset];
                nextAddress = (ulong)((long)Context.Rip + offset) + ldata.size;
            }

            if ((data[ldata.opcd_offset] == 0xE2))
            {
                // LOOP

                if (Context.Rcx == 1)
                {
                    // this instruction will make ECX 0, so we fall thru the jump now
                    nextAddress = (ulong)((long)Context.Rip + ldata.size);
                }
                else if (Context.Rcx > 1)
                {
                    // this instruction will decrement ECX but it wont be 0 yet, so jump!
                    sbyte disp = (sbyte)data[1];
                    nextAddress = (uint)((long)Context.Rip + disp) + ldata.size;
                }
            }

            if ((data[ldata.opcd_offset] == 0xE0))
            {
                //LOOPNZ LOOPNE
                if (Context.Rcx == 1 && Context.GetFlag(NIContextFlag.ZERO) == false)
                {
                    nextAddress = (ulong)((long)Context.Rip + ldata.size);
                }
                else if (Context.Rcx > 1 || Context.GetFlag(NIContextFlag.ZERO) != false)
                {
                    sbyte disp = (sbyte)data[1];
                    nextAddress = (ulong)((long)Context.Rip + disp) + ldata.size;
                }
            }

            if ((data[ldata.opcd_offset] == 0xE1))
            {
                //LOOPZ LOOPE
                if (Context.Rcx == 1 && Context.GetFlag(NIContextFlag.ZERO) == true)
                {
                    nextAddress = (ulong)((long)Context.Rip + ldata.size);
                }
                else if (Context.Rcx > 1 || Context.GetFlag(NIContextFlag.ZERO) != true)
                {
                    sbyte disp = (sbyte)data[1];
                    nextAddress = (ulong)((long)Context.Rip + disp) + ldata.size;
                }
            }

            if (ldata.opcd_size == 1 && ((data[ldata.opcd_offset] == 0xE9) || (data[ldata.opcd_offset] == 0xE8)))
            {
                // we have a long JMP or CALL here
                int offset = BitConverter.ToInt32(data, ldata.imm_offset);
                if ((data[ldata.opcd_offset] == 0xE9) || (StepIntoCalls && (data[ldata.opcd_offset] == 0xE8)))
                {
                    nextAddress = (ulong)((long)Context.Rip + offset) + ldata.size;
                }
            }

            if (ldata.opcd_size == 1 && ((data[ldata.opcd_offset] >= 0x70 && (data[ldata.opcd_offset] <= 0x7F)) || (data[ldata.opcd_offset] == 0xE3)))
            {
                // we have a 1byte jcc here
                bool willJump = evalJcc(data[ldata.opcd_offset]);

                if (willJump)
                {
                    sbyte offset = (sbyte)data[ldata.imm_offset];
                    nextAddress = (ulong)((long)Context.Rip + offset) + ldata.size;
                }
            }

            if (ldata.opcd_size == 2 && ((data[ldata.opcd_offset] == 0x0F) || (data[ldata.opcd_offset + 1] == 0x80)))
            {
                // we have a 2 byte jcc here

                bool willJump = evalJcc(data[ldata.opcd_offset + 1]);

                if (willJump)
                {
                    int offset = BitConverter.ToInt32(data, ldata.imm_offset);
                    nextAddress = (ulong)(((long)Context.Rip + offset) + ldata.size);
                }
            }

            if (data[ldata.opcd_offset] == 0xC3 || data[ldata.opcd_offset] == 0xC2)
            {
                ReadStackValue(0, out nextAddress);
            }

            if (data[ldata.opcd_offset] == 0xFF && ldata.opcd_size == 1 && ldata.modrm != 0x00)
            {
                // let's parse ModRM!
                var  reg2       = (ldata.modrm & 0x38) >> 3;
                var  mod        = (ldata.modrm & 0xC0) >> 6;
                var  reg1       = (ldata.modrm & 0x7);
                bool addressSet = false;
                if (reg2 == 2)
                {
                    if (StepIntoCalls == false)
                    {
                        nextAddress = (uint)Context.Rip + ldata.size;
                        addressSet  = true;
                    }

                    Console.Write("RegOp tells me this is a CALL\r\n");
                }
                else if (reg2 == 4)
                {
                    Console.Write("RegOp tells me this is a JMP\r\n");
                }
                else
                {
                    nextAddress = (uint)Context.Rip + ldata.size;
                    addressSet  = true;
                }

                if (addressSet == false)
                {
                    if (reg1 == 4)
                    {
                        //txtFacts.Text += "Reg1 is a 4 which means there is a SIB byte\r\n";
                        var ss    = (ldata.sib & 0xC0) >> 6;
                        var index = (ldata.sib & 0x38) >> 3;
                        var Base  = (ldata.sib & 0x07);


                        int scale = (int)Math.Pow(2, ss);
                        nextAddress = (uint)GetRegisterByNumber(index) * (uint)scale;
                        if (Base == 5)
                        {
                            if (mod == 0)
                            {
                                nextAddress = (uint)((int)nextAddress + BitConverter.ToInt32(data, ldata.disp_offset));
                            }
                            else if (mod == 1)
                            {
                                nextAddress += GetRegisterByNumber(Base);
                                nextAddress  = (uint)((int)(nextAddress) + (sbyte)data[ldata.disp_offset]);
                            }
                            else if (mod == 2)
                            {
                                nextAddress += GetRegisterByNumber(Base);
                                nextAddress  = (uint)((int)nextAddress + BitConverter.ToInt32(data, ldata.disp_offset));
                            }
                        }
                    }
                    else
                    {
                        if (mod == 0)
                        {
                            if (reg1 != 5)
                            {
                                nextAddress = GetRegisterByNumber(reg1);
                            }
                            else
                            {
                                nextAddress = (uint)BitConverter.ToInt32(data, ldata.disp_offset);
                            }
                        }
                        else if (mod == 1)
                        {
                            nextAddress = GetRegisterByNumber(reg1);
                            nextAddress = (uint)((int)(nextAddress) + (sbyte)data[ldata.disp_offset]);
                        }
                        else if (mod == 2)
                        {
                            nextAddress = GetRegisterByNumber(reg1);
                            nextAddress = (uint)((int)nextAddress + BitConverter.ToInt32(data, ldata.disp_offset));
                        }
                    }
                    if (mod != 3)
                    {
                        //ReadDWORD(nextAddress, out nextAddress);
                    }

                    Console.WriteLine("Next Address: " + nextAddress.ToString("X8"));
                }
            }

            updateContext(getCurrentThreadId());
            SetBreakpoint(nextAddress);

            Continue();

            ClearBreakpoint(nextAddress);

            return(this);
        }