/// <summary> /// Reading from unmanaged memory pointer address. /// </summary> /// <param name="memPtr"></param> /// <param name="index"></param> private static void Load(IntPtr memPtr) { long index = 0; // Reading e_lfanew from the dos header uint e_lfanew = (uint)Marshal.ReadInt16(new IntPtr(memPtr.ToInt64() + 0x3C)); index += e_lfanew + 4; // Reading NumberOfSections the file header ushort NumberOfSections = (ushort)Marshal.ReadInt16(new IntPtr(memPtr.ToInt64() + index + 2)); index += NumberOfSections + 16; // See the optional header magic to determine 32-bit vs 64-bit short optMagic = Marshal.ReadInt16(new IntPtr(memPtr.ToInt64() + index)); if (optMagic != 0x20b) // IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b { index += 0xE0; // size of IMAGE_OPTIONAL_HEADER32 } else { index += 0xF0; // size of IMAGE_OPTIONAL_HEADER64 } // Read section headers ImageSectionHeaders = new IMAGE_SECTION_HEADER[NumberOfSections]; for (int headerNo = 0; headerNo < ImageSectionHeaders.Length; headerNo++) { ImageSectionHeaders[headerNo] = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(new IntPtr(memPtr.ToInt64() + index), typeof(IMAGE_SECTION_HEADER)); index += Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)); } }
protected IMAGE_SECTION_HEADER[] getSectionHeaders(int count) { /* IMAGE_SECTION_HEADER */ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680341.aspx if (count < 1) { return(new IMAGE_SECTION_HEADER[0]); } byte[] data = new byte[count * IMAGE_SECTION_HEADER.IMAGE_SIZEOF_SECTION_HEADER]; reader.Read(data, 0, data.Length); var br = new BReader(data); var sections = new IMAGE_SECTION_HEADER[count]; for (int i = 0; i < count; ++i) { sections[i].Name = br.next <BYTE[]>(8); sections[i].Misc = br.next <DWORD>(); sections[i].VirtualAddress = br.next <DWORD>(); sections[i].SizeOfRawData = br.next <DWORD>(); sections[i].PointerToRawData = br.next <DWORD>(); sections[i].PointerToRelocations = br.next <DWORD>(); sections[i].PointerToLinenumbers = br.next <DWORD>(); sections[i].NumberOfRelocations = br.next <WORD>(); sections[i].NumberOfLinenumbers = br.next <WORD>(); sections[i].Characteristics = br.next <DWORD>(); } return(sections); }
/* 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"); }
/// <summary> /// Locate the <see cref="IMAGE_SECTION_HEADER"/> that corresponds to the given RVA /// </summary> /// <param name="rva">The address to map to a header.</param> /// <returns></returns> public IMAGE_SECTION_HEADER GetSectionFromRva(uint rva) { IMAGE_SECTION_HEADER section = new IMAGE_SECTION_HEADER(); var sections = ImageSectionHeaders.ToArray(); int i = 0; while (i < FileHeader.NumberOfSections) { if (rva < sections[i].VirtualAddress + AlignTo(sections[i].VirtualSize, SectionAlignment)) { if (rva < sections[i].VirtualAddress) { return(section); } else { return(sections[i]); } } i++; } return(section); }
public void CopySections(Byte[] data, IMAGE_NT_HEADERS oldHeaders, IntPtr headers, IMAGE_DOS_HEADER dosHeader) { Int32 i; IntPtr codebase = _module.codeBase; IMAGE_SECTION_HEADER section = PointerHelpers.ToStruct <IMAGE_SECTION_HEADER>(headers, (UInt32)(24 + dosHeader.e_lfanew + oldHeaders.FileHeader.SizeOfOptionalHeader)); for (i = 0; i < _module.headers.FileHeader.NumberOfSections; i++) { IntPtr dest; if (section.SizeOfRawData == 0) { UInt32 size = oldHeaders.OptionalHeader.SectionAlignment; if (size > 0) { dest = new IntPtr((Win32Imports.VirtualAlloc((UInt32)(codebase.ToInt32() + (Int32)section.VirtualAddress), size, Win32Constants.MEM_COMMIT, Win32Constants.PAGE_READWRITE))); section.PhysicalAddress = (UInt32)dest; IntPtr write = new IntPtr(headers.ToInt32() + (32 + dosHeader.e_lfanew + oldHeaders.FileHeader.SizeOfOptionalHeader) + (Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)) * (i))); Marshal.WriteInt32(write, (Int32)dest); Byte[] datazz = new Byte[size + 1]; Marshal.Copy(datazz, 0, dest, (Int32)size); } section = PointerHelpers.ToStruct <IMAGE_SECTION_HEADER>(headers, (UInt32)((24 + dosHeader.e_lfanew + oldHeaders.FileHeader.SizeOfOptionalHeader) + (Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)) * (i + 1)))); continue; } dest = new IntPtr((Win32Imports.VirtualAlloc((UInt32)(codebase.ToInt32() + (Int32)section.VirtualAddress), section.SizeOfRawData, Win32Constants.MEM_COMMIT, Win32Constants.PAGE_READWRITE))); Marshal.Copy(data, (Int32)section.PointerToRawData, dest, (Int32)section.SizeOfRawData); section.PhysicalAddress = (UInt32)dest; IntPtr write2 = new IntPtr(headers.ToInt32() + (32 + dosHeader.e_lfanew + oldHeaders.FileHeader.SizeOfOptionalHeader) + (Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)) * (i))); Marshal.WriteInt32(write2, (Int32)dest); section = PointerHelpers.ToStruct <IMAGE_SECTION_HEADER>(headers, (UInt32)((24 + dosHeader.e_lfanew + oldHeaders.FileHeader.SizeOfOptionalHeader) + (Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)) * (i + 1)))); } }
/// <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 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); } }
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()); }
private string[] ReadExportNameTable(IMAGE_SECTION_HEADER header, Stream peStream) { long nameTableOffset = (_directory.RvaOfNames - header.VirtualAddress) + header.PointerToRawData; peStream.Seek(nameTableOffset, SeekOrigin.Begin); int nNames = checked ((int)_directory.NumberOfNames); var names = new string[nNames]; for (int i = 0; i < nNames; i++) { int rva = peStream.Read <int>(); long curOffset = peStream.Position; long nameOffset = (rva - header.VirtualAddress) + header.PointerToRawData; peStream.Seek(nameOffset, SeekOrigin.Begin); names[i] = peStream.ReadAsciiZeroTerminated(); peStream.Seek(curOffset, SeekOrigin.Begin); } return(names); }
private ExportedSymbol[] ReadExportAddresTable(IMAGE_SECTION_HEADER header, Stream peStream) { long eatOffset = (_directory.RvaOfExportAddressTable - header.VirtualAddress) + header.PointerToRawData; peStream.Seek(eatOffset, SeekOrigin.Begin); int eatSize = checked ((int)_directory.NumberOfFunctions); var exportAddressTable = new ExportedSymbol[eatSize]; for (int i = 0; i < eatSize; i++) { int rva = peStream.Read <int>(); if (header.VirtualAddress <= rva && rva < (header.VirtualAddress + header.VirtualSize)) { long curOffset = peStream.Position; long exportNameOffset = (rva - header.VirtualAddress) + header.PointerToRawData; peStream.Seek(exportNameOffset, SeekOrigin.Begin); string exportName = peStream.ReadAsciiZeroTerminated(); peStream.Seek(curOffset, SeekOrigin.Begin); exportAddressTable[i] = new ExportedSymbol(exportName); } else { exportAddressTable[i] = new ExportedSymbol(rva); } } return(exportAddressTable); }
/// <summary> /// Reading from unmanaged memory pointer address. /// </summary> /// <param name="memPtr"></param> /// <param name="index"></param> private static void Load(IntPtr memPtr, long index) { var startIndex = index; // Reading the dos header dosHeader = FromMemoryPtr <IMAGE_DOS_HEADER>(memPtr, ref index); index = startIndex + dosHeader.e_lfanew + 4; // Reading the file header fileHeader = FromMemoryPtr <IMAGE_FILE_HEADER>(memPtr, ref index); // See the optional 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); } // Read section headers 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 void RVAtoFileMapping01ThrowsNullReferenceException960() { uint u; IMAGE_SECTION_HEADER[] iMAGE_SECTION_HEADERs = new IMAGE_SECTION_HEADER[1]; u = this.RVAtoFileMapping01 (0u, (ICollection <IMAGE_SECTION_HEADER>)iMAGE_SECTION_HEADERs); }
public void RVAtoFileMapping01ThrowsInvalidOperationException55() { uint u; IMAGE_SECTION_HEADER[] iMAGE_SECTION_HEADERs = new IMAGE_SECTION_HEADER[0]; u = this.RVAtoFileMapping01 (0u, (ICollection <IMAGE_SECTION_HEADER>)iMAGE_SECTION_HEADERs); }
public void RVAtoFileMappingThrowsNullReferenceException257() { ulong l; IMAGE_SECTION_HEADER[] iMAGE_SECTION_HEADERs = new IMAGE_SECTION_HEADER[1]; l = this.RVAtoFileMapping (0uL, (ICollection <IMAGE_SECTION_HEADER>)iMAGE_SECTION_HEADERs); }
private void ReadImageSectionHeaders() { using (FileStream stream = new FileStream(Path, FileMode.Open, FileAccess.Read, FileShare.Read)) using (BinaryReader reader = new BinaryReader(stream)) { _imageSectionHeaders = IMAGE_SECTION_HEADER.Read(reader, NumberOfImageSectionHeaders, FirstImageSectionHeaderOffset); } }
public void RVAtoFileMappingThrowsInvalidOperationException207() { ulong l; IMAGE_SECTION_HEADER[] iMAGE_SECTION_HEADERs = new IMAGE_SECTION_HEADER[0]; l = this.RVAtoFileMapping (0uL, (ICollection <IMAGE_SECTION_HEADER>)iMAGE_SECTION_HEADERs); }
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); }
internal SectionTableEntry(PortableExecutableImage image, SectionTable sectionTable, IMAGE_SECTION_HEADER entryHeader, ulong entryOffset, ulong imageBase) { _image = image; _header = entryHeader; Table = sectionTable; Location = new Location(image, entryOffset, entryOffset.ToUInt32(), imageBase + entryOffset, _headerSize, _headerSize); Name = GetName(); }
private void RewriteRelocationDirectory(ICode oldCode, ICode newCode, PeFile peFile, out byte[] programExtensionBuffer) { programExtensionBuffer = null; if (newCode.CodeInMemoryLayout.RelocationDirectoryInfo == null) { return; } var newRelocationDirectorySize = newCode.CodeInMemoryLayout.RelocationDirectoryInfo.RelocationDirectorySize; //UPDATE THE RELOCATION DIRECTORY SIZE //old reloation directory size is different than the new code if (oldCode.CodeInMemoryLayout.RelocationDirectoryInfo.RelocationDirectorySize != newRelocationDirectorySize) { peFile.ImageNtHeaders.OptionalHeader.DataDirectory[(int)PeNet.Constants.DataDirectoryIndex.BaseReloc].Size = newRelocationDirectorySize; //if the section of reloaction physical size is shorter than new relocation size, //we need to extend the buffer size (and actually the program size) IMAGE_SECTION_HEADER relocationSection = peFile.FindRelocationSection(); if (relocationSection.SizeOfRawData < newRelocationDirectorySize) { if (peFile.GetSectionsOrderedByPhysicalLayout().Last() != relocationSection) { throw new ApplicationException("can not extend program relocation directory, because the information about" + " the relocations is not the last in the program. This program do not repack program sections, and so can not obfuscate it(-;)"); } relocationSection.SizeOfRawData = newRelocationDirectorySize; relocationSection.VirtualSize = newRelocationDirectorySize; programExtensionBuffer = new byte[newRelocationDirectorySize - relocationSection.SizeOfRawData]; } } //UPDATE THE RELOCATION DIRECTORY var offsetInBufferOfRelocationDirectory = oldCode.CodeInMemoryLayout. RelocationDirectoryInfo.OffsetInBuffer; if (programExtensionBuffer == null) { Array.Copy(newCode.CodeInMemoryLayout.RelocationDirectoryInfo.Buffer, 0, peFile.Buff, (int)offsetInBufferOfRelocationDirectory, newRelocationDirectorySize); } else { //copy the relocation buffer to program buffer first Array.Copy(newCode.CodeInMemoryLayout.RelocationDirectoryInfo.Buffer, 0, peFile.Buff, (int)offsetInBufferOfRelocationDirectory, newRelocationDirectorySize - programExtensionBuffer.Length); //copy the rest of relocation bytes to extended buffer Array.Copy(newCode.CodeInMemoryLayout.RelocationDirectoryInfo.Buffer, newRelocationDirectorySize - programExtensionBuffer.Length, programExtensionBuffer, 0, programExtensionBuffer.Length); } }
public ImageSection(PeFile file, IMAGE_SECTION_HEADER header) { this.file = file; SectionHeader = header; Name = Encoding.ASCII.GetString(header.Name); if (Name.IndexOf('\0') != -1) { Name = Name.Substring(0, Name.IndexOf('\0')); } }
public ManagedDllProvider(Stream stream) { using (BinaryReader binaryReader = new BinaryReader(stream)) { var dosHeader = binaryReader.ReadStruct <IMAGE_DOS_HEADER>(); binaryReader.BaseStream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); byte[] array = binaryReader.ReadBytes(4); if (Encoding.ASCII.GetString(array) != "PE\0\0") { throw new Exception("Not a PE File"); } var fileHeader = binaryReader.ReadStruct <IMAGE_FILE_HEADER>(); if ((IMAGE_FILE_32BIT_MACHINE & fileHeader.Characteristics) != IMAGE_FILE_32BIT_MACHINE) { throw new Exception("Not a 32-bit PE File"); } binaryReader.ReadStruct <IMAGE_OPTIONAL_HEADER>(); var sectionHeaders = new IMAGE_SECTION_HEADER[(int)fileHeader.NumberOfSections]; IMAGE_SECTION_HEADER?rsrcSection = default(IMAGE_SECTION_HEADER?); for (int i = 0; i < (int)fileHeader.NumberOfSections; i++) { sectionHeaders[i] = binaryReader.ReadStruct <IMAGE_SECTION_HEADER>(); if (sectionHeaders[i].Section == ".rsrc") { rsrcSection = new IMAGE_SECTION_HEADER?(sectionHeaders[i]); } } if (!rsrcSection.HasValue) { throw new Exception("No resources"); } binaryReader.BaseStream.Seek((long)((ulong)rsrcSection.Value.PointerToRawData), SeekOrigin.Begin); var rootDirectory = binaryReader.ReadStruct <IMAGE_RESOURCE_DIRECTORY>(); int num = (int)(rootDirectory.NumberOfIdEntries + rootDirectory.NumberOfNamedEntries); var entries = new IMAGE_RESOURCE_DIRECTORY_ENTRY[num]; for (int j = 0; j < num; j++) { entries[j] = binaryReader.ReadStruct <IMAGE_RESOURCE_DIRECTORY_ENTRY>(); } Strings = new Dictionary <int, string>(); Infocards = new Dictionary <int, string>(); for (int k = 0; k < num; k++) { if (entries[k].Name == RT_STRING) { ReadStringTable(binaryReader, entries[k].OffsetToData, rsrcSection.Value.PointerToRawData); } if (entries[k].Name == RT_RCDATA) { ReadXML(binaryReader, entries[k].OffsetToData, rsrcSection.Value.PointerToRawData); } } binaryReader.Close(); } }
static IMAGE_SECTION_HEADER AddSection(ref PeFile pe, string name, uint size, uint characteristics = DEFAULT_CHARACTERISTICS) { if (name.Length > SECTION_NAME) { throw new Exception("Section name is too long"); } // sizeof(IMAGE_SECTION_HEADER); const uint headerSize = 0x28; uint headerOffset = GetOffset(pe.ImageSectionHeaders.Last()) + headerSize; if (headerOffset + headerSize > pe.ImageNtHeaders.OptionalHeader.SizeOfHeaders) { throw new Exception("Not enough room for additional SECTION_HEADER"); } uint virtualSize = AlignUp(size, pe.ImageNtHeaders.OptionalHeader.SectionAlignment); uint virtualAddress = AlignUp( pe.ImageSectionHeaders.Last().VirtualAddress + pe.ImageSectionHeaders.Last().VirtualSize, pe.ImageNtHeaders.OptionalHeader.SectionAlignment ); uint rawSize = AlignUp(size, pe.ImageNtHeaders.OptionalHeader.FileAlignment); uint rawPtr = AlignUp( pe.ImageSectionHeaders.Last().PointerToRawData + pe.ImageSectionHeaders.Last().SizeOfRawData, pe.ImageNtHeaders.OptionalHeader.FileAlignment ); byte[] nullPadding = new byte[SECTION_NAME]; IMAGE_SECTION_HEADER section = new IMAGE_SECTION_HEADER( pe.Buff, headerOffset, pe.ImageNtHeaders.OptionalHeader.ImageBase) { Name = Encoding.ASCII.GetBytes(name).Concat(nullPadding).ToArray(), VirtualAddress = virtualAddress, PointerToRawData = rawPtr, VirtualSize = virtualSize, SizeOfRawData = rawSize, Characteristics = characteristics, PointerToRelocations = 0, NumberOfRelocations = 0, NumberOfLinenumbers = 0, PointerToLinenumbers = 0, }; pe.ImageNtHeaders.FileHeader.NumberOfSections += 1; pe.ImageNtHeaders.OptionalHeader.SizeOfImage = virtualAddress + virtualSize; byte[] resizedBuffer = pe.Buff; Array.Resize(ref resizedBuffer, pe.Buff.Length + (int)rawSize); pe = new PeFile(resizedBuffer); return(section); }
private static byte[] GetSectionBytes(IntPtr hProcess, IntPtr baseAddress, string section, ref IntPtr sectionAddress) { IMAGE_SECTION_HEADER image_section_header = GetSection(hProcess, baseAddress, section); if (image_section_header.Name == null) { throw new Exception("Could not find section " + section); } sectionAddress = new IntPtr(baseAddress.ToInt64() + image_section_header.VirtualAddress); return(ReadBytes(hProcess, sectionAddress, image_section_header.Misc)); }
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); }
protected override IMAGE_SECTION_HEADER[] ParseTarget() { var sh = new IMAGE_SECTION_HEADER[_numOfSections]; const uint secSize = 0x28; // Every section header is 40 bytes in size. for (uint i = 0; i < _numOfSections; i++) { sh[i] = new IMAGE_SECTION_HEADER(Buff, Offset + i*secSize); } return sh; }
protected override IMAGE_SECTION_HEADER[] ParseTarget() { var sh = new IMAGE_SECTION_HEADER[_numOfSections]; uint secSize = 0x28; // Every section header is 40 bytes in size. for (uint i = 0; i < _numOfSections; i++) { sh[i] = new IMAGE_SECTION_HEADER(_buff, _offset + i * secSize, _imageBaseAddress); } return(sh); }
private static IMAGE_SECTION_HEADER ReadSection(byte[] fileContent, int ptr) { try { // Get the size of a section header for later int sectionSize = Marshal.SizeOf <IMAGE_SECTION_HEADER>(); // If the contents are null or the wrong size, we can't read a section if (fileContent == null || fileContent.Length < sectionSize) { return(null); } // Create a new section and try our best to read one IMAGE_SECTION_HEADER section = null; IntPtr tempPtr = IntPtr.Zero; try { // Get the pointer to where the section will go tempPtr = Marshal.AllocHGlobal(sectionSize); // If we couldn't get the space, just return null if (tempPtr == IntPtr.Zero) { return(null); } // Copy from the array to the new space Marshal.Copy(fileContent, ptr, tempPtr, sectionSize); // Get the new section and return section = Marshal.PtrToStructure <IMAGE_SECTION_HEADER>(tempPtr); } catch { // We don't care what the error was return(null); } finally { if (tempPtr != IntPtr.Zero) { Marshal.FreeHGlobal(tempPtr); } } return(section); } catch { return(null); } }
public IMAGE_SECTION_HEADER(BinaryReader reader) { IMAGE_SECTION_HEADER section = new IMAGE_SECTION_HEADER(); this = section; byte[] buffer = new byte[Marshal.SizeOf(this)]; reader.Read(buffer, 0, buffer.Length); section = buffer.ToStructure <IMAGE_SECTION_HEADER>(); this = section; }
static void FinalizeSections(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode, IntPtr pNTHeaders, uint PageSize) { UIntPtr imageOffset = (Is64BitProcess ? (UIntPtr)(unchecked ((ulong)pCode.ToInt64()) & 0xffffffff00000000) : UIntPtr.Zero); IntPtr pSection = Win.IMAGE_FIRST_SECTION(pNTHeaders, OrgNTHeaders.FileHeader.SizeOfOptionalHeader); IMAGE_SECTION_HEADER Section = PtrRead <IMAGE_SECTION_HEADER>(pSection); SectionFinalizeData sectionData = new SectionFinalizeData(); sectionData.Address = PtrBitOr(PtrAdd((IntPtr)0, Section.PhysicalAddress), imageOffset); sectionData.AlignedAddress = PtrAlignDown(sectionData.Address, (UIntPtr)PageSize); sectionData.Size = GetRealSectionSize(ref Section, ref OrgNTHeaders); sectionData.Characteristics = Section.Characteristics; sectionData.Last = false; pSection = PtrAdd(pSection, Sz.IMAGE_SECTION_HEADER); // loop through all sections and change access flags for (int i = 1; i < OrgNTHeaders.FileHeader.NumberOfSections; i++, pSection = PtrAdd(pSection, Sz.IMAGE_SECTION_HEADER)) { Section = PtrRead <IMAGE_SECTION_HEADER>(pSection); IntPtr sectionAddress = PtrBitOr(PtrAdd((IntPtr)0, Section.PhysicalAddress), imageOffset); IntPtr alignedAddress = PtrAlignDown(sectionAddress, (UIntPtr)PageSize); IntPtr sectionSize = GetRealSectionSize(ref Section, ref OrgNTHeaders); // Combine access flags of all sections that share a page // TODO(fancycode): We currently share flags of a trailing large section with the page of a first small section. This should be optimized. IntPtr a = PtrAdd(sectionData.Address, sectionData.Size); ulong b = unchecked ((ulong)a.ToInt64()), c = unchecked ((ulong)alignedAddress); if (sectionData.AlignedAddress == alignedAddress || unchecked ((ulong)PtrAdd(sectionData.Address, sectionData.Size).ToInt64()) > unchecked ((ulong)alignedAddress)) { // Section shares page with previous if ((Section.Characteristics & Win.IMAGE_SCN_MEM_DISCARDABLE) == 0 || (sectionData.Characteristics & Win.IMAGE_SCN_MEM_DISCARDABLE) == 0) { sectionData.Characteristics = (sectionData.Characteristics | Section.Characteristics) & ~Win.IMAGE_SCN_MEM_DISCARDABLE; } else { sectionData.Characteristics |= Section.Characteristics; } sectionData.Size = PtrSub(PtrAdd(sectionAddress, sectionSize), sectionData.Address); continue; } FinalizeSection(sectionData, PageSize, OrgNTHeaders.OptionalHeader.SectionAlignment); sectionData.Address = sectionAddress; sectionData.AlignedAddress = alignedAddress; sectionData.Size = sectionSize; sectionData.Characteristics = Section.Characteristics; } sectionData.Last = true; FinalizeSection(sectionData, PageSize, OrgNTHeaders.OptionalHeader.SectionAlignment); }
/// <inheritdoc /> public bool TryGetSectionHeader(string sectionName, out IMAGE_SECTION_HEADER header) { int index; if (_sectionNameToIndex.TryGetValue(sectionName, out index)) { header = _sectionHeaders[index]; return(true); } header = default(IMAGE_SECTION_HEADER); return(false); }
/// <summary> /// Writes the PE _header. /// </summary> /// <param name="writer">The writer.</param> private void WritePEHeader(BinaryWriter writer) { // Write the PE signature and headers ntHeaders.Signature = IMAGE_NT_HEADERS.PE_SIGNATURE; // Prepare the file _header ntHeaders.FileHeader.Machine = IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386; ntHeaders.FileHeader.NumberOfSections = CountSections(); ntHeaders.FileHeader.TimeDateStamp = (uint)(DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds; ntHeaders.FileHeader.PointerToSymbolTable = 0; ntHeaders.FileHeader.NumberOfSymbols = 0; ntHeaders.FileHeader.SizeOfOptionalHeader = 0x00E0; ntHeaders.FileHeader.Characteristics = 0x010E; // FIXME: Use an enum here // Prepare the "optional" headers ntHeaders.OptionalHeader.Magic = IMAGE_OPTIONAL_HEADER.IMAGE_OPTIONAL_HEADER_MAGIC; ntHeaders.OptionalHeader.MajorLinkerVersion = 6; ntHeaders.OptionalHeader.MinorLinkerVersion = 0; ntHeaders.OptionalHeader.SizeOfCode = AlignValue(GetSectionLength(SectionKind.Text), this.sectionAlignment); ntHeaders.OptionalHeader.SizeOfInitializedData = AlignValue(GetSectionLength(SectionKind.Data) + GetSectionLength(SectionKind.ROData), this.sectionAlignment); ntHeaders.OptionalHeader.SizeOfUninitializedData = AlignValue(GetSectionLength(SectionKind.BSS), this.sectionAlignment); ntHeaders.OptionalHeader.AddressOfEntryPoint = (uint)(this.EntryPoint.VirtualAddress.ToInt64() - this.BaseAddress); ntHeaders.OptionalHeader.BaseOfCode = (uint)(GetSectionAddress(SectionKind.Text) - this.BaseAddress); long sectionAddress = GetSectionAddress(SectionKind.Data); if (sectionAddress != 0) ntHeaders.OptionalHeader.BaseOfData = (uint)(sectionAddress - this.BaseAddress); ntHeaders.OptionalHeader.ImageBase = (uint)this.BaseAddress; // FIXME: Linker Script/cmdline ntHeaders.OptionalHeader.SectionAlignment = this.sectionAlignment; // FIXME: Linker Script/cmdline ntHeaders.OptionalHeader.FileAlignment = this.fileAlignment; // FIXME: Linker Script/cmdline ntHeaders.OptionalHeader.MajorOperatingSystemVersion = 4; ntHeaders.OptionalHeader.MinorOperatingSystemVersion = 0; ntHeaders.OptionalHeader.MajorImageVersion = 0; ntHeaders.OptionalHeader.MinorImageVersion = 0; ntHeaders.OptionalHeader.MajorSubsystemVersion = 4; ntHeaders.OptionalHeader.MinorSubsystemVersion = 0; ntHeaders.OptionalHeader.Win32VersionValue = 0; ntHeaders.OptionalHeader.SizeOfImage = CalculateSizeOfImage(); ntHeaders.OptionalHeader.SizeOfHeaders = this.fileAlignment; // FIXME: Use the full _header size ntHeaders.OptionalHeader.CheckSum = 0; ntHeaders.OptionalHeader.Subsystem = 0x03; ntHeaders.OptionalHeader.DllCharacteristics = 0x0540; ntHeaders.OptionalHeader.SizeOfStackReserve = 0x100000; ntHeaders.OptionalHeader.SizeOfStackCommit = 0x1000; ntHeaders.OptionalHeader.SizeOfHeapReserve = 0x100000; ntHeaders.OptionalHeader.SizeOfHeapCommit = 0x1000; ntHeaders.OptionalHeader.LoaderFlags = 0; ntHeaders.OptionalHeader.NumberOfRvaAndSizes = IMAGE_OPTIONAL_HEADER.IMAGE_NUMBEROF_DIRECTORY_ENTRIES; ntHeaders.OptionalHeader.DataDirectory = new IMAGE_DATA_DIRECTORY[IMAGE_OPTIONAL_HEADER.IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; // Populate the CIL data directory ntHeaders.OptionalHeader.DataDirectory[14].VirtualAddress = (uint)GetSymbol(CLI_HEADER.SymbolName).VirtualAddress.ToInt64(); ntHeaders.OptionalHeader.DataDirectory[14].Size = CLI_HEADER.Length; ntHeaders.Write(writer); // Write the section headers uint address = this.fileAlignment; foreach (LinkerSection section in this.sections.Values) { if (section.Length > 0) { IMAGE_SECTION_HEADER ish = new IMAGE_SECTION_HEADER(); ish.Name = section.Name; ish.VirtualSize = (uint)section.Length; ish.VirtualAddress = (uint)(section.VirtualAddress.ToInt64() - this.BaseAddress); if (section.SectionKind != SectionKind.BSS) ish.SizeOfRawData = (uint)section.Length; ish.PointerToRawData = address; ish.PointerToRelocations = 0; ish.PointerToLinenumbers = 0; ish.NumberOfRelocations = 0; ish.NumberOfLinenumbers = 0; switch (section.SectionKind) { case SectionKind.BSS: ish.Characteristics = 0x40000000 | 0x80000000 | 0x00000080; break; case SectionKind.Data: ish.Characteristics = 0x40000000 | 0x80000000 | 0x00000040; break; case SectionKind.ROData: ish.Characteristics = 0x40000000 | 0x00000040; break; case SectionKind.Text: ish.Characteristics = 0x20000000 | 0x40000000 | 0x80000000 | 0x00000020; break; } ish.Write(writer); address += (uint)section.Length; address = AlignValue(address, this.fileAlignment); } } WritePaddingToPosition(writer, this.fileAlignment); }
public IMAGE_SECTION_HEADER_MOD(IMAGE_SECTION_HEADER section) { this.Name = oMemoryFunctions.byteArrayToString(section.Name); this.PhysicalAddress = section.PhysicalAddress; this.VirtualAddress = section.VirtualAddress; this.SizeOfRawData = section.SizeOfRawData; this.PointerToRawData = section.PointerToRawData; this.PointerToRelocations = section.PointerToRelocations; this.PointerToLinenumbers = section.PointerToLinenumbers; this.NumberOfRelocations = section.NumberOfRelocations; this.NumberOfLinenumbers = section.NumberOfLinenumbers; this.Characteristics = section.Characteristics; }
public section(System.Diagnostics.Process process, UInt64 address) { // Parse the section struct byte[] headerData = MemoryFunctions.ReadMemory(process, (IntPtr)address, (uint)Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER))); _sectionHeader = (IMAGE_SECTION_HEADER)MemoryFunctions.RawDataToObject(ref headerData, typeof(IMAGE_SECTION_HEADER)); }