示例#1
0
        //- reading in ----------------------------------------------------------------

        public static CoffSection readSection(BinaryIn source)
        {
            string      name = source.getAsciiString(8);
            CoffSection sec  = new CoffSection(name);

            sec.memSize  = source.getFour();
            sec.memPos   = source.getFour();
            sec.fileSize = source.getFour();
            sec.filePos  = source.getFour();

            sec.relocTblPos = source.getFour();
            uint skip1 = source.getFour();              //line numbers are deprecated

            sec.relocTblCount = source.getTwo();
            uint skip2 = source.getTwo();

            uint flagval = source.getFour();

            sec.settings = SectionSettings.decodeFlags(flagval);

            uint mark = source.getPos();

            source.seek(sec.filePos);
            byte[] secdata = source.getRange(sec.fileSize);
            sec.data = new List <byte>(secdata);
            source.seek(mark);

            return(sec);
        }
示例#2
0
 public CoffSymbol(String _name)
 {
     name    = _name;
     bind    = SYMBIND.NONE;
     typ     = SYMTYPE.NONE;
     section = null;
     ofs     = 0;
     size    = 0;
 }
示例#3
0
 private void loadSections(BinaryIn source, uint secCount)
 {
     for (int i = 0; i < secCount; i++)
     {
         CoffSection sec = CoffSection.readSection(source);
         sec.owner  = this;
         sec.secNum = i + 1;
         sections.Add(sec);
     }
 }
示例#4
0
        //-----------------------------------------------------------------------------

        public CoffSection findSection(String name)
        {
            CoffSection sec = null;

            if (secNames.ContainsKey(name))
            {
                sec = secNames[name];
            }
            return(sec);
        }
示例#5
0
        public void buildSectionTable()
        {
            //uint secStart = sizeOfHeaders;
            for (int i = 0; i < sections.Count; i++)
            {
                CoffSection sec = sections[i];

                //file pos- if file size != 0, use that instead of data count
                sec.filePos = filepos;
                uint datasize = (uint)sec.data.Count;
                if (sec.fileSize > 0)
                {
                    datasize = sec.fileSize;
                }
                sec.fileSize = (datasize + (fileAlignment - 1)) & ~(fileAlignment - 1);
                filepos     += sec.fileSize;

                uint msize = (sec.memSize + fileAlignment - 1) & ~(fileAlignment - 1);
                if (sec.settings.hasCode)
                {
                    sizeOfCode += msize;
                    if (baseOfCode == 0)
                    {
                        baseOfCode = sec.memPos;
                    }
                }
                if (sec.settings.hasInitData)
                {
                    sizeOfInitializedData += msize;
                    if (baseOfData == 0)
                    {
                        baseOfData = sec.memPos;
                    }
                }
                if (sec.settings.hasUninitData)
                {
                    sizeOfUninitializedData += msize;
                }

                uint memsize = (sec.memSize + memAlignment - 1) & ~(memAlignment - 1);
                mempos += memsize;
            }
        }
示例#6
0
        public static void loadRelocations(BinaryIn source, CoffSection sec, Win32Obj objfile)
        {
            source.seek(sec.relocTblPos);
            for (int i = 0; i < sec.relocTblCount; i++)
            {
                uint addr      = source.getFour();
                int  symidx    = (int)source.getFour();
                uint reloctype = source.getTwo();

                CoffRelocation.Reloctype reltype = CoffRelocation.Reloctype.NONE;
                switch (reloctype)
                {
                case 06:
                    reltype = CoffRelocation.Reloctype.ABSOLUTE;            //IMAGE_REL_I386_DIR32
                    break;

                case 07:
                    reltype = CoffRelocation.Reloctype.RVA;                 //IMAGE_REL_I386_DIR32NB
                    break;

                case 11:
                    reltype = CoffRelocation.Reloctype.SECREL32;            //IMAGE_REL_I386_SECREL
                    break;

                case 20:
                    reltype = CoffRelocation.Reloctype.RELATIVE;            //IMAGE_REL_I386_REL32
                    break;

                default:
                    break;
                }

                CoffSymbol     sym   = objfile.symbols[symidx];
                CoffRelocation reloc = new CoffRelocation(addr - sec.memPos, sym, reltype);
                sec.relocations.Add(reloc);
            }
        }
