Beispiel #1
0
 public void SetSectionParams(string sectionName, PESectionParameters sectParams)
 {
     for (var i = 0; i < _sectionParameters.Count; i++)
     {
         if (_sectionParameters[i].Name == sectionName)
         {
             _sectionParameters[i] = sectParams;
             Array.Copy(sectParams.ToBytes(), 0, _content,
                        _PEHeaderOffset + _sectionsOffset + PESectionParameters.SECTION_DESCRIPTOR_SIZE * i,
                        PESectionParameters.SECTION_DESCRIPTOR_SIZE);
             return;
         }
     }
     throw new Exception($"Section '{sectionName}' not found (SetSectionParams)");
 }
Beispiel #2
0
        // Consts
        //private const int SECTION_DESCRIPTOR_SIZE = 40;

        public PEFile(string path)
        {
            _content = File.ReadAllBytes(path);
            // DOS header
            if (((_content[0] == 0x4d) && (_content[1] == 0x5a)) || (((_content[0] == 0x5a) && (_content[1] == 0x4d))))
            // MZ
            {
                _PEHeaderOffset = (Int32)BitConverter.ToUInt32(_content, 0x3c);
                // PE header
                if ((_content[_PEHeaderOffset] == 0x50) && (_content[_PEHeaderOffset + 1] == 0x45)) // PE
                {
                    const int MACHINE_OFFSET = 4;
                    var       machine        = BitConverter.ToUInt16(_content, _PEHeaderOffset + MACHINE_OFFSET);
                    if (machine == 0x014c)
                    {
                        Console.WriteLine("   [.] Machine: pe32");
                        _is64 = false;
                    }
                    else if (machine == 0x8664)
                    {
                        Console.WriteLine("   [.] Machine: pe64");
                        _is64 = true;
                    }
                    else
                    {
                        throw new Exception("Unsupported machine value");
                    }

                    const int SECTION_COUNT_OFFSET = MACHINE_OFFSET + 2;
                    var       countOfSections      = BitConverter.ToUInt16(_content, _PEHeaderOffset + SECTION_COUNT_OFFSET);
                    Console.WriteLine($"   [.] Sections count: {countOfSections}");

                    const int OPTIONAL_HEADER_SIZE_OFFSET = SECTION_COUNT_OFFSET + 14;
                    var       optionalHeaderSize          = BitConverter.ToUInt16(_content,
                                                                                  _PEHeaderOffset + OPTIONAL_HEADER_SIZE_OFFSET);
                    Console.WriteLine($"   [.] Optional header size: {optionalHeaderSize}");

                    // Optional Header
                    const int OPTIONAL_HEADER_OFFSET = OPTIONAL_HEADER_SIZE_OFFSET + 4;
                    var       optionalHeaderMagic    = BitConverter.ToUInt16(_content, _PEHeaderOffset + OPTIONAL_HEADER_OFFSET);
                    bool      isMagic64;
                    if (optionalHeaderMagic == 0x010b)
                    {
                        Console.WriteLine("   [.] OptHeader Magic: 32bit");
                        isMagic64 = false;
                    }
                    else if (optionalHeaderMagic == 0x020b)
                    {
                        Console.WriteLine("   [.] OptHeader Magic: 64bit");
                        isMagic64 = true;
                    }
                    else
                    {
                        throw new Exception("Unsupported OptHeader magic value");
                    }
                    if (_is64 != isMagic64)
                    {
                        throw new Exception("OptHeader magic does not match machine");
                    }

                    // Data Directories
                    const int DATADIR_COUNT  = 16;
                    const int DATADIR_SIZE   = 8;
                    int       dataDirsOffset = OPTIONAL_HEADER_OFFSET + optionalHeaderSize - DATADIR_COUNT * DATADIR_SIZE;
                    _importDataDirRVAOffset = dataDirsOffset + 8;
                    var importDataDirRVA = BitConverter.ToUInt32(_content, _PEHeaderOffset + _importDataDirRVAOffset);

                    _importDataDirSizeOffset = _importDataDirRVAOffset + 4;
                    var importDataDirSize = BitConverter.ToUInt32(_content, _PEHeaderOffset + _importDataDirSizeOffset);

                    // Sections Table
                    _sectionsOffset = OPTIONAL_HEADER_OFFSET + optionalHeaderSize;
                    var index = _sectionsOffset;
                    _sections          = new List <string>();
                    _sectionParameters = new List <PESectionParameters>();
                    for (var i = 0; i < countOfSections; i++)
                    {
                        var sectionBytes = new byte[PESectionParameters.SECTION_DESCRIPTOR_SIZE];
                        Array.Copy(_content, _PEHeaderOffset + index, sectionBytes, 0,
                                   PESectionParameters.SECTION_DESCRIPTOR_SIZE);
                        index += PESectionParameters.SECTION_DESCRIPTOR_SIZE;
                        var p = new PESectionParameters(sectionBytes);
                        _sectionParameters.Add(p);
                        _sections.Add(p.Name);
                        Console.WriteLine($"   [.] Find section: '{p.Name}'");
                    }

                    // Find section with import
                    var sectionWithImport = -1;
                    for (var i = 0; i < _sectionParameters.Count; i++)
                    {
                        var p = _sectionParameters[i];
                        if ((p.VirtualAddress <= importDataDirRVA) &&
                            (p.VirtualAddress + p.SizeOfRawData >= importDataDirRVA + importDataDirSize))
                        {
                            sectionWithImport = i;
                        }
                    }
                    if (sectionWithImport == -1)
                    {
                        throw new Exception("Unable to find section with Import Directory");
                    }
                    Console.WriteLine($"   [.] Import found at section '{_sectionParameters[sectionWithImport].Name}'");

                    var importDataDirOffset = importDataDirRVA - _sectionParameters[sectionWithImport].VirtualAddress + _sectionParameters[sectionWithImport].PointerToRawData;
                    _importData = new byte[importDataDirSize];
                    Array.Copy(_content, importDataDirOffset, _importData, 0, importDataDirSize);
                    return;
                }
            }
            throw new Exception("Bad PE");
        }