public static GetName ( ulong name, byte buff ) : string | ||
name | ulong | Offset of the string. |
buff | byte | Containing buffer. |
return | string |
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; } }
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()); }