Example #1
0
 static bool IsHostPEGUIApp(string path)
 {
     Execute.PE pe = SharpSploit.Execution.PE.Load(File.ReadAllBytes(path));
     return(pe.OptionalHeader64.Subsystem == 2);
 }
Example #2
0
        /// <summary>
        /// Loads a PE with a specified byte array. (Requires Admin) **(*Currently broken. Works for Mimikatz, but not arbitrary PEs*)
        /// </summary>
        /// <param name="PEBytes"></param>
        /// <returns>PE</returns>
        public static PE Load(byte[] PEBytes)
        {
            PE pe = new PE(PEBytes);

            if (pe.Is32BitHeader)
            {
                // Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader32.ImageBase.ToString("X4"));
                codebase = Win32.Kernel32.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader32.SizeOfImage, Win32.Kernel32.MEM_COMMIT, Win32.WinNT.PAGE_EXECUTE_READWRITE);
                // Console.WriteLine("Allocated Space For {0} at {1}", pe.OptionalHeader32.SizeOfImage.ToString("X4"), codebase.ToString("X4"));
            }
            else
            {
                // Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader64.ImageBase.ToString("X4"));
                codebase = Win32.Kernel32.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader64.SizeOfImage, Win32.Kernel32.MEM_COMMIT, Win32.WinNT.PAGE_EXECUTE_READWRITE);
                // Console.WriteLine("Allocated Space For {0} at {1}", pe.OptionalHeader64.SizeOfImage.ToString("X4"), codebase.ToString("X4"));
            }

            // Copy Sections
            for (int i = 0; i < pe.FileHeader.NumberOfSections; i++)
            {
                IntPtr y = Win32.Kernel32.VirtualAlloc(IntPtrAdd(codebase, (int)pe.ImageSectionHeaders[i].VirtualAddress), pe.ImageSectionHeaders[i].SizeOfRawData, Win32.Kernel32.MEM_COMMIT, Win32.WinNT.PAGE_EXECUTE_READWRITE);
                Marshal.Copy(pe.PEBytes, (int)pe.ImageSectionHeaders[i].PointerToRawData, y, (int)pe.ImageSectionHeaders[i].SizeOfRawData);
                // Console.WriteLine("Section {0}, Copied To {1}", new string(pe.ImageSectionHeaders[i].Name), y.ToString("X4"));
            }

            // Perform Base Relocation
            // Calculate Delta
            IntPtr currentbase = codebase;
            long   delta;

            if (pe.Is32BitHeader)
            {
                delta = (int)(currentbase.ToInt32() - (int)pe.OptionalHeader32.ImageBase);
            }
            else
            {
                delta = (long)(currentbase.ToInt64() - (long)pe.OptionalHeader64.ImageBase);
            }
            // Console.WriteLine("Delta = {0}", delta.ToString("X4"));

            // Modify Memory Based On Relocation Table
            IntPtr relocationTable;

            if (pe.Is32BitHeader)
            {
                relocationTable = (IntPtrAdd(codebase, (int)pe.OptionalHeader32.BaseRelocationTable.VirtualAddress));
            }
            else
            {
                relocationTable = (IntPtrAdd(codebase, (int)pe.OptionalHeader64.BaseRelocationTable.VirtualAddress));
            }

            Win32.Kernel32.IMAGE_BASE_RELOCATION relocationEntry = new Win32.Kernel32.IMAGE_BASE_RELOCATION();
            relocationEntry = (Win32.Kernel32.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(Win32.Kernel32.IMAGE_BASE_RELOCATION));

            int    imageSizeOfBaseRelocation = Marshal.SizeOf(typeof(Win32.Kernel32.IMAGE_BASE_RELOCATION));
            IntPtr nextEntry       = relocationTable;
            int    sizeofNextBlock = (int)relocationEntry.SizeOfBlock;
            IntPtr offset          = relocationTable;

            while (true)
            {
                Win32.Kernel32.IMAGE_BASE_RELOCATION relocationNextEntry = new Win32.Kernel32.IMAGE_BASE_RELOCATION();
                IntPtr x = IntPtrAdd(relocationTable, sizeofNextBlock);
                relocationNextEntry = (Win32.Kernel32.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(x, typeof(Win32.Kernel32.IMAGE_BASE_RELOCATION));

                IntPtr dest = IntPtrAdd(codebase, (int)relocationEntry.VirtualAdress);

                for (int i = 0; i < (int)((relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); i++)
                {
                    IntPtr patchAddr;
                    UInt16 value = (UInt16)Marshal.ReadInt16(offset, 8 + (2 * i));

                    UInt16 type  = (UInt16)(value >> 12);
                    UInt16 fixup = (UInt16)(value & 0xfff);

                    switch (type)
                    {
                    case 0x0:
                        break;

                    case 0x3:
                        patchAddr = IntPtrAdd(dest, fixup);
                        //Add Delta To Location.
                        int originalx86Addr = Marshal.ReadInt32(patchAddr);
                        Marshal.WriteInt32(patchAddr, originalx86Addr + (int)delta);
                        break;

                    case 0xA:
                        patchAddr = IntPtrAdd(dest, fixup);
                        //Add Delta To Location.
                        long originalAddr = Marshal.ReadInt64(patchAddr);
                        Marshal.WriteInt64(patchAddr, originalAddr + delta);
                        break;
                    }
                }

                offset           = IntPtrAdd(relocationTable, sizeofNextBlock);
                sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock;
                relocationEntry  = relocationNextEntry;

                nextEntry = IntPtrAdd(nextEntry, sizeofNextBlock);

                if (relocationNextEntry.SizeOfBlock == 0)
                {
                    break;
                }
            }

            // Resolve Imports

            IntPtr z;
            IntPtr oa1;
            int    oa2;

            if (pe.Is32BitHeader)
            {
                z   = IntPtrAdd(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress);
                oa1 = IntPtrAdd(codebase, (int)pe.OptionalHeader32.ImportTable.VirtualAddress);
                oa2 = Marshal.ReadInt32(IntPtrAdd(oa1, 16));
            }
            else
            {
                z   = IntPtrAdd(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress);
                oa1 = IntPtrAdd(codebase, (int)pe.OptionalHeader64.ImportTable.VirtualAddress);
                oa2 = Marshal.ReadInt32(IntPtrAdd(oa1, 16));
            }

            // Get And Display Each DLL To Load
            IntPtr threadStart;
            int    VirtualAddress, AddressOfEntryPoint, ByteSize;

            if (pe.Is32BitHeader)
            {
                VirtualAddress      = (int)pe.OptionalHeader32.ImportTable.VirtualAddress;
                AddressOfEntryPoint = (int)pe.OptionalHeader32.AddressOfEntryPoint;
                ByteSize            = 4;
            }
            else
            {
                VirtualAddress      = (int)pe.OptionalHeader64.ImportTable.VirtualAddress;
                AddressOfEntryPoint = (int)pe.OptionalHeader64.AddressOfEntryPoint;
                ByteSize            = 8;
            }
            int j = 0;

            while (true)
            {
                IntPtr a1          = IntPtrAdd(codebase, (20 * j) + VirtualAddress);
                int    entryLength = Marshal.ReadInt32(IntPtrAdd(a1, 16));
                IntPtr a2          = IntPtrAdd(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress + (entryLength - oa2));
                IntPtr dllNamePTR  = (IntPtr)(IntPtrAdd(codebase, Marshal.ReadInt32(IntPtrAdd(a1, 12))));
                string DllName     = Marshal.PtrToStringAnsi(dllNamePTR);
                if (DllName == "")
                {
                    break;
                }

                IntPtr handle = Win32.Kernel32.LoadLibrary(DllName);
                // Console.WriteLine("Loaded {0}", DllName);
                int k = 0;
                while (true)
                {
                    IntPtr dllFuncNamePTR = (IntPtrAdd(codebase, Marshal.ReadInt32(a2)));
                    string DllFuncName    = Marshal.PtrToStringAnsi(IntPtrAdd(dllFuncNamePTR, 2));
                    IntPtr funcAddy       = Win32.Kernel32.GetProcAddress(handle, DllFuncName);
                    if (pe.Is32BitHeader)
                    {
                        Marshal.WriteInt32(a2, (int)funcAddy);
                    }
                    else
                    {
                        Marshal.WriteInt64(a2, (long)funcAddy);
                    }
                    a2 = IntPtrAdd(a2, ByteSize);
                    if (DllFuncName == "")
                    {
                        break;
                    }
                    k++;
                }
                j++;
            }
            // Transfer Control To OEP
            // Call dllmain
            threadStart = IntPtrAdd(codebase, AddressOfEntryPoint);
            main dllmain = (main)Marshal.GetDelegateForFunctionPointer(threadStart, typeof(main));

            dllmain(codebase, 1, IntPtr.Zero);
            // Console.WriteLine("Thread Complete");
            return(pe);
        }