Exetools  

Go Back   Exetools > General > General Discussion

Notices

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #10  
Old 07-04-2018, 11:34
cachito cachito is offline
Friend
 
Join Date: Aug 2015
Location: argentina
Posts: 58
Rept. Given: 0
Rept. Rcvd 12 Times in 8 Posts
Thanks Given: 162
Thanks Rcvd at 81 Times in 44 Posts
cachito Reputation: 13
I made this loader/debugger long ago for a simple target, but never finished it. It worked for native x64 targets. I don't know if setting 0x01 (bp il opcode) will fire up the ExceptionCode.STATUS_BREAKPOINT. I tried to follow here https://github.com/dotnet/coreclr/blob/master/src/vm/excep.cpp but I am a very bad coder...


Code:
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Microsoft.Samples.Debugging.Native;

namespace Test2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        #region WinNT Definitions
        private const uint CONTEXT_FULL = 0x10007;
        private const ushort IMAGE_DOS_SIGNATURE = 0x5A4D; // MZ
        private const uint IMAGE_NT_SIGNATURE = 0x00004550; // PE00

        private static short SW_SHOWNORMAL = 1;
        private const uint STARTF_USESTDHANDLES = 0x00000100;
        private const uint STARTF_USESHOWWINDOW = 0x00000001;
        private CreateProcessFlags flags;
        #endregion

        private void button1_Click(object sender, EventArgs e)
        {
            // PART 1 !!!!!
            STARTUPINFO si = new STARTUPINFO();
            si.cb = Marshal.SizeOf(si);

            flags = CreateProcessFlags.DEBUG_ONLY_THIS_PROCESS | CreateProcessFlags.CREATE_SUSPENDED;

            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
            CreateProcess(@"test.exe", null, IntPtr.Zero, IntPtr.Zero, false, flags, IntPtr.Zero, null, si, pi);

            // Taken from Kao's solution in part 1 :)

            PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION();
            int d;
            NtQueryInformationProcess(pi.hProcess, 0, ref pbi, Marshal.SizeOf(pbi), out d);

            byte[] dummy2 = new byte[8];
            int dummy;
            // in 64bit OS, main module imagebase is at PEB+0x10
            ReadProcessMemory(pi.hProcess, new IntPtr((Int64)pbi.PebBaseAddress + 0x10), dummy2, (UIntPtr)8, out dummy);
            Int64 realImageBase = BitConverter.ToInt64(dummy2, 0);

            textBox1.Text = realImageBase.ToString("X2");

            // STARTUPINFO
            STARTUPINFO StartupInfo = new STARTUPINFO();
            StartupInfo.dwFlags = (int)(STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW);
            StartupInfo.wShowWindow = SW_SHOWNORMAL;

            /*var IMAGE_SECTION_HEADER = new byte[0x28]; // pish
            var IMAGE_NT_HEADERS = new byte[0xf8]; // pinh
            var IMAGE_DOS_HEADER = new byte[0x40]; // pidh
            var PROCESS_INFO = new int[0x4]; // pi

            byte* pish;
            fixed (byte* p = &IMAGE_SECTION_HEADER[0]) pish = p;

            byte* pinh;
            fixed (byte* p = &IMAGE_NT_HEADERS[0]) pinh = p;

            byte* pidh;
            fixed (byte* p = &IMAGE_DOS_HEADER[0]) pidh = p;

            // Get the DOS header of the EXE.
            ReadProcessMemory(pi.hProcess, new IntPtr(realImageBase), IMAGE_DOS_HEADER, (UIntPtr)IMAGE_DOS_HEADER.Length, out dummy);

            // Sanity check:  See if we have MZ header.
            if (*(ushort*)(pidh + 0x0) != IMAGE_DOS_SIGNATURE)
                MessageBox.Show("Bad MZ header");

            var e_lfanew = *(int*)(pidh + 0x3c);

            textBox2.Text = e_lfanew.ToString("X2");

            // Get the NT header of the EXE.
            ReadProcessMemory(pi.hProcess, new IntPtr(realImageBase + e_lfanew), IMAGE_NT_HEADERS, (UIntPtr)IMAGE_NT_HEADERS.Length, out dummy);

            // Sanity check: See if we have PE00 header.
            if (*(uint*)(pinh + 0x0) != IMAGE_NT_SIGNATURE)
                MessageBox.Show("Bad PE00 header");

            var AddressOfEntryPoint = *(int*)(pinh + 0x28);

            textBox3.Text = AddressOfEntryPoint.ToString("X2");

            byte[] OEPData = new byte[9];
            ReadProcessMemory(pi.hProcess, new IntPtr(realImageBase + AddressOfEntryPoint), OEPData, (UIntPtr)9, out dummy);

            textBox4.Text = BitConverter.ToString(OEPData).Replace("-", "");*/

            // PART 2 !!!!!

            var buffer = new byte[1] { 0xCC };
            var origIN_OUT = new byte[1] { 0x48 };
            var dummy4 = new UIntPtr();
            byte[] buffer2 = new byte[5];

            WriteProcessMemory(pi.hProcess, new IntPtr(realImageBase + 0x1B1AA4), buffer, (UIntPtr)1, out dummy4);
            WriteProcessMemory(pi.hProcess, new IntPtr(realImageBase + 0x1B1AA9), buffer, (UIntPtr)1, out dummy4);

            ContinueStatus dwContinueStatus = ContinueStatus.DBG_CONTINUE;
            DebugEvent64 event64 = new DebugEvent64();

            ResumeThread(pi.hThread);

            bool continuar = true;
            while (continuar)
            {
                if (!WaitForDebugEvent64(ref event64, -1))
                {
                    MessageBox.Show("Debug loop aborted");
                    return;
                }

                switch (event64.header.dwDebugEventCode)
                {
                    case NativeDebugEventCode.EXIT_PROCESS_DEBUG_EVENT:
                        CloseHandle(pi.hThread);
                        CloseHandle(pi.hProcess);
                        return;

                    case NativeDebugEventCode.EXCEPTION_DEBUG_EVENT:
                        {
                            EXCEPTION_DEBUG_INFO exception = event64.union.Exception;

                            switch (exception.ExceptionRecord.ExceptionCode)
                            {
                                case ExceptionCode.STATUS_BREAKPOINT:
                                    {
                                        SuspendThread(pi.hThread); // Always suspend target before getting context or you will get bad data

                                        CONTEXT64 context = new CONTEXT64(); // Create a new Context64 struct.
                                        context.ContextFlags = ContextFlags.AMD64ContextAll;

                                        if (!GetThreadContext(pi.hThread, ref context)) // Read thread context
                                            MessageBox.Show("There was a problem getting context");

                                        if (context.Rip == (ulong)(realImageBase + 0x1B1AA4 + 1)) // Compare in BP
                                        {
                                            context.Rip -= 1; // Change EIP to -1
                                            if (!SetThreadContext(pi.hThread, ref context)) // Update changed context
                                                MessageBox.Show("There was a problem setting context");

                                            // Do the stuff
                                            MessageBox.Show("Message box open");

                                            WriteProcessMemory(pi.hProcess, new IntPtr(realImageBase + 0x1B1AA4), origIN_OUT, (UIntPtr)1, out dummy4); // Set original bytes to resume process

                                        }
                                        if (context.Rip == (ulong)(realImageBase + 0x1B1AA9 + 1)) // Compare out BP
                                        {
                                            context.Rip -= 1; // Change EIP to -1
                                            if (!SetThreadContext(pi.hThread, ref context)) // Update changed context
                                                MessageBox.Show("There was a problem setting context");

                                            // Do the stuff
                                            MessageBox.Show("Message box closed");

                                            WriteProcessMemory(pi.hProcess, new IntPtr(realImageBase + 0x1B1AA9), origIN_OUT, (UIntPtr)1, out dummy4); // Set original bytes to resume process
                                        }

                                        ResumeThread(pi.hThread); // Resume target

                                        await Task.Delay(200); // Small delay before putting BPs back or they might get hit more than once
                                        break;
                                    }

                                default:
                                    {
                                        dwContinueStatus = ContinueStatus.DBG_EXCEPTION_NOT_HANDLED;
                                        break;
                                    }
                            }
                            break;
                        }

                }
                if (!ContinueDebugEvent(event64.header.dwProcessId, event64.header.dwThreadId, dwContinueStatus))
                    MessageBox.Show("Error continuing debug event");

                // Reset
                dwContinueStatus = ContinueStatus.DBG_CONTINUE;

                // Set BPs again
                WriteProcessMemory(pi.hProcess, new IntPtr(realImageBase + 0x1B1AA4), buffer, (UIntPtr)1, out dummy4);
                WriteProcessMemory(pi.hProcess, new IntPtr(realImageBase + 0x1B1AA9), buffer, (UIntPtr)1, out dummy4);
            }
        }

    }
}
Reply With Quote
The Following 2 Users Say Thank You to cachito For This Useful Post:
chants (08-26-2018), taos (07-04-2018)
 

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
.NET dll Memory Patch Avi_RE General Discussion 0 10-14-2023 16:46
Somebody know..., Get a memory value and patch-cut s3ct0r General Discussion 0 07-15-2005 03:50


All times are GMT +8. The time now is 03:20.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( Since 1998 )