示例#7
0
        public void buildRelocSection()
        {
            relocList.Sort();

            BinaryOut relData   = new BinaryOut();
            uint      basepage  = relocList[0].addr & 0xFFFFF000;
            uint      blocksize = 8;

            relData.putFour(basepage);
            uint blockstart = relData.getPos();

            relData.putFour(0);
            foreach (CoffRelocationEntry rel in relocList)
            {
                uint page = rel.addr & 0xFFFFF000;
                if (page != basepage)
                {
                    if (blocksize % 4 != 0)
                    {
                        relData.putTwo(0);
                        blocksize += 2;
                    }
                    uint blockend = relData.getPos();
                    relData.seek(blockstart);
                    relData.putFour(blocksize);
                    relData.seek(blockend);
                    basepage  = page;
                    blocksize = 8;
                    relData.putFour(basepage);
                    blockstart = relData.getPos();
                    relData.putFour(0);
                }
                uint ofs = rel.addr % 0x1000;
                ofs += 0x3000;
                relData.putTwo(ofs);
                blocksize += 2;
            }
            if (blocksize % 4 != 0)
            {
                relData.putTwo(0);
                blocksize += 2;
            }
            relData.seek(blockstart);
            relData.putFour(blocksize);

            relocSec      = new CoffSection(".reloc");
            relocSec.data = new List <byte>(relData.getData());
            uint datasize = (uint)relocSec.data.Count;

            relocSec.filePos  = filepos;
            relocSec.fileSize = (datasize + (fileAlignment - 1)) & ~(fileAlignment - 1);
            filepos          += relocSec.fileSize;

            relocSec.memPos  = mempos;
            relocSec.memSize = datasize;
            mempos          += (datasize + (memAlignment - 1)) & ~(memAlignment - 1);

            relocSec.settings.canRead     = true;
            relocSec.settings.hasInitData = true;
            relocSec.settings.canDiscard  = true;

            uint msize = (relocSec.memSize + fileAlignment - 1) & ~(fileAlignment - 1);

            sizeOfInitializedData += msize;

            sections.Add(relocSec);
            baseRelocationTable.rva  = relocSec.memPos;
            baseRelocationTable.size = relocSec.memSize;
        }
示例#8
0
        //standard sections
        public void buildExportSection()
        {
            uint      ordinalBase = 1;
            BinaryOut expData     = new BinaryOut();

            expData.putFour(0);
            expData.putFour((uint)getTimestamp());
            expData.putTwo(1);
            expData.putTwo(0);
            expData.putFour(0);                             //filename addr
            expData.putFour(ordinalBase);
            expData.putFour((uint)exportList.Count);
            expData.putFour((uint)exportList.Count);
            expData.putFour(0x28 + mempos);
            uint expnametbl = 0x28 + 4 * (uint)exportList.Count;

            expData.putFour(expnametbl + mempos);
            uint ordtbl = expnametbl + 4 * (uint)exportList.Count;

            expData.putFour(ordtbl + mempos);

            //export addr tbl
            foreach (CoffExportEntry exp in exportList)
            {
                expData.putFour(exp.addr);
            }

            //export name tbl
            expData.skip(4 * (uint)exportList.Count);

            //ordinal number tbl
            foreach (CoffExportEntry exp in exportList)
            {
                expData.putTwo(exp.ord - ordinalBase);
            }

            uint faddr = expData.getPos() + mempos;

            expData.putString(filename);
            List <uint> nameaddrs = new List <uint>();

            foreach (CoffExportEntry exp in exportList)
            {
                nameaddrs.Add(expData.getPos() + mempos);
                expData.putString(exp.name);
            }

            expData.seek(0xc);
            expData.putFour(faddr);
            expData.seek(expnametbl);
            foreach (uint nameaddr in nameaddrs)
            {
                expData.putFour(nameaddr);
            }

            exportSec      = new CoffSection(".edata");
            exportSec.data = new List <byte>(expData.getData());
            uint datasize = (uint)exportSec.data.Count;

            exportSec.filePos  = filepos;
            exportSec.fileSize = (datasize + (fileAlignment - 1)) & ~(fileAlignment - 1);
            filepos           += exportSec.fileSize;

            exportSec.memPos  = mempos;
            exportSec.memSize = datasize;
            mempos           += (datasize + (memAlignment - 1)) & ~(memAlignment - 1);

            exportSec.settings.canRead     = true;
            exportSec.settings.hasInitData = true;

            uint msize = (exportSec.memSize + fileAlignment - 1) & ~(fileAlignment - 1);

            sizeOfInitializedData += msize;

            sections.Add(exportSec);
            dExportTable.rva  = exportSec.memPos;
            dExportTable.size = exportSec.memSize;
        }
