Example #1
0
        public static unsafe NTHeaders *GetNtHeaders(byte *pBin)
        {
            // Bin is binary btw. Imo clearer than using peFile.

            MS_DOS_Stub *stub = (MS_DOS_Stub *)(pBin);

            if (stub->e_magic != IMAGE_DOS_SIGNATURE)
            {
                throw new FormatException("Error, Invalid file. DOS Signature is incorrect.");
            }

            NTHeaders *ntHeaders = (NTHeaders *)(pBin + stub->e_lfanew);

            if (ntHeaders->MagicNumber != IMAGE_NT_PEHEADER_SIGNATURE)
            {
                throw new FormatException("Error, Invalid file. PE File signature incorrect.");
            }

            if (ntHeaders->optnHeader.magic == Magic.PE32)
            {
                throw new FormatException("Error, Invalid file. 32 Bit DLL's are not supported.");
            }
            else if (ntHeaders->optnHeader.magic != Magic.PE64)
            {
                throw new FormatException("Error, Invalid file. Optional header signature is incorrect.");
            }

            return(ntHeaders);
        }
Example #2
0
        public static unsafe Dictionary <string, UInt32> dumpSymbolsFromFile(byte *pBin)
        {
            Dictionary <string, UInt32> ExportTable = new Dictionary <string, UInt32>();

            NTHeaders *ntHeaders = GetNtHeaders(pBin);

            IMAGE_EXPORT_DIRECTORY *exportDir = (IMAGE_EXPORT_DIRECTORY *)(pBin +
                                                                           RVAtoOffset(ntHeaders->optnHeader.exportTable.VirtualAddress, ntHeaders, pBin));

            if (ntHeaders->optnHeader.numberOfRvaAndSizes <= 0)
            {
                throw new ArgumentException("Error, This file has no exports.");
            }

            for (UInt32 i = 0; i < exportDir->NumberOfNames; i++)
            {
                UInt32 offset = (UInt32)RVAtoOffset((*(UInt32 *)(pBin + RVAtoOffset(exportDir->AddressOfFunctions, ntHeaders, pBin) + (i * sizeof(UInt32)))), ntHeaders, pBin);


                UInt32 nameOffset = (UInt32)RVAtoOffset((UInt32)exportDir->AddressOfNames, ntHeaders, pBin) + (i * sizeof(UInt32));

                string methodName = Marshal.PtrToStringAnsi((IntPtr)
                                                            (pBin + RVAtoOffset((*(UInt32 *)(pBin + nameOffset)), ntHeaders, pBin)));


                ExportTable.Add(methodName, offset);
            }

            return(ExportTable);
        }
Example #3
0
        // The offset is where the data is located in the file
        // The RVA (Relative Virtual Address) is where the data is located relative to the start of the file when loaded into memory.
        // The VA (Virtual Address) is the address of something in its own sandbox.
        //
        // These can be calculated by:
        // VA = Offset + SectionHeader.VirtualAddress
        // RVA = Offset + (SectionHeader.VirtualAddress - SectionTable.PointerToRawData)
        //

        public static unsafe UInt64 RVAtoOffset(UInt64 rva, NTHeaders *ntHeaders, byte *pBin)
        {
            MS_DOS_Stub *stub = (MS_DOS_Stub *)(pBin);

            for (int i = 0; i < ntHeaders->FileHeader.numberOfSections; i++)
            {
                section_table *secTable = (section_table *)(pBin + stub->e_lfanew + sizeof(NTHeaders) + sizeof(section_table) * i);

                if (secTable->virtualAddress <= rva && rva < secTable->virtualAddress + secTable->virtualSize)
                {
                    return((UInt64)(rva) + secTable->pointerToRawData - secTable->virtualAddress);
                }
            }

            throw new Exception("Erorr: Could not map RVA to Offset.");
        }