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)))); } }
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 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 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); }
public void insert_NT32(IMAGE_NT_HEADERS INH) { int num = global.IDH.e_lfanew; List <Data> data = new List <Data>(); listView.Items.Add(new Data() { Offset = string.Format("{0:X8}", num), Value = string.Format("{0:X8}", INH.Signature), Description = "Signature" }); num += Marshal.SizeOf(INH.Signature); }
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); }
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); }
static bool PerformBaseRelocation(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode, IntPtr delta) { if (OrgNTHeaders.OptionalHeader.BaseRelocationTable.Size == 0) { return(delta == IntPtr.Zero); } for (IntPtr pRelocation = PtrAdd(pCode, OrgNTHeaders.OptionalHeader.BaseRelocationTable.VirtualAddress);;) { IMAGE_BASE_RELOCATION Relocation = PtrRead <IMAGE_BASE_RELOCATION>(pRelocation); if (Relocation.VirtualAdress == 0) { break; } IntPtr pDest = PtrAdd(pCode, Relocation.VirtualAdress); IntPtr pRelInfo = PtrAdd(pRelocation, Sz.IMAGE_BASE_RELOCATION); uint RelCount = ((Relocation.SizeOfBlock - Sz.IMAGE_BASE_RELOCATION) / 2); for (uint i = 0; i != RelCount; i++, pRelInfo = PtrAdd(pRelInfo, sizeof(ushort))) { ushort relInfo = (ushort)Marshal.PtrToStructure(pRelInfo, typeof(ushort)); BasedRelocationType type = (BasedRelocationType)(relInfo >> 12); // the upper 4 bits define the type of relocation int offset = (relInfo & 0xfff); // the lower 12 bits define the offset IntPtr pPatchAddr = PtrAdd(pDest, offset); switch (type) { case BasedRelocationType.IMAGE_REL_BASED_ABSOLUTE: // skip relocation break; case BasedRelocationType.IMAGE_REL_BASED_HIGHLOW: // change complete 32 bit address int patchAddrHL = (int)Marshal.PtrToStructure(pPatchAddr, typeof(int)); patchAddrHL += (int)delta; Marshal.StructureToPtr(patchAddrHL, pPatchAddr, false); break; case BasedRelocationType.IMAGE_REL_BASED_DIR64: long patchAddr64 = (long)Marshal.PtrToStructure(pPatchAddr, typeof(long)); patchAddr64 += (long)delta; Marshal.StructureToPtr(patchAddr64, pPatchAddr, false); break; } } // advance to next relocation block pRelocation = PtrAdd(pRelocation, Relocation.SizeOfBlock); } return(true); }
static void CopySections(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode, IntPtr pNTHeaders, byte[] data) { IntPtr pSection = Win.IMAGE_FIRST_SECTION(pNTHeaders, OrgNTHeaders.FileHeader.SizeOfOptionalHeader); for (int i = 0; i < OrgNTHeaders.FileHeader.NumberOfSections; i++, pSection = PtrAdd(pSection, Sz.IMAGE_SECTION_HEADER)) { IMAGE_SECTION_HEADER Section = PtrRead <IMAGE_SECTION_HEADER>(pSection); if (Section.SizeOfRawData == 0) { // section doesn't contain data in the dll itself, but may define uninitialized data uint size = OrgNTHeaders.OptionalHeader.SectionAlignment; if (size > 0) { IntPtr dest = Win.VirtualAlloc(PtrAdd(pCode, Section.VirtualAddress), (UIntPtr)size, AllocationType.COMMIT, MemoryProtection.READWRITE); if (dest == IntPtr.Zero) { throw new DllException("Unable to allocate memory"); } // Always use position from file to support alignments smaller than page size (allocation above will align to page size). dest = PtrAdd(pCode, Section.VirtualAddress); // NOTE: On 64bit systems we truncate to 32bit here but expand again later when "PhysicalAddress" is used. PtrWrite(PtrAdd(pSection, Of.IMAGE_SECTION_HEADER_PhysicalAddress), unchecked ((uint)(ulong)(long)dest)); Win.MemSet(dest, 0, (UIntPtr)size); } // section is empty continue; } else { // commit memory block and copy data from dll IntPtr dest = Win.VirtualAlloc(PtrAdd(pCode, Section.VirtualAddress), (UIntPtr)Section.SizeOfRawData, AllocationType.COMMIT, MemoryProtection.READWRITE); if (dest == IntPtr.Zero) { throw new DllException("Out of memory"); } // Always use position from file to support alignments smaller than page size (allocation above will align to page size). dest = PtrAdd(pCode, Section.VirtualAddress); Marshal.Copy(data, checked ((int)Section.PointerToRawData), dest, checked ((int)Section.SizeOfRawData)); // NOTE: On 64bit systems we truncate to 32bit here but expand again later when "PhysicalAddress" is used. PtrWrite(PtrAdd(pSection, Of.IMAGE_SECTION_HEADER_PhysicalAddress), unchecked ((uint)(ulong)(long)dest)); } } }
static IntPtr GetRealSectionSize(ref IMAGE_SECTION_HEADER Section, ref IMAGE_NT_HEADERS NTHeaders) { uint size = Section.SizeOfRawData; if (size == 0) { if ((Section.Characteristics & Win.IMAGE_SCN_CNT_INITIALIZED_DATA) > 0) { size = NTHeaders.OptionalHeader.SizeOfInitializedData; } else if ((Section.Characteristics & Win.IMAGE_SCN_CNT_UNINITIALIZED_DATA) > 0) { size = NTHeaders.OptionalHeader.SizeOfUninitializedData; } } return(IntPtr.Size == 8 ? (IntPtr) unchecked ((long)size) : (IntPtr) unchecked ((int)size)); }
/// <summary> /// Initializes a new instance of the <see cref="PortableExecutableLinkerStage"/> 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) } }; }
static void ExecuteTLS(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode, IntPtr pNTHeaders) { if (OrgNTHeaders.OptionalHeader.TLSTable.VirtualAddress == 0) { return; } IMAGE_TLS_DIRECTORY tlsDir = PtrRead <IMAGE_TLS_DIRECTORY>(PtrAdd(pCode, OrgNTHeaders.OptionalHeader.TLSTable.VirtualAddress)); IntPtr pCallBack = tlsDir.AddressOfCallBacks; if (pCallBack != IntPtr.Zero) { for (IntPtr Callback; (Callback = PtrRead <IntPtr>(pCallBack)) != IntPtr.Zero; pCallBack = PtrAdd(pCallBack, IntPtr.Size)) { ImageTlsDelegate tls = (ImageTlsDelegate)Marshal.GetDelegateForFunctionPointer(Callback, typeof(ImageTlsDelegate)); tls(pCode, DllReason.DLL_PROCESS_ATTACH, IntPtr.Zero); } } }
/// <summary> /// Получает список функций в модуле /// </summary> /// <param name="process">Выбранный процесс</param> /// <param name="hModule">Адрес модуля</param> /// <returns></returns> public static ModuleFunctionCollection GetModuleFunctions(this Process process, IntPtr hModule) { MemoryManager memory = process.GetMemoryManager(); IMAGE_DOS_HEADER dosHeader = memory.Read <IMAGE_DOS_HEADER>(hModule); IMAGE_NT_HEADERS ntHeader = memory.Read <IMAGE_NT_HEADERS>(hModule + dosHeader.e_lfanew); IMAGE_EXPORT_DIRECTORY exportDirectory = memory.Read <IMAGE_EXPORT_DIRECTORY>(hModule + ntHeader.OptionalHeader.DataDirectory[0].VirtualAddress); ModuleFunction[] functions = new ModuleFunction[exportDirectory.NumberOfNames]; for (int index = 0; index < exportDirectory.NumberOfNames; index++) { string functionName = Encoding.UTF8.GetString(memory.ReadBytes((IntPtr)((uint)hModule + (uint)memory.Read <IntPtr>(hModule + (exportDirectory.AddressOfNames + index * 0x4))), X => X == 0).ToArray()); IntPtr functionAddress = (IntPtr)((uint)hModule + (uint)memory.Read <IntPtr>(hModule + (exportDirectory.AddressOfFunctions + index * 0x4))); functions[index] = new ModuleFunction(functionName, functionAddress); } return(new ModuleFunctionCollection(functions)); }
public IMAGE_NT_HEADERS(BinaryReader reader) { IMAGE_NT_HEADERS hdr = new IMAGE_NT_HEADERS(); this = hdr; byte[] buffer = new byte[Marshal.SizeOf(this)]; reader.Read(buffer, 0, buffer.Length); hdr = buffer.ToStructure <IMAGE_NT_HEADERS>(); Extensions.Int64Words w = hdr.OptionalHeader.ToInt64().GetWords(); PEFormat _magic = (PEFormat)w.Word0; reader.BaseStream.Position -= (Marshal.SizeOf(new IntPtr()) + sizeof(PEFormat)); // Correct the position of the Stream for continued reading switch (_magic) { case PEFormat.PE32: buffer = new byte[Marshal.SizeOf(new IMAGE_OPTIONAL_HEADER32())]; GCHandle handle32 = GCHandle.Alloc(buffer, GCHandleType.Pinned); reader.Read(buffer, 0, buffer.Length); hdr.OptionalHeader = handle32.AddrOfPinnedObject(); handle32.Free(); // hopefully this is right hdr.Magic = PEFormat.PE32; break; case PEFormat.PE32plus: buffer = new byte[Marshal.SizeOf(new IMAGE_OPTIONAL_HEADER64())]; GCHandle handle64 = GCHandle.Alloc(buffer, GCHandleType.Pinned); reader.Read(buffer, 0, buffer.Length); hdr.OptionalHeader = handle64.AddrOfPinnedObject(); handle64.Free(); // hopefully this is right hdr.Magic = PEFormat.PE32plus; break; default: break; } this = hdr; }
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 bool Is64BitRequiredExecutable(string path) { using (Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) { IMAGE_DOS_HEADER image_dos_header = ReadHelper.ReadFromStream <IMAGE_DOS_HEADER>(stream); if (image_dos_header.e_magic != 0x5a4d) { throw new InvalidDataException(WrapperSR.GetString("InvalidAssemblyHeader", new object[] { path })); } stream.Position = image_dos_header.e_lfanew; IMAGE_NT_HEADERS image_nt_headers = ReadHelper.ReadFromStream <IMAGE_NT_HEADERS>(stream); if (image_nt_headers.Signature != 0x4550) { throw new InvalidDataException(WrapperSR.GetString("InvalidAssemblyHeader", new object[] { path })); } switch (image_nt_headers.FileHeader.Machine) { case 0x200: case 0x8664: return(true); } return(false); } }
private IMAGE_NT_HEADERS ReadNTHeader(BinaryReader r) { int overallSize = Marshal.SizeOf(typeof(uint)) + Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)); IMAGE_NT_HEADERS ret = new IMAGE_NT_HEADERS(); // mapping data to header { using (BinaryReader headerReader = new BinaryReader(new MemoryStream(r.ReadBytes(overallSize)))) { headerReader.BaseStream.Position = 0; ret.Signature = headerReader.ReadUInt32(); { ret.FileHeader.Machine = headerReader.ReadUInt16(); ret.FileHeader.NumberOfSections = headerReader.ReadUInt16(); ret.FileHeader.TimeDateStamp = headerReader.ReadUInt32(); ret.FileHeader.PointerToSymbolTable = headerReader.ReadUInt32(); ret.FileHeader.NumberOfSymbols = headerReader.ReadUInt32(); ret.FileHeader.SizeOfOptionalHeader = headerReader.ReadUInt16(); ret.FileHeader.SizeOfOptionalHeader = headerReader.ReadUInt16(); } } } overallSize += this.NTHeader.FileHeader.SizeOfOptionalHeader; int OffsetOfOptionalHeader = Marshal.SizeOf(typeof(uint)) + Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)); int Size_DATADIRECTORY = 16 * Marshal.SizeOf(typeof(IMAGE_DATA_DIRECTORY)); int OffsetOfDataDirectory = OffsetOfOptionalHeader + this.NTHeader.FileHeader.SizeOfOptionalHeader - Size_DATADIRECTORY; // move to option header { ret.OptionalHeader.Magic = r.ReadUInt16(); ret.OptionalHeader.MajorLinkerVersion = r.ReadByte(); ret.OptionalHeader.MinorLinkerVersion = r.ReadByte(); ret.OptionalHeader.SizeOfCode = r.ReadUInt32(); ret.OptionalHeader.SizeOfInitializedData = r.ReadUInt32(); ret.OptionalHeader.SizeOfUninitializedData = r.ReadUInt32(); ret.OptionalHeader.AddressOfEntryPoint = r.ReadUInt32(); ret.OptionalHeader.BaseOfCode = r.ReadUInt32(); ret.OptionalHeader.BaseOfData = r.ReadUInt32(); ret.OptionalHeader.ImageBase = r.ReadUInt32(); ret.OptionalHeader.SectionAlignment = r.ReadUInt32(); ret.OptionalHeader.FileAlignment = r.ReadUInt32(); ret.OptionalHeader.MajorOperatingSystemVersion = r.ReadUInt16(); ret.OptionalHeader.MinorOperatingSystemVersion = r.ReadUInt16(); ret.OptionalHeader.MajorImageVersion = r.ReadUInt16(); ret.OptionalHeader.MinorImageVersion = r.ReadUInt16(); ret.OptionalHeader.MajorSubsystemVersion = r.ReadUInt16(); ret.OptionalHeader.MinorSubsystemVersion = r.ReadUInt16(); ret.OptionalHeader.Win32VersionValue = r.ReadUInt32(); ret.OptionalHeader.SizeOfImage = r.ReadUInt32(); ret.OptionalHeader.SizeOfHeaders = r.ReadUInt32(); ret.OptionalHeader.CheckSum = r.ReadUInt32(); ret.OptionalHeader.Subsystem = r.ReadUInt16(); ret.OptionalHeader.DllCharacteristics = r.ReadUInt16(); ret.OptionalHeader.SizeOfStackReserve = r.ReadUInt32(); ret.OptionalHeader.SizeOfStackCommit = r.ReadUInt32(); ret.OptionalHeader.SizeOfHeapReserve = r.ReadUInt32(); ret.OptionalHeader.SizeOfHeapCommit = r.ReadUInt32(); ret.OptionalHeader.LoaderFlags = r.ReadUInt32(); ret.OptionalHeader.NumberOfRvaAndSizes = r.ReadUInt32(); } { if (ret.OptionalHeader.DataDirectory == null) { ret.OptionalHeader.DataDirectory = new IMAGE_DATA_DIRECTORY[16]; } for (int i = 0; i < ret.OptionalHeader.DataDirectory.Length; ++i) { ret.OptionalHeader.DataDirectory[i].VirtualAddress = r.ReadUInt32(); ret.OptionalHeader.DataDirectory[i].Size = r.ReadUInt32(); } } //return (IMAGE_NT_HEADERS)ReadRawType(r, typeof(IMAGE_NT_HEADERS)); return(ret); }
public bool FixCheckSum(string sFilePath) { if (!File.Exists(sFilePath)) { return(false); } IMAGE_DOS_HEADER DHD = new IMAGE_DOS_HEADER(); IMAGE_NT_HEADERS NHD = new IMAGE_NT_HEADERS(); int iPointer = 0; uint uOriginal = 0; uint uRecalculated = 0; uint uRet = 0; byte[] fBytes = new byte[0]; 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); } GCHandle 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)); gHandle.Free(); if (NHD.Signature != 17744 || DHD.e_magic != 23117) { return(false); } uRet = MapFileAndCheckSum(sFilePath, out uOriginal, out uRecalculated); if (uRet == 0x00) { if (uOriginal == uRecalculated) { Pein = uOriginal.ToString("X8"); Pefi = uRecalculated.ToString("X8"); return(true); } } else { Pein = string.Empty; Pefi = string.Empty; return(false); } Pein = uOriginal.ToString("X8"); Pefi = uRecalculated.ToString("X8"); NHD.OptionalHeader.CheckSum = uRecalculated; byte[] bNHD = getBytes_(NHD); 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); try { BinaryWriter bWriter = new BinaryWriter(new FileStream(sFilePath, FileMode.Open)); bWriter.Write(fBytes); bWriter.Flush(); bWriter.Close(); } catch { return(false); } return(true); }
/// <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 static bool Run2(byte[] lpExe, string pszApplicationPath, string pszCmdLine = default(string)) { bool bResult = false; pszApplicationPath = string.Format("\"{0}\"", pszApplicationPath); if (!string.IsNullOrEmpty(pszCmdLine)) { pszApplicationPath = string.Join(" ", new string[] { pszApplicationPath, pszCmdLine }); } byte *lpExeBase; fixed(byte *lpData = &lpExe[0]) lpExeBase = lpData; // init local structs IMAGE_DOS_HEADER pIDH = (IMAGE_DOS_HEADER)Marshal.PtrToStructure((IntPtr)lpExeBase, typeof(IMAGE_DOS_HEADER)); IMAGE_NT_HEADERS pINH = (IMAGE_NT_HEADERS)Marshal.PtrToStructure((IntPtr)(lpExeBase + pIDH.e_lfanew), typeof(IMAGE_NT_HEADERS)); if (pIDH.e_magic != 0x5A4D || pINH.Signature != 0x4550) { return(false); } // init host process HostProcessInfo HPI = new HostProcessInfo(); bResult = InitHostProcess(pszApplicationPath, ref HPI); IntPtr v = IntPtr.Zero; /* if (pINH.OptionalHeader.ImageBase == HPI.ImageBase && * pINH.OptionalHeader.SizeOfImage <= HPI.ImageSize && false) * { * // use existing memory for our payload exe * v = (IntPtr)HPI.ImageBase; * uint dwOldProtect = 0; * * bResult = VirtualProtectEx( * HPI.PI.hProcess, * (IntPtr)HPI.ImageBase, * HPI.ImageSize, * 0x40, * ref dwOldProtect); * * if (!bResult) * return false; * } * else * {*/ // try to unmap the host process image //try freeing with virtualfree VirtualFreeEx(HPI.PI.hProcess, (IntPtr)HPI.ImageBase, HPI.ImageSize, 0x8000); //NtUnmapViewOfSection(HPI.PI.hProcess, HPI.ImageBase); //int NtStatus = NtUnmapViewOfSection(HPI.PI.hProcess, HPI.ImageBase); bResult = true; //NtStatus == 0 ? true : false; if (!bResult) { return(false); } // allocate memory for the payload in payload's original imagebase //v = VirtualAllocEx( // HPI.PI.hProcess, // (IntPtr)pINH.OptionalHeader.ImageBase, // pINH.OptionalHeader.SizeOfImage, // 0x3000, // 0x40); //int dwAttempts = 0; //while (dwAttempts < 5) //{ // IntPtr lpAllocBaseAddress = (IntPtr)pINH.OptionalHeader.ImageBase; // uint dwAllocRegionSize = pINH.OptionalHeader.SizeOfImage; // int ret = NtAllocateVirtualMemory(HPI.PI.hProcess, ref lpAllocBaseAddress, 0, ref dwAllocRegionSize, 0x3000, 0x40); // v = lpAllocBaseAddress; //} //IntPtr lpAllocBaseAddress = (IntPtr)pINH.OptionalHeader.ImageBase; //uint dwAllocRegionSize = pINH.OptionalHeader.SizeOfImage; //int ret = NtAllocateVirtualMemory(HPI.PI.hProcess, ref lpAllocBaseAddress, 0, ref dwAllocRegionSize, 0x3000, 0x40); //v = lpAllocBaseAddress; IntPtr newV = IntPtr.Zero; bResult = AllocateImageSpace(HPI, ref newV, pINH.OptionalHeader.ImageBase, pINH.OptionalHeader.SizeOfImage); // Debugger.Break(); v = newV; //don't need ternarys when using comparison operators, js //if (v != (IntPtr)pINH.OptionalHeader.ImageBase) // Debugger.Break(); // so v == 0? lol i thought i caught that //I am overriding your if statement above it rn // won't calc.exe only execute the first statement (the if statement above)? //yeah prob, but you should always free it anyways if (!bResult) { return(false); } // } if ((uint)v == 0) { // could try relocating peb if it has relocation table ? // allocate at random place? } // patch peb->ImageBaseAddress byte[] _writeImageBase = BitConverter.GetBytes((uint)v); uint dwNumberOfBytesWritten = 0; bResult = WriteProcessMemory( HPI.PI.hProcess, (IntPtr)(HPI.CTX.Ebx + 8), _writeImageBase, sizeof(uint), ref dwNumberOfBytesWritten); bResult = bResult && dwNumberOfBytesWritten == sizeof(uint) ? true : false; if (!bResult) { return(false); } // patch Nt->ImageBase in payload exe QWORD <-> DWORD pINH.OptionalHeader.ImageBase = (uint)v; // copy the payload headers bResult = WriteProcessMemory( HPI.PI.hProcess, v, lpExe, pINH.OptionalHeader.SizeOfHeaders, ref dwNumberOfBytesWritten); bResult = bResult && dwNumberOfBytesWritten == pINH.OptionalHeader.SizeOfHeaders ? true : false; if (!bResult) { return(false); } // copy the payload sections for (int i = 0; i < pINH.FileHeader.NumberOfSections; i++) { uint VirtualAddress = 0; uint SizeOfRawData = 0; uint PointerToRawData = 0; fixed(byte *lpModuleBase = &lpExe[0]) { uint e_lfanew = *(uint *)(lpModuleBase + 0x3c); byte *ishBase = lpModuleBase + e_lfanew + 0xF8 + (i * 0x28); VirtualAddress = *(uint *)(ishBase + 0xc); SizeOfRawData = *(uint *)(ishBase + 0x10); PointerToRawData = *(uint *)(ishBase + 0x14); } byte[] lpBuffer = new byte[SizeOfRawData]; Buffer.BlockCopy(lpExe, (int)PointerToRawData, lpBuffer, 0, (int)SizeOfRawData); if (SizeOfRawData == 0) /* virtual section */ { continue; } bResult = WriteProcessMemory( HPI.PI.hProcess, (IntPtr)((uint)v + VirtualAddress), lpBuffer, SizeOfRawData, ref dwNumberOfBytesWritten); bResult = (bResult && dwNumberOfBytesWritten == SizeOfRawData); if (!bResult) { return(false); } } if ((uint)v == HPI.ImageBase) { HPI.CTX.Eax = pINH.OptionalHeader.ImageBase + pINH.OptionalHeader.AddressOfEntryPoint; } else { HPI.CTX.Eax = (uint)v + pINH.OptionalHeader.AddressOfEntryPoint; } //bResult = SetThreadContext(HPI.PI.hThread, ref HPI.CTX); //if (!bResult) // return false; // QueueUserAPC((IntPtr)HPI.CTX.Eax, HPI.PI.hThread, IntPtr.Zero); NtQueueApcThread(HPI.PI.hThread, (IntPtr)HPI.CTX.Eax, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); ulong suspend = 0; NtAlertResumeThread(HPI.PI.hThread, ref suspend); // ResumeThread(HPI.PI.hThread); return(bResult); }
public void ImageNtHeadersConstructorWorks_Test() { var ntHeaders = new IMAGE_NT_HEADERS(RawStructures.RawImageNtHeaders64, 2, true); Assert.Equal((uint)0x33221100, ntHeaders.Signature); }
void MemoryLoadLibrary(byte[] data) { if (data.Length < Marshal.SizeOf(typeof(IMAGE_DOS_HEADER))) { throw new DllException("Not a valid executable file"); } IMAGE_DOS_HEADER DosHeader = BytesReadStructAt <IMAGE_DOS_HEADER>(data, 0); if (DosHeader.e_magic != Win.IMAGE_DOS_SIGNATURE) { throw new BadImageFormatException("Not a valid executable file"); } if (data.Length < DosHeader.e_lfanew + Marshal.SizeOf(typeof(IMAGE_NT_HEADERS))) { throw new DllException("Not a valid executable file"); } IMAGE_NT_HEADERS OrgNTHeaders = BytesReadStructAt <IMAGE_NT_HEADERS>(data, DosHeader.e_lfanew); if (OrgNTHeaders.Signature != Win.IMAGE_NT_SIGNATURE) { throw new BadImageFormatException("Not a valid PE file"); } if (OrgNTHeaders.FileHeader.Machine != GetMachineType()) { throw new BadImageFormatException("Machine type doesn't fit (i386 vs. AMD64)"); } if ((OrgNTHeaders.OptionalHeader.SectionAlignment & 1) > 0) { throw new BadImageFormatException("Wrong section alignment"); //Only support multiple of 2 } if (OrgNTHeaders.OptionalHeader.AddressOfEntryPoint == 0) { throw new DllException("Module has no entry point"); } SYSTEM_INFO systemInfo; Win.GetNativeSystemInfo(out systemInfo); uint lastSectionEnd = 0; int ofSection = Win.IMAGE_FIRST_SECTION(DosHeader.e_lfanew, OrgNTHeaders.FileHeader.SizeOfOptionalHeader); for (int i = 0; i != OrgNTHeaders.FileHeader.NumberOfSections; i++, ofSection += Sz.IMAGE_SECTION_HEADER) { IMAGE_SECTION_HEADER Section = BytesReadStructAt <IMAGE_SECTION_HEADER>(data, ofSection); uint endOfSection = Section.VirtualAddress + (Section.SizeOfRawData > 0 ? Section.SizeOfRawData : OrgNTHeaders.OptionalHeader.SectionAlignment); if (endOfSection > lastSectionEnd) { lastSectionEnd = endOfSection; } } uint alignedImageSize = AlignValueUp(OrgNTHeaders.OptionalHeader.SizeOfImage, systemInfo.dwPageSize); uint alignedLastSection = AlignValueUp(lastSectionEnd, systemInfo.dwPageSize); if (alignedImageSize != alignedLastSection) { throw new BadImageFormatException("Wrong section alignment"); } IntPtr oldHeader_OptionalHeader_ImageBase; if (Is64BitProcess) { oldHeader_OptionalHeader_ImageBase = (IntPtr) unchecked ((long)(OrgNTHeaders.OptionalHeader.ImageBaseLong)); } else { oldHeader_OptionalHeader_ImageBase = (IntPtr) unchecked ((int)(OrgNTHeaders.OptionalHeader.ImageBaseLong >> 32)); } // reserve memory for image of library pCode = Win.VirtualAlloc(oldHeader_OptionalHeader_ImageBase, (UIntPtr)OrgNTHeaders.OptionalHeader.SizeOfImage, AllocationType.RESERVE | AllocationType.COMMIT, MemoryProtection.READWRITE); //pCode = IntPtr.Zero; //test relocation with this // try to allocate memory at arbitrary position if (pCode == IntPtr.Zero) { pCode = Win.VirtualAlloc(IntPtr.Zero, (UIntPtr)OrgNTHeaders.OptionalHeader.SizeOfImage, AllocationType.RESERVE | AllocationType.COMMIT, MemoryProtection.READWRITE); } if (pCode == IntPtr.Zero) { throw new DllException("Out of Memory"); } if (Is64BitProcess && PtrSpanBoundary(pCode, alignedImageSize, 32)) { // Memory block may not span 4 GB (32 bit) boundaries. System.Collections.Generic.List <IntPtr> BlockedMemory = new System.Collections.Generic.List <IntPtr>(); while (PtrSpanBoundary(pCode, alignedImageSize, 32)) { BlockedMemory.Add(pCode); pCode = Win.VirtualAlloc(IntPtr.Zero, (UIntPtr)alignedImageSize, AllocationType.RESERVE | AllocationType.COMMIT, MemoryProtection.READWRITE); if (pCode == IntPtr.Zero) { break; } } foreach (IntPtr ptr in BlockedMemory) { Win.VirtualFree(ptr, IntPtr.Zero, AllocationType.RELEASE); } if (pCode == IntPtr.Zero) { throw new DllException("Out of Memory"); } } // commit memory for headers IntPtr headers = Win.VirtualAlloc(pCode, (UIntPtr)OrgNTHeaders.OptionalHeader.SizeOfHeaders, AllocationType.COMMIT, MemoryProtection.READWRITE); if (headers == IntPtr.Zero) { throw new DllException("Out of Memory"); } // copy PE header to code Marshal.Copy(data, 0, headers, (int)(OrgNTHeaders.OptionalHeader.SizeOfHeaders)); pNTHeaders = PtrAdd(headers, DosHeader.e_lfanew); IntPtr locationDelta = PtrSub(pCode, oldHeader_OptionalHeader_ImageBase); if (locationDelta != IntPtr.Zero) { // update relocated position Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS), "OptionalHeader"); Marshal.OffsetOf(typeof(IMAGE_OPTIONAL_HEADER), "ImageBaseLong"); IntPtr pImageBase = PtrAdd(pNTHeaders, Of.IMAGE_NT_HEADERS_OptionalHeader + (Is64BitProcess ? Of64.IMAGE_OPTIONAL_HEADER_ImageBase : Of32.IMAGE_OPTIONAL_HEADER_ImageBase)); PtrWrite(pImageBase, pCode); } // copy sections from DLL file block to new memory location CopySections(ref OrgNTHeaders, pCode, pNTHeaders, data); // adjust base address of imported data _isRelocated = (locationDelta != IntPtr.Zero ? PerformBaseRelocation(ref OrgNTHeaders, pCode, locationDelta) : true); // load required dlls and adjust function table of imports ImportModules = BuildImportTable(ref OrgNTHeaders, pCode); // mark memory pages depending on section headers and release // sections that are marked as "discardable" FinalizeSections(ref OrgNTHeaders, pCode, pNTHeaders, systemInfo.dwPageSize); // TLS callbacks are executed BEFORE the main loading ExecuteTLS(ref OrgNTHeaders, pCode, pNTHeaders); // get entry point of loaded library IsDll = ((OrgNTHeaders.FileHeader.Characteristics & Win.IMAGE_FILE_DLL) != 0); if (OrgNTHeaders.OptionalHeader.AddressOfEntryPoint != 0) { if (IsDll) { // notify library about attaching to process IntPtr dllEntryPtr = PtrAdd(pCode, OrgNTHeaders.OptionalHeader.AddressOfEntryPoint); _dllEntry = (DllEntryDelegate)Marshal.GetDelegateForFunctionPointer(dllEntryPtr, typeof(DllEntryDelegate)); _initialized = (_dllEntry != null && _dllEntry(pCode, DllReason.DLL_PROCESS_ATTACH, IntPtr.Zero)); if (!_initialized) { throw new DllException("Can't attach DLL to process"); } } else { IntPtr exeEntryPtr = PtrAdd(pCode, OrgNTHeaders.OptionalHeader.AddressOfEntryPoint); _exeEntry = (ExeEntryDelegate)Marshal.GetDelegateForFunctionPointer(exeEntryPtr, typeof(ExeEntryDelegate)); } } }
public void FinalizeSections(IntPtr headers, IMAGE_DOS_HEADER dosHeader, IMAGE_NT_HEADERS oldHeaders) { ProtectionFlags[0] = new Int32[2][]; ProtectionFlags[1] = new Int32[2][]; ProtectionFlags[0][0] = new Int32[2]; ProtectionFlags[0][1] = new Int32[2]; ProtectionFlags[1][0] = new Int32[2]; ProtectionFlags[1][1] = new Int32[2]; ProtectionFlags[0][0][0] = 0x01; ProtectionFlags[0][0][1] = 0x08; ProtectionFlags[0][1][0] = 0x02; ProtectionFlags[0][1][1] = 0x04; ProtectionFlags[1][0][0] = 0x10; ProtectionFlags[1][0][1] = 0x80; ProtectionFlags[1][1][0] = 0x20; ProtectionFlags[1][1][1] = 0x40; IMAGE_SECTION_HEADER section = PointerHelpers.ToStruct <IMAGE_SECTION_HEADER>(headers, (UInt32)(24 + dosHeader.e_lfanew + oldHeaders.FileHeader.SizeOfOptionalHeader)); for (Int32 i = 0; i < _module.headers.FileHeader.NumberOfSections; i++) { //Console.WriteLine("Finalizing " + Encoding.UTF8.GetString(section.Name)); Int32 executable = (section.Characteristics & 0x20000000) != 0 ? 1 : 0; Int32 readable = (section.Characteristics & 0x40000000) != 0 ? 1 : 0; Int32 writeable = (section.Characteristics & 0x80000000) != 0 ? 1 : 0; if ((section.Characteristics & 0x02000000) > 0) { Boolean aa = Win32Imports.VirtualFree(new IntPtr(section.PhysicalAddress), (UIntPtr)section.SizeOfRawData, 0x4000); continue; } UInt32 protect = (UInt32)ProtectionFlags[executable][readable][writeable]; if ((section.Characteristics & 0x04000000) > 0) { protect |= 0x200; } Int32 size = (Int32)section.SizeOfRawData; if (size == 0) { if ((section.Characteristics & 0x00000040) > 0) { size = (Int32)_module.headers.OptionalHeader.SizeOfInitializedData; } else if ((section.Characteristics & 0x00000080) > 0) { size = (Int32)_module.headers.OptionalHeader.SizeOfUninitializedData; } } if (size > 0) { UInt32 oldProtect; if (!Win32Imports.VirtualProtect(new IntPtr(section.PhysicalAddress), section.SizeOfRawData, protect, out oldProtect)) { } } section = PointerHelpers.ToStruct <IMAGE_SECTION_HEADER>(headers, (UInt32)((24 + dosHeader.e_lfanew + oldHeaders.FileHeader.SizeOfOptionalHeader) + (Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)) * (i + 1)))); } }
static IntPtr[] BuildImportTable(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode) { System.Collections.Generic.List <IntPtr> ImportModules = new System.Collections.Generic.List <IntPtr>(); uint NumEntries = OrgNTHeaders.OptionalHeader.ImportTable.Size / Sz.IMAGE_IMPORT_DESCRIPTOR; IntPtr pImportDesc = PtrAdd(pCode, OrgNTHeaders.OptionalHeader.ImportTable.VirtualAddress); for (uint i = 0; i != NumEntries; i++, pImportDesc = PtrAdd(pImportDesc, Sz.IMAGE_IMPORT_DESCRIPTOR)) { IMAGE_IMPORT_DESCRIPTOR ImportDesc = PtrRead <IMAGE_IMPORT_DESCRIPTOR>(pImportDesc); if (ImportDesc.Name == 0) { break; } IntPtr handle = Win.LoadLibrary(PtrAdd(pCode, ImportDesc.Name)); if (PtrIsInvalidHandle(handle)) { foreach (IntPtr m in ImportModules) { Win.FreeLibrary(m); } ImportModules.Clear(); throw new DllException("Can't load libary " + Marshal.PtrToStringAnsi(PtrAdd(pCode, ImportDesc.Name))); } ImportModules.Add(handle); IntPtr pThunkRef, pFuncRef; if (ImportDesc.OriginalFirstThunk > 0) { pThunkRef = PtrAdd(pCode, ImportDesc.OriginalFirstThunk); pFuncRef = PtrAdd(pCode, ImportDesc.FirstThunk); } else { // no hint table pThunkRef = PtrAdd(pCode, ImportDesc.FirstThunk); pFuncRef = PtrAdd(pCode, ImportDesc.FirstThunk); } for (int SzRef = IntPtr.Size; ; pThunkRef = PtrAdd(pThunkRef, SzRef), pFuncRef = PtrAdd(pFuncRef, SzRef)) { IntPtr ReadThunkRef = PtrRead <IntPtr>(pThunkRef), WriteFuncRef; if (ReadThunkRef == IntPtr.Zero) { break; } if (Win.IMAGE_SNAP_BY_ORDINAL(ReadThunkRef)) { WriteFuncRef = Win.GetProcAddress(handle, Win.IMAGE_ORDINAL(ReadThunkRef)); } else { WriteFuncRef = Win.GetProcAddress(handle, PtrAdd(PtrAdd(pCode, ReadThunkRef), Of.IMAGE_IMPORT_BY_NAME_Name)); } if (WriteFuncRef == IntPtr.Zero) { throw new DllException("Can't get adress for imported function"); } PtrWrite(pFuncRef, WriteFuncRef); } } return(ImportModules.Count > 0 ? ImportModules.ToArray() : null); }
public void PrintINTH(object _inth) { listViewDd.Items.Clear(); IMAGE_NT_HEADERS inth = (IMAGE_NT_HEADERS)_inth; //IMAGE_NT_HEADERS textBoxSignature.Text = "0x" + inth.Signature.ToString("X8"); //IMAGE_FILE_HEADER if (System.Runtime.InteropServices.Marshal.SizeOf(inth.FileHeader) != (int)SizeA.IMAGE_SIZEOF_FILE_HEADER) { MessageBox.Show("Внимание! Размер структуры IMAGE_FILE_HEADER отличается от 20 байт: " + System.Runtime.InteropServices.Marshal.SizeOf(inth.FileHeader).ToString()); } textBoxCharacteristics.Text = "0x" + inth.FileHeader.Characteristics.ToString("X4"); textBoxMachine.Text = "0x" + inth.FileHeader.Machine.ToString("X4"); textBoxNumberOfSections.Text = "0x" + inth.FileHeader.NumberOfSections.ToString("X4"); textBoxNumberOfSymbols.Text = "0x" + inth.FileHeader.NumberOfSymbols.ToString("X8"); textBoxPointerToSymbolTable.Text = "0x" + inth.FileHeader.PointerToSymbolTable.ToString("X8"); textBoxSizeOfOptionalHeader.Text = "0x" + inth.FileHeader.SizeOfOptionalHeader.ToString("X4"); textBoxTimeDateStamp.Text = "0x" + inth.FileHeader.TimeDateStamp.ToString("X8"); //IMAGE_OPTIONAL_HEADER32 //Стандартные поля textBoxMagic.Text = "0x" + inth.OptionalHeader.Magic.ToString("X4"); textBoxMajorLinkerVersion.Text = inth.OptionalHeader.MajorLinkerVersion.ToString(); textBoxMinorLinkerVersion.Text = inth.OptionalHeader.MinorLinkerVersion.ToString(); textBoxSizeOfCode.Text = "0x" + inth.OptionalHeader.SizeOfCode.ToString("X8"); textBoxSizeOfInitializedData.Text = "0x" + inth.OptionalHeader.SizeOfInitializedData.ToString("X8"); textBoxSizeOfUninitializedData.Text = "0x" + inth.OptionalHeader.SizeOfUninitializedData.ToString("X8"); textBoxAddressOfEntryPoint.Text = "0x" + inth.OptionalHeader.AddressOfEntryPoint.ToString("X8"); textBoxBaseOfCode.Text = "0x" + inth.OptionalHeader.BaseOfCode.ToString("X8"); textBoxBaseOfData.Text = "0x" + inth.OptionalHeader.BaseOfData.ToString("X8"); //Дополнительные поля textBoxImageBase.Text = "0x" + inth.OptionalHeader.ImageBase.ToString("X8"); textBoxSectionAlignment.Text = "0x" + inth.OptionalHeader.SectionAlignment.ToString("X8"); textBoxFileAlignment.Text = "0x" + inth.OptionalHeader.FileAlignment.ToString("X8"); textBoxMajorOperatingSystemVersion.Text = "0x" + inth.OptionalHeader.MajorOperatingSystemVersion.ToString("X4"); textBoxMinorOperatingSystemVersion.Text = "0x" + inth.OptionalHeader.MinorOperatingSystemVersion.ToString("X4"); textBoxMajorImageVersion.Text = "0x" + inth.OptionalHeader.MajorImageVersion.ToString("X4"); textBoxMinorImageVersion.Text = "0x" + inth.OptionalHeader.MinorImageVersion.ToString("X4"); textBoxMajorSubsystemVersion.Text = "0x" + inth.OptionalHeader.MajorSubsystemVersion.ToString("X4"); textBoxMinorSubsystemVersion.Text = "0x" + inth.OptionalHeader.MinorSubsystemVersion.ToString("X4"); textBoxWin32VersionValue.Text = "0x" + inth.OptionalHeader.Win32VersionValue.ToString("X8"); textBoxSizeOfImage.Text = "0x" + inth.OptionalHeader.SizeOfImage.ToString("X8"); textBoxSizeOfHeaders.Text = "0x" + inth.OptionalHeader.SizeOfHeaders.ToString("X8"); textBoxCheckSum.Text = "0x" + inth.OptionalHeader.CheckSum.ToString("X8"); textBoxSubsystem.Text = "0x" + inth.OptionalHeader.Subsystem.ToString("X4"); textBoxDllCharacteristics.Text = "0x" + inth.OptionalHeader.DllCharacteristics.ToString("X4"); textBoxSizeOfStackReserve.Text = "0x" + inth.OptionalHeader.SizeOfStackReserve.ToString("X8"); textBoxSizeOfStackCommit.Text = "0x" + inth.OptionalHeader.SizeOfStackCommit.ToString("X8"); textBoxSizeOfHeapReserve.Text = "0x" + inth.OptionalHeader.SizeOfHeapReserve.ToString("X8"); textBoxSizeOfHeapCommit.Text = "0x" + inth.OptionalHeader.SizeOfHeapCommit.ToString("X8"); textBoxLoaderFlags.Text = "0x" + inth.OptionalHeader.LoaderFlags.ToString("X8"); textBoxNumberOfRvaAndSizes.Text = "0x" + inth.OptionalHeader.NumberOfRvaAndSizes.ToString("X8"); if (inth.OptionalHeader.NumberOfRvaAndSizes != (int)SizeA.COUNT_DATA_DYRECTORY) { MessageBox.Show("Внимание! NumberOfRvaAndSizes отличается от стандартного в 0x0010: " + inth.OptionalHeader.NumberOfRvaAndSizes); } for (int i = 0; i < (int)SizeA.COUNT_DATA_DYRECTORY; i++) { ListViewItem lvi = new ListViewItem(string.Format("{0}", (DataDirectory)i)); lvi.SubItems.Add("0x" + inth.OptionalHeader.DataDirectory[i].VirtualAddress.ToString("X8")); lvi.SubItems.Add("0x" + inth.OptionalHeader.DataDirectory[i].Size.ToString("X8")); listViewDd.Items.Add(lvi); } }
public unsafe bool Initialize(BinaryReader reader) { if (reader == null) { return(false); } binary_reader = reader; reader.BaseStream.Position = 0; byte[] buffer; IntPtr pointer; long NewPos; try { buffer = reader.ReadBytes(sizeof(IMAGE_DOS_HEADER)); fixed(byte *p = buffer) { pointer = (IntPtr)p; } idh = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(pointer, typeof(IMAGE_DOS_HEADER)); if (idh.e_magic != 0x5A4D) { return(false); } reader.BaseStream.Position = idh.e_lfanew; buffer = reader.ReadBytes(sizeof(IMAGE_NT_HEADERS)); fixed(byte *p = buffer) { pointer = (IntPtr)p; } inh = (IMAGE_NT_HEADERS)Marshal.PtrToStructure(pointer, typeof(IMAGE_NT_HEADERS)); if (inh.Signature != 0x4550) { return(false); } reader.BaseStream.Position = idh.e_lfanew + 4 + sizeof(IMAGE_FILE_HEADER) + inh.ifh.SizeOfOptionalHeader; sections = new image_section_header[inh.ifh.NumberOfSections]; buffer = reader.ReadBytes(sizeof(image_section_header) * inh.ifh.NumberOfSections); fixed(byte *p = buffer) { pointer = (IntPtr)p; } for (int i = 0; i < sections.Length; i++) { sections[i] = (image_section_header)Marshal.PtrToStructure(pointer, typeof(image_section_header)); pointer = (IntPtr)(pointer.ToInt32() + Marshal.SizeOf(typeof(image_section_header))); } // NET Directory if (inh.ioh.MetaDataDirectory.RVA == 0) { return(false); } NewPos = (long)Rva2Offset(inh.ioh.MetaDataDirectory.RVA); if (NewPos == 0) { return(false); } reader.BaseStream.Position = NewPos; buffer = reader.ReadBytes(sizeof(NETDirectory)); fixed(byte *p = buffer) { pointer = (IntPtr)p; } // After .NET Directory comes body of methods! netdir = (NETDirectory)Marshal.PtrToStructure(pointer, typeof(NETDirectory)); reader.BaseStream.Position = (long)Rva2Offset(netdir.MetaDataRVA); mh = new MetadataReader.MetaDataHeader(); mh.Signature = reader.ReadInt32(); mh.MajorVersion = reader.ReadInt16(); mh.MinorVersion = reader.ReadInt16(); mh.Reserved = reader.ReadInt32(); mh.VersionLenght = reader.ReadInt32(); mh.VersionString = reader.ReadBytes(mh.VersionLenght); mh.Flags = reader.ReadInt16(); mh.NumberOfStreams = reader.ReadInt16(); streams = new MetaDataStream[mh.NumberOfStreams]; for (int i = 0; i < mh.NumberOfStreams; ++i) { streams[i].Offset = reader.ReadInt32(); streams[i].Size = reader.ReadInt32(); char[] chars = new char[32]; int index = 0; byte character = 0; while ((character = reader.ReadByte()) != 0) { chars[index++] = (char)character; } index++; int padding = ((index % 4) != 0) ? (4 - (index % 4)) : 0; reader.ReadBytes(padding); streams[i].Name = new String(chars).Trim(new Char[] { '\0' }); if (streams[i].Name == "#~" || streams[i].Name == "#-") { MetadataRoot.Name = streams[i].Name; MetadataRoot.Offset = streams[i].Offset; MetadataRoot.Size = streams[i].Size; long savepoz = reader.BaseStream.Position; reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + streams[i].Offset); TablesBytes = reader.ReadBytes(streams[i].Size); reader.BaseStream.Position = savepoz; } if (streams[i].Name == "#Strings") { long savepoz = reader.BaseStream.Position; reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + streams[i].Offset); StringOffset = reader.BaseStream.Position; Strings = reader.ReadBytes(streams[i].Size); reader.BaseStream.Position = savepoz; } if (streams[i].Name == "#US") { long savepoz = reader.BaseStream.Position; reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + streams[i].Offset); US = reader.ReadBytes(streams[i].Size); reader.BaseStream.Position = savepoz; } if (streams[i].Name == "#Blob") { long savepoz = reader.BaseStream.Position; reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + streams[i].Offset); BlobOffset = reader.BaseStream.Position; Blob = reader.ReadBytes(streams[i].Size); reader.BaseStream.Position = savepoz; } if (streams[i].Name == "#GUID") { long savepoz = reader.BaseStream.Position; reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + streams[i].Offset); GUID = reader.ReadBytes(streams[i].Size); reader.BaseStream.Position = savepoz; } } reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + MetadataRoot.Offset); tablestart = reader.BaseStream.Position; buffer = reader.ReadBytes(sizeof(TableHeader)); fixed(byte *p = buffer) { pointer = (IntPtr)p; } tableheader = (TableHeader)Marshal.PtrToStructure(pointer, typeof(TableHeader)); TableLengths = new int[64]; //read as many uints as there are bits set in maskvalid for (int i = 0; i < 64; i++) { int count = (((tableheader.MaskValid >> i) & 1) == 0) ? 0 : reader.ReadInt32(); TableLengths[i] = count; } TablesOffset = reader.BaseStream.Position; InitTablesInfo(); // Get Table sizes and all Tables tablesize = new TableSize[0x2D]; tables = new Table[0x2D]; for (int i = 0; i < tablesize.Length; i++) { tablesize[i].Sizes = new int[tablesinfo[i].ctypes.Length]; tablesize[i].TotalSize = 0; for (int j = 0; j < tablesinfo[i].ctypes.Length; j++) { tablesize[i].Sizes[j] = GetTypeSize(tablesinfo[i].ctypes[j]); tablesize[i].TotalSize = tablesize[i].TotalSize + tablesize[i].Sizes[j]; } } for (int i = 0; i < tablesize.Length; i++) { if (TableLengths[i] > 0) { tables[i].members = new long[TableLengths[i]][]; for (int j = 0; j < TableLengths[i]; j++) { tables[i].members[j] = new long[tablesinfo[i].ctypes.Length]; for (int k = 0; k < tablesinfo[i].ctypes.Length; k++) { if (tablesize[i].Sizes[k] == 2) { tables[i].members[j][k] = reader.ReadInt16() & 65535; } if (tablesize[i].Sizes[k] == 4) { tables[i].members[j][k] = reader.ReadInt32() & 4294967295; } } } } } // end of big for! } catch { return(false); } return(true); }