示例#9
0
        public Win32Exe()
        {
            filename = null;
            isDLL    = false;

            mempos  = 0;
            filepos = 0;

            dosHeader = null;

            //coff header fields
            machine         = MachineType.IMAGE_FILE_MACHINE_I386;
            timeStamp       = DateTime.Now;
            characteristics = new Characteristics();

            //optional header fields
            magicNum                = 0x010b;   //PE32 executable
            majorLinkerVersion      = 0;
            minorLinkerVersion      = 1;
            sizeOfCode              = 0;
            sizeOfInitializedData   = 0;
            sizeOfUninitializedData = 0;
            addressOfEntryPoint     = 0;
            baseOfCode              = 0;
            baseOfData              = 0;
            imageBase               = 0x400000; //exe default image base
            memAlignment            = 0x1000;
            fileAlignment           = 0x200;
            majorOSVersion          = 5;
            minorOSVersion          = 1;
            majorImageVersion       = 0;
            minorImageVersion       = 0;
            majorSubsystemVersion   = 5;
            minorSubsystemVersion   = 1;
            win32VersionValue       = 0;             //reserved, must be zero
            sizeOfImage             = 0;
            sizeOfHeaders           = 0;
            checksum                = 0;
            subsystem               = 2;
            dLLCharacteristics      = 0x140;
            sizeOfStackReserve      = 0x100000;
            sizeOfStackCommit       = 0x1000;
            sizeOfHeapReserve       = 0x100000;
            sizeOfHeapCommit        = 0x1000;
            loaderFlags             = 0;            //reserved, must be zero
            numberOfRvaAndSizes     = 0x10;         //"not fixed" but the PE format spec only defines 16 of these

            //data directory
            dExportTable            = new DataDirectory();
            dImportTable            = new DataDirectory();
            dResourceTable          = new DataDirectory();
            exceptionTable          = new DataDirectory();
            certificatesTable       = new DataDirectory();
            baseRelocationTable     = new DataDirectory();
            debugTable              = new DataDirectory();
            architecture            = new DataDirectory();
            globalPtr               = new DataDirectory();
            threadLocalStorageTable = new DataDirectory();
            loadConfigurationTable  = new DataDirectory();
            boundImportTable        = new DataDirectory();
            importAddressTable      = new DataDirectory();
            delayImportDescriptor   = new DataDirectory();
            CLRRuntimeHeader        = new DataDirectory();
            reserved = new DataDirectory();

            sections = new List <CoffSection>();

            //standard sections
            importSec    = null;
            importList   = new List <CoffImportEntry>();
            exportSec    = null;
            exportList   = new List <CoffExportEntry>();
            resourceSec  = null;
            resourceList = new List <ResourceData>();
            relocSec     = null;
            relocList    = new List <CoffRelocationEntry>();
        }
