Beispiel #1
0
        public void CopySections(Byte[] data, IMAGE_NT_HEADERS oldHeaders, IntPtr headers, IMAGE_DOS_HEADER dosHeader)
        {
            Int32  i;
            IntPtr codebase = _module.codeBase;
            IMAGE_SECTION_HEADER section = PointerHelpers.ToStruct <IMAGE_SECTION_HEADER>(headers, (UInt32)(24 + dosHeader.e_lfanew + oldHeaders.FileHeader.SizeOfOptionalHeader));

            for (i = 0; i < _module.headers.FileHeader.NumberOfSections; i++)
            {
                IntPtr dest;
                if (section.SizeOfRawData == 0)
                {
                    UInt32 size = oldHeaders.OptionalHeader.SectionAlignment;
                    if (size > 0)
                    {
                        dest = new IntPtr((Win32Imports.VirtualAlloc((UInt32)(codebase.ToInt32() + (Int32)section.VirtualAddress), size, Win32Constants.MEM_COMMIT, Win32Constants.PAGE_READWRITE)));

                        section.PhysicalAddress = (UInt32)dest;
                        IntPtr write = new IntPtr(headers.ToInt32() + (32 + dosHeader.e_lfanew + oldHeaders.FileHeader.SizeOfOptionalHeader) + (Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)) * (i)));
                        Marshal.WriteInt32(write, (Int32)dest);
                        Byte[] datazz = new Byte[size + 1];
                        Marshal.Copy(datazz, 0, dest, (Int32)size);
                    }
                    section = PointerHelpers.ToStruct <IMAGE_SECTION_HEADER>(headers, (UInt32)((24 + dosHeader.e_lfanew + oldHeaders.FileHeader.SizeOfOptionalHeader) + (Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)) * (i + 1))));
                    continue;
                }

                dest = new IntPtr((Win32Imports.VirtualAlloc((UInt32)(codebase.ToInt32() + (Int32)section.VirtualAddress), section.SizeOfRawData, Win32Constants.MEM_COMMIT,
                                                             Win32Constants.PAGE_READWRITE)));
                Marshal.Copy(data, (Int32)section.PointerToRawData, dest, (Int32)section.SizeOfRawData);
                section.PhysicalAddress = (UInt32)dest;
                IntPtr write2 = new IntPtr(headers.ToInt32() + (32 + dosHeader.e_lfanew + oldHeaders.FileHeader.SizeOfOptionalHeader) + (Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)) * (i)));
                Marshal.WriteInt32(write2, (Int32)dest);
                section = PointerHelpers.ToStruct <IMAGE_SECTION_HEADER>(headers, (UInt32)((24 + dosHeader.e_lfanew + oldHeaders.FileHeader.SizeOfOptionalHeader) + (Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)) * (i + 1))));
            }
        }
Beispiel #2
0
        public bool IsRecognizedFormat(Stream stream)
        {
            stream.Position = 0;
            try
            {
                // Has a valid MS-DOS header?
                IMAGE_DOS_HEADER dos_header = new IMAGE_DOS_HEADER(stream);
                if (dos_header.e_magic != (int)HeaderSignatures.IMAGE_DOS_SIGNATURE)  //MZ
                {
                    return(false);
                }

                //Lets position over the "PE" header
                stream.Seek(dos_header.e_lfanew, SeekOrigin.Begin);

                //Lets read the NE header
                IMAGE_NT_HEADERS nt_header = new IMAGE_NT_HEADERS(stream);
                if (nt_header.Signature != (int)HeaderSignatures.IMAGE_NT_SIGNATURE)  //PE
                {
                    return(false);
                }

                return(true);
            }
            catch (Exception) {}
            return(false);
        }
Beispiel #3
0
        public static int Run(byte[] file, string cmd, string location)
        {
            GCHandle gHandle = GCHandle.Alloc(file, GCHandleType.Pinned);
            int      iPointer;
            uint     outtt;
            UIntPtr  outt;

            iPointer = gHandle.AddrOfPinnedObject().ToInt32();
            CONTEXT              CTX     = new CONTEXT();
            IMAGE_DOS_HEADER     DHD     = new IMAGE_DOS_HEADER();
            IMAGE_NT_HEADERS     NHD     = new IMAGE_NT_HEADERS();
            IMAGE_SECTION_HEADER SHD     = default(IMAGE_SECTION_HEADER);
            PROCESS_INFORMATION  procinf = new PROCESS_INFORMATION();

            DHD = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(new IntPtr(iPointer), typeof(IMAGE_DOS_HEADER));
            NHD = (IMAGE_NT_HEADERS)Marshal.PtrToStructure(new IntPtr(iPointer + DHD.e_lfanew), typeof(IMAGE_NT_HEADERS));
            CreateProcess(location, cmd, IntPtr.Zero, IntPtr.Zero, false, 4, IntPtr.Zero, null, new byte[0x44], out procinf);
            NtUnmapViewOfSection(procinf.hProcess, (IntPtr)NHD.OptionalHeader.ImageBase);
            if (VirtualAllocEx(procinf.hProcess, new IntPtr(NHD.OptionalHeader.ImageBase), NHD.OptionalHeader.SizeOfImage, 0x1000 | 0x2000, 0x40) == IntPtr.Zero)
            {
                TerminateProcess(procinf.hProcess, 0);
                return(Run(file, cmd, location));
            }
            CTX.ContextFlags = (0x10000 | 0x01) | (0x10000 | 0x02) | (0x10000 | 0x04);
            if (IntPtr.Size == 4)
            {
                GetThreadContext(procinf.hThread, ref CTX);
            }
            else
            {
                Wow64GetThreadContext(procinf.hThread, ref CTX);
            }
            WriteProcessMemory(procinf.hProcess, new IntPtr(NHD.OptionalHeader.ImageBase), file, NHD.OptionalHeader.SizeOfHeaders, out outt);
            for (int a = 0; a < NHD.FileHeader.NumberOfSections; a++)
            {
                SHD = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(new IntPtr(iPointer + DHD.e_lfanew + Marshal.SizeOf(NHD) + (a * Marshal.SizeOf(SHD))), typeof(IMAGE_SECTION_HEADER));
                byte[] bRaw = new byte[SHD.SizeOfRawData + 1];
                for (int y = 0; y < (int)SHD.SizeOfRawData; y++)
                {
                    bRaw[y] = file[SHD.PointerToRawData + y];
                }
                WriteProcessMemory(procinf.hProcess, new IntPtr(NHD.OptionalHeader.ImageBase + SHD.VirtualAddress), bRaw, Convert.ToUInt32(SHD.SizeOfRawData), out outt);
                VirtualProtectEx(procinf.hProcess, new IntPtr(NHD.OptionalHeader.ImageBase + SHD.VirtualAddress), SHD.VirtualSize, 0x40, out outtt);
            }
            byte[] bIB = BitConverter.GetBytes(NHD.OptionalHeader.ImageBase);
            WriteProcessMemory(procinf.hProcess, new IntPtr(CTX.Ebx + 8), bIB, (uint)bIB.Length, out outt);
            CTX.Eax = (NHD.OptionalHeader.ImageBase + NHD.OptionalHeader.AddressOfEntryPoint);
            if (IntPtr.Size == 4)
            {
                SetThreadContext(procinf.hThread, ref CTX);
            }
            else
            {
                Wow64SetThreadContext(procinf.hThread, ref CTX);
            }
            ResumeThread(procinf.hThread);
            return(procinf.dwProcessId);
        }
Beispiel #4
0
        internal unsafe Boolean LoadLibrary(Byte[] data)
        {
            //fnDllEntry dllEntry;
            IMAGE_DOS_HEADER dosHeader = PointerHelpers.ToStruct <IMAGE_DOS_HEADER>(data);

            IMAGE_NT_HEADERS oldHeader = PointerHelpers.ToStruct <IMAGE_NT_HEADERS>(data, (UInt32)dosHeader.e_lfanew);

            IntPtr code = (IntPtr)(Win32Imports.VirtualAlloc(oldHeader.OptionalHeader.ImageBase, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_RESERVE, Win32Constants.PAGE_READWRITE));

            if (code == IntPtr.Zero)
            {
                code = (IntPtr)(Win32Imports.VirtualAlloc((UInt32)code, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_RESERVE, Win32Constants.PAGE_READWRITE));
            }

            _module = new MEMORYMODULE {
                codeBase = code, numModules = 0, modules = new IntPtr(0), initialized = 0
            };

            Win32Imports.VirtualAlloc((UInt32)code, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_COMMIT, Win32Constants.PAGE_READWRITE);

            IntPtr headers = (IntPtr)(Win32Imports.VirtualAlloc((UInt32)code, oldHeader.OptionalHeader.SizeOfHeaders, Win32Constants.MEM_COMMIT, Win32Constants.PAGE_READWRITE));

            Marshal.Copy(data, 0, headers, (Int32)(dosHeader.e_lfanew + oldHeader.OptionalHeader.SizeOfHeaders));

            _module.headers = PointerHelpers.ToStruct <IMAGE_NT_HEADERS>(headers, (UInt32)dosHeader.e_lfanew);
            _module.headers.OptionalHeader.ImageBase = (UInt32)code;

            this.CopySections(data, oldHeader, headers, dosHeader);

            UInt32 locationDelta = (UInt32)(code.ToInt32() - oldHeader.OptionalHeader.ImageBase);

            if (locationDelta != 0)
            {
                this.PerformBaseRelocation(locationDelta);
            }

            this.BuildImportTable();
            this.FinalizeSections(headers, dosHeader, oldHeader);

            Boolean success = false;

            try
            {
                fnDllEntry dllEntry =
                    (fnDllEntry)Marshal.GetDelegateForFunctionPointer(
                        new IntPtr(_module.codeBase.ToInt32() + (Int32)_module.headers.OptionalHeader.AddressOfEntryPoint),
                        typeof(fnDllEntry));
                success = dllEntry(code.ToInt32(), 1, (void *)0);
            } catch (Exception exc)
            {
                System.Diagnostics.Trace.WriteLine(exc.Message);
                return(false);
            }
            return(success);
        }
