using System; using System.IO; using System.Text; using System.Runtime.InteropServices; { class AddSection { public bool AddSection(string sFilePath, string sSectionName, uint lSectionSize, uint lCharacteristics) { IMAGE_DOS_HEADER DHD = new IMAGE_DOS_HEADER(); IMAGE_NT_HEADERS NHD = new IMAGE_NT_HEADERS(); IMAGE_SECTION_HEADER[] SHD = new IMAGE_SECTION_HEADER[1]; int iPointer = 0; byte[] fBytes = new byte[0]; byte[] bName = new byte[8]; GCHandle gHandle; try { BinaryReader bReader = new BinaryReader(new FileStream(sFilePath, FileMode.Open, FileAccess.Read)); fBytes = bReader.ReadBytes((int)bReader.BaseStream.Length); bReader.Close(); } catch { } if (fBytes.Length <= 0) { return false; } gHandle = GCHandle.Alloc(fBytes, GCHandleType.Pinned); iPointer = gHandle.AddrOfPinnedObject().ToInt32(); 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)); if (NHD.Signature != 17744 || DHD.e_magic != 23117) { return false; } Array.Resize(ref SHD, NHD.FileHeader.NumberOfSections); int x = DHD.e_lfanew + 248; for (int a = 0; a <= NHD.FileHeader.NumberOfSections - 1; a++) { SHD[a] = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(new IntPtr(iPointer + x), typeof(IMAGE_SECTION_HEADER)); x = x + 40; } gHandle.Free(); NHD.FileHeader.NumberOfSections++; Array.Resize(ref SHD, NHD.FileHeader.NumberOfSections); if (sSectionName.Length > 8) { sSectionName = sSectionName.Substring(0, 8); } Array.Copy(Encoding.Default.GetBytes(sSectionName), 0, bName, 0, Encoding.Default.GetBytes(sSectionName).Length); SHD[NHD.FileHeader.NumberOfSections - 1].Name = bName; SHD[NHD.FileHeader.NumberOfSections - 1].Characteristics = lCharacteristics; SHD[NHD.FileHeader.NumberOfSections - 1].PointerToRawData = Convert.ToUInt32(Align(getLastSectionRaw(SHD), NHD.OptionalHeader.FileAlignment)); SHD[NHD.FileHeader.NumberOfSections - 1].SizeOfRawData = Convert.ToUInt32(Align(lSectionSize, NHD.OptionalHeader.FileAlignment)); SHD[NHD.FileHeader.NumberOfSections - 1].VirtualAddress = Convert.ToUInt32(Align(getLastSectionVirtual(SHD), NHD.OptionalHeader.SectionAlignment)); SHD[NHD.FileHeader.NumberOfSections - 1].VirtualSize = Convert.ToUInt32(Align(lSectionSize, NHD.OptionalHeader.SectionAlignment)); NHD.OptionalHeader.DataDirectory[12].VirtualAddress = 0; NHD.OptionalHeader.DataDirectory[12].Size = 0; NHD.OptionalHeader.SizeOfImage = NHD.OptionalHeader.SizeOfImage + SHD[NHD.FileHeader.NumberOfSections - 1].VirtualSize; byte[] bNHD = getBytes_(NHD); byte[] bSHD = getBytes_(SHD[NHD.FileHeader.NumberOfSections - 1]); byte[] bClear = Encoding.Default.GetBytes(Convert.ToChar(0x00).ToString()); if (fBytes.Length - (DHD.e_lfanew + bNHD.Length) <= 0) { Array.Resize(ref fBytes, (int)(fBytes.Length + bNHD.Length)); } Array.Copy(bNHD, 0, fBytes, DHD.e_lfanew, bNHD.Length); if (fBytes.Length - (x + bSHD.Length) <= 0) { Array.Resize(ref fBytes, (int)(fBytes.Length + bSHD.Length)); } Array.Copy(bSHD, 0, fBytes, x, bSHD.Length); if (fBytes.Length - (SHD[NHD.FileHeader.NumberOfSections - 1].PointerToRawData + SHD[NHD.FileHeader.NumberOfSections - 1].SizeOfRawData + (bClear.Length * 4)) <= 0) { Array.Resize(ref fBytes, (int)(fBytes.Length + ((SHD[NHD.FileHeader.NumberOfSections - 1].PointerToRawData + SHD[NHD.FileHeader.NumberOfSections - 1].SizeOfRawData + (bClear.Length)) - fBytes.Length))); } Array.Copy(bClear, 0, fBytes, (SHD[NHD.FileHeader.NumberOfSections - 1].PointerToRawData + SHD[NHD.FileHeader.NumberOfSections - 1].SizeOfRawData), bClear.Length); try { BinaryWriter bWriter = new BinaryWriter(new FileStream(sFilePath, FileMode.Open)); bWriter.Write(fBytes); bWriter.Flush(); bWriter.Close(); } catch { return false; } return true; } private byte[] getBytes_(object oObject) { int iSize = Marshal.SizeOf(oObject); IntPtr ipBuffer = Marshal.AllocHGlobal(iSize); Marshal.StructureToPtr(oObject, ipBuffer, false); byte[] bData = new byte[iSize]; Marshal.Copy(ipBuffer, bData, 0, iSize); Marshal.FreeHGlobal(ipBuffer); return bData; } private long Align(long dwValue, long dwAlign) { if (dwAlign != 0) { if ((dwValue % dwAlign) != 0) { return (dwValue + dwAlign) - (dwValue % dwAlign); } else { return dwValue; } } else { return dwValue; } } private long getLastSectionRaw(IMAGE_SECTION_HEADER[] Sections) { long lRet = 0; for (int i = 0; i <= Sections.Length - 1; i++) { if (Sections[i].SizeOfRawData + Sections[i].PointerToRawData > lRet) { lRet = Sections[i].SizeOfRawData + Sections[i].PointerToRawData; } } return lRet; } private long getLastSectionVirtual(IMAGE_SECTION_HEADER[] Sections) { long lRet = 0; for (int i = 0; i <= Sections.Length - 1; i++) { if (Sections[i].VirtualSize + Sections[i].VirtualAddress > lRet) { lRet = Sections[i].VirtualSize + Sections[i].VirtualAddress; } } return lRet; } //Structures [StructLayout(LayoutKind.Sequential)] private struct IMAGE_DOS_HEADER { public UInt16 e_magic; public UInt16 e_cblp; public UInt16 e_cp; public UInt16 e_crlc; public UInt16 e_cparhdr; public UInt16 e_minalloc; public UInt16 e_maxalloc; public UInt16 e_ss; public UInt16 e_sp; public UInt16 e_csum; public UInt16 e_ip; public UInt16 e_cs; public UInt16 e_lfarlc; public UInt16 e_ovno; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public UInt16[] e_res1; public UInt16 e_oemid; public UInt16 e_oeminfo; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public UInt16[] e_res2; public Int32 e_lfanew; } [StructLayout(LayoutKind.Sequential)] private struct IMAGE_NT_HEADERS { public UInt32 Signature; public IMAGE_FILE_HEADER FileHeader; public IMAGE_OPTIONAL_HEADER32 OptionalHeader; } [StructLayout(LayoutKind.Sequential)] private struct IMAGE_FILE_HEADER { public UInt16 Machine; public UInt16 NumberOfSections; public UInt32 TimeDateStamp; public UInt32 PointerToSymbolTable; public UInt32 NumberOfSymbols; public UInt16 SizeOfOptionalHeader; public UInt16 Characteristics; } [StructLayout(LayoutKind.Sequential)] private struct IMAGE_OPTIONAL_HEADER32 { public UInt16 Magic; public Byte MajorLinkerVersion; public Byte MinorLinkerVersion; public UInt32 SizeOfCode; public UInt32 SizeOfInitializedData; public UInt32 SizeOfUninitializedData; public UInt32 AddressOfEntryPoint; public UInt32 BaseOfCode; public UInt32 BaseOfData; public UInt32 ImageBase; public UInt32 SectionAlignment; public UInt32 FileAlignment; public UInt16 MajorOperatingSystemVersion; public UInt16 MinorOperatingSystemVersion; public UInt16 MajorImageVersion; public UInt16 MinorImageVersion; public UInt16 MajorSubsystemVersion; public UInt16 MinorSubsystemVersion; public UInt32 Win32VersionValue; public UInt32 SizeOfImage; public UInt32 SizeOfHeaders; public UInt32 CheckSum; public UInt16 Subsystem; public UInt16 DllCharacteristics; public UInt32 SizeOfStackReserve; public UInt32 SizeOfStackCommit; public UInt32 SizeOfHeapReserve; public UInt32 SizeOfHeapCommit; public UInt32 LoaderFlags; public UInt32 NumberOfRvaAndSizes; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public IMAGE_DATA_DIRECTORY[] DataDirectory; } [StructLayout(LayoutKind.Sequential)] private struct IMAGE_DATA_DIRECTORY { public UInt32 VirtualAddress; public UInt32 Size; } [StructLayout(LayoutKind.Sequential)] private struct IMAGE_SECTION_HEADER { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] Name; public uint VirtualSize; public uint VirtualAddress; public uint SizeOfRawData; public uint PointerToRawData; public uint PointerToRelocations; public uint PointerToLinenumbers; public short NumberOfRelocations; public short NumberOfLinenumbers; public uint Characteristics; } } }