Example #1
0
        private void FinalizeSections64(IntPtr codeBase, IntPtr headers, IMAGE_DOS_HEADER dosHeader, IMAGE_NT_HEADERS64 header64)
        {
            var section = headers.ToStruct<IMAGE_SECTION_HEADER>((uint)(24 + dosHeader.e_lfanew + header64.FileHeader.SizeOfOptionalHeader));
            for (int i = 0; i < header64.FileHeader.NumberOfSections; i++)
            {                                
                //Console.WriteLine("Finalize section " + Encoding.UTF8.GetString(section.Name));

                if ((section.Characteristics & 0x02000000) > 0)
                {
                    bool aa = Native.VirtualFree(codeBase.Add(section.VirtualAddress), (UIntPtr)section.SizeOfRawData, 0x4000);
                    continue;
                }

                int execute = (section.Characteristics & 0x20000000) != 0 ? 1 : 0;
                int readable = (section.Characteristics & 0x40000000) != 0 ? 1 : 0;
                int writeable = (section.Characteristics & 0x80000000) != 0 ? 1 : 0;

                var protect = (uint)ProtectionFlags[execute][readable][writeable];

                if ((section.Characteristics & 0x04000000) > 0) protect |= 0x200;

                var size = (int)section.SizeOfRawData;

                if (size == 0)
                {
                    if ((section.Characteristics & 0x00000040) > 0)
                    {
                        size = (int)header64.OptionalHeader.SizeOfInitializedData;
                    }
                    else if ((section.Characteristics & 0x00000080) > 0)
                    {
                        size = (int)header64.OptionalHeader.SizeOfUninitializedData;
                    }
                }

                if (size > 0)
                {
                    uint oldProtect;
                    IntPtr physicalAddress = codeBase.Add(section.VirtualAddress);
                    if (!Native.VirtualProtect(physicalAddress, section.SizeOfRawData, protect, out oldProtect))                    
                    {
                        Log.Error("Error protecting memory page of physical address 0x" + physicalAddress.ToString("X16"));
                    }
                }

                section = headers.ToStruct<IMAGE_SECTION_HEADER>((uint)((24 + dosHeader.e_lfanew + header64.FileHeader.SizeOfOptionalHeader) + (Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)) * (i + 1))));
            }

        }
Example #2
0
        private void CopySections64(byte[] data, IntPtr codeBase, IMAGE_NT_HEADERS64 header64, IntPtr headers, IMAGE_DOS_HEADER dosHeader)
        {            
            IMAGE_SECTION_HEADER section = headers.ToStruct<IMAGE_SECTION_HEADER>(24 + dosHeader.e_lfanew + header64.FileHeader.SizeOfOptionalHeader);

            for (int i = 0; i < header64.FileHeader.NumberOfSections; i++)
            {
                //ConsoleWindow.Pause("Section " + i + "/"+ (header64.FileHeader.NumberOfSections-1) + " (" + Encoding.UTF8.GetString(section.Name) + ") -> 0x"+ section.VirtualAddress.ToString("X16") + "...");

                IntPtr dest;                                
                if (section.SizeOfRawData == 0)
                {
                    uint sectionSize = header64.OptionalHeader.SectionAlignment;
                    if (sectionSize > 0)
                    {
                        dest = Native.VirtualAlloc(codeBase.Add(section.VirtualAddress), sectionSize, MEM_COMMIT, PAGE_READWRITE);
                        Marshal.Copy(new byte[sectionSize + 1], 0, dest, (int)sectionSize);

                        //section.PhysicalAddress = (uint)dest;
                        //ConsoleWindow.WriteLine("section(NoRaw).PhysicalAddress=0x" + section.PhysicalAddress.ToString("X16")+", dest=0x" + dest.ToString("X16"));

                        //write = headers.Add(32 + dosHeader.e_lfanew + header64.FileHeader.SizeOfOptionalHeader + (Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)) * i));
                        //Marshal.WriteInt64(write, (long)dest);                      
                    }
                }
                else
                {
                    dest = Native.VirtualAlloc(codeBase.Add(section.VirtualAddress), section.SizeOfRawData, MEM_COMMIT, PAGE_READWRITE);
                    Marshal.Copy(data, (int)section.PointerToRawData, dest, (int)section.SizeOfRawData);

                    //section.PhysicalAddress = (uint)dest;
                    //ConsoleWindow.WriteLine("section.PhysicalAddress=0x" + section.PhysicalAddress.ToString("X16") + ", dest=0x" + dest.ToString("X16"));

                    //write = headers.Add(32 + dosHeader.e_lfanew + header64.FileHeader.SizeOfOptionalHeader + (Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)) * i));
                    //Marshal.WriteInt64(write, (long)dest);
                }
                section = headers.ToStruct<IMAGE_SECTION_HEADER>(24 + dosHeader.e_lfanew + header64.FileHeader.SizeOfOptionalHeader + (Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)) * (i+1)));
            }
        }