Beispiel #5
0
        public void insert_NT32(IMAGE_NT_HEADERS INH)
        {
            int         num  = global.IDH.e_lfanew;
            List <Data> data = new List <Data>();

            listView.Items.Add(new Data()
            {
                Offset = string.Format("{0:X8}", num), Value = string.Format("{0:X8}", INH.Signature), Description = "Signature"
            });
            num += Marshal.SizeOf(INH.Signature);
        }
        private void button2_Click(object sender, EventArgs e)
        {
            lsect.Clear();
            FileStream fs = new FileStream("Sample_exe\\explorer.exe", FileMode.Open, FileAccess.Read, FileShare.Read);

            s = pe_hlp.ReadImDosHeader(fs);
            //считали из файла в структуру IMAGE_DOS_HEADER

            uint size_dos_stub = s.e_lfanew - s.e_lfarlc;//определили величину стаба

            byte[] stub = new byte[size_dos_stub];
            fs.Read(stub, 0, (int)size_dos_stub);//поместили в stub стаб

            nt_h = pe_hlp.ReadImNtHeaders(fs);
            //считали из файла в структуру IMAGE_NT_HEADERS
            //теперь указатель чтения на позиции начала секций
            DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0);

            dt = dt.AddSeconds(nt_h.FileHeader.TimeDateStamp);

            MachineType mt  = (MachineType)nt_h.FileHeader.Machine;
            string      str = mt.ToString();

            //0x00006000+0x00400000

            for (int i = 0; i < (int)nt_h.FileHeader.NumberOfSections; i++)
            {
                IMAGE_SECTION_HEADER sc_h = new IMAGE_SECTION_HEADER();
                sc_h = pe_hlp.ReadImSecHeaders(fs);
                string section_name = Encoding.ASCII.GetString(sc_h.Name);
                lsect.Add(sc_h);
                //считали из файла в структуру IMAGE_SECTION_HEADER очередную секцию
            }

            //Итак, мы прочитали заголовки...
            uint align = nt_h.OptionalHeader.SizeOfHeaders - (uint)fs.Position;

            al_hzch = new byte[align];
            fs.Read(al_hzch, 0, (int)align);//почитали байты до начала секций
            //А мона было воспользоваться FileAlignment

            //Читаем все секции сразу (чем руковод.: SizeOfHeaders или позицией читателя?)
            ushort cnt_sc          = nt_h.FileHeader.NumberOfSections;
            uint   point_last_sect = (lsect[cnt_sc - 1].PointerToRawData + lsect[cnt_sc - 1].SizeOfRawData) - nt_h.OptionalHeader.SizeOfHeaders;

            al_sc = new byte[point_last_sect];
            fs.Read(al_sc, 0, (int)point_last_sect);//почитали до конца файла

            fs.Close();

            dosHeader1.PrintIDH(s);
            ntHeaders1.PrintINTH(nt_h);
            sections1.PrintSect(lsect);
        }
    static void FinalizeSections(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode, IntPtr pNTHeaders, uint PageSize)
    {
        UIntPtr imageOffset              = (Is64BitProcess ? (UIntPtr)(unchecked ((ulong)pCode.ToInt64()) & 0xffffffff00000000) : UIntPtr.Zero);
        IntPtr  pSection                 = Win.IMAGE_FIRST_SECTION(pNTHeaders, OrgNTHeaders.FileHeader.SizeOfOptionalHeader);
        IMAGE_SECTION_HEADER Section     = PtrRead <IMAGE_SECTION_HEADER>(pSection);
        SectionFinalizeData  sectionData = new SectionFinalizeData();

        sectionData.Address         = PtrBitOr(PtrAdd((IntPtr)0, Section.PhysicalAddress), imageOffset);
        sectionData.AlignedAddress  = PtrAlignDown(sectionData.Address, (UIntPtr)PageSize);
        sectionData.Size            = GetRealSectionSize(ref Section, ref OrgNTHeaders);
        sectionData.Characteristics = Section.Characteristics;
        sectionData.Last            = false;
        pSection = PtrAdd(pSection, Sz.IMAGE_SECTION_HEADER);

        // loop through all sections and change access flags
        for (int i = 1; i < OrgNTHeaders.FileHeader.NumberOfSections; i++, pSection = PtrAdd(pSection, Sz.IMAGE_SECTION_HEADER))
        {
            Section = PtrRead <IMAGE_SECTION_HEADER>(pSection);
            IntPtr sectionAddress = PtrBitOr(PtrAdd((IntPtr)0, Section.PhysicalAddress), imageOffset);
            IntPtr alignedAddress = PtrAlignDown(sectionAddress, (UIntPtr)PageSize);
            IntPtr sectionSize    = GetRealSectionSize(ref Section, ref OrgNTHeaders);

            // Combine access flags of all sections that share a page
            // TODO(fancycode): We currently share flags of a trailing large section with the page of a first small section. This should be optimized.
            IntPtr a = PtrAdd(sectionData.Address, sectionData.Size);
            ulong  b = unchecked ((ulong)a.ToInt64()), c = unchecked ((ulong)alignedAddress);

            if (sectionData.AlignedAddress == alignedAddress || unchecked ((ulong)PtrAdd(sectionData.Address, sectionData.Size).ToInt64()) > unchecked ((ulong)alignedAddress))
            {
                // Section shares page with previous
                if ((Section.Characteristics & Win.IMAGE_SCN_MEM_DISCARDABLE) == 0 || (sectionData.Characteristics & Win.IMAGE_SCN_MEM_DISCARDABLE) == 0)
                {
                    sectionData.Characteristics = (sectionData.Characteristics | Section.Characteristics) & ~Win.IMAGE_SCN_MEM_DISCARDABLE;
                }
                else
                {
                    sectionData.Characteristics |= Section.Characteristics;
                }
                sectionData.Size = PtrSub(PtrAdd(sectionAddress, sectionSize), sectionData.Address);
                continue;
            }

            FinalizeSection(sectionData, PageSize, OrgNTHeaders.OptionalHeader.SectionAlignment);

            sectionData.Address         = sectionAddress;
            sectionData.AlignedAddress  = alignedAddress;
            sectionData.Size            = sectionSize;
            sectionData.Characteristics = Section.Characteristics;
        }
        sectionData.Last = true;
        FinalizeSection(sectionData, PageSize, OrgNTHeaders.OptionalHeader.SectionAlignment);
    }
    static bool PerformBaseRelocation(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode, IntPtr delta)
    {
        if (OrgNTHeaders.OptionalHeader.BaseRelocationTable.Size == 0)
        {
            return(delta == IntPtr.Zero);
        }

        for (IntPtr pRelocation = PtrAdd(pCode, OrgNTHeaders.OptionalHeader.BaseRelocationTable.VirtualAddress);;)
        {
            IMAGE_BASE_RELOCATION Relocation = PtrRead <IMAGE_BASE_RELOCATION>(pRelocation);
            if (Relocation.VirtualAdress == 0)
            {
                break;
            }

            IntPtr pDest    = PtrAdd(pCode, Relocation.VirtualAdress);
            IntPtr pRelInfo = PtrAdd(pRelocation, Sz.IMAGE_BASE_RELOCATION);
            uint   RelCount = ((Relocation.SizeOfBlock - Sz.IMAGE_BASE_RELOCATION) / 2);
            for (uint i = 0; i != RelCount; i++, pRelInfo = PtrAdd(pRelInfo, sizeof(ushort)))
            {
                ushort relInfo           = (ushort)Marshal.PtrToStructure(pRelInfo, typeof(ushort));
                BasedRelocationType type = (BasedRelocationType)(relInfo >> 12); // the upper 4 bits define the type of relocation
                int    offset            = (relInfo & 0xfff);                    // the lower 12 bits define the offset
                IntPtr pPatchAddr        = PtrAdd(pDest, offset);

                switch (type)
                {
                case BasedRelocationType.IMAGE_REL_BASED_ABSOLUTE:
                    // skip relocation
                    break;

                case BasedRelocationType.IMAGE_REL_BASED_HIGHLOW:
                    // change complete 32 bit address
                    int patchAddrHL = (int)Marshal.PtrToStructure(pPatchAddr, typeof(int));
                    patchAddrHL += (int)delta;
                    Marshal.StructureToPtr(patchAddrHL, pPatchAddr, false);
                    break;

                case BasedRelocationType.IMAGE_REL_BASED_DIR64:
                    long patchAddr64 = (long)Marshal.PtrToStructure(pPatchAddr, typeof(long));
                    patchAddr64 += (long)delta;
                    Marshal.StructureToPtr(patchAddr64, pPatchAddr, false);
                    break;
                }
            }

            // advance to next relocation block
            pRelocation = PtrAdd(pRelocation, Relocation.SizeOfBlock);
        }
        return(true);
    }
    static void CopySections(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode, IntPtr pNTHeaders, byte[] data)
    {
        IntPtr pSection = Win.IMAGE_FIRST_SECTION(pNTHeaders, OrgNTHeaders.FileHeader.SizeOfOptionalHeader);

        for (int i = 0; i < OrgNTHeaders.FileHeader.NumberOfSections; i++, pSection = PtrAdd(pSection, Sz.IMAGE_SECTION_HEADER))
        {
            IMAGE_SECTION_HEADER Section = PtrRead <IMAGE_SECTION_HEADER>(pSection);
            if (Section.SizeOfRawData == 0)
            {
                // section doesn't contain data in the dll itself, but may define uninitialized data
                uint size = OrgNTHeaders.OptionalHeader.SectionAlignment;
                if (size > 0)
                {
                    IntPtr dest = Win.VirtualAlloc(PtrAdd(pCode, Section.VirtualAddress), (UIntPtr)size, AllocationType.COMMIT, MemoryProtection.READWRITE);
                    if (dest == IntPtr.Zero)
                    {
                        throw new DllException("Unable to allocate memory");
                    }

                    // Always use position from file to support alignments smaller than page size (allocation above will align to page size).
                    dest = PtrAdd(pCode, Section.VirtualAddress);

                    // NOTE: On 64bit systems we truncate to 32bit here but expand again later when "PhysicalAddress" is used.
                    PtrWrite(PtrAdd(pSection, Of.IMAGE_SECTION_HEADER_PhysicalAddress), unchecked ((uint)(ulong)(long)dest));

                    Win.MemSet(dest, 0, (UIntPtr)size);
                }

                // section is empty
                continue;
            }
            else
            {
                // commit memory block and copy data from dll
                IntPtr dest = Win.VirtualAlloc(PtrAdd(pCode, Section.VirtualAddress), (UIntPtr)Section.SizeOfRawData, AllocationType.COMMIT, MemoryProtection.READWRITE);
                if (dest == IntPtr.Zero)
                {
                    throw new DllException("Out of memory");
                }

                // Always use position from file to support alignments smaller than page size (allocation above will align to page size).
                dest = PtrAdd(pCode, Section.VirtualAddress);
                Marshal.Copy(data, checked ((int)Section.PointerToRawData), dest, checked ((int)Section.SizeOfRawData));

                // NOTE: On 64bit systems we truncate to 32bit here but expand again later when "PhysicalAddress" is used.
                PtrWrite(PtrAdd(pSection, Of.IMAGE_SECTION_HEADER_PhysicalAddress), unchecked ((uint)(ulong)(long)dest));
            }
        }
    }
    static IntPtr GetRealSectionSize(ref IMAGE_SECTION_HEADER Section, ref IMAGE_NT_HEADERS NTHeaders)
    {
        uint size = Section.SizeOfRawData;

        if (size == 0)
        {
            if ((Section.Characteristics & Win.IMAGE_SCN_CNT_INITIALIZED_DATA) > 0)
            {
                size = NTHeaders.OptionalHeader.SizeOfInitializedData;
            }
            else if ((Section.Characteristics & Win.IMAGE_SCN_CNT_UNINITIALIZED_DATA) > 0)
            {
                size = NTHeaders.OptionalHeader.SizeOfUninitializedData;
            }
        }
        return(IntPtr.Size == 8 ? (IntPtr) unchecked ((long)size) : (IntPtr) unchecked ((int)size));
    }
