public DacLibrary(DataTarget dataTarget, string dacDll) { if (dataTarget is null) { throw new ArgumentNullException(nameof(dataTarget)); } if (dataTarget.ClrVersions.Count == 0) { throw new ClrDiagnosticsException("Process is not a CLR process!"); } IntPtr dacLibrary = DataTarget.PlatformFunctions.LoadLibrary(dacDll); if (dacLibrary == IntPtr.Zero) { throw new ClrDiagnosticsException("Failed to load dac: " + dacLibrary); } OwningLibrary = new RefCountedFreeLibrary(dacLibrary); IntPtr initAddr = DataTarget.PlatformFunctions.GetProcAddress(dacLibrary, "DAC_PAL_InitializeDLL"); if (initAddr == IntPtr.Zero) { initAddr = DataTarget.PlatformFunctions.GetProcAddress(dacLibrary, "PAL_InitializeDLL"); } if (initAddr != IntPtr.Zero) { IntPtr dllMain = DataTarget.PlatformFunctions.GetProcAddress(dacLibrary, "DllMain"); if (dllMain == IntPtr.Zero) { throw new ClrDiagnosticsException("Failed to obtain Dac DllMain"); } DllMain main = (DllMain)Marshal.GetDelegateForFunctionPointer(dllMain, typeof(DllMain)); main(dacLibrary, 1, IntPtr.Zero); } IntPtr addr = DataTarget.PlatformFunctions.GetProcAddress(dacLibrary, "CLRDataCreateInstance"); if (addr == IntPtr.Zero) { throw new ClrDiagnosticsException("Failed to obtain Dac CLRDataCreateInstance"); } DacDataTarget = new DacDataTargetWrapper(dataTarget); CreateDacInstance func = (CreateDacInstance)Marshal.GetDelegateForFunctionPointer(addr, typeof(CreateDacInstance)); Guid guid = new Guid("5c552ab6-fc09-4cb3-8e36-22fa03c798b7"); int res = func(ref guid, DacDataTarget.IDacDataTarget, out IntPtr iUnk); if (res != 0) { throw new ClrDiagnosticsException($"Failure loading DAC: CreateDacInstance failed 0x{res:x}", ClrDiagnosticsExceptionKind.DacError, res); } InternalDacPrivateInterface = new ClrDataProcess(this, iUnk); }
static int RoutineAll(DllMain kl) { int errCode = kl.RoutineCtrl(out uint data); if (errCode != (int)ErrCode.NoError) { return(errCode); } string msg = kl.DecodeRoutineCode(data, out int act); Console.WriteLine(msg + "," + act); while (data != 0xAF) { errCode = kl.RoutineCtrl(out data); if (errCode != (int)ErrCode.NoError) { return(errCode); } msg = kl.DecodeRoutineCode(data, out act); Console.WriteLine(msg + "," + act); } return((int)ErrCode.NoError); }
/// <summary> /// Call a manually mapped DLL by DllMain -> DLL_PROCESS_ATTACH. /// </summary> /// <author>Ruben Boonen (@FuzzySec)</author> /// <param name="PEINFO">Module meta data struct (PE.PE_META_DATA).</param> /// <param name="ModuleMemoryBase">Base address of the module in memory.</param> /// <returns>void</returns> private static void CallMappedDLLModule(PE_META_DATA PEINFO, IntPtr ModuleMemoryBase) { IntPtr lpEntryPoint = PEINFO.Is32Bit ? (IntPtr)((UInt64)ModuleMemoryBase + PEINFO.OptHeader32.AddressOfEntryPoint) : (IntPtr)((UInt64)ModuleMemoryBase + PEINFO.OptHeader64.AddressOfEntryPoint); DllMain fDllMain = (DllMain)Marshal.GetDelegateForFunctionPointer(lpEntryPoint, typeof(DllMain)); bool CallRes = fDllMain(ModuleMemoryBase, DLL_PROCESS_ATTACH, IntPtr.Zero); if (!CallRes) { throw new Exception(DSTR(DSTR_DINVOKE_MAIN_FAILED)); } }
static int InitAndGetAllECUInfo(DllMain kl, out string DABS, out string DAPG, out string DSWV) { DAPG = string.Empty; DSWV = string.Empty; int errCode = kl.Initialize(out DABS); if (errCode != (int)ErrCode.NoError) { return(errCode); } Console.WriteLine("DABS: " + DABS); errCode = kl.GetOneECUInfo(out DAPG); if (errCode != (int)ErrCode.NoError) { return(errCode); } Console.WriteLine("DAPG: " + DAPG); errCode = kl.GetOneECUInfo(out DSWV); if (errCode != (int)ErrCode.NoError) { return(errCode); } Console.WriteLine("DSWV: " + DSWV); errCode = kl.GetOneECUInfo(out byte[] temp); if (errCode != (int)ErrCode.NoError) { return(errCode); } Console.Write("Others: "); foreach (var item in temp) { Console.Write(item.ToString("X2") + " "); } Console.WriteLine(); return((int)ErrCode.NoError); }
/// <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 PEOld Load(byte[] PEBytes) { PEOld pe = new PEOld(PEBytes); if (pe.Is32BitHeader) { // Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader32.ImageBase.ToString("X4")); codebase = PInvoke.Win32.Kernel32.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader32.SizeOfImage, Win32.Kernel32.AllocationType.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 = PInvoke.Win32.Kernel32.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader64.SizeOfImage, Win32.Kernel32.AllocationType.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 = PInvoke.Win32.Kernel32.VirtualAlloc(IntPtrAdd(codebase, (int)pe.ImageSectionHeaders[i].VirtualAddress), pe.ImageSectionHeaders[i].SizeOfRawData, Win32.Kernel32.AllocationType.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 = PInvoke.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 = PInvoke.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); DllMain dllmain = (DllMain)Marshal.GetDelegateForFunctionPointer(threadStart, typeof(DllMain)); dllmain(codebase, 1, IntPtr.Zero); // Console.WriteLine("Thread Complete"); return(pe); }
static PluginApiExporter() { DllMain.Main(); }
static B() { DllMain.OnStaticConstructor(); }
static void Main(string[] args) { DllMain kl = new DllMain(Environment.CurrentDirectory); Console.WriteLine("Start Initialize()..."); int code = InitAndGetAllECUInfo(kl, out string DABS, out string DAPG, out string DSWV); Console.WriteLine("Initialize() return code: " + (ErrCode)code); Console.WriteLine(string.Format("DABS:{0}, DAPG:{1}, DSWV:{2}", DABS, DAPG, DSWV)); if (code != (int)ErrCode.NoError) { Console.ReadKey(); return; } Console.WriteLine("Start GetDescription()..."); code = kl.GetAllECUInfo(out DABS, out DAPG, out DSWV); Console.WriteLine("GetDescription() return code: " + (ErrCode)code); Console.WriteLine(string.Format("DABS:{0}, DAPG:{1}, DSWV:{2}", DABS, DAPG, DSWV)); if (code != (int)ErrCode.NoError) { Console.ReadKey(); return; } Console.WriteLine("Start GetDTC()..."); code = kl.ReadDTC(out uint[] DTCs); Console.WriteLine("GetDTC() return code: " + (ErrCode)code); foreach (uint item in DTCs) { Console.Write(item.ToString("X6") + " "); } Console.WriteLine(); if (code != (int)ErrCode.NoError) { Console.ReadKey(); return; } Console.WriteLine("Start ClearDTC()..."); code = kl.ClearDTC(); Console.WriteLine("ClearDTC() return code: " + (ErrCode)code); if (code != (int)ErrCode.NoError) { Console.ReadKey(); return; } //System.Threading.Thread.Sleep(1000); Console.WriteLine("Start RoutineAll()..."); code = RoutineAll(kl); Console.WriteLine("RoutineAll() return code: " + (ErrCode)code); if (code != (int)ErrCode.NoError) { Console.ReadKey(); return; } //System.Threading.Thread.Sleep(1000); Console.WriteLine("Start ReadSensorData()..."); for (int i = 0; i < 43; i++) { code = kl.ReadSensorData(out uint data); Console.WriteLine("ReadSensorData() return code: " + (ErrCode)code); Console.WriteLine(string.Format("LF:{0:X2}, RF:{1:X2}, LR:{2:X2}, RR:{3:X2} - {4}Time(s)", (data >> 24) & 0x000000FF, (data >> 16) & 0x000000FF, (data >> 8) & 0x000000FF, data & 0x000000FF, i + 1)); if (code != (int)ErrCode.NoError) { Console.ReadKey(); return; } } Console.WriteLine("Start Exit()..."); code = kl.Exit(); Console.WriteLine("Exit() return code: " + (ErrCode)code); if (code != (int)ErrCode.NoError) { Console.ReadKey(); return; } Console.ReadKey(); }