示例#10
0
        public static void loadSymbols(BinaryIn source, uint count, byte[] strtbl, Win32Obj objfile)
        {
            for (int i = 0; i < count;)
            {
                //get short name or pos in string tbl
                uint   nameloc   = source.getPos();
                uint   namezeros = source.getFour();
                String name      = "";
                if (namezeros == 0)         //if first 4 bytes = 0, 2nd 4 bytes = ofs into str tbl
                {
                    int namepos = (int)source.getFour();
                    name = readString(strtbl, namepos);
                }
                else
                {
                    source.seek(nameloc);
                    name = source.getAsciiString(8);
                }

                //read rest of sym entry
                uint             val     = source.getFour();
                uint             secval  = source.getTwo();
                uint             type    = source.getTwo();
                CoffStorageClass storage = (CoffStorageClass)source.getOne();
                uint             aux     = source.getOne();

                CoffSymbol         sym  = null;
                CoffSymbol.SYMBIND bind = CoffSymbol.SYMBIND.EXTERNAL;
                uint        size        = 0;
                uint        addr        = 0;
                CoffSection sec         = null;

                switch (storage)
                {
                case CoffStorageClass.IMAGE_SYM_CLASS_EXTERNAL:
                    if (secval == 0)
                    {
                        if (val == 0)
                        {
                            bind = CoffSymbol.SYMBIND.EXTERNAL;
                        }
                        else
                        {
                            bind = CoffSymbol.SYMBIND.COMMON;
                            size = val;
                        }
                    }
                    else
                    {
                        bind = CoffSymbol.SYMBIND.GLOBAL;
                        sec  = objfile.sections[(int)secval - 1];
                        if (val >= sec.memPos)
                        {
                            addr = val - sec.memPos;
                        }
                    }
                    sym         = new CoffSymbol(name);
                    sym.bind    = bind;
                    sym.typ     = CoffSymbol.SYMTYPE.FUNCTION;
                    sym.section = sec;
                    sym.ofs     = addr;
                    sym.size    = size;
                    break;

                case CoffStorageClass.IMAGE_SYM_CLASS_STATIC:
                case CoffStorageClass.IMAGE_SYM_CLASS_LABEL:
                    if (secval != 0xffff)
                    {
                        sec = objfile.sections[(int)secval - 1];
                        if (val >= sec.memPos)
                        {
                            addr = val - sec.memPos;
                        }
                        sym         = new CoffSymbol(name);
                        sym.bind    = CoffSymbol.SYMBIND.LOCAL;
                        sym.typ     = CoffSymbol.SYMTYPE.FUNCTION;
                        sym.section = sec;
                        sym.ofs     = addr;
                        sym.size    = size;
                    }
                    break;

                case CoffStorageClass.IMAGE_SYM_CLASS_SECTION:
                    sec         = objfile.sections[(int)secval - 1];
                    sym         = new CoffSymbol(name);
                    sym.bind    = CoffSymbol.SYMBIND.LOCAL;
                    sym.typ     = CoffSymbol.SYMTYPE.FUNCTION;
                    sym.section = sec;
                    sym.ofs     = addr;
                    sym.size    = size;
                    break;

                case CoffStorageClass.IMAGE_SYM_CLASS_FUNCTION:
                case CoffStorageClass.IMAGE_SYM_CLASS_FILE:
                    break;

                default:
                    break;
                }
                i++;

                objfile.symbols.Add(sym);
                if (sym != null)
                {
                    objfile.symNames[sym.name] = sym;
                }

                //skip any aux sym entries
                for (int j = 0; j < aux; j++)
                {
                    source.skip(CoffSymbol.SYMTBLENTRYSIZE);
                    objfile.symbols.Add(null);
                    i++;
                }
            }
        }
示例#11
0
        public static Win32Obj readFromFile(String filename)
        {
            Win32Obj objfile = new Win32Obj(filename);
            BinaryIn source  = new BinaryIn(filename);

            //coff header
            objfile.machine = (MachineType)source.getTwo();
            uint sectionCount = source.getTwo();

            objfile.timeStamp = source.getFour();
            uint symbolTblAddr   = source.getFour();
            uint symbolCount     = source.getFour();
            uint optionalHdrSize = source.getTwo();

            objfile.characteristics = (int)source.getTwo();

            //string tbl - follows symbol tbl
            uint strtblpos = symbolTblAddr + symbolCount * CoffSymbol.SYMTBLENTRYSIZE;

            source.seek(strtblpos);
            byte[] strtbl = null;
            uint   len    = source.getFour();

            if (len > 4)
            {
                source.seek(strtblpos);
                strtbl = source.getRange(len);
            }

            //section tbl
            source.seek(COFFHDRSIZE);
            for (int i = 0; i < sectionCount; i++)
            {
                //if section name is stored in string tbl, we read in index & let caller deref the actual name
                String secname = source.getAsciiString(8);
                if (secname[0] == '/')
                {
                    int stridx = Int32.Parse(secname.Substring(1));
                    secname = readString(strtbl, stridx);
                }

                //read section hdr field
                uint memSize  = source.getFour();       //don't use - 0 in object files
                uint memPos   = source.getFour();
                uint fileSize = source.getFour();
                uint filePos  = source.getFour();

                uint relocPos     = source.getFour();
                uint lineNumPos   = source.getFour();   //don't use - deprecated
                uint relocCount   = source.getTwo();
                uint lineNumCount = source.getTwo();    //don't use
                uint flagval      = source.getFour();

                SectionSettings settings = SectionSettings.decodeFlags(flagval);
                CoffSection     section  = new CoffSection(secname, settings);
                section.owner         = objfile;
                section.secNum        = i + 1;
                section.memPos        = memPos;
                section.fileSize      = fileSize;
                section.filePos       = filePos;
                section.relocTblPos   = relocPos;
                section.relocTblCount = relocCount;

                objfile.sections.Add(section);
                objfile.secNames[section.name] = section;
            }

            //load symbols
            source.seek(symbolTblAddr);
            loadSymbols(source, symbolCount, strtbl, objfile);

            foreach (CoffSection section in objfile.sections)
            {
                //load section data
                section.data = new List <Byte>(source.getRange(section.filePos, section.fileSize));

                //load sectionrelocs
                loadRelocations(source, section, objfile);
            }


            return(objfile);
        }