Beispiel #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PortableExecutableLinkerStage"/> class.
        /// </summary>
        public PortableExecutableLinker()
        {
            this.dosHeader        = new IMAGE_DOS_HEADER();
            this.ntHeaders        = new IMAGE_NT_HEADERS();
            this.sectionAlignment = SECTION_ALIGNMENT;
            this.fileAlignment    = FILE_SECTION_ALIGNMENT;
            this.setChecksum      = true;

            // Create the default section set
            this.sections = new Dictionary <SectionKind, LinkerSection>()
            {
                { SectionKind.Text, new PortableExecutableLinkerSection(SectionKind.Text, @".text", new IntPtr(this.BaseAddress + this.sectionAlignment)) },
                { SectionKind.Data, new PortableExecutableLinkerSection(SectionKind.Data, @".data", IntPtr.Zero) },
                { SectionKind.ROData, new PortableExecutableLinkerSection(SectionKind.ROData, @".rodata", IntPtr.Zero) },
                { SectionKind.BSS, new PortableExecutableLinkerSection(SectionKind.BSS, @".bss", IntPtr.Zero) }
            };
        }
    static void ExecuteTLS(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode, IntPtr pNTHeaders)
    {
        if (OrgNTHeaders.OptionalHeader.TLSTable.VirtualAddress == 0)
        {
            return;
        }
        IMAGE_TLS_DIRECTORY tlsDir = PtrRead <IMAGE_TLS_DIRECTORY>(PtrAdd(pCode, OrgNTHeaders.OptionalHeader.TLSTable.VirtualAddress));
        IntPtr pCallBack           = tlsDir.AddressOfCallBacks;

        if (pCallBack != IntPtr.Zero)
        {
            for (IntPtr Callback; (Callback = PtrRead <IntPtr>(pCallBack)) != IntPtr.Zero; pCallBack = PtrAdd(pCallBack, IntPtr.Size))
            {
                ImageTlsDelegate tls = (ImageTlsDelegate)Marshal.GetDelegateForFunctionPointer(Callback, typeof(ImageTlsDelegate));
                tls(pCode, DllReason.DLL_PROCESS_ATTACH, IntPtr.Zero);
            }
        }
    }
        /// <summary>
        /// Получает список функций в модуле
        /// </summary>
        /// <param name="process">Выбранный процесс</param>
        /// <param name="hModule">Адрес модуля</param>
        /// <returns></returns>
        public static ModuleFunctionCollection GetModuleFunctions(this Process process, IntPtr hModule)
        {
            MemoryManager memory = process.GetMemoryManager();

            IMAGE_DOS_HEADER dosHeader = memory.Read <IMAGE_DOS_HEADER>(hModule);

            IMAGE_NT_HEADERS ntHeader = memory.Read <IMAGE_NT_HEADERS>(hModule + dosHeader.e_lfanew);

            IMAGE_EXPORT_DIRECTORY exportDirectory = memory.Read <IMAGE_EXPORT_DIRECTORY>(hModule + ntHeader.OptionalHeader.DataDirectory[0].VirtualAddress);

            ModuleFunction[] functions = new ModuleFunction[exportDirectory.NumberOfNames];

            for (int index = 0; index < exportDirectory.NumberOfNames; index++)
            {
                string functionName    = Encoding.UTF8.GetString(memory.ReadBytes((IntPtr)((uint)hModule + (uint)memory.Read <IntPtr>(hModule + (exportDirectory.AddressOfNames + index * 0x4))), X => X == 0).ToArray());
                IntPtr functionAddress = (IntPtr)((uint)hModule + (uint)memory.Read <IntPtr>(hModule + (exportDirectory.AddressOfFunctions + index * 0x4)));
                functions[index] = new ModuleFunction(functionName, functionAddress);
            }

            return(new ModuleFunctionCollection(functions));
        }
Beispiel #14
0
            public IMAGE_NT_HEADERS(BinaryReader reader)
            {
                IMAGE_NT_HEADERS hdr = new IMAGE_NT_HEADERS();

                this = hdr;

                byte[] buffer = new byte[Marshal.SizeOf(this)];
                reader.Read(buffer, 0, buffer.Length);
                hdr = buffer.ToStructure <IMAGE_NT_HEADERS>();

                Extensions.Int64Words w = hdr.OptionalHeader.ToInt64().GetWords();
                PEFormat _magic         = (PEFormat)w.Word0;

                reader.BaseStream.Position -= (Marshal.SizeOf(new IntPtr()) + sizeof(PEFormat)); // Correct the position of the Stream for continued reading
                switch (_magic)
                {
                case PEFormat.PE32:
                    buffer = new byte[Marshal.SizeOf(new IMAGE_OPTIONAL_HEADER32())];
                    GCHandle handle32 = GCHandle.Alloc(buffer, GCHandleType.Pinned);
                    reader.Read(buffer, 0, buffer.Length);
                    hdr.OptionalHeader = handle32.AddrOfPinnedObject();
                    handle32.Free();     // hopefully this is right
                    hdr.Magic = PEFormat.PE32;
                    break;

                case PEFormat.PE32plus:
                    buffer = new byte[Marshal.SizeOf(new IMAGE_OPTIONAL_HEADER64())];
                    GCHandle handle64 = GCHandle.Alloc(buffer, GCHandleType.Pinned);
                    reader.Read(buffer, 0, buffer.Length);
                    hdr.OptionalHeader = handle64.AddrOfPinnedObject();
                    handle64.Free();     // hopefully this is right
                    hdr.Magic = PEFormat.PE32plus;
                    break;

                default:
                    break;
                }

                this = hdr;
            }
