private void MapAndLoad(FileHandle fileHandle, bool readOnly) { using (Section section = new Section( fileHandle, false, readOnly ? MemoryProtection.ExecuteRead : MemoryProtection.ExecuteReadWrite )) { _size = (int)fileHandle.GetSize(); _view = section.MapView(_size); _memory = _view; byte *start = (byte *)_memory; if (start[0] != 'M' || start[1] != 'Z') { throw new Exception("The file is not a valid executable image."); } _ntHeaders = this.GetNtHeaders(); _sections = (ImageSectionHeader *)((byte *)&_ntHeaders->OptionalHeader + _ntHeaders->FileHeader.SizeOfOptionalHeader); _magic = _ntHeaders->OptionalHeader.Magic; if (_magic != Win32.Pe32Magic && _magic != Win32.Pe32PlusMagic) { throw new Exception("The file is not a PE32 or PE32+ image."); } } }
public void *RvaToVa(int rva) { ImageSectionHeader *section = this.RvaToSection(rva); if (section == null) { return(null); } return((byte *)_memory + section->PointerToRawData - section->VirtualAddress + rva); }
public static unsafe IntPtr GetExportedFunctionPointerForModule(long moduleBaseAddress, string importName) { ImageNtHeaders * imageNtHeaders = AnalyseModuleWin((IntPtr)moduleBaseAddress); ImageSectionHeader *pSech = ImageFirstSection(imageNtHeaders); ImageDataDirectory *imageDirectoryEntryExport = MelonUtils.IsGame32Bit() ? &imageNtHeaders->optionalHeader32.exportTable : &imageNtHeaders->optionalHeader64.exportTable; ImageExportDirectory *pExportDirectory = (ImageExportDirectory *)((long)moduleBaseAddress + imageDirectoryEntryExport->virtualAddress); //MelonLoader.MelonLogger.Msg("pExportDirectory at " + string.Format("{0:X}", (ulong)pExportDirectory - (ulong)moduleBaseAddress)); for (uint i = 0; i < imageDirectoryEntryExport->size / sizeof(ImageExportDirectory); ++i) { ImageExportDirectory *pExportDirectoryI = pExportDirectory + i; //MelonLoader.MelonLogger.Msg("pExportDirectoryI->name: " + string.Format("{0:X}", pExportDirectoryI->name)); if (pExportDirectoryI->name != 0) { string imagename = Marshal.PtrToStringAnsi((IntPtr)((long)moduleBaseAddress + pExportDirectoryI->name)); //string imagename = CppUtils.CharArrayPtrToString((IntPtr)pExportDirectoryI->name); //MelonLoader.MelonLogger.Msg("imagename: " + imagename); /* * if (imagename != "UnityPlayer.dll") * continue; */ long baseNameOrdinalOffset = moduleBaseAddress + (int)pExportDirectoryI->addressOfNameOrdinals; long baseFunctionOffset = moduleBaseAddress + (int)pExportDirectoryI->addressOfFunctions; long baseNameOffset = moduleBaseAddress + (int)pExportDirectoryI->addressOfNames; for (int j = 0; j < pExportDirectoryI->numberOfNames; ++j) { ushort ordinal = *(ushort *)((long)baseNameOrdinalOffset + j * 2); long functionnameAddress = moduleBaseAddress + *(int *)(baseNameOffset + j * 4); long functionaddress = moduleBaseAddress + *(int *)(baseFunctionOffset + ordinal * 4); string importname = Marshal.PtrToStringAnsi((IntPtr)functionnameAddress); //MelonLoader.MelonLogger.Msg($"{imagename}::{importname} @ 0x{((ulong)functionaddress - (ulong)moduleBaseAddress):X} (0x{functionaddress:X} - 0x{moduleBaseAddress:X})"); if (importname == importName) { return((IntPtr)functionaddress); } } } } return(IntPtr.Zero); }
private void Load(void *memory) { _memory = memory; byte *start = (byte *)_memory; if (start[0] != 'M' || start[1] != 'Z') { throw new Exception("The file is not a valid executable image."); } _ntHeaders = this.GetNtHeaders(); _sections = (ImageSectionHeader *)((byte *)&_ntHeaders->OptionalHeader + _ntHeaders->FileHeader.SizeOfOptionalHeader); _magic = _ntHeaders->OptionalHeader.Magic; if (_magic != Win32.Pe32Magic && _magic != Win32.Pe32PlusMagic) { throw new Exception("The file is not a PE32 or PE32+ image."); } }
public string GetSectionName(ImageSectionHeader *section) { return(new string((sbyte *)section->Name, 0, 8).TrimEnd('\0')); }
private void MapAndLoad(FileHandle fileHandle, bool readOnly) { using (Section section = new Section( fileHandle, false, readOnly ? MemoryProtection.ExecuteRead : MemoryProtection.ExecuteReadWrite )) { _size = (int)fileHandle.GetSize(); _view = section.MapView(_size); _memory = _view; byte* start = (byte*)_memory; if (start[0] != 'M' || start[1] != 'Z') throw new Exception("The file is not a valid executable image."); _ntHeaders = this.GetNtHeaders(); _sections = (ImageSectionHeader*)((byte*)&_ntHeaders->OptionalHeader + _ntHeaders->FileHeader.SizeOfOptionalHeader); _magic = _ntHeaders->OptionalHeader.Magic; if (_magic != Win32.Pe32Magic && _magic != Win32.Pe32PlusMagic) throw new Exception("The file is not a PE32 or PE32+ image."); } }
private unsafe void Read() { // Preprare lists #region COFF Header // COFF header listCOFFHeader.Items.Clear(); listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Target Machine", _mappedImage.NtHeaders->FileHeader.Machine.ToString() })); listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Number of Sections", _mappedImage.NtHeaders->FileHeader.NumberOfSections.ToString() })); listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Time/Date Stamp", Utils.GetDateTimeFromUnixTime((uint)_mappedImage.NtHeaders->FileHeader.TimeDateStamp).ToString() })); listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Pointer to Symbol Table", Utils.FormatAddress(_mappedImage.NtHeaders->FileHeader.PointerToSymbolTable) })); listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Number of Symbols", _mappedImage.NtHeaders->FileHeader.NumberOfSymbols.ToString() })); listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Size of Optional Header", _mappedImage.NtHeaders->FileHeader.SizeOfOptionalHeader.ToString() })); listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Characteristics", _mappedImage.NtHeaders->FileHeader.Characteristics.ToString() })); #endregion #region COFF Optional Header // COFF optional header listCOFFOptionalHeader.Items.Clear(); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Magic", _mappedImage.NtHeaders->OptionalHeader.Magic == Win32.Pe32Magic ? "PE32 (0x10b)" : (_mappedImage.NtHeaders->OptionalHeader.Magic == Win32.Pe32PlusMagic ? "PE32+ (0x20b)" : "Unknown (0x" + _mappedImage.NtHeaders->OptionalHeader.Magic.ToString("x") + ")") })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Linker Version", _mappedImage.NtHeaders->OptionalHeader.MajorLinkerVersion.ToString() + "." + _mappedImage.NtHeaders->OptionalHeader.MinorLinkerVersion.ToString() })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Code", "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfCode.ToString("x") })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Initialized Data", "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfInitializedData.ToString("x") })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Uninitialized Data", "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfUninitializedData.ToString("x") })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Entry Point RVA", "0x" + _mappedImage.NtHeaders->OptionalHeader.AddressOfEntryPoint.ToString("x") })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Base of Code", "0x" + _mappedImage.NtHeaders->OptionalHeader.BaseOfCode.ToString("x") })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Preferred Image Base", "0x" + _mappedImage.NtHeaders->OptionalHeader.ImageBase.ToString("x") })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Section Alignment", _mappedImage.NtHeaders->OptionalHeader.SectionAlignment.ToString() })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "File Alignment", _mappedImage.NtHeaders->OptionalHeader.FileAlignment.ToString() })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Operating System Version", _mappedImage.NtHeaders->OptionalHeader.MajorOperatingSystemVersion.ToString() + "." + _mappedImage.NtHeaders->OptionalHeader.MinorOperatingSystemVersion.ToString() })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Image Version", _mappedImage.NtHeaders->OptionalHeader.MajorImageVersion.ToString() + "." + _mappedImage.NtHeaders->OptionalHeader.MinorImageVersion.ToString() })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Subsystem Version", _mappedImage.NtHeaders->OptionalHeader.MajorSubsystemVersion.ToString() + "." + _mappedImage.NtHeaders->OptionalHeader.MinorSubsystemVersion.ToString() })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Image", "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfImage.ToString("x") })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Headers", "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfHeaders.ToString("x") })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Checksum", "0x" + _mappedImage.NtHeaders->OptionalHeader.CheckSum.ToString("x") })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Subsystem", _mappedImage.NtHeaders->OptionalHeader.Subsystem.ToString() })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "DLL Characteristics", _mappedImage.NtHeaders->OptionalHeader.DllCharacteristics.ToString() })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Stack Reserve", "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfStackReserve.ToString("x") })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Stack Commit", "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfStackCommit.ToString("x") })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Heap Reserve", "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfHeapReserve.ToString("x") })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Heap Commit", "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfHeapCommit.ToString("x") })); listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Number of Data Directory Entries", _mappedImage.NtHeaders->OptionalHeader.NumberOfRvaAndSizes.ToString() })); #endregion #region Image Data listImageData.Items.Clear(); for (int i = 0; i < _mappedImage.NumberOfDataEntries; i++) { ImageDataDirectory *dataEntry; dataEntry = _mappedImage.GetDataEntry((ImageDataEntry)i); if (dataEntry != null && dataEntry->VirtualAddress != 0) { ListViewItem item = new ListViewItem { Text = ((ImageDataEntry)i).ToString() }; item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + dataEntry->VirtualAddress.ToString("x"))); item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + dataEntry->Size.ToString("x"))); listImageData.Items.Add(item); } } #endregion #region Sections listSections.Items.Clear(); for (int i = 0; i < _mappedImage.NumberOfSections; i++) { ImageSectionHeader *section = &_mappedImage.Sections[i]; ListViewItem item = new ListViewItem { Text = this._mappedImage.GetSectionName(section) }; item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + section->VirtualAddress.ToString("x"))); item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + section->SizeOfRawData.ToString("x"))); item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + section->PointerToRawData.ToString("x"))); item.SubItems.Add(new ListViewItem.ListViewSubItem(item, section->Characteristics.ToString())); listSections.Items.Add(item); } #endregion #region Exports listExports.VirtualListSize = _mappedImage.Exports.Count; #endregion #region Imports listImports.Items.Clear(); listImports.Groups.Clear(); var list = new List <KeyValuePair <string, int> >(); for (int i = 0; i < _mappedImage.Imports.Count; i++) { list.Add(new KeyValuePair <string, int>(_mappedImage.Imports[i].Name, i)); } list.Sort((kvp1, kvp2) => StringComparer.CurrentCultureIgnoreCase.Compare(kvp1.Key, kvp2.Key)); for (int i = 0; i < list.Count; i++) { var dll = _mappedImage.Imports[list[i].Value]; int index = list[i].Value; listImports.Groups.Add(new ListViewGroup(list[i].Key)); for (int j = 0; j < dll.Count; j++) { var entry = dll[j]; ListViewItem item = new ListViewItem(listImports.Groups[listImports.Groups.Count - 1]); if (entry.Name == null) { item.Text = "(Ordinal " + entry.Ordinal.ToString() + ")"; item.SubItems.Add(new ListViewItem.ListViewSubItem()); } else { item.Text = entry.Name; item.SubItems.Add(new ListViewItem.ListViewSubItem(item, entry.NameHint.ToString())); } listImports.Items.Add(item); } } // We set GroupState here else there are no groups to set state. listImports.SetGroupState(ListViewGroupState.Collapsible, "Properties"); #endregion }
private void Load(void* memory) { _memory = memory; byte* start = (byte*)_memory; if (start[0] != 'M' || start[1] != 'Z') throw new Exception("The file is not a valid executable image."); _ntHeaders = this.GetNtHeaders(); _sections = (ImageSectionHeader*)((byte*)&_ntHeaders->OptionalHeader + _ntHeaders->FileHeader.SizeOfOptionalHeader); _magic = _ntHeaders->OptionalHeader.Magic; if (_magic != Win32.Pe32Magic && _magic != Win32.Pe32PlusMagic) throw new Exception("The file is not a PE32 or PE32+ image."); }