public static RVAtoFileMapping ( this RVA, ICollection |
||
RVA | this | Relative Virtual Address |
sh | ICollection |
Section Headers |
return | uint |
public IMAGE_THUNK_DATA(byte[] buff, UInt32 offset, IMAGE_SECTION_HEADER[] sh, bool is32Bit) { if (is32Bit) { Ordinal = Utility.BytesToUInt32(buff, Utility.RVAtoFileMapping(offset, sh)); // Check if import by name or by ordinal. // If it is an import by ordinal, the most significant bit of "Ordinal" is "1" and the ordinal can // be extracted from the least significant bits. // Else it is an import by name and the link to the IMAGE_IMPORT_BY_NAME has to be followed if ((Ordinal & 0x80000000) == 0x80000000) { Ordinal = (Ordinal & 0x7FFFFFFF); } else { var ordinal = Utility.RVAtoFileMapping((UInt32)Ordinal, sh); ImageImportByName = ParseImageImportByName(nextItdAddress, mode2, buff, st); } } else { Ordinal = Utility.BytesToUInt64(buff, Utility.RVAtoFileMapping(offset, sh)); if ((Ordinal & 0x8000000000000000) == 0x8000000000000000) { Ordinal = (Ordinal & 0x7FFFFFFFFFFFFFFF); } else { var ordinal = Utility.RVAtoFileMapping(Ordinal, sh); ImageImportByName = ParseImageImportByName(nextItdAddress, mode2, buff, st); } }
ImportFunction[] ParseImportedFunctions(byte[] buff, IMAGE_IMPORT_DESCRIPTOR[] idescs, IMAGE_SECTION_HEADER[] sh) { var impFuncs = new List <ImportFunction>(); UInt32 sizeOfThunk = (UInt32)(Is64Bit ? 0x8 : 0x4); // Size of IMAGE_THUNK_DATA UInt64 ordinalBit = (UInt64)(Is64Bit ? 0x8000000000000000 : 0x80000000); UInt64 ordinalMask = (UInt64)(Is64Bit ? 0x7FFFFFFFFFFFFFFF : 0x7FFFFFFF); foreach (var idesc in idescs) { var dllAdr = Utility.RVAtoFileMapping(idesc.Name, sh); var dll = Utility.GetName(dllAdr, buff); var tmpAdr = (idesc.OriginalFirstThunk != 0) ? idesc.OriginalFirstThunk : idesc.FirstThunk; if (tmpAdr == 0) { continue; } var thunkAdr = Utility.RVAtoFileMapping(tmpAdr, sh); UInt32 round = 0; while (true) { var t = new IMAGE_THUNK_DATA(buff, thunkAdr + round * sizeOfThunk, Is64Bit); if (t.AddressOfData == 0) { break; } // Check if import by name or by ordinal. // If it is an import by ordinal, the most significant bit of "Ordinal" is "1" and the ordinal can // be extracted from the least significant bits. // Else it is an import by name and the link to the IMAGE_IMPORT_BY_NAME has to be followed if ((t.Ordinal & ordinalBit) == ordinalBit) // Import by ordinal { impFuncs.Add(new ImportFunction(null, dll, (UInt16)(t.Ordinal & ordinalMask))); } else // Import by name { var ibn = new IMAGE_IMPORT_BY_NAME(buff, Utility.RVAtoFileMapping(t.AddressOfData, sh)); impFuncs.Add(new ImportFunction(ibn.Name, dll, ibn.Hint)); } round++; } } return(impFuncs.ToArray()); }
public IMAGE_IMPORT_DESCRIPTOR(byte[] buff, UInt32 offset, IMAGE_SECTION_HEADER[] sh) { OriginalFirstThunk = Utility.BytesToUInt32(buff, offset); TimeDataStamp = Utility.BytesToUInt32(buff, offset + sizeof(UInt32)); ForwarderChain = Utility.BytesToUInt32(buff, offset + 2 * sizeof(UInt32)); Name = Utility.BytesToUInt32(buff, offset + 3 * sizeof(UInt32)); FirstThunk = Utility.BytesToUInt32(buff, offset + 4 * sizeof(UInt32)); try { // If no name can be resolved, break NameResolved = Utility.GetName(Utility.RVAtoFileMapping(Name, sh), buff); } catch { NameResolved = null; } }
public UNWIND_INFO GetUnwindInfo(RUNTIME_FUNCTION runtimeFunction) { UInt32 uwAddress = 0x00; // Check if the last bit is set in the UnwindInfo. If so, it is a chained // information. if ((runtimeFunction.UnwindInfo & 0x1) == 0x1) { uwAddress = runtimeFunction.UnwindInfo & 0xFFFE; } else { uwAddress = runtimeFunction.UnwindInfo; } var uw = new UNWIND_INFO(_buff, Utility.RVAtoFileMapping(uwAddress, ImageSectionHeaders)); return(uw); }
ExportFunction[] ParseExportedFunctions(byte[] buff, IMAGE_EXPORT_DIRECTORY ed, IMAGE_SECTION_HEADER[] sh) { var expFuncs = new ExportFunction[ed.NumberOfNames]; var funcOffsetPointer = Utility.RVAtoFileMapping(ed.AddressOfFunctions, sh); var ordOffset = Utility.RVAtoFileMapping(ed.AddressOfNameOrdinals, sh); var nameOffsetPointer = Utility.RVAtoFileMapping(ed.AddressOfNames, sh); var funcOffset = Utility.BytesToUInt32(buff, funcOffsetPointer); for (UInt32 i = 0; i < expFuncs.Length; i++) { var namePtr = Utility.BytesToUInt32(buff, nameOffsetPointer + sizeof(UInt32) * i); var nameAdr = Utility.RVAtoFileMapping(namePtr, sh); var name = Utility.GetName(nameAdr, buff); var ordinalIndex = (UInt32)Utility.GetOrdinal(ordOffset + sizeof(UInt16) * i, buff); var ordinal = ordinalIndex + ed.Base; var address = Utility.BytesToUInt32(buff, funcOffsetPointer + sizeof(UInt32) * ordinalIndex); expFuncs[i] = new ExportFunction(name, address, (UInt16)ordinal); } return(expFuncs); }
private IMAGE_IMPORT_BY_NAME[] ParseImageImportByName(UInt32 nextItdAddress, bool mode2, byte[] buff, IMAGE_SECTION_HEADER[] sh) { var iibns = new List <IMAGE_IMPORT_BY_NAME>(); UInt64 address = Utility.RVAtoFileMapping(AddressOfData, sh); if (nextItdAddress != 0) { nextItdAddress = Utility.RVAtoFileMapping(nextItdAddress, sh); // Runs until the address of the next IMAGE_IMPORT_BY_NAME structure is reached. while (address + 1 < nextItdAddress) { var name = Utility.GetName(address + 2, buff); if (name == "" || name[0] < 0x41 || name[0] > 0x7a) { address += 1; continue; } var length = GetNameLength(address + 2, buff); ushort hint = BytesToUshort(buff, address); if (!mode2) { address += (UInt32)(2 + length + 1); // 2 byte hint, length of name, one terminating null byte } else { address += (UInt32)length + 2; for (int i = 0; i < 4; i++) { if (buff[address] != 0) { address -= 2; break; } address++; if (i == 3) { break; } } } iibns.Add(new DATADIRECTORIES.IMAGE_IMPORT_BY_NAME() { Hint = hint, Name = name }); } } else { int counter = 0; while (counter <= 3) { var name = GetName(address + 2, buff); if (name == "" || name[0] < 0x41 || name[0] > 0x7a) { address += 1; counter++; continue; } counter = 0; var length = GetNameLength(address + 2, buff); ushort hint = BytesToUshort(buff, address); address += (UInt32)(2 + length + 1); // 2 byte hint, length of name, one terminating null byte iibns.Add(new DATADIRECTORIES.IMAGE_IMPORT_BY_NAME() { Hint = hint, Name = name }); } } return(iibns.ToArray()); }
public PeFile(byte [] buff) { UInt32 secHeaderOffset = 0; _buff = buff; ImageDosHeader = new IMAGE_DOS_HEADER(buff); // Check if the PE file is 64 bit. Is64Bit = (Utility.BytesToUInt16(buff, ImageDosHeader.e_lfanew + 0x4) == Constants.IMAGE_FILE_MACHINE_AMD64); secHeaderOffset = (UInt32)(Is64Bit ? 0x108 : 0xF8); ImageNtHeaders = new IMAGE_NT_HEADERS(buff, ImageDosHeader.e_lfanew, Is64Bit); ImageSectionHeaders = ParseImageSectionHeaders( buff, ImageNtHeaders.FileHeader.NumberOfSections, ImageDosHeader.e_lfanew + secHeaderOffset ); if (ImageNtHeaders.OptionalHeader.DataDirectory[(int)Constants.DataDirectoryIndex.Export].VirtualAddress != 0) { try { ImageExportDirectory = new IMAGE_EXPORT_DIRECTORY( buff, Utility.RVAtoFileMapping(ImageNtHeaders.OptionalHeader.DataDirectory[0].VirtualAddress, ImageSectionHeaders) ); ExportedFunctions = ParseExportedFunctions( buff, ImageExportDirectory, ImageSectionHeaders ); } catch { // No or invalid export directory. HasValidExportDir = false; } } if (ImageNtHeaders.OptionalHeader.DataDirectory[1].VirtualAddress != 0) { try { ImageImportDescriptors = ParseImportDescriptors( buff, Utility.RVAtoFileMapping(ImageNtHeaders.OptionalHeader.DataDirectory[(int)Constants.DataDirectoryIndex.Import].VirtualAddress, ImageSectionHeaders), ImageSectionHeaders ); ImportedFunctions = ParseImportedFunctions(buff, ImageImportDescriptors, ImageSectionHeaders); } catch { // No or invalid import directory. HasValidImportDir = false; } } // Parse the resource directory. if (ImageNtHeaders.OptionalHeader.DataDirectory[2].VirtualAddress != 0) { try { ImageResourceDirectory = ParseImageResourceDirectory( buff, Utility.RVAtoFileMapping(ImageNtHeaders.OptionalHeader.DataDirectory[(int)Constants.DataDirectoryIndex.Resource].VirtualAddress, ImageSectionHeaders), ImageSectionHeaders ); } catch { // No or invalid resource directory. ImageResourceDirectory = null; HasValidResourceDir = false; } } // Parse x64 Exception directory if (Is64Bit) { if (ImageNtHeaders.OptionalHeader.DataDirectory[(UInt32)Constants.DataDirectoryIndex.Exception].VirtualAddress != 0) { try { RuntimeFunctions = PareseExceptionDirectory( buff, Utility.RVAtoFileMapping(ImageNtHeaders.OptionalHeader.DataDirectory[(UInt32)Constants.DataDirectoryIndex.Exception].VirtualAddress, ImageSectionHeaders), ImageNtHeaders.OptionalHeader.DataDirectory[(UInt32)Constants.DataDirectoryIndex.Exception].Size, ImageSectionHeaders ); } catch { // No or invalid Exception directory. RuntimeFunctions = null; HasValidExceptionDir = false; } } } // Parse the security directory for certificates if (ImageNtHeaders.OptionalHeader.DataDirectory[(int)Constants.DataDirectoryIndex.Security].VirtualAddress != 0) { try { WinCertificate = ParseImageSecurityDirectory( buff, ImageNtHeaders.OptionalHeader.DataDirectory[(int)Constants.DataDirectoryIndex.Security].VirtualAddress, ImageSectionHeaders); } catch (Exception) { // Invalid Security Directory WinCertificate = null; HasValidSecurityDir = false; } } }