Example #3
0
        public MemoryModule(byte[] bytes)
        {
            IntPtr address = IntPtr.Zero;
            IntPtr dllEntryPoint = IntPtr.Zero;

            ProtectionFlags[0] = new int[2][];
            ProtectionFlags[1] = new int[2][];
            ProtectionFlags[0][0] = new int[2];
            ProtectionFlags[0][1] = new int[2];
            ProtectionFlags[1][0] = new int[2];
            ProtectionFlags[1][1] = new int[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_DOS_HEADER dosHeader = bytes.ToStruct<IMAGE_DOS_HEADER>();
            IMAGE_NT_HEADERS32 ntHeader = bytes.ToStruct<IMAGE_NT_HEADERS32>((uint)dosHeader.e_lfanew);

            Is64Bit = (ntHeader.OptionalHeader.Magic == 0x020B || ntHeader.FileHeader.Machine == 0x8664);

            #region [ Load x64 Machine Dynamic Link Library ]
            if (Is64Bit)
            {
                IMAGE_NT_HEADERS64 header64 = bytes.ToStruct<IMAGE_NT_HEADERS64>((uint)dosHeader.e_lfanew);

                address = Native.VirtualAlloc((IntPtr)header64.OptionalHeader.ImageBase, header64.OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
                if (address == IntPtr.Zero) address = Native.VirtualAlloc(address, header64.OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

                if (address != IntPtr.Zero)
                {
                    //Log.Console("Memory Address: 0x" + address.ToString("X16"));                                        

                    IntPtr headers = Native.VirtualAlloc(address, header64.OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_READWRITE);
                    Marshal.Copy(bytes, 0, headers, (int)(dosHeader.e_lfanew + header64.OptionalHeader.SizeOfHeaders));

                    CopySections64(bytes, address, header64, headers, dosHeader);

                    int moduleCount = GetModuleCount(address, header64.OptionalHeader.ImportTable);

                    module64 = new MEMORYMODULE64
                    {
                        codeBase = address,
                        numModules = moduleCount,
                        modules = Marshal.AllocHGlobal(moduleCount * sizeof(int)),
                        initialized = 0
                    };

                    module64.headers = headers.ToStruct<IMAGE_NT_HEADERS64>((uint)dosHeader.e_lfanew);
                    module64.headers.OptionalHeader.ImageBase = (ulong)address;                    

                    ulong locationDelta = (ulong)address - header64.OptionalHeader.ImageBase;
                    if (locationDelta != 0) PerformBaseRelocation64(locationDelta);

                    BuildImportTable64(module64);                    

                    FinalizeSections64(address, headers, dosHeader, header64);

                    dllEntryPoint = address.Add(header64.OptionalHeader.AddressOfEntryPoint);
                }
            }
            #endregion

            #region [ Load x86 Machine Dynamic Link Library ]
            else
            {
                IMAGE_NT_HEADERS32 header32 = bytes.ToStruct<IMAGE_NT_HEADERS32>((uint)dosHeader.e_lfanew);

                address = Native.VirtualAlloc((IntPtr)header32.OptionalHeader.ImageBase, header32.OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
                if (address == IntPtr.Zero) address = Native.VirtualAlloc(address, header32.OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

                if (address != IntPtr.Zero)
                {
                    //Log.Console("Memory Address: 0x" + address.ToString("X16"));                    

                    IntPtr headers = Native.VirtualAlloc(address, header32.OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_READWRITE);
                    Marshal.Copy(bytes, 0, headers, (int)(dosHeader.e_lfanew + header32.OptionalHeader.SizeOfHeaders));

                    CopySections32(bytes, address, header32, headers, dosHeader);

                    int moduleCount = GetModuleCount(address, header32.OptionalHeader.ImportTable);

                    module32 = new MEMORYMODULE32
                    {
                        codeBase = address,
                        numModules = 0,
                        modules = new IntPtr(0),
                        initialized = 0
                    };

                    module32.headers = headers.ToStruct<IMAGE_NT_HEADERS32>((uint)dosHeader.e_lfanew);
                    module32.headers.OptionalHeader.ImageBase = (uint)address;

                    ulong locationDelta = (ulong)address - header32.OptionalHeader.ImageBase;
                    if (locationDelta != 0) PerformBaseRelocation32(locationDelta);

                    BuildImportTable32(module32);

                    FinalizeSections32(address, headers, dosHeader, header32);

                    dllEntryPoint = address.Add(header32.OptionalHeader.AddressOfEntryPoint);
                }
            }
            #endregion

            //Log.Console("DllEntryPoint: 0x" + dllEntryPoint.ToString("X16"));
            DllEntry dllEntry = (DllEntry)Marshal.GetDelegateForFunctionPointer(dllEntryPoint, typeof(DllEntry));
            dllEntry(address, 1, IntPtr.Zero);
        }