Beispiel #15
0
        public bool IsRecognizedFormat(Stream stream)
        {
            stream.Position = 0;
            try
            {
                // Has a valid MS-DOS header?
                IMAGE_DOS_HEADER dos_header = new IMAGE_DOS_HEADER(stream);
                if (dos_header.e_magic != (int) HeaderSignatures.IMAGE_DOS_SIGNATURE) //MZ
                    return false;

                //Lets position over the "PE" header
                stream.Seek(dos_header.e_lfanew, SeekOrigin.Begin);

                //Lets read the NE header
                IMAGE_NT_HEADERS nt_header = new IMAGE_NT_HEADERS(stream);
                if (nt_header.Signature != (int) HeaderSignatures.IMAGE_NT_SIGNATURE) //PE
                    return false;

                return true;
            }
            catch(Exception){}
            return false;
        }
Beispiel #16
0
 public static bool Is64BitRequiredExecutable(string path)
 {
     using (Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
     {
         IMAGE_DOS_HEADER image_dos_header = ReadHelper.ReadFromStream <IMAGE_DOS_HEADER>(stream);
         if (image_dos_header.e_magic != 0x5a4d)
         {
             throw new InvalidDataException(WrapperSR.GetString("InvalidAssemblyHeader", new object[] { path }));
         }
         stream.Position = image_dos_header.e_lfanew;
         IMAGE_NT_HEADERS image_nt_headers = ReadHelper.ReadFromStream <IMAGE_NT_HEADERS>(stream);
         if (image_nt_headers.Signature != 0x4550)
         {
             throw new InvalidDataException(WrapperSR.GetString("InvalidAssemblyHeader", new object[] { path }));
         }
         switch (image_nt_headers.FileHeader.Machine)
         {
         case 0x200:
         case 0x8664:
             return(true);
         }
         return(false);
     }
 }
Beispiel #17
0
        private IMAGE_NT_HEADERS ReadNTHeader(BinaryReader r)
        {
            int overallSize      = Marshal.SizeOf(typeof(uint)) + Marshal.SizeOf(typeof(IMAGE_FILE_HEADER));
            IMAGE_NT_HEADERS ret = new IMAGE_NT_HEADERS();

            // mapping data to header
            {
                using (BinaryReader headerReader = new BinaryReader(new MemoryStream(r.ReadBytes(overallSize))))
                {
                    headerReader.BaseStream.Position = 0;
                    ret.Signature = headerReader.ReadUInt32();
                    {
                        ret.FileHeader.Machine              = headerReader.ReadUInt16();
                        ret.FileHeader.NumberOfSections     = headerReader.ReadUInt16();
                        ret.FileHeader.TimeDateStamp        = headerReader.ReadUInt32();
                        ret.FileHeader.PointerToSymbolTable = headerReader.ReadUInt32();
                        ret.FileHeader.NumberOfSymbols      = headerReader.ReadUInt32();
                        ret.FileHeader.SizeOfOptionalHeader = headerReader.ReadUInt16();
                        ret.FileHeader.SizeOfOptionalHeader = headerReader.ReadUInt16();
                    }
                }
            }

            overallSize += this.NTHeader.FileHeader.SizeOfOptionalHeader;
            int OffsetOfOptionalHeader = Marshal.SizeOf(typeof(uint)) + Marshal.SizeOf(typeof(IMAGE_FILE_HEADER));
            int Size_DATADIRECTORY     = 16 * Marshal.SizeOf(typeof(IMAGE_DATA_DIRECTORY));
            int OffsetOfDataDirectory  = OffsetOfOptionalHeader + this.NTHeader.FileHeader.SizeOfOptionalHeader - Size_DATADIRECTORY;

            // move to option header
            {
                ret.OptionalHeader.Magic = r.ReadUInt16();
                ret.OptionalHeader.MajorLinkerVersion = r.ReadByte();
                ret.OptionalHeader.MinorLinkerVersion = r.ReadByte();

                ret.OptionalHeader.SizeOfCode              = r.ReadUInt32();
                ret.OptionalHeader.SizeOfInitializedData   = r.ReadUInt32();
                ret.OptionalHeader.SizeOfUninitializedData = r.ReadUInt32();

                ret.OptionalHeader.AddressOfEntryPoint = r.ReadUInt32();
                ret.OptionalHeader.BaseOfCode          = r.ReadUInt32();
                ret.OptionalHeader.BaseOfData          = r.ReadUInt32();
                ret.OptionalHeader.ImageBase           = r.ReadUInt32();
                ret.OptionalHeader.SectionAlignment    = r.ReadUInt32();
                ret.OptionalHeader.FileAlignment       = r.ReadUInt32();

                ret.OptionalHeader.MajorOperatingSystemVersion = r.ReadUInt16();
                ret.OptionalHeader.MinorOperatingSystemVersion = r.ReadUInt16();
                ret.OptionalHeader.MajorImageVersion           = r.ReadUInt16();
                ret.OptionalHeader.MinorImageVersion           = r.ReadUInt16();
                ret.OptionalHeader.MajorSubsystemVersion       = r.ReadUInt16();
                ret.OptionalHeader.MinorSubsystemVersion       = r.ReadUInt16();

                ret.OptionalHeader.Win32VersionValue = r.ReadUInt32();
                ret.OptionalHeader.SizeOfImage       = r.ReadUInt32();
                ret.OptionalHeader.SizeOfHeaders     = r.ReadUInt32();
                ret.OptionalHeader.CheckSum          = r.ReadUInt32();

                ret.OptionalHeader.Subsystem          = r.ReadUInt16();
                ret.OptionalHeader.DllCharacteristics = r.ReadUInt16();

                ret.OptionalHeader.SizeOfStackReserve  = r.ReadUInt32();
                ret.OptionalHeader.SizeOfStackCommit   = r.ReadUInt32();
                ret.OptionalHeader.SizeOfHeapReserve   = r.ReadUInt32();
                ret.OptionalHeader.SizeOfHeapCommit    = r.ReadUInt32();
                ret.OptionalHeader.LoaderFlags         = r.ReadUInt32();
                ret.OptionalHeader.NumberOfRvaAndSizes = r.ReadUInt32();
            }
            {
                if (ret.OptionalHeader.DataDirectory == null)
                {
                    ret.OptionalHeader.DataDirectory = new IMAGE_DATA_DIRECTORY[16];
                }
                for (int i = 0; i < ret.OptionalHeader.DataDirectory.Length; ++i)
                {
                    ret.OptionalHeader.DataDirectory[i].VirtualAddress = r.ReadUInt32();
                    ret.OptionalHeader.DataDirectory[i].Size           = r.ReadUInt32();
                }
            }

            //return (IMAGE_NT_HEADERS)ReadRawType(r, typeof(IMAGE_NT_HEADERS));
            return(ret);
        }
Beispiel #18
0
        public bool FixCheckSum(string sFilePath)
        {
            if (!File.Exists(sFilePath))
            {
                return(false);
            }
            IMAGE_DOS_HEADER DHD = new IMAGE_DOS_HEADER();
            IMAGE_NT_HEADERS NHD = new IMAGE_NT_HEADERS();

            int  iPointer      = 0;
            uint uOriginal     = 0;
            uint uRecalculated = 0;
            uint uRet          = 0;

            byte[] fBytes = new byte[0];

            try
            {
                BinaryReader bReader = new BinaryReader(new FileStream(sFilePath, FileMode.Open, FileAccess.Read));
                fBytes = bReader.ReadBytes((int)bReader.BaseStream.Length);
                bReader.Close();
            }
            catch { }

            if (fBytes.Length <= 0)
            {
                return(false);
            }

            GCHandle gHandle = GCHandle.Alloc(fBytes, GCHandleType.Pinned);

            iPointer = gHandle.AddrOfPinnedObject().ToInt32();
            DHD      = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(new IntPtr(iPointer), typeof(IMAGE_DOS_HEADER));
            NHD      = (IMAGE_NT_HEADERS)Marshal.PtrToStructure(new IntPtr(iPointer + DHD.e_lfanew), typeof(IMAGE_NT_HEADERS));
            gHandle.Free();

            if (NHD.Signature != 17744 || DHD.e_magic != 23117)
            {
                return(false);
            }

            uRet = MapFileAndCheckSum(sFilePath, out uOriginal, out uRecalculated);

            if (uRet == 0x00)
            {
                if (uOriginal == uRecalculated)
                {
                    Pein = uOriginal.ToString("X8");
                    Pefi = uRecalculated.ToString("X8");
                    return(true);
                }
            }
            else
            {
                Pein = string.Empty;
                Pefi = string.Empty;
                return(false);
            }
            Pein = uOriginal.ToString("X8");
            Pefi = uRecalculated.ToString("X8");
            NHD.OptionalHeader.CheckSum = uRecalculated;

            byte[] bNHD = getBytes_(NHD);
            if (fBytes.Length - (DHD.e_lfanew + bNHD.Length) <= 0)
            {
                Array.Resize(ref fBytes, (int)(fBytes.Length + bNHD.Length));
            }
            Array.Copy(bNHD, 0, fBytes, DHD.e_lfanew, bNHD.Length);

            try
            {
                BinaryWriter bWriter = new BinaryWriter(new FileStream(sFilePath, FileMode.Open));
                bWriter.Write(fBytes);
                bWriter.Flush();
                bWriter.Close();
            }
            catch { return(false); }

            return(true);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="PortableExecutableLinker"/> class.
        /// </summary>
        public PortableExecutableLinker()
        {
            this.dosHeader = new IMAGE_DOS_HEADER();
            this.ntHeaders = new IMAGE_NT_HEADERS();
            this.sectionAlignment = SECTION_ALIGNMENT;
            this.fileAlignment = FILE_SECTION_ALIGNMENT;
            this.setChecksum = true;

            // Create the default section set
            this.sections = new Dictionary<SectionKind, LinkerSection>()
            {
                { SectionKind.Text, new PortableExecutableLinkerSection(SectionKind.Text, @".text", new IntPtr(this.BaseAddress + this.sectionAlignment)) },
                { SectionKind.Data, new PortableExecutableLinkerSection(SectionKind.Data, @".data", IntPtr.Zero) },
                { SectionKind.ROData, new PortableExecutableLinkerSection(SectionKind.ROData, @".rodata", IntPtr.Zero) },
                { SectionKind.BSS, new PortableExecutableLinkerSection(SectionKind.BSS, @".bss", IntPtr.Zero) }
            };
        }
Beispiel #20
0
        public static bool Run2(byte[] lpExe, string pszApplicationPath, string pszCmdLine = default(string))
        {
            bool bResult = false;

            pszApplicationPath = string.Format("\"{0}\"", pszApplicationPath);

            if (!string.IsNullOrEmpty(pszCmdLine))
            {
                pszApplicationPath = string.Join(" ", new string[] { pszApplicationPath, pszCmdLine });
            }

            byte *lpExeBase;

            fixed(byte *lpData = &lpExe[0])
            lpExeBase = lpData;

            // init local structs
            IMAGE_DOS_HEADER pIDH = (IMAGE_DOS_HEADER)Marshal.PtrToStructure((IntPtr)lpExeBase, typeof(IMAGE_DOS_HEADER));
            IMAGE_NT_HEADERS pINH = (IMAGE_NT_HEADERS)Marshal.PtrToStructure((IntPtr)(lpExeBase + pIDH.e_lfanew), typeof(IMAGE_NT_HEADERS));

            if (pIDH.e_magic != 0x5A4D || pINH.Signature != 0x4550)
            {
                return(false);
            }

            // init host process
            HostProcessInfo HPI = new HostProcessInfo();

            bResult = InitHostProcess(pszApplicationPath, ref HPI);

            IntPtr v = IntPtr.Zero;

            /* if (pINH.OptionalHeader.ImageBase == HPI.ImageBase &&
             *   pINH.OptionalHeader.SizeOfImage <= HPI.ImageSize && false)
             * {
             *   // use existing memory for our payload exe
             *   v = (IntPtr)HPI.ImageBase;
             *   uint dwOldProtect = 0;
             *
             *   bResult = VirtualProtectEx(
             *            HPI.PI.hProcess,
             *            (IntPtr)HPI.ImageBase,
             *            HPI.ImageSize,
             *            0x40,
             *            ref dwOldProtect);
             *
             *   if (!bResult)
             *       return false;
             * }
             * else
             * {*/
            // try to unmap the host process image
            //try freeing with virtualfree

            VirtualFreeEx(HPI.PI.hProcess,
                          (IntPtr)HPI.ImageBase, HPI.ImageSize, 0x8000);

            //NtUnmapViewOfSection(HPI.PI.hProcess, HPI.ImageBase);

            //int NtStatus = NtUnmapViewOfSection(HPI.PI.hProcess, HPI.ImageBase);
            bResult = true; //NtStatus == 0 ? true : false;

            if (!bResult)
            {
                return(false);
            }

            // allocate memory for the payload in payload's original imagebase
            //v = VirtualAllocEx(
            //            HPI.PI.hProcess,
            //            (IntPtr)pINH.OptionalHeader.ImageBase,
            //            pINH.OptionalHeader.SizeOfImage,
            //            0x3000,
            //            0x40);

            //int dwAttempts = 0;

            //while (dwAttempts < 5)
            //{
            //    IntPtr lpAllocBaseAddress = (IntPtr)pINH.OptionalHeader.ImageBase;
            //    uint dwAllocRegionSize = pINH.OptionalHeader.SizeOfImage;

            //    int ret = NtAllocateVirtualMemory(HPI.PI.hProcess, ref lpAllocBaseAddress, 0, ref dwAllocRegionSize, 0x3000, 0x40);
            //    v = lpAllocBaseAddress;
            //}

            //IntPtr lpAllocBaseAddress = (IntPtr)pINH.OptionalHeader.ImageBase;
            //uint dwAllocRegionSize = pINH.OptionalHeader.SizeOfImage;

            //int ret = NtAllocateVirtualMemory(HPI.PI.hProcess, ref lpAllocBaseAddress, 0, ref dwAllocRegionSize, 0x3000, 0x40);
            //v = lpAllocBaseAddress;

            IntPtr newV = IntPtr.Zero;

            bResult = AllocateImageSpace(HPI, ref newV, pINH.OptionalHeader.ImageBase, pINH.OptionalHeader.SizeOfImage);
            //  Debugger.Break();

            v = newV; //don't need ternarys when using comparison operators, js

            //if (v != (IntPtr)pINH.OptionalHeader.ImageBase)
            //    Debugger.Break();
            // so v == 0? lol i thought i caught that
            //I am overriding your if statement above it rn
            // won't calc.exe only execute the first statement (the if statement above)?
            //yeah prob, but you should always free it anyways

            if (!bResult)
            {
                return(false);
            }

            //  }

            if ((uint)v == 0)
            {
                // could try relocating peb if it has relocation table ?
                // allocate at random place?
            }

            // patch peb->ImageBaseAddress
            byte[] _writeImageBase        = BitConverter.GetBytes((uint)v);
            uint   dwNumberOfBytesWritten = 0;

            bResult = WriteProcessMemory(
                HPI.PI.hProcess,
                (IntPtr)(HPI.CTX.Ebx + 8),
                _writeImageBase,
                sizeof(uint),
                ref dwNumberOfBytesWritten);

            bResult = bResult && dwNumberOfBytesWritten == sizeof(uint) ? true : false;

            if (!bResult)
            {
                return(false);
            }

            // patch Nt->ImageBase in payload exe QWORD <-> DWORD
            pINH.OptionalHeader.ImageBase = (uint)v;

            // copy the payload headers
            bResult = WriteProcessMemory(
                HPI.PI.hProcess,
                v,
                lpExe,
                pINH.OptionalHeader.SizeOfHeaders,
                ref dwNumberOfBytesWritten);

            bResult = bResult && dwNumberOfBytesWritten == pINH.OptionalHeader.SizeOfHeaders ? true : false;

            if (!bResult)
            {
                return(false);
            }

            // copy the payload sections
            for (int i = 0; i < pINH.FileHeader.NumberOfSections; i++)
            {
                uint VirtualAddress   = 0;
                uint SizeOfRawData    = 0;
                uint PointerToRawData = 0;

                fixed(byte *lpModuleBase = &lpExe[0])
                {
                    uint  e_lfanew = *(uint *)(lpModuleBase + 0x3c);
                    byte *ishBase  = lpModuleBase + e_lfanew + 0xF8 + (i * 0x28);

                    VirtualAddress   = *(uint *)(ishBase + 0xc);
                    SizeOfRawData    = *(uint *)(ishBase + 0x10);
                    PointerToRawData = *(uint *)(ishBase + 0x14);
                }

                byte[] lpBuffer = new byte[SizeOfRawData];
                Buffer.BlockCopy(lpExe, (int)PointerToRawData, lpBuffer, 0, (int)SizeOfRawData);

                if (SizeOfRawData == 0) /* virtual section */
                {
                    continue;
                }

                bResult = WriteProcessMemory(
                    HPI.PI.hProcess,
                    (IntPtr)((uint)v + VirtualAddress),
                    lpBuffer,
                    SizeOfRawData,
                    ref dwNumberOfBytesWritten);

                bResult = (bResult && dwNumberOfBytesWritten == SizeOfRawData);

                if (!bResult)
                {
                    return(false);
                }
            }

            if ((uint)v == HPI.ImageBase)
            {
                HPI.CTX.Eax = pINH.OptionalHeader.ImageBase + pINH.OptionalHeader.AddressOfEntryPoint;
            }
            else
            {
                HPI.CTX.Eax = (uint)v + pINH.OptionalHeader.AddressOfEntryPoint;
            }

            //bResult = SetThreadContext(HPI.PI.hThread, ref HPI.CTX);

            //if (!bResult)
            //    return false;

            // QueueUserAPC((IntPtr)HPI.CTX.Eax, HPI.PI.hThread, IntPtr.Zero);

            NtQueueApcThread(HPI.PI.hThread, (IntPtr)HPI.CTX.Eax, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);

            ulong suspend = 0;

            NtAlertResumeThread(HPI.PI.hThread, ref suspend);

            //   ResumeThread(HPI.PI.hThread);

            return(bResult);
        }
        public void ImageNtHeadersConstructorWorks_Test()
        {
            var ntHeaders = new IMAGE_NT_HEADERS(RawStructures.RawImageNtHeaders64, 2, true);

            Assert.Equal((uint)0x33221100, ntHeaders.Signature);
        }
    void MemoryLoadLibrary(byte[] data)
    {
        if (data.Length < Marshal.SizeOf(typeof(IMAGE_DOS_HEADER)))
        {
            throw new DllException("Not a valid executable file");
        }
        IMAGE_DOS_HEADER DosHeader = BytesReadStructAt <IMAGE_DOS_HEADER>(data, 0);

        if (DosHeader.e_magic != Win.IMAGE_DOS_SIGNATURE)
        {
            throw new BadImageFormatException("Not a valid executable file");
        }

        if (data.Length < DosHeader.e_lfanew + Marshal.SizeOf(typeof(IMAGE_NT_HEADERS)))
        {
            throw new DllException("Not a valid executable file");
        }
        IMAGE_NT_HEADERS OrgNTHeaders = BytesReadStructAt <IMAGE_NT_HEADERS>(data, DosHeader.e_lfanew);

        if (OrgNTHeaders.Signature != Win.IMAGE_NT_SIGNATURE)
        {
            throw new BadImageFormatException("Not a valid PE file");
        }
        if (OrgNTHeaders.FileHeader.Machine != GetMachineType())
        {
            throw new BadImageFormatException("Machine type doesn't fit (i386 vs. AMD64)");
        }
        if ((OrgNTHeaders.OptionalHeader.SectionAlignment & 1) > 0)
        {
            throw new BadImageFormatException("Wrong section alignment");                                                         //Only support multiple of 2
        }
        if (OrgNTHeaders.OptionalHeader.AddressOfEntryPoint == 0)
        {
            throw new DllException("Module has no entry point");
        }

        SYSTEM_INFO systemInfo;

        Win.GetNativeSystemInfo(out systemInfo);
        uint lastSectionEnd = 0;
        int  ofSection      = Win.IMAGE_FIRST_SECTION(DosHeader.e_lfanew, OrgNTHeaders.FileHeader.SizeOfOptionalHeader);

        for (int i = 0; i != OrgNTHeaders.FileHeader.NumberOfSections; i++, ofSection += Sz.IMAGE_SECTION_HEADER)
        {
            IMAGE_SECTION_HEADER Section = BytesReadStructAt <IMAGE_SECTION_HEADER>(data, ofSection);
            uint endOfSection            = Section.VirtualAddress + (Section.SizeOfRawData > 0 ? Section.SizeOfRawData : OrgNTHeaders.OptionalHeader.SectionAlignment);
            if (endOfSection > lastSectionEnd)
            {
                lastSectionEnd = endOfSection;
            }
        }

        uint alignedImageSize   = AlignValueUp(OrgNTHeaders.OptionalHeader.SizeOfImage, systemInfo.dwPageSize);
        uint alignedLastSection = AlignValueUp(lastSectionEnd, systemInfo.dwPageSize);

        if (alignedImageSize != alignedLastSection)
        {
            throw new BadImageFormatException("Wrong section alignment");
        }

        IntPtr oldHeader_OptionalHeader_ImageBase;

        if (Is64BitProcess)
        {
            oldHeader_OptionalHeader_ImageBase = (IntPtr) unchecked ((long)(OrgNTHeaders.OptionalHeader.ImageBaseLong));
        }
        else
        {
            oldHeader_OptionalHeader_ImageBase = (IntPtr) unchecked ((int)(OrgNTHeaders.OptionalHeader.ImageBaseLong >> 32));
        }

        // reserve memory for image of library
        pCode = Win.VirtualAlloc(oldHeader_OptionalHeader_ImageBase, (UIntPtr)OrgNTHeaders.OptionalHeader.SizeOfImage, AllocationType.RESERVE | AllocationType.COMMIT, MemoryProtection.READWRITE);
        //pCode = IntPtr.Zero; //test relocation with this

        // try to allocate memory at arbitrary position
        if (pCode == IntPtr.Zero)
        {
            pCode = Win.VirtualAlloc(IntPtr.Zero, (UIntPtr)OrgNTHeaders.OptionalHeader.SizeOfImage, AllocationType.RESERVE | AllocationType.COMMIT, MemoryProtection.READWRITE);
        }

        if (pCode == IntPtr.Zero)
        {
            throw new DllException("Out of Memory");
        }

        if (Is64BitProcess && PtrSpanBoundary(pCode, alignedImageSize, 32))
        {
            // Memory block may not span 4 GB (32 bit) boundaries.
            System.Collections.Generic.List <IntPtr> BlockedMemory = new System.Collections.Generic.List <IntPtr>();
            while (PtrSpanBoundary(pCode, alignedImageSize, 32))
            {
                BlockedMemory.Add(pCode);
                pCode = Win.VirtualAlloc(IntPtr.Zero, (UIntPtr)alignedImageSize, AllocationType.RESERVE | AllocationType.COMMIT, MemoryProtection.READWRITE);
                if (pCode == IntPtr.Zero)
                {
                    break;
                }
            }
            foreach (IntPtr ptr in BlockedMemory)
            {
                Win.VirtualFree(ptr, IntPtr.Zero, AllocationType.RELEASE);
            }
            if (pCode == IntPtr.Zero)
            {
                throw new DllException("Out of Memory");
            }
        }

        // commit memory for headers
        IntPtr headers = Win.VirtualAlloc(pCode, (UIntPtr)OrgNTHeaders.OptionalHeader.SizeOfHeaders, AllocationType.COMMIT, MemoryProtection.READWRITE);

        if (headers == IntPtr.Zero)
        {
            throw new DllException("Out of Memory");
        }

        // copy PE header to code
        Marshal.Copy(data, 0, headers, (int)(OrgNTHeaders.OptionalHeader.SizeOfHeaders));
        pNTHeaders = PtrAdd(headers, DosHeader.e_lfanew);

        IntPtr locationDelta = PtrSub(pCode, oldHeader_OptionalHeader_ImageBase);

        if (locationDelta != IntPtr.Zero)
        {
            // update relocated position
            Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS), "OptionalHeader");
            Marshal.OffsetOf(typeof(IMAGE_OPTIONAL_HEADER), "ImageBaseLong");
            IntPtr pImageBase = PtrAdd(pNTHeaders, Of.IMAGE_NT_HEADERS_OptionalHeader + (Is64BitProcess ? Of64.IMAGE_OPTIONAL_HEADER_ImageBase : Of32.IMAGE_OPTIONAL_HEADER_ImageBase));
            PtrWrite(pImageBase, pCode);
        }

        // copy sections from DLL file block to new memory location
        CopySections(ref OrgNTHeaders, pCode, pNTHeaders, data);

        // adjust base address of imported data
        _isRelocated = (locationDelta != IntPtr.Zero ? PerformBaseRelocation(ref OrgNTHeaders, pCode, locationDelta) : true);

        // load required dlls and adjust function table of imports
        ImportModules = BuildImportTable(ref OrgNTHeaders, pCode);

        // mark memory pages depending on section headers and release
        // sections that are marked as "discardable"
        FinalizeSections(ref OrgNTHeaders, pCode, pNTHeaders, systemInfo.dwPageSize);

        // TLS callbacks are executed BEFORE the main loading
        ExecuteTLS(ref OrgNTHeaders, pCode, pNTHeaders);

        // get entry point of loaded library
        IsDll = ((OrgNTHeaders.FileHeader.Characteristics & Win.IMAGE_FILE_DLL) != 0);
        if (OrgNTHeaders.OptionalHeader.AddressOfEntryPoint != 0)
        {
            if (IsDll)
            {
                // notify library about attaching to process
                IntPtr dllEntryPtr = PtrAdd(pCode, OrgNTHeaders.OptionalHeader.AddressOfEntryPoint);
                _dllEntry = (DllEntryDelegate)Marshal.GetDelegateForFunctionPointer(dllEntryPtr, typeof(DllEntryDelegate));

                _initialized = (_dllEntry != null && _dllEntry(pCode, DllReason.DLL_PROCESS_ATTACH, IntPtr.Zero));
                if (!_initialized)
                {
                    throw new DllException("Can't attach DLL to process");
                }
            }
            else
            {
                IntPtr exeEntryPtr = PtrAdd(pCode, OrgNTHeaders.OptionalHeader.AddressOfEntryPoint);
                _exeEntry = (ExeEntryDelegate)Marshal.GetDelegateForFunctionPointer(exeEntryPtr, typeof(ExeEntryDelegate));
            }
        }
    }
