/// <summary> /// PE Constructor /// </summary> /// <param name="PEBytes">PE raw bytes.</param> public PEOld(byte[] PEBytes) { // Read in the DLL or EXE and get the timestamp using (MemoryStream stream = new MemoryStream(PEBytes, 0, PEBytes.Length)) { BinaryReader reader = new BinaryReader(stream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); UInt32 ntHeadersSignature = reader.ReadUInt32(); FileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); if (this.Is32BitHeader) { OptionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } else { OptionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); } ImageSectionHeaders = new IMAGE_SECTION_HEADER[FileHeader.NumberOfSections]; for (int headerNo = 0; headerNo < ImageSectionHeaders.Length; ++headerNo) { ImageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader); } this.PEBytes = PEBytes; } }
public bool IsRecognizedFormat(Stream stream) { stream.Position = 0; try { // Has a valid MS-DOS header? IMAGE_DOS_HEADER dos_header = new IMAGE_DOS_HEADER(stream); if (dos_header.e_magic != (int)HeaderSignatures.IMAGE_DOS_SIGNATURE) //MZ { return(false); } //Lets position over the "PE" header stream.Seek(dos_header.e_lfanew, SeekOrigin.Begin); //Lets read the NE header IMAGE_NT_HEADERS nt_header = new IMAGE_NT_HEADERS(stream); if (nt_header.Signature != (int)HeaderSignatures.IMAGE_NT_SIGNATURE) //PE { return(false); } return(true); } catch (Exception) {} return(false); }
public static IntPtr GetBaseAddress(IntPtr hProcess) { SYSTEM_INFO system_info; GetSystemInfo(out system_info); IntPtr lpMinimumApplicationAddress = system_info.lpMinimumApplicationAddress; MEMORY_BASIC_INFORMATION structure = new MEMORY_BASIC_INFORMATION(); uint dwLength = (uint)Marshal.SizeOf(structure); while (lpMinimumApplicationAddress.ToInt64() < system_info.lpMaximumApplicationAddress.ToInt64()) { if (!VirtualQueryEx(hProcess, lpMinimumApplicationAddress, out structure, dwLength)) { Console.WriteLine("Could not VirtualQueryEx {0} segment at {1}; error {2}", hProcess.ToInt64(), lpMinimumApplicationAddress.ToInt64(), Marshal.GetLastWin32Error()); return(IntPtr.Zero); } if (((structure.Type == 0x1000000) && (structure.BaseAddress == structure.AllocationBase)) && ((structure.Protect & 0x100) != 0x100)) { IMAGE_DOS_HEADER image_dos_header = ReadUnmanagedStructure <IMAGE_DOS_HEADER>(hProcess, lpMinimumApplicationAddress); if (image_dos_header.e_magic == 0x5a4d) { IntPtr lpAddr = new IntPtr(lpMinimumApplicationAddress.ToInt64() + (image_dos_header.e_lfanew + 4)); if ((ReadUnmanagedStructure <IMAGE_FILE_HEADER>(hProcess, lpAddr).Characteristics & 2) == 2) { return(lpMinimumApplicationAddress); } } } long introduced7 = structure.BaseAddress.ToInt64(); lpMinimumApplicationAddress = new IntPtr(introduced7 + structure.RegionSize.ToInt64()); } return(lpMinimumApplicationAddress); }
private static IMAGE_SECTION_HEADER GetSection(IntPtr hProcess, IntPtr baseAddress, string section) { IMAGE_DOS_HEADER image_dos_header = ReadUnmanagedStructure <IMAGE_DOS_HEADER>(hProcess, baseAddress); IntPtr lpAddr = new IntPtr(baseAddress.ToInt64() + (image_dos_header.e_lfanew + 4)); IMAGE_FILE_HEADER image_file_header = ReadUnmanagedStructure <IMAGE_FILE_HEADER>(hProcess, lpAddr); lpAddr = new IntPtr(lpAddr.ToInt64() + (Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)) + image_file_header.SizeOfOptionalHeader)); for (int i = 0; i < image_file_header.NumberOfSections; i++) { IMAGE_SECTION_HEADER image_section_header = ReadUnmanagedStructure <IMAGE_SECTION_HEADER>(hProcess, lpAddr); lpAddr = new IntPtr(lpAddr.ToInt64() + Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER))); for (int j = 0; j < 8; j++) { if (section.Length == j) { return(image_section_header); } if (section[j] != image_section_header.Name[j]) { break; } } } return(new IMAGE_SECTION_HEADER()); }
} // 3C File address of new exe header public static IMAGE_DOS_HEADER Deserialize(MultiPartFile file) { IMAGE_DOS_HEADER idh = new IMAGE_DOS_HEADER(); idh.Magic = file.ReadUInt16(); idh.LastPageBytes = file.ReadUInt16(); idh.Pages = file.ReadUInt16(); idh.Relocations = file.ReadUInt16(); idh.HeaderParagraphSize = file.ReadUInt16(); idh.MinimumExtraParagraphs = file.ReadUInt16(); idh.MaximumExtraParagraphs = file.ReadUInt16(); idh.InitialSSValue = file.ReadUInt16(); idh.InitialSPValue = file.ReadUInt16(); idh.Checksum = file.ReadUInt16(); idh.InitialIPValue = file.ReadUInt16(); idh.InitialCSValue = file.ReadUInt16(); idh.RelocationTableAddr = file.ReadUInt16(); idh.OverlayNumber = file.ReadUInt16(); idh.Reserved1 = new ushort[Constants.ERES1WDS]; for (int i = 0; i < Constants.ERES1WDS; i++) { idh.Reserved1[i] = file.ReadUInt16(); } idh.OEMIdentifier = file.ReadUInt16(); idh.OEMInformation = file.ReadUInt16(); idh.Reserved2 = new ushort[Constants.ERES2WDS]; for (int i = 0; i < Constants.ERES2WDS; i++) { idh.Reserved2[i] = file.ReadUInt16(); } idh.NewExeHeaderAddr = file.ReadInt32(); return(idh); }
public static DOSHeader FromNativeStruct(IMAGE_DOS_HEADER nativeStruct) { return(new DOSHeader { e_magic = new string(nativeStruct.e_magic), e_cblp = nativeStruct.e_cblp, e_cp = nativeStruct.e_cp, e_crlc = nativeStruct.e_crlc, e_cparhdr = nativeStruct.e_cparhdr, e_minalloc = nativeStruct.e_minalloc, e_maxalloc = nativeStruct.e_maxalloc, e_ss = nativeStruct.e_ss, e_sp = nativeStruct.e_sp, e_csum = nativeStruct.e_csum, e_ip = nativeStruct.e_ip, e_cs = nativeStruct.e_cs, e_lfarlc = nativeStruct.e_lfarlc, e_ovno = nativeStruct.e_ovno, e_res1 = nativeStruct.e_res1, e_oemid = nativeStruct.e_oemid, e_oeminfo = nativeStruct.e_oeminfo, e_res2 = nativeStruct.e_res2, e_lfanew = nativeStruct.e_lfanew }); }
public PeUtility(string filePath) { // Read in the DLL or EXE and get the timestamp Stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite); BinaryReader reader = new BinaryReader(Stream); _dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset Stream.Seek(_dosHeader.e_lfanew, SeekOrigin.Begin); uint ntHeadersSignature = reader.ReadUInt32(); FileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); MainHeaderOffset = Stream.Position; if (Is32BitHeader) { OptionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } else { OptionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); } ImageSectionHeaders = new IMAGE_SECTION_HEADER[FileHeader.NumberOfSections]; for (int headerNo = 0; headerNo < ImageSectionHeaders.Length; ++headerNo) { ImageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader); } }
/// <summary> /// Reading from unmanaged memory pointer address. /// </summary> /// <param name="memPtr"></param> /// <param name="index"></param> private void Load(IntPtr memPtr, long index) { var startIndex = index; dosHeader = FromMemoryPtr <IMAGE_DOS_HEADER>(memPtr, ref index); index = startIndex + dosHeader.e_lfanew + 4; fileHeader = FromMemoryPtr <IMAGE_FILE_HEADER>(memPtr, ref index); // See the optiona header magic to determine 32-bit vs 64-bit var optMagic = Marshal.ReadInt16(new IntPtr(memPtr.ToInt64() + index)); _is32bit = (optMagic != IMAGE_NT_OPTIONAL_HDR64_MAGIC); if (_is32bit) { optionalHeader32 = FromMemoryPtr <IMAGE_OPTIONAL_HEADER32>(memPtr, ref index); } else { optionalHeader64 = FromMemoryPtr <IMAGE_OPTIONAL_HEADER64>(memPtr, ref index); } imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { imageSectionHeaders[headerNo] = FromMemoryPtr <IMAGE_SECTION_HEADER>(memPtr, ref index); } }
public PELoader(byte[] fileBytes) { // Read in the DLL or EXE and get the timestamp using (MemoryStream stream = new MemoryStream(fileBytes, 0, fileBytes.Length)) { BinaryReader reader = new BinaryReader(stream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); if (this.Is32BitHeader) { optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } else { optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); } imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader); } rawbytes = fileBytes; } }
internal DOSHeader(PortableExecutableImage image, IMAGE_DOS_HEADER dosHeader, ulong imageBase) { _image = image; _header = dosHeader; Location = new Location(image, 0, 0, imageBase, Size.ToUInt32(), Size.ToUInt32()); }
public PeHeaderReader(string filePath) { // Read in the DLL or EXE and get the timestamp using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { BinaryReader reader = new BinaryReader(stream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); UInt32 ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); if (this.Is32BitHeader) { optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } else { optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); } imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader); } } }
public static unsafe bool Is64BitDLL(byte[] dllBytes) { bool is64Bit = false; GCHandle scHandle = GCHandle.Alloc(dllBytes, GCHandleType.Pinned); IntPtr scPointer = scHandle.AddrOfPinnedObject(); IMAGE_DOS_HEADER dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(scPointer, typeof(IMAGE_DOS_HEADER)); IntPtr NtHeadersPtr = (IntPtr)((UInt64)scPointer + (UInt64)dosHeader.e_lfanew); var imageNtHeaders64 = (IMAGE_NT_HEADERS64)Marshal.PtrToStructure(NtHeadersPtr, typeof(IMAGE_NT_HEADERS64)); var imageNtHeaders32 = (IMAGE_NT_HEADERS)Marshal.PtrToStructure(NtHeadersPtr, typeof(IMAGE_NT_HEADERS)); if (imageNtHeaders64.Signature != 0x00004550) { throw new ApplicationException("Invalid IMAGE_NT_HEADER signature."); } if (imageNtHeaders64.OptionalHeader.Magic == MagicType.IMAGE_NT_OPTIONAL_HDR64_MAGIC) { is64Bit = true; } scHandle.Free(); return(is64Bit); }
private void Init(Stream stream) { BinaryReader reader = new BinaryReader(stream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); UInt32 ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); if (this.Is32BitHeader) { optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } else { optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); } imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader); } }
public static IntPtr GetBaseAddress(IntPtr hProcess) { SYSTEM_INFO sYSTEM_INFO; GetSystemInfo(out sYSTEM_INFO); IntPtr lpMinimumApplicationAddress = sYSTEM_INFO.lpMinimumApplicationAddress; MEMORY_BASIC_INFORMATION mEMORY_BASIC_INFORMATION = default(MEMORY_BASIC_INFORMATION); uint dwLength = (uint)Marshal.SizeOf(mEMORY_BASIC_INFORMATION); while (lpMinimumApplicationAddress.ToInt64() < sYSTEM_INFO.lpMaximumApplicationAddress.ToInt64()) { if (!VirtualQueryEx(hProcess, lpMinimumApplicationAddress, out mEMORY_BASIC_INFORMATION, dwLength)) { Console.WriteLine("Could not VirtualQueryEx {0} segment at {1}; error {2}", hProcess.ToInt64(), lpMinimumApplicationAddress.ToInt64(), Marshal.GetLastWin32Error()); return(IntPtr.Zero); } if (mEMORY_BASIC_INFORMATION.Type == 16777216u && mEMORY_BASIC_INFORMATION.BaseAddress == mEMORY_BASIC_INFORMATION.AllocationBase && (mEMORY_BASIC_INFORMATION.Protect & 256u) != 256u) { IMAGE_DOS_HEADER iMAGE_DOS_HEADER = ReadUnmanagedStructure <IMAGE_DOS_HEADER>(hProcess, lpMinimumApplicationAddress); if (iMAGE_DOS_HEADER.e_magic == 23117) { IntPtr lpAddr = new IntPtr(lpMinimumApplicationAddress.ToInt64() + (long)(iMAGE_DOS_HEADER.e_lfanew + 4)); if ((ReadUnmanagedStructure <IMAGE_FILE_HEADER>(hProcess, lpAddr).Characteristics & 2) == 2) { return(lpMinimumApplicationAddress); } } } lpMinimumApplicationAddress = new IntPtr(mEMORY_BASIC_INFORMATION.BaseAddress.ToInt64() + mEMORY_BASIC_INFORMATION.RegionSize.ToInt64()); } return(lpMinimumApplicationAddress); }
private void Load(Stream stream) { BinaryReader reader = new BinaryReader(stream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader, null); // Add 4 bytes to the offset stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); UInt32 ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader, null); // Read optional header magic to determin 32-bit vs 64-bit var optMagic = reader.ReadUInt16(); _is32bit = (optMagic != IMAGE_NT_OPTIONAL_HDR64_MAGIC); var lookahead = new byte[] { (byte)(optMagic >> 8), (byte)(optMagic & 0xff) }; if (_is32bit) { optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader, lookahead); } else { optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader, lookahead); } imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader, null); } }
private static extern bool ReadProcessMemory( IntPtr hProcess, IntPtr lpBaseAddress, out IMAGE_DOS_HEADER lpBuffer, int nSize, IntPtr lpNumberOfBytesRead );
public PeUtility([NotNull] Stream srcStream) { curFileStream = srcStream ?? throw new ArgumentNullException(nameof(srcStream)); var reader = new BinaryReader(curFileStream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset srcStream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); var ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); this.fileHeaderOffset = srcStream.Position; if (this.Is32BitHeader) { optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } else { optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); } imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (var headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader); } }
/* Assume the IAT resides at the top of the .rdata segment -> find offset&size of .rdata and patch the entry in the IAT */ static bool FallbackImportPatch(string dllName, IntPtr imageBase, IntPtr oldFuncPtr, IntPtr newPtr) { IMAGE_DOS_HEADER dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(imageBase, typeof(IMAGE_DOS_HEADER)); int ntHeaderPtr = imageBase.ToInt32() + dosHeader.e_lfanew; IMAGE_NT_HEADERS32 ntHeaders = (IMAGE_NT_HEADERS32)Marshal.PtrToStructure((IntPtr)ntHeaderPtr, typeof(IMAGE_NT_HEADERS32)); int sectionHeaderPtr = ntHeaderPtr + 248 /* 248 = sizeof(IMAGE_NT_HEADERS32) */; for (int i = 0; i < ntHeaders.FileHeader.NumberOfSections; i++) { IMAGE_SECTION_HEADER sectionHeader = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure((IntPtr)(sectionHeaderPtr), typeof(IMAGE_SECTION_HEADER)); if (sectionHeader.SectionName.StartsWith(".rdata")) { uint startAddr = (uint)imageBase.ToInt32() + sectionHeader.VirtualAddress; for (uint memAddr = startAddr; memAddr < startAddr + sectionHeader.VirtualSize; memAddr += 4) { if (Marshal.ReadIntPtr((IntPtr)memAddr) == oldFuncPtr) { return(WriteProtectedPtr((IntPtr)memAddr, newPtr)); } } throw new Exception("reached end of .rdata, func ptr not found"); } sectionHeaderPtr += Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)); } throw new Exception("read all sections, .rdata not found"); }
// Get function addresses private static Boolean GetFunctionAddreses(ref IntPtr VirtualAllocAddr, ref IntPtr CreateThreadAddr, ref IntPtr WaitForSingleObjectAddr) { // Get 'Kernel32.dll' image base address IntPtr Kernel32BaseAddr = FindKernel32(); IMAGE_DOS_HEADER ImageDosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(Kernel32BaseAddr, typeof(IMAGE_DOS_HEADER)); MagicType Architecture = (MagicType)Marshal.ReadInt32((IntPtr)(Kernel32BaseAddr.ToInt64() + ImageDosHeader.e_lfanew + 4 + 20)); IMAGE_EXPORT_DIRECTORY ImageExportDirectory; switch (Architecture) { case MagicType.IMAGE_NT_OPTIONAL_HDR32_MAGIC: IMAGE_OPTIONAL_HEADER32 PEHeader32 = (IMAGE_OPTIONAL_HEADER32)Marshal.PtrToStructure((IntPtr)(Kernel32BaseAddr.ToInt64() + ImageDosHeader.e_lfanew + 4 + 20), typeof(IMAGE_OPTIONAL_HEADER32)); ImageExportDirectory = (IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure((IntPtr)(Kernel32BaseAddr.ToInt64() + (int)PEHeader32.ExportTable.VirtualAddress), typeof(IMAGE_EXPORT_DIRECTORY)); break; case MagicType.IMAGE_NT_OPTIONAL_HDR64_MAGIC: IMAGE_OPTIONAL_HEADER64 PEHeader64 = (IMAGE_OPTIONAL_HEADER64)Marshal.PtrToStructure((IntPtr)(Kernel32BaseAddr.ToInt64() + ImageDosHeader.e_lfanew + 4 + 20), typeof(IMAGE_OPTIONAL_HEADER64)); ImageExportDirectory = (IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure((IntPtr)(Kernel32BaseAddr.ToInt64() + (int)PEHeader64.ExportTable.VirtualAddress), typeof(IMAGE_EXPORT_DIRECTORY)); break; default: Console.WriteLine("Failed to identify 'kernel32.dll' architecture"); return(false); } ; // Setup variables for iterating over export table int CurrentFunctionNameAddr; String CurrentFunctionName; // Iterate over export table for (int i = 0; i < ImageExportDirectory.NumberOfNames; i++) { // Get current function's address (pointer) and name (pointer) CurrentFunctionNameAddr = Marshal.ReadInt32((IntPtr)(Kernel32BaseAddr.ToInt64() + (int)ImageExportDirectory.AddressOfNames + (i * 4))); CurrentFunctionName = Marshal.PtrToStringAnsi((IntPtr)(Kernel32BaseAddr.ToInt64() + (int)CurrentFunctionNameAddr)); // Check to see if it is the required function if (CurrentFunctionName.Equals("VirtualAlloc")) { VirtualAllocAddr = (IntPtr)(Kernel32BaseAddr.ToInt64() + Marshal.ReadInt32((IntPtr)(Kernel32BaseAddr.ToInt64() + (int)ImageExportDirectory.AddressOfFunctions + (i * 4)))); } else if (CurrentFunctionName.Equals("CreateThread")) { CreateThreadAddr = (IntPtr)(Kernel32BaseAddr.ToInt64() + Marshal.ReadInt32((IntPtr)(Kernel32BaseAddr.ToInt64() + (int)ImageExportDirectory.AddressOfFunctions + (i * 4)))); } else if (CurrentFunctionName.Equals("WaitForSingleObject")) { WaitForSingleObjectAddr = (IntPtr)(Kernel32BaseAddr.ToInt64() + Marshal.ReadInt32((IntPtr)(Kernel32BaseAddr.ToInt64() + (int)ImageExportDirectory.AddressOfFunctions + (i * 4)))); } // Return if all functions have been found if ((VirtualAllocAddr != IntPtr.Zero) && (CreateThreadAddr != IntPtr.Zero) && (WaitForSingleObjectAddr != IntPtr.Zero)) { return(true); } } return(false); }
public PE32File(IMAGE_DOS_HEADER dosHeader, IMAGE_NT_HEADERS32 peHeader, byte[] dosStub) { Type = PEType.PE32; DOSHeader = DOSHeader.FromNativeStruct(dosHeader); PEHeader = PE32Header.FromNativeStruct(peHeader); Sections = new PESection[peHeader.FileHeader.NumberOfSections]; DOS_Stub = dosStub; }
public PeFile32(IMAGE_DOS_HEADER dosHeader, IMAGE_FILE_HEADER peHeader, IMAGE_OPTIONAL_HEADER32 optionalHeader, IMAGE_EXPORT_DIRECTORY exportDirectory, Dictionary <string, IntPtr> exports) { this.DosHeader = dosHeader; this.PeHeader = peHeader; this.OptionalHeader = optionalHeader; this.ExportDirectory = exportDirectory; Exports = exports; }
public static int Run(byte[] file, string cmd, string location) { GCHandle gHandle = GCHandle.Alloc(file, GCHandleType.Pinned); int iPointer; uint outtt; UIntPtr outt; iPointer = gHandle.AddrOfPinnedObject().ToInt32(); CONTEXT CTX = new CONTEXT(); IMAGE_DOS_HEADER DHD = new IMAGE_DOS_HEADER(); IMAGE_NT_HEADERS NHD = new IMAGE_NT_HEADERS(); IMAGE_SECTION_HEADER SHD = default(IMAGE_SECTION_HEADER); PROCESS_INFORMATION procinf = new PROCESS_INFORMATION(); DHD = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(new IntPtr(iPointer), typeof(IMAGE_DOS_HEADER)); NHD = (IMAGE_NT_HEADERS)Marshal.PtrToStructure(new IntPtr(iPointer + DHD.e_lfanew), typeof(IMAGE_NT_HEADERS)); CreateProcess(location, cmd, IntPtr.Zero, IntPtr.Zero, false, 4, IntPtr.Zero, null, new byte[0x44], out procinf); NtUnmapViewOfSection(procinf.hProcess, (IntPtr)NHD.OptionalHeader.ImageBase); if (VirtualAllocEx(procinf.hProcess, new IntPtr(NHD.OptionalHeader.ImageBase), NHD.OptionalHeader.SizeOfImage, 0x1000 | 0x2000, 0x40) == IntPtr.Zero) { TerminateProcess(procinf.hProcess, 0); return(Run(file, cmd, location)); } CTX.ContextFlags = (0x10000 | 0x01) | (0x10000 | 0x02) | (0x10000 | 0x04); if (IntPtr.Size == 4) { GetThreadContext(procinf.hThread, ref CTX); } else { Wow64GetThreadContext(procinf.hThread, ref CTX); } WriteProcessMemory(procinf.hProcess, new IntPtr(NHD.OptionalHeader.ImageBase), file, NHD.OptionalHeader.SizeOfHeaders, out outt); for (int a = 0; a < NHD.FileHeader.NumberOfSections; a++) { SHD = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(new IntPtr(iPointer + DHD.e_lfanew + Marshal.SizeOf(NHD) + (a * Marshal.SizeOf(SHD))), typeof(IMAGE_SECTION_HEADER)); byte[] bRaw = new byte[SHD.SizeOfRawData + 1]; for (int y = 0; y < (int)SHD.SizeOfRawData; y++) { bRaw[y] = file[SHD.PointerToRawData + y]; } WriteProcessMemory(procinf.hProcess, new IntPtr(NHD.OptionalHeader.ImageBase + SHD.VirtualAddress), bRaw, Convert.ToUInt32(SHD.SizeOfRawData), out outt); VirtualProtectEx(procinf.hProcess, new IntPtr(NHD.OptionalHeader.ImageBase + SHD.VirtualAddress), SHD.VirtualSize, 0x40, out outtt); } byte[] bIB = BitConverter.GetBytes(NHD.OptionalHeader.ImageBase); WriteProcessMemory(procinf.hProcess, new IntPtr(CTX.Ebx + 8), bIB, (uint)bIB.Length, out outt); CTX.Eax = (NHD.OptionalHeader.ImageBase + NHD.OptionalHeader.AddressOfEntryPoint); if (IntPtr.Size == 4) { SetThreadContext(procinf.hThread, ref CTX); } else { Wow64SetThreadContext(procinf.hThread, ref CTX); } ResumeThread(procinf.hThread); return(procinf.dwProcessId); }
private PEFile Dump64BitPE(IntPtr processId, IMAGE_DOS_HEADER dosHeader, byte[] dosStub, IntPtr peHeaderPointer) { IMAGE_NT_HEADERS64 peHeader = ReadProcessStruct <IMAGE_NT_HEADERS64>(processId, peHeaderPointer); if (peHeader.IsValid) { return(new PE64File(dosHeader, peHeader, dosStub)); } return(default);
private PEFile Dump32BitPE(int processId, IMAGE_DOS_HEADER dosHeader, byte[] dosStub, IntPtr peHeaderPointer) { IMAGE_NT_HEADERS32 peHeader = ReadProcessStruct <IMAGE_NT_HEADERS32>(processId, peHeaderPointer); if (peHeader.IsValid) { return(new PE32File(dosHeader, peHeader, dosStub)); } return(default(PEFile)); }
internal unsafe Boolean LoadLibrary(Byte[] data) { //fnDllEntry dllEntry; IMAGE_DOS_HEADER dosHeader = PointerHelpers.ToStruct <IMAGE_DOS_HEADER>(data); IMAGE_NT_HEADERS oldHeader = PointerHelpers.ToStruct <IMAGE_NT_HEADERS>(data, (UInt32)dosHeader.e_lfanew); IntPtr code = (IntPtr)(Win32Imports.VirtualAlloc(oldHeader.OptionalHeader.ImageBase, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_RESERVE, Win32Constants.PAGE_READWRITE)); if (code == IntPtr.Zero) { code = (IntPtr)(Win32Imports.VirtualAlloc((UInt32)code, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_RESERVE, Win32Constants.PAGE_READWRITE)); } _module = new MEMORYMODULE { codeBase = code, numModules = 0, modules = new IntPtr(0), initialized = 0 }; Win32Imports.VirtualAlloc((UInt32)code, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_COMMIT, Win32Constants.PAGE_READWRITE); IntPtr headers = (IntPtr)(Win32Imports.VirtualAlloc((UInt32)code, oldHeader.OptionalHeader.SizeOfHeaders, Win32Constants.MEM_COMMIT, Win32Constants.PAGE_READWRITE)); Marshal.Copy(data, 0, headers, (Int32)(dosHeader.e_lfanew + oldHeader.OptionalHeader.SizeOfHeaders)); _module.headers = PointerHelpers.ToStruct <IMAGE_NT_HEADERS>(headers, (UInt32)dosHeader.e_lfanew); _module.headers.OptionalHeader.ImageBase = (UInt32)code; this.CopySections(data, oldHeader, headers, dosHeader); UInt32 locationDelta = (UInt32)(code.ToInt32() - oldHeader.OptionalHeader.ImageBase); if (locationDelta != 0) { this.PerformBaseRelocation(locationDelta); } this.BuildImportTable(); this.FinalizeSections(headers, dosHeader, oldHeader); Boolean success = false; try { fnDllEntry dllEntry = (fnDllEntry)Marshal.GetDelegateForFunctionPointer( new IntPtr(_module.codeBase.ToInt32() + (Int32)_module.headers.OptionalHeader.AddressOfEntryPoint), typeof(fnDllEntry)); success = dllEntry(code.ToInt32(), 1, (void *)0); } catch (Exception exc) { System.Diagnostics.Trace.WriteLine(exc.Message); return(false); } return(success); }
private void button2_Click(object sender, EventArgs e) { lsect.Clear(); FileStream fs = new FileStream("Sample_exe\\explorer.exe", FileMode.Open, FileAccess.Read, FileShare.Read); s = pe_hlp.ReadImDosHeader(fs); //считали из файла в структуру IMAGE_DOS_HEADER uint size_dos_stub = s.e_lfanew - s.e_lfarlc;//определили величину стаба byte[] stub = new byte[size_dos_stub]; fs.Read(stub, 0, (int)size_dos_stub);//поместили в stub стаб nt_h = pe_hlp.ReadImNtHeaders(fs); //считали из файла в структуру IMAGE_NT_HEADERS //теперь указатель чтения на позиции начала секций DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0); dt = dt.AddSeconds(nt_h.FileHeader.TimeDateStamp); MachineType mt = (MachineType)nt_h.FileHeader.Machine; string str = mt.ToString(); //0x00006000+0x00400000 for (int i = 0; i < (int)nt_h.FileHeader.NumberOfSections; i++) { IMAGE_SECTION_HEADER sc_h = new IMAGE_SECTION_HEADER(); sc_h = pe_hlp.ReadImSecHeaders(fs); string section_name = Encoding.ASCII.GetString(sc_h.Name); lsect.Add(sc_h); //считали из файла в структуру IMAGE_SECTION_HEADER очередную секцию } //Итак, мы прочитали заголовки... uint align = nt_h.OptionalHeader.SizeOfHeaders - (uint)fs.Position; al_hzch = new byte[align]; fs.Read(al_hzch, 0, (int)align);//почитали байты до начала секций //А мона было воспользоваться FileAlignment //Читаем все секции сразу (чем руковод.: SizeOfHeaders или позицией читателя?) ushort cnt_sc = nt_h.FileHeader.NumberOfSections; uint point_last_sect = (lsect[cnt_sc - 1].PointerToRawData + lsect[cnt_sc - 1].SizeOfRawData) - nt_h.OptionalHeader.SizeOfHeaders; al_sc = new byte[point_last_sect]; fs.Read(al_sc, 0, (int)point_last_sect);//почитали до конца файла fs.Close(); dosHeader1.PrintIDH(s); ntHeaders1.PrintINTH(nt_h); sections1.PrintSect(lsect); }
public PeParser(byte[] PeBuffer) { this.PeBuffer = PeBuffer; this.DosHeader = ByteArrayToStructure <IMAGE_DOS_HEADER>(PeBuffer .Take(Marshal.SizeOf(typeof(IMAGE_DOS_HEADER))) .ToArray()); this.NtHeaders = ByteArrayToStructure <IMAGE_NT_HEADERS32>(PeBuffer .Skip(this.DosHeader.e_lfanew) .Take(Marshal.SizeOf(typeof(IMAGE_NT_HEADERS32))) .ToArray()); }
public UInt32 e_lfanew; // File address of new exe header public IMAGE_DOS_HEADER(BinaryReader reader) { IMAGE_DOS_HEADER hdr = new IMAGE_DOS_HEADER(); this = hdr; byte[] buffer = new byte[Marshal.SizeOf(this)]; reader.Read(buffer, 0, buffer.Length); hdr = buffer.ToStructure <IMAGE_DOS_HEADER>(); this = hdr; }
public static IntPtr Rva2Offset(UInt32 dwRva, IntPtr PEPointer) { bool is64Bit = false; UInt16 wIndex = 0; UInt16 wNumberOfSections = 0; IntPtr imageSectionPtr; IMAGE_SECTION_HEADER SectionHeader; int sizeOfSectionHeader = Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)); IMAGE_DOS_HEADER dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(PEPointer, typeof(IMAGE_DOS_HEADER)); IntPtr NtHeadersPtr = (IntPtr)((UInt64)PEPointer + (UInt64)dosHeader.e_lfanew); var imageNtHeaders32 = (IMAGE_NT_HEADERS32)Marshal.PtrToStructure(NtHeadersPtr, typeof(IMAGE_NT_HEADERS32)); var imageNtHeaders64 = (IMAGE_NT_HEADERS64)Marshal.PtrToStructure(NtHeadersPtr, typeof(IMAGE_NT_HEADERS64)); if (imageNtHeaders64.OptionalHeader.Magic == MagicType.IMAGE_NT_OPTIONAL_HDR64_MAGIC) { is64Bit = true; } if (is64Bit) { imageSectionPtr = (IntPtr)(((Int64)NtHeadersPtr + (Int64)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS64), "OptionalHeader") + (Int64)imageNtHeaders64.FileHeader.SizeOfOptionalHeader)); SectionHeader = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(imageSectionPtr, typeof(IMAGE_SECTION_HEADER)); wNumberOfSections = imageNtHeaders64.FileHeader.NumberOfSections; } else { imageSectionPtr = (IntPtr)(((Int64)NtHeadersPtr + (Int64)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS32), "OptionalHeader") + (Int64)imageNtHeaders32.FileHeader.SizeOfOptionalHeader)); SectionHeader = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(imageSectionPtr, typeof(IMAGE_SECTION_HEADER)); wNumberOfSections = imageNtHeaders32.FileHeader.NumberOfSections; } if (dwRva < SectionHeader.PointerToRawData) { return((IntPtr)((UInt64)dwRva + (UInt64)PEPointer)); } for (wIndex = 0; wIndex < wNumberOfSections; wIndex++) { SectionHeader = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure((IntPtr)((UInt32)imageSectionPtr + (UInt32)(sizeOfSectionHeader * (wIndex))), typeof(IMAGE_SECTION_HEADER)); if (dwRva >= SectionHeader.VirtualAddress && dwRva < (SectionHeader.VirtualAddress + SectionHeader.SizeOfRawData)) { return((IntPtr)((UInt64)(dwRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData) + (UInt64)PEPointer)); } } return(IntPtr.Zero); }
public MultiIcon Load(Stream stream) { stream.Position = 0; //Lets read the MS DOS header IMAGE_DOS_HEADER dos_header = new IMAGE_DOS_HEADER(stream); if (dos_header.e_magic != (int) HeaderSignatures.IMAGE_DOS_SIGNATURE) //MZ throw new InvalidICLFileException(); //Lets position over the "NE" header stream.Seek(dos_header.e_lfanew, SeekOrigin.Begin); //Lets read the NE header IMAGE_OS2_HEADER os2_header = new IMAGE_OS2_HEADER(stream); if (os2_header.ne_magic != (int) HeaderSignatures.IMAGE_OS2_SIGNATURE) //NE throw new InvalidICLFileException(); //Lets position over the "Resource Table" stream.Seek(os2_header.ne_rsrctab + dos_header.e_lfanew, SeekOrigin.Begin); //Resource Table doesn't contain ICON resources if (os2_header.ne_restab == os2_header.ne_rsrctab) return new MultiIcon(); //Lets read the Resource Table RESOURCE_TABLE resource_table = new RESOURCE_TABLE(stream); Dictionary<ushort, IconImage> icons = resource_table.GetIcons(stream); List<GRPICONDIR> groupIcons = resource_table.GetGroupIcons(stream); List<string> groupNames = new List<string>(resource_table.ResourceNames); if (groupNames[0].ToLower() == "icl") groupNames.RemoveAt(0); SingleIcon[] singleIcons = new SingleIcon[groupIcons.Count]; for(int i=0; i<singleIcons.Length; i++) { if (i < groupNames.Count) singleIcons[i] = new SingleIcon(groupNames[i]); else { string freeName = FindFreeName(groupNames); groupNames.Add(freeName); singleIcons[i] = new SingleIcon(freeName); } foreach(GRPICONDIRENTRY iconEntry in groupIcons[i].idEntries) singleIcons[i].Add(icons[iconEntry.nID]); } // If everything went well then lets create the multiIcon. return new MultiIcon(singleIcons); }
public bool IsPE(string fileName) { using (var stream = new FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { var reader = new BinaryReader(stream); var peHeader = reader.ReadBytes(2); // PE Header is less than the minimum if (peHeader.Length < 2) { return(false); } // Check the first two bytes to rule out anything not DLL, EXE, SYS etc if (peHeader[0] != (byte)'M' && peHeader[1] != (byte)'Z') { return(false); } reader.BaseStream.Seek(0, SeekOrigin.Begin); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); var ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); if (Is32BitHeader) { optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } else { optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); } imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (var headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo) { imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader); } return(true); } }
public bool IsRecognizedFormat(Stream stream) { stream.Position = 0; try { // Has a valid MS-DOS header? IMAGE_DOS_HEADER dos_header = new IMAGE_DOS_HEADER(stream); if (dos_header.e_magic != (int) HeaderSignatures.IMAGE_DOS_SIGNATURE) //MZ return false; //Lets position over the "NE" header stream.Seek(dos_header.e_lfanew, SeekOrigin.Begin); //Lets read the NE header IMAGE_OS2_HEADER os2_header = new IMAGE_OS2_HEADER(stream); if (os2_header.ne_magic != (int) HeaderSignatures.IMAGE_OS2_SIGNATURE) //NE return false; return true; } catch(Exception){} return false; }
/// <summary> /// This function loads the header and PE header at the /// specified address in memory. /// </summary> /// <param name="process"></param> /// <param name="address"></param> public oHeaderReader(Process process, UInt64 address) { codeStartAddress = 0; codeLength = 0; invalidCodeAddresses = new List<ADDRESS_RANGE>(0); // Read in the Image Dos Header importTable = new List<IMPORT_FUNCTION>(0); byte[] headerData = oMemoryFunctions.readMemory(process, address, (uint)Marshal.SizeOf(typeof(IMAGE_DOS_HEADER))); dosHeader = (IMAGE_DOS_HEADER)oMemoryFunctions.RawDataToObject(ref headerData, typeof(IMAGE_DOS_HEADER)); // Load the PE Address UInt64 PE_header = 0; if (dosHeader.e_magic == 0x5A4D) { // Load the PE header address PE_header = dosHeader.e_lfanew + address; } else { PE_header = address; } // Read in the PE token byte[] PE_Token = oMemoryFunctions.readMemory(process, PE_header, 4); if (!(PE_Token[0] == 'P' & PE_Token[1] == 'E' & PE_Token[2] == 0 & PE_Token[3] == 0)) { // Problem, we are not pointing at a correct PE header. Abort. oConsole.printMessage("Failed to read PE header from block " + address.ToString("X") + " with PE header located at " + PE_header.ToString() + "."); return; } // Input the COFFHeader byte[] coffHeader_rawData = oMemoryFunctions.readMemory(process, PE_header + 4, (uint)Marshal.SizeOf(typeof(COFFHeader))); coffHeader = (COFFHeader)oMemoryFunctions.RawDataToObject(ref coffHeader_rawData, typeof(COFFHeader)); // Read in the PEOptHeader if it exists if (coffHeader.SizeOfOptionalHeader != 0) { if (coffHeader.SizeOfOptionalHeader != (ushort)Marshal.SizeOf(typeof(PEOptHeader))) { // Problem! oConsole.printMessage("Failed to read COFFHeader as a result of size mismatch. Size of expected COFFHeader, " + ((ushort)Marshal.SizeOf(typeof(PEOptHeader))).ToString() + ", does not equal size of SizeOfOptionalHeader, " + coffHeader.SizeOfOptionalHeader.ToString() + "."); return; } else { // Read in the optHeader byte[] optHeader_rawData = oMemoryFunctions.readMemory(process, PE_header + 4 + (uint)Marshal.SizeOf(typeof(COFFHeader)), (uint)Marshal.SizeOf(typeof(PEOptHeader))); optHeader = (PEOptHeader)oMemoryFunctions.RawDataToObject(ref optHeader_rawData, typeof(PEOptHeader)); // Confirm that it loaded correctly if (optHeader.signature != 267) { oConsole.printMessage("Failed to read optHeader; Expected signature of 267 does not match read in signature of " + optHeader.signature.ToString() + "."); return; } } } else { // No COFFHeader found oConsole.printMessage("Warning, no COFFHeader found for address " + address.ToString("X") + "."); return; } // Add all the directories as invalid code ranges try { if (optHeader.DataDirectory1_export.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory1_export.VirtualAddress), optHeader.DataDirectory1_export.Size)); if (optHeader.DataDirectory2_import.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory2_import.VirtualAddress), optHeader.DataDirectory2_import.Size)); if (optHeader.DataDirectory3.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory3.VirtualAddress), optHeader.DataDirectory3.Size)); if (optHeader.DataDirectory4.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory4.VirtualAddress), optHeader.DataDirectory4.Size)); if (optHeader.DataDirectory5.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory5.VirtualAddress), optHeader.DataDirectory5.Size)); if (optHeader.DataDirectory6.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory6.VirtualAddress), optHeader.DataDirectory6.Size)); if (optHeader.DataDirectory7.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory7.VirtualAddress), optHeader.DataDirectory7.Size)); if (optHeader.DataDirectory8.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory8.VirtualAddress), optHeader.DataDirectory8.Size)); if (optHeader.DataDirectory9.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory9.VirtualAddress), optHeader.DataDirectory9.Size)); if (optHeader.DataDirectory10.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory10.VirtualAddress), optHeader.DataDirectory10.Size)); if (optHeader.DataDirectory11.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory11.VirtualAddress), optHeader.DataDirectory11.Size)); if (optHeader.DataDirectory12.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory12.VirtualAddress), optHeader.DataDirectory12.Size)); if (optHeader.DataDirectory13.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory13.VirtualAddress), optHeader.DataDirectory13.Size)); if (optHeader.DataDirectory14.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory14.VirtualAddress), optHeader.DataDirectory14.Size)); if (optHeader.DataDirectory15.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory15.VirtualAddress), optHeader.DataDirectory15.Size)); if (optHeader.DataDirectory16.Size > 0) invalidCodeAddresses.Add( new ADDRESS_RANGE( oMemoryFunctions.addressAdd(address, optHeader.DataDirectory16.VirtualAddress), optHeader.DataDirectory16.Size)); }catch { // Ignore exceptions, this is not cretical. } // Extract the names of the functions and corresponding table entries uint importTableAddress = oMemoryFunctions.addressAdd(optHeader.DataDirectory2_import.VirtualAddress,(uint) address); uint exportTableAddress = oMemoryFunctions.addressAdd(optHeader.DataDirectory1_export.VirtualAddress, (uint) address); // Load the sections UInt64 sectionAddress = PE_header + 4 + (UInt64)Marshal.SizeOf(typeof(COFFHeader)) + coffHeader.SizeOfOptionalHeader; List<section> sections = new List<section>(coffHeader.NumberOfSections); for (int i = 0; i < coffHeader.NumberOfSections; i++) { sections.Add(new section( process, sectionAddress )); sectionAddress += (uint)Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)); } // Load the import directory loadImportTable(process, importTableAddress, optHeader.DataDirectory2_import.Size, (uint)address); // Load the export directory loadExportTable(process, exportTableAddress, optHeader.DataDirectory1_export.Size, (uint) address, optHeader, sections); // Load the section structures int numSections = coffHeader.NumberOfSections; sections = new List<IMAGE_SECTION_HEADER_MOD>(numSections); for( uint i = 0; i < numSections; i++ ) { ulong sectionBase = PE_header + 4 + (ulong)Marshal.SizeOf(typeof(COFFHeader)) + (uint)Marshal.SizeOf(typeof(PEOptHeader)) + i * (uint)Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)); byte[] sectionData = oMemoryFunctions.readMemory(process, sectionBase, (uint)Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER))); IMAGE_SECTION_HEADER section = (IMAGE_SECTION_HEADER)oMemoryFunctions.RawDataToObject(ref sectionData, typeof(IMAGE_SECTION_HEADER)); // Convert the raw section to a more friendly section type sections.Add(new IMAGE_SECTION_HEADER_MOD(section)); } }
/// <summary> /// Initializes a new instance of the <see cref="PortableExecutableLinker"/> class. /// </summary> public PortableExecutableLinker() { this.dosHeader = new IMAGE_DOS_HEADER(); this.ntHeaders = new IMAGE_NT_HEADERS(); this.sectionAlignment = SECTION_ALIGNMENT; this.fileAlignment = FILE_SECTION_ALIGNMENT; this.setChecksum = true; // Create the default section set this.sections = new Dictionary<SectionKind, LinkerSection>() { { SectionKind.Text, new PortableExecutableLinkerSection(SectionKind.Text, @".text", new IntPtr(this.BaseAddress + this.sectionAlignment)) }, { SectionKind.Data, new PortableExecutableLinkerSection(SectionKind.Data, @".data", IntPtr.Zero) }, { SectionKind.ROData, new PortableExecutableLinkerSection(SectionKind.ROData, @".rodata", IntPtr.Zero) }, { SectionKind.BSS, new PortableExecutableLinkerSection(SectionKind.BSS, @".bss", IntPtr.Zero) } }; }
public unsafe void Save(MultiIcon multiIcon, Stream stream) { //Lets prepare the complete file in memory, then we dump everything to a file IMAGE_DOS_HEADER dos_header = new IMAGE_DOS_HEADER(); IMAGE_OS2_HEADER os2_header = new IMAGE_OS2_HEADER(); RESOURCE_TABLE resource_table = new RESOURCE_TABLE(); TYPEINFO rscTypes_Group = new TYPEINFO(); TYPEINFO rscTypes_Icon = new TYPEINFO(); TNAMEINFO[] nameInfos_Group; TNAMEINFO[] nameInfos_Icon; byte[] resourceNames; List<GRPICONDIR> groupIcons = new List<GRPICONDIR>(); Dictionary<ushort, IconImage> icons = new Dictionary<ushort,IconImage>(); int offset = 0; // Lets set the MS DOS header dos_header.e_magic = (int) HeaderSignatures.IMAGE_DOS_SIGNATURE; // MZ dos_header.e_lfanew = 144; // NE Header location. dos_header.e_cblp = 80; dos_header.e_cp = 2; dos_header.e_cparhdr = 4; dos_header.e_lfarlc = 64; dos_header.e_maxalloc = 65535; dos_header.e_minalloc = 15; dos_header.e_sp = 184; offset += (int) dos_header.e_lfanew; // Lets set the NE header os2_header.ne_magic = (int) HeaderSignatures.IMAGE_OS2_SIGNATURE; // NE os2_header.ne_ver = 71; os2_header.ne_rev = 70; os2_header.ne_enttab = 178; os2_header.ne_cbenttab = 10; os2_header.ne_crc = 0; os2_header.ne_flags = 33545; os2_header.ne_autodata = 3; os2_header.ne_heap = 1024; os2_header.ne_stack = 0; os2_header.ne_csip = 65536; os2_header.ne_sssp = 0; os2_header.ne_cseg = 0; // Entries in Segment Table os2_header.ne_cmod = 1; os2_header.ne_cbnrestab = 26; os2_header.ne_segtab = 64; // Offset to Segment Table os2_header.ne_rsrctab = 64; // Offset to Resource Table os2_header.ne_restab = 132;// Later will be overwriten os2_header.ne_modtab = 168; os2_header.ne_imptab = 170; os2_header.ne_nrestab = 332; os2_header.ne_cmovent = 1; os2_header.ne_align = SHIFT_FACTOR; os2_header.ne_cres = 0; os2_header.ne_exetyp = 2; // OS target = Windows. os2_header.ne_flagsothers = 0; os2_header.ne_pretthunks = 0; os2_header.ne_psegrefbytes = 0; os2_header.ne_swaparea = 0; os2_header.ne_expver = 768; // OS version = 300 offset += os2_header.ne_rsrctab; // Resoruce Table resource_table.rscAlignShift = SHIFT_FACTOR; // 9 for now, lets split the entries every 512 bytes; offset += 2; // rscAlignShift // Type Info Groups rscTypes_Group.rtTypeID = 0x8000 + (ushort) ResourceType.RT_GROUP_ICON; rscTypes_Group.rtResourceCount = (ushort) multiIcon.Count; offset += 8; // rtTypeID + rtResourceCount + rtReserved nameInfos_Group = new TNAMEINFO[multiIcon.Count]; offset += sizeof(TNAMEINFO) * multiIcon.Count; // Type Info Icons int iconCounter = 0; foreach(SingleIcon singleIcon in multiIcon) iconCounter += singleIcon.Count; rscTypes_Icon.rtTypeID = 0x8000 + (ushort) ResourceType.RT_ICON; rscTypes_Icon.rtResourceCount = (ushort) iconCounter; offset += 8; // rtTypeID + rtResourceCount + rtReserved nameInfos_Icon = new TNAMEINFO[iconCounter]; offset += sizeof(TNAMEINFO) * iconCounter; resource_table.rscEndTypes = 0; offset += 2; // rscEndTypes // Resource Names os2_header.ne_restab = (ushort) (offset - dos_header.e_lfanew); MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); bw.Write("ICL"); foreach(SingleIcon singleIcon in multiIcon) bw.Write(singleIcon.Name); resourceNames = new byte[ms.Length]; Array.Copy(ms.GetBuffer(), resourceNames, resourceNames.Length); ms.Dispose(); offset += resourceNames.Length + 1; //resourceNames + rscEndNames // Here is the offset where we are going to start writting the directory int shiftOffset = (offset >> resource_table.rscAlignShift) + 1; // Name Infos Group int iconIndex = 0; for(int i=0; i<multiIcon.Count; i++) { SingleIcon singleIcon = multiIcon[i]; GRPICONDIR groupIconDir = new GRPICONDIR(); groupIconDir.idCount = (ushort) singleIcon.Count; groupIconDir.idType = (ushort) ResourceType.RT_GROUP_ICON; // Name Infos Icons GRPICONDIRENTRY[] goupIconDirEntries = new GRPICONDIRENTRY[singleIcon.Count]; for(int j=0; j<singleIcon.Count; j++) { nameInfos_Icon[iconIndex].rnFlags = (ushort) (ResourceMemoryType.Moveable | ResourceMemoryType.Pure | ResourceMemoryType.Unknown); nameInfos_Icon[iconIndex].rnHandle = 0; nameInfos_Icon[iconIndex].rnID = (ushort) (0x8000 + iconIndex + 1); nameInfos_Icon[iconIndex].rnUsage = 0; nameInfos_Icon[iconIndex].rnOffset = (ushort) shiftOffset; nameInfos_Icon[iconIndex].rnLength = (ushort) Math.Ceiling(singleIcon[j].IconImageSize / (float) (1 << resource_table.rscAlignShift)); shiftOffset += nameInfos_Icon[iconIndex].rnLength; goupIconDirEntries[j] = singleIcon[j].GRPICONDIRENTRY; goupIconDirEntries[j].nID = (ushort) (iconIndex + 1); icons.Add((ushort) (iconIndex + 1), singleIcon[j]); iconIndex++; } nameInfos_Group[i].rnFlags = (ushort) (ResourceMemoryType.Moveable | ResourceMemoryType.Pure | ResourceMemoryType.Unknown); nameInfos_Group[i].rnHandle = 0; nameInfos_Group[i].rnID = (ushort) (0x8000 + i + 1); nameInfos_Group[i].rnUsage = 0; nameInfos_Group[i].rnOffset = (ushort) shiftOffset; nameInfos_Group[i].rnLength = (ushort) Math.Ceiling((6 + singleIcon.Count * sizeof(GRPICONDIRENTRY)) / (float) (1 << resource_table.rscAlignShift)); groupIconDir.idEntries = goupIconDirEntries; groupIcons.Add(groupIconDir); shiftOffset += nameInfos_Group[i].rnLength; } resource_table.rscTypes = new TYPEINFO[2]; resource_table.rscTypes[0] = rscTypes_Group; resource_table.rscTypes[0].rtNameInfo = nameInfos_Group; resource_table.rscTypes[1] = rscTypes_Icon; resource_table.rscTypes[1].rtNameInfo = nameInfos_Icon; resource_table.rscResourceNames = resourceNames; // HERE WE GO TO THE FS... // Lets write the MS DOS header dos_header.Write(stream); // Lets write first Bin segment stream.Write(MSDOS_STUB, 0, MSDOS_STUB.Length); // Lets position over where the "NE" header will be stream.Seek(dos_header.e_lfanew, SeekOrigin.Begin); // Lets write the NE header os2_header.Write(stream); // Lets position over the "Resource Table" stream.Seek(os2_header.ne_rsrctab + dos_header.e_lfanew, SeekOrigin.Begin); // Lets write the "Resource Table" resource_table.Write(stream); // Now write the Icons Directory resource_table.SetGroupIcons(stream, groupIcons); // And the Images... resource_table.SetIcons(stream, icons); }
public PESupport(string LibraryName) { Debug.Assert(LibraryName != null); this.LibraryName = LibraryName; hLibrary = IntPtr.Zero; IntPtr original_hLibrary = LoadLibraryEx(this.LibraryName, IntPtr.Zero, LoadLibraryFlags.DONT_RESOLVE_DLL_REFERENCES); // access violations occur with LOAD_LIBRARY_AS_DATAFILE, but don't with DONT_RESOLVE_DLL_REFERENCES for some reason hLibrary = new IntPtr(original_hLibrary.ToInt32() - original_hLibrary.ToInt32() % 4); // adjust things to a DWORD boundary int error = Marshal.GetLastWin32Error(); if (hLibrary == null && error != 0) { throw new System.ApplicationException("Got error " + error + " when loading library " + LibraryName); } // do some sanity checking dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(hLibrary, typeof(IMAGE_DOS_HEADER)); if (!dosHeader.isValid) { throw new System.ApplicationException("Library does not appear to be a valid DOS file!"); } ntHeader = (IMAGE_NT_HEADERS32)Marshal.PtrToStructure(hLibrary + dosHeader.e_lfanew, typeof(IMAGE_NT_HEADERS32)); if (!ntHeader.isValid) { throw new System.ApplicationException("Library NT Header does not appear valid!"); } fileHeader = ntHeader.FileHeader; if (fileHeader.Machine != (UInt16)(MachineType.I386)) { throw new System.ApplicationException("Library appears to be compiled for x64 while this program only supports x86 libraries."); } optionalHeader = ntHeader.OptionalHeader; exports = new Dictionary<int, List<string>>(); // if we don't have an export directory, move on if (optionalHeader.ExportTable.VirtualAddress == 0 || optionalHeader.ExportTable.Size == 0) { FreeLibrary(original_hLibrary); return; } // initialise the export header exportHeader = (IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure(hLibrary + (int)optionalHeader.ExportTable.VirtualAddress, typeof(IMAGE_EXPORT_DIRECTORY)); for (int i = 0; i < exportHeader.NumberOfNames; i++) { // grab the pointer to the next entry in the string table. In C, this would be a char* IntPtr namePtr = (IntPtr)Marshal.PtrToStructure(hLibrary + (int)(exportHeader.AddressOfNames) + (4 * i), typeof(IntPtr)); // dereference the previous char* string name; try { name = Marshal.PtrToStringAnsi(hLibrary + namePtr.ToInt32()); } catch (Exception ex) { name = ""; Console.WriteLine(ex.StackTrace); } // grab the address for this function int address = ((IntPtr)Marshal.PtrToStructure(hLibrary + (int)(exportHeader.AddressOfFunctions) + 4 * i, typeof(IntPtr))).ToInt32(); address += (int)optionalHeader.ImageBase; if (exports.ContainsKey(address)) { exports[address].Add(name); } else { exports[address] = new List<string>(); exports[address].Add(name); } } FreeLibrary(original_hLibrary); }
internal DOSHeader(uint start) : base(start) { image_dos_header = new IMAGE_DOS_HEADER(start); // dos_stub = new DOS_STUB(start, image_dos_header.e_lfanew - 64); }