RVAtoFileMapping() public static method

Map an relative virtual address to the raw file address.
public static RVAtoFileMapping ( this RVA, ICollection sh ) : uint
RVA this Relative Virtual Address
sh ICollection Section Headers
return uint
Ejemplo n.º 1
0
            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);
                    }
                }
Ejemplo n.º 2
0
        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());
        }
Ejemplo n.º 3
0
            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;
                }
            }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
                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());
                }
Ejemplo n.º 7
0
        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;
                }
            }
        }