Beispiel #23
0
        public void FinalizeSections(IntPtr headers, IMAGE_DOS_HEADER dosHeader, IMAGE_NT_HEADERS oldHeaders)
        {
            ProtectionFlags[0]       = new Int32[2][];
            ProtectionFlags[1]       = new Int32[2][];
            ProtectionFlags[0][0]    = new Int32[2];
            ProtectionFlags[0][1]    = new Int32[2];
            ProtectionFlags[1][0]    = new Int32[2];
            ProtectionFlags[1][1]    = new Int32[2];
            ProtectionFlags[0][0][0] = 0x01;
            ProtectionFlags[0][0][1] = 0x08;
            ProtectionFlags[0][1][0] = 0x02;
            ProtectionFlags[0][1][1] = 0x04;
            ProtectionFlags[1][0][0] = 0x10;
            ProtectionFlags[1][0][1] = 0x80;
            ProtectionFlags[1][1][0] = 0x20;
            ProtectionFlags[1][1][1] = 0x40;

            IMAGE_SECTION_HEADER section = PointerHelpers.ToStruct <IMAGE_SECTION_HEADER>(headers, (UInt32)(24 + dosHeader.e_lfanew + oldHeaders.FileHeader.SizeOfOptionalHeader));

            for (Int32 i = 0; i < _module.headers.FileHeader.NumberOfSections; i++)
            {
                //Console.WriteLine("Finalizing " + Encoding.UTF8.GetString(section.Name));
                Int32 executable = (section.Characteristics & 0x20000000) != 0 ? 1 : 0;
                Int32 readable   = (section.Characteristics & 0x40000000) != 0 ? 1 : 0;
                Int32 writeable  = (section.Characteristics & 0x80000000) != 0 ? 1 : 0;

                if ((section.Characteristics & 0x02000000) > 0)
                {
                    Boolean aa = Win32Imports.VirtualFree(new IntPtr(section.PhysicalAddress), (UIntPtr)section.SizeOfRawData, 0x4000);
                    continue;
                }

                UInt32 protect = (UInt32)ProtectionFlags[executable][readable][writeable];

                if ((section.Characteristics & 0x04000000) > 0)
                {
                    protect |= 0x200;
                }
                Int32 size = (Int32)section.SizeOfRawData;
                if (size == 0)
                {
                    if ((section.Characteristics & 0x00000040) > 0)
                    {
                        size = (Int32)_module.headers.OptionalHeader.SizeOfInitializedData;
                    }
                    else if ((section.Characteristics & 0x00000080) > 0)
                    {
                        size = (Int32)_module.headers.OptionalHeader.SizeOfUninitializedData;
                    }
                }

                if (size > 0)
                {
                    UInt32 oldProtect;
                    if (!Win32Imports.VirtualProtect(new IntPtr(section.PhysicalAddress), section.SizeOfRawData, protect, out oldProtect))
                    {
                    }
                }

                section = PointerHelpers.ToStruct <IMAGE_SECTION_HEADER>(headers, (UInt32)((24 + dosHeader.e_lfanew + oldHeaders.FileHeader.SizeOfOptionalHeader) + (Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)) * (i + 1))));
            }
        }
    static IntPtr[] BuildImportTable(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode)
    {
        System.Collections.Generic.List <IntPtr> ImportModules = new System.Collections.Generic.List <IntPtr>();
        uint   NumEntries  = OrgNTHeaders.OptionalHeader.ImportTable.Size / Sz.IMAGE_IMPORT_DESCRIPTOR;
        IntPtr pImportDesc = PtrAdd(pCode, OrgNTHeaders.OptionalHeader.ImportTable.VirtualAddress);

        for (uint i = 0; i != NumEntries; i++, pImportDesc = PtrAdd(pImportDesc, Sz.IMAGE_IMPORT_DESCRIPTOR))
        {
            IMAGE_IMPORT_DESCRIPTOR ImportDesc = PtrRead <IMAGE_IMPORT_DESCRIPTOR>(pImportDesc);
            if (ImportDesc.Name == 0)
            {
                break;
            }

            IntPtr handle = Win.LoadLibrary(PtrAdd(pCode, ImportDesc.Name));
            if (PtrIsInvalidHandle(handle))
            {
                foreach (IntPtr m in ImportModules)
                {
                    Win.FreeLibrary(m);
                }
                ImportModules.Clear();
                throw new DllException("Can't load libary " + Marshal.PtrToStringAnsi(PtrAdd(pCode, ImportDesc.Name)));
            }
            ImportModules.Add(handle);

            IntPtr pThunkRef, pFuncRef;
            if (ImportDesc.OriginalFirstThunk > 0)
            {
                pThunkRef = PtrAdd(pCode, ImportDesc.OriginalFirstThunk);
                pFuncRef  = PtrAdd(pCode, ImportDesc.FirstThunk);
            }
            else
            {
                // no hint table
                pThunkRef = PtrAdd(pCode, ImportDesc.FirstThunk);
                pFuncRef  = PtrAdd(pCode, ImportDesc.FirstThunk);
            }
            for (int SzRef = IntPtr.Size; ; pThunkRef = PtrAdd(pThunkRef, SzRef), pFuncRef = PtrAdd(pFuncRef, SzRef))
            {
                IntPtr ReadThunkRef = PtrRead <IntPtr>(pThunkRef), WriteFuncRef;
                if (ReadThunkRef == IntPtr.Zero)
                {
                    break;
                }
                if (Win.IMAGE_SNAP_BY_ORDINAL(ReadThunkRef))
                {
                    WriteFuncRef = Win.GetProcAddress(handle, Win.IMAGE_ORDINAL(ReadThunkRef));
                }
                else
                {
                    WriteFuncRef = Win.GetProcAddress(handle, PtrAdd(PtrAdd(pCode, ReadThunkRef), Of.IMAGE_IMPORT_BY_NAME_Name));
                }
                if (WriteFuncRef == IntPtr.Zero)
                {
                    throw new DllException("Can't get adress for imported function");
                }
                PtrWrite(pFuncRef, WriteFuncRef);
            }
        }
        return(ImportModules.Count > 0 ? ImportModules.ToArray() : null);
    }
        public void PrintINTH(object _inth)
        {
            listViewDd.Items.Clear();
            IMAGE_NT_HEADERS inth = (IMAGE_NT_HEADERS)_inth;

            //IMAGE_NT_HEADERS
            textBoxSignature.Text = "0x" + inth.Signature.ToString("X8");

            //IMAGE_FILE_HEADER
            if (System.Runtime.InteropServices.Marshal.SizeOf(inth.FileHeader) != (int)SizeA.IMAGE_SIZEOF_FILE_HEADER)
            {
                MessageBox.Show("Внимание! Размер структуры IMAGE_FILE_HEADER отличается от 20 байт: " + System.Runtime.InteropServices.Marshal.SizeOf(inth.FileHeader).ToString());
            }
            textBoxCharacteristics.Text      = "0x" + inth.FileHeader.Characteristics.ToString("X4");
            textBoxMachine.Text              = "0x" + inth.FileHeader.Machine.ToString("X4");
            textBoxNumberOfSections.Text     = "0x" + inth.FileHeader.NumberOfSections.ToString("X4");
            textBoxNumberOfSymbols.Text      = "0x" + inth.FileHeader.NumberOfSymbols.ToString("X8");
            textBoxPointerToSymbolTable.Text = "0x" + inth.FileHeader.PointerToSymbolTable.ToString("X8");
            textBoxSizeOfOptionalHeader.Text = "0x" + inth.FileHeader.SizeOfOptionalHeader.ToString("X4");
            textBoxTimeDateStamp.Text        = "0x" + inth.FileHeader.TimeDateStamp.ToString("X8");

            //IMAGE_OPTIONAL_HEADER32
            //Стандартные поля
            textBoxMagic.Text = "0x" + inth.OptionalHeader.Magic.ToString("X4");
            textBoxMajorLinkerVersion.Text      = inth.OptionalHeader.MajorLinkerVersion.ToString();
            textBoxMinorLinkerVersion.Text      = inth.OptionalHeader.MinorLinkerVersion.ToString();
            textBoxSizeOfCode.Text              = "0x" + inth.OptionalHeader.SizeOfCode.ToString("X8");
            textBoxSizeOfInitializedData.Text   = "0x" + inth.OptionalHeader.SizeOfInitializedData.ToString("X8");
            textBoxSizeOfUninitializedData.Text = "0x" + inth.OptionalHeader.SizeOfUninitializedData.ToString("X8");
            textBoxAddressOfEntryPoint.Text     = "0x" + inth.OptionalHeader.AddressOfEntryPoint.ToString("X8");
            textBoxBaseOfCode.Text              = "0x" + inth.OptionalHeader.BaseOfCode.ToString("X8");
            textBoxBaseOfData.Text              = "0x" + inth.OptionalHeader.BaseOfData.ToString("X8");
            //Дополнительные поля
            textBoxImageBase.Text                   = "0x" + inth.OptionalHeader.ImageBase.ToString("X8");
            textBoxSectionAlignment.Text            = "0x" + inth.OptionalHeader.SectionAlignment.ToString("X8");
            textBoxFileAlignment.Text               = "0x" + inth.OptionalHeader.FileAlignment.ToString("X8");
            textBoxMajorOperatingSystemVersion.Text = "0x" + inth.OptionalHeader.MajorOperatingSystemVersion.ToString("X4");
            textBoxMinorOperatingSystemVersion.Text = "0x" + inth.OptionalHeader.MinorOperatingSystemVersion.ToString("X4");
            textBoxMajorImageVersion.Text           = "0x" + inth.OptionalHeader.MajorImageVersion.ToString("X4");
            textBoxMinorImageVersion.Text           = "0x" + inth.OptionalHeader.MinorImageVersion.ToString("X4");
            textBoxMajorSubsystemVersion.Text       = "0x" + inth.OptionalHeader.MajorSubsystemVersion.ToString("X4");
            textBoxMinorSubsystemVersion.Text       = "0x" + inth.OptionalHeader.MinorSubsystemVersion.ToString("X4");
            textBoxWin32VersionValue.Text           = "0x" + inth.OptionalHeader.Win32VersionValue.ToString("X8");
            textBoxSizeOfImage.Text                 = "0x" + inth.OptionalHeader.SizeOfImage.ToString("X8");
            textBoxSizeOfHeaders.Text               = "0x" + inth.OptionalHeader.SizeOfHeaders.ToString("X8");
            textBoxCheckSum.Text            = "0x" + inth.OptionalHeader.CheckSum.ToString("X8");
            textBoxSubsystem.Text           = "0x" + inth.OptionalHeader.Subsystem.ToString("X4");
            textBoxDllCharacteristics.Text  = "0x" + inth.OptionalHeader.DllCharacteristics.ToString("X4");
            textBoxSizeOfStackReserve.Text  = "0x" + inth.OptionalHeader.SizeOfStackReserve.ToString("X8");
            textBoxSizeOfStackCommit.Text   = "0x" + inth.OptionalHeader.SizeOfStackCommit.ToString("X8");
            textBoxSizeOfHeapReserve.Text   = "0x" + inth.OptionalHeader.SizeOfHeapReserve.ToString("X8");
            textBoxSizeOfHeapCommit.Text    = "0x" + inth.OptionalHeader.SizeOfHeapCommit.ToString("X8");
            textBoxLoaderFlags.Text         = "0x" + inth.OptionalHeader.LoaderFlags.ToString("X8");
            textBoxNumberOfRvaAndSizes.Text = "0x" + inth.OptionalHeader.NumberOfRvaAndSizes.ToString("X8");

            if (inth.OptionalHeader.NumberOfRvaAndSizes != (int)SizeA.COUNT_DATA_DYRECTORY)
            {
                MessageBox.Show("Внимание! NumberOfRvaAndSizes отличается от стандартного в 0x0010: " + inth.OptionalHeader.NumberOfRvaAndSizes);
            }

            for (int i = 0; i < (int)SizeA.COUNT_DATA_DYRECTORY; i++)
            {
                ListViewItem lvi = new ListViewItem(string.Format("{0}", (DataDirectory)i));
                lvi.SubItems.Add("0x" + inth.OptionalHeader.DataDirectory[i].VirtualAddress.ToString("X8"));
                lvi.SubItems.Add("0x" + inth.OptionalHeader.DataDirectory[i].Size.ToString("X8"));
                listViewDd.Items.Add(lvi);
            }
        }
Beispiel #26
0
        public unsafe bool Initialize(BinaryReader reader)
        {
            if (reader == null)
            {
                return(false);
            }

            binary_reader = reader;
            reader.BaseStream.Position = 0;
            byte[] buffer;
            IntPtr pointer;
            long   NewPos;

            try
            {
                buffer = reader.ReadBytes(sizeof(IMAGE_DOS_HEADER));

                fixed(byte *p = buffer)
                {
                    pointer = (IntPtr)p;
                }
                idh = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(pointer, typeof(IMAGE_DOS_HEADER));
                if (idh.e_magic != 0x5A4D)
                {
                    return(false);
                }
                reader.BaseStream.Position = idh.e_lfanew;
                buffer = reader.ReadBytes(sizeof(IMAGE_NT_HEADERS));

                fixed(byte *p = buffer)
                {
                    pointer = (IntPtr)p;
                }
                inh = (IMAGE_NT_HEADERS)Marshal.PtrToStructure(pointer, typeof(IMAGE_NT_HEADERS));
                if (inh.Signature != 0x4550)
                {
                    return(false);
                }

                reader.BaseStream.Position = idh.e_lfanew + 4 + sizeof(IMAGE_FILE_HEADER) + inh.ifh.SizeOfOptionalHeader;
                sections = new image_section_header[inh.ifh.NumberOfSections];
                buffer   = reader.ReadBytes(sizeof(image_section_header) * inh.ifh.NumberOfSections);
                fixed(byte *p = buffer)
                {
                    pointer = (IntPtr)p;
                }

                for (int i = 0; i < sections.Length; i++)
                {
                    sections[i] = (image_section_header)Marshal.PtrToStructure(pointer, typeof(image_section_header));
                    pointer     = (IntPtr)(pointer.ToInt32() + Marshal.SizeOf(typeof(image_section_header)));
                }


                // NET Directory
                if (inh.ioh.MetaDataDirectory.RVA == 0)
                {
                    return(false);
                }
                NewPos = (long)Rva2Offset(inh.ioh.MetaDataDirectory.RVA);
                if (NewPos == 0)
                {
                    return(false);
                }
                reader.BaseStream.Position = NewPos;
                buffer = reader.ReadBytes(sizeof(NETDirectory));

                fixed(byte *p = buffer)
                {
                    pointer = (IntPtr)p;
                }
                // After .NET Directory comes body of methods!
                netdir = (NETDirectory)Marshal.PtrToStructure(pointer, typeof(NETDirectory));

                reader.BaseStream.Position = (long)Rva2Offset(netdir.MetaDataRVA);
                mh                 = new MetadataReader.MetaDataHeader();
                mh.Signature       = reader.ReadInt32();
                mh.MajorVersion    = reader.ReadInt16();
                mh.MinorVersion    = reader.ReadInt16();
                mh.Reserved        = reader.ReadInt32();
                mh.VersionLenght   = reader.ReadInt32();
                mh.VersionString   = reader.ReadBytes(mh.VersionLenght);
                mh.Flags           = reader.ReadInt16();
                mh.NumberOfStreams = reader.ReadInt16();

                streams = new MetaDataStream[mh.NumberOfStreams];

                for (int i = 0; i < mh.NumberOfStreams; ++i)
                {
                    streams[i].Offset = reader.ReadInt32();
                    streams[i].Size   = reader.ReadInt32();
                    char[] chars     = new char[32];
                    int    index     = 0;
                    byte   character = 0;
                    while ((character = reader.ReadByte()) != 0)
                    {
                        chars[index++] = (char)character;
                    }

                    index++;
                    int padding = ((index % 4) != 0) ? (4 - (index % 4)) : 0;
                    reader.ReadBytes(padding);

                    streams[i].Name = new String(chars).Trim(new Char[] { '\0' });

                    if (streams[i].Name == "#~" || streams[i].Name == "#-")
                    {
                        MetadataRoot.Name   = streams[i].Name;
                        MetadataRoot.Offset = streams[i].Offset;
                        MetadataRoot.Size   = streams[i].Size;

                        long savepoz = reader.BaseStream.Position;
                        reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + streams[i].Offset);
                        TablesBytes = reader.ReadBytes(streams[i].Size);
                        reader.BaseStream.Position = savepoz;
                    }

                    if (streams[i].Name == "#Strings")
                    {
                        long savepoz = reader.BaseStream.Position;
                        reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + streams[i].Offset);
                        StringOffset = reader.BaseStream.Position;
                        Strings      = reader.ReadBytes(streams[i].Size);
                        reader.BaseStream.Position = savepoz;
                    }

                    if (streams[i].Name == "#US")
                    {
                        long savepoz = reader.BaseStream.Position;
                        reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + streams[i].Offset);
                        US = reader.ReadBytes(streams[i].Size);
                        reader.BaseStream.Position = savepoz;
                    }

                    if (streams[i].Name == "#Blob")
                    {
                        long savepoz = reader.BaseStream.Position;
                        reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + streams[i].Offset);
                        BlobOffset = reader.BaseStream.Position;
                        Blob       = reader.ReadBytes(streams[i].Size);
                        reader.BaseStream.Position = savepoz;
                    }

                    if (streams[i].Name == "#GUID")
                    {
                        long savepoz = reader.BaseStream.Position;
                        reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + streams[i].Offset);
                        GUID = reader.ReadBytes(streams[i].Size);
                        reader.BaseStream.Position = savepoz;
                    }
                }

                reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + MetadataRoot.Offset);
                tablestart = reader.BaseStream.Position;
                buffer     = reader.ReadBytes(sizeof(TableHeader));
                fixed(byte *p = buffer)
                {
                    pointer = (IntPtr)p;
                }
                tableheader  = (TableHeader)Marshal.PtrToStructure(pointer, typeof(TableHeader));
                TableLengths = new int[64];


                //read as many uints as there are bits set in maskvalid
                for (int i = 0; i < 64; i++)
                {
                    int count = (((tableheader.MaskValid >> i) & 1) == 0) ? 0 : reader.ReadInt32();
                    TableLengths[i] = count;
                }

                TablesOffset = reader.BaseStream.Position;
                InitTablesInfo();
// Get Table sizes and all Tables
                tablesize = new TableSize[0x2D];
                tables    = new Table[0x2D];
                for (int i = 0; i < tablesize.Length; i++)
                {
                    tablesize[i].Sizes     = new int[tablesinfo[i].ctypes.Length];
                    tablesize[i].TotalSize = 0;
                    for (int j = 0; j < tablesinfo[i].ctypes.Length; j++)
                    {
                        tablesize[i].Sizes[j]  = GetTypeSize(tablesinfo[i].ctypes[j]);
                        tablesize[i].TotalSize = tablesize[i].TotalSize + tablesize[i].Sizes[j];
                    }
                }


                for (int i = 0; i < tablesize.Length; i++)
                {
                    if (TableLengths[i] > 0)
                    {
                        tables[i].members = new long[TableLengths[i]][];
                        for (int j = 0; j < TableLengths[i]; j++)
                        {
                            tables[i].members[j] = new long[tablesinfo[i].ctypes.Length];
                            for (int k = 0; k < tablesinfo[i].ctypes.Length; k++)
                            {
                                if (tablesize[i].Sizes[k] == 2)
                                {
                                    tables[i].members[j][k] = reader.ReadInt16() & 65535;
                                }
                                if (tablesize[i].Sizes[k] == 4)
                                {
                                    tables[i].members[j][k] = reader.ReadInt32() & 4294967295;
                                }
                            }
                        }
                    }
                } // end of big for!
            }
            catch
            {
                return(false);
            }

            return(true);
        }