예제 #1
0
        /// <summary>
        /// Gets the total amount of modules within an assembly.
        /// </summary>
        public int GetModuleCount()
        {
            int    count    = 0;
            IntPtr codeBase = module.codeBase;
            IMAGE_DATA_DIRECTORY directory = module.headers.OptionalHeader.DataDirectory[1];

            if (directory.Size > 0)
            {
                var importDesc = PointerHelpers.ToStruct <IMAGE_IMPORT_DESCRIPTOR>(codeBase, directory.VirtualAddress);
                while (importDesc.Name > 0)
                {
                    var    str    = codeBase + (int)importDesc.Name;
                    string tmp    = Marshal.PtrToStringAnsi(str);
                    int    handle = Win32Imports.LoadLibrary(tmp);

                    if (handle == -1)
                    {
                        break;
                    }
                    count++;
                    importDesc = PointerHelpers.ToStruct <IMAGE_IMPORT_DESCRIPTOR>(codeBase, (uint)(directory.VirtualAddress + (Marshal.SizeOf(typeof(IMAGE_IMPORT_DESCRIPTOR)) * (count))));
                }
            }
            return(count);
        }
예제 #2
0
        /// <summary>
        /// Obtains the memory address of an assembly.
        /// </summary>
        /// <param name="name">The name of the assembly to find the address of.</param>
        public uint GetProcAddress(string name)
        {
            unsafe
            {
                IntPtr codeBase = module.codeBase;
                int    idx      = -1;
                uint   i;
                IMAGE_DATA_DIRECTORY directory = module.headers.OptionalHeader.DataDirectory[0];
                if (directory.Size == 0)
                {
                    return(0);
                }
                var exports = PointerHelpers.ToStruct <IMAGE_EXPORT_DIRECTORY>(codeBase, directory.VirtualAddress);
                var nameRef = (uint *)new IntPtr(codeBase.ToInt32() + exports.AddressOfNames);
                var ordinal = (ushort *)new IntPtr(codeBase.ToInt32() + exports.AddressOfNameOrdinals);
                for (i = 0; i < exports.NumberOfNames; i++, nameRef++, ordinal++)
                {
                    var    str = codeBase + (int)(*nameRef);
                    string tmp = Marshal.PtrToStringAnsi(str);
                    if (tmp == name)
                    {
                        idx = *ordinal;
                        break;
                    }
                }

                var tmpaa = (uint *)(codeBase.ToInt32() + (exports.AddressOfFunctions + (idx * 4)));
                var addr  = (uint)((codeBase.ToInt32()) + (*tmpaa));
                return(addr);
            }
        }
예제 #3
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))));
            }
        }
예제 #4
0
        public String[] GetProcedures()
        {
            unsafe
            {
                IntPtr codeBase = this._module.codeBase;
                IMAGE_DATA_DIRECTORY directory = this._module.headers.OptionalHeader.DataDirectory[0];
                if (directory.Size == 0)
                {
                    return new String[] { }
                }
                ;

                IMAGE_EXPORT_DIRECTORY exports = PointerHelpers.ToStruct <IMAGE_EXPORT_DIRECTORY>(codeBase, directory.VirtualAddress);
                UInt32 *nameRef = (UInt32 *)new IntPtr(codeBase.ToInt32() + exports.AddressOfNames);
                UInt16 *ordinal = (UInt16 *)new IntPtr(codeBase.ToInt32() + exports.AddressOfNameOrdinals);

                String[] result = new String[exports.NumberOfNames];
                for (UInt32 i = 0; i < exports.NumberOfNames; i++, nameRef++, ordinal++)
                {
                    IntPtr str = new IntPtr(codeBase.ToInt32() + (Int32)(*nameRef));
                    result[i] = Marshal.PtrToStringAnsi(str);
                }
                return(result);
            }
        }
예제 #5
0
        public Int32 GetModuleCount()
        {
            Int32  count    = 0;
            IntPtr codeBase = this._module.codeBase;
            IMAGE_DATA_DIRECTORY directory = this._module.headers.OptionalHeader.DataDirectory[1];

            if (directory.Size > 0)
            {
                IMAGE_IMPORT_DESCRIPTOR importDesc = PointerHelpers.ToStruct <IMAGE_IMPORT_DESCRIPTOR>(codeBase, directory.VirtualAddress);
                while (importDesc.Name > 0)
                {
                    Int32  str    = codeBase.ToInt32() + (Int32)importDesc.Name;
                    String tmp    = Marshal.PtrToStringAnsi(new IntPtr(str));
                    Int32  handle = Win32Imports.LoadLibrary(tmp);

                    if (handle == -1)
                    {
                        break;
                    }

                    count++;
                    importDesc = PointerHelpers.ToStruct <IMAGE_IMPORT_DESCRIPTOR>(codeBase, (UInt32)(directory.VirtualAddress + (Marshal.SizeOf(typeof(IMAGE_IMPORT_DESCRIPTOR)) * (count))));
                }
            }
            return(count);
        }
예제 #6
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);
        }
예제 #7
0
        /// <summary>
        /// Loads a native assembly into memory from bytes.
        /// </summary>
        /// <param name="data">The assembly data to inject.</param>
        public unsafe bool LoadAssembly(byte[] data)
        {
            var dosHeader = PointerHelpers.ToStruct <IMAGE_DOS_HEADER>(data);
            var oldHeader = PointerHelpers.ToStruct <IMAGE_NT_HEADERS>(data, (uint)dosHeader.e_lfanew);
            var code      = (IntPtr)(Win32Imports.VirtualAlloc(oldHeader.OptionalHeader.ImageBase, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_RESERVE, Win32Constants.PAGE_READWRITE));

            if (code.ToInt32() == 0)
            {
                code = (IntPtr)(Win32Imports.VirtualAlloc((uint)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((uint)code, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_COMMIT, Win32Constants.PAGE_READWRITE);
            var headers = (IntPtr)(Win32Imports.VirtualAlloc((uint)code, oldHeader.OptionalHeader.SizeOfHeaders, Win32Constants.MEM_COMMIT, Win32Constants.PAGE_READWRITE));

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

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

            CopySections(data, oldHeader, headers, dosHeader);

            var locationDelta = (uint)(code - (int)oldHeader.OptionalHeader.ImageBase);

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

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

            bool success = false;

            try
            {
                fnDllEntry dllEntry =
                    (fnDllEntry)
                    Marshal.GetDelegateForFunctionPointer(
                        new IntPtr(module.codeBase.ToInt32() + (int)module.headers.OptionalHeader.AddressOfEntryPoint),
                        typeof(fnDllEntry));
                success = dllEntry(code.ToInt32(), 1, (void *)0);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return(success);
        }
예제 #8
0
        public void PerformBaseRelocation(uint delta)
        {
            IntPtr codeBase   = module.codeBase;
            int    sizeOfBase = Marshal.SizeOf(typeof(IMAGE_BASE_RELOCATION));
            IMAGE_DATA_DIRECTORY directory = module.headers.OptionalHeader.DataDirectory[5];
            int cnt = 0;

            if (directory.Size > 0)
            {
                var relocation = PointerHelpers.ToStruct <IMAGE_BASE_RELOCATION>(codeBase, directory.VirtualAddress);
                while (relocation.VirtualAddress > 0)
                {
                    unsafe
                    {
                        var  dest    = (IntPtr)(codeBase.ToInt32() + (int)relocation.VirtualAddress);
                        var  relInfo = (ushort *)(codeBase.ToInt32() + (int)directory.VirtualAddress + sizeOfBase);
                        uint i;
                        for (i = 0;
                             i < ((relocation.SizeOfBlock - Marshal.SizeOf(typeof(IMAGE_BASE_RELOCATION))) / 2);
                             i++, relInfo++)
                        {
                            int type   = *relInfo >> 12;
                            int offset = (*relInfo & 0xfff);
                            switch (type)
                            {
                            case 0x00:
                                break;

                            case 0x03:
                                var patchAddrHl  = (uint *)((dest) + (offset));
                                *   patchAddrHl += delta;
                                break;
                            }
                        }
                    }

                    cnt       += (int)relocation.SizeOfBlock;
                    relocation =
                        PointerHelpers.ToStruct <IMAGE_BASE_RELOCATION>(codeBase,
                                                                        (uint)(directory.VirtualAddress + cnt));
                }
            }
        }
예제 #9
0
        public void PerformBaseRelocation(UInt32 delta)
        {
            IntPtr codeBase   = _module.codeBase;
            Int32  sizeOfBase = Marshal.SizeOf(typeof(IMAGE_BASE_RELOCATION));
            IMAGE_DATA_DIRECTORY directory = _module.headers.OptionalHeader.DataDirectory[5];
            Int32 cnt = 0;

            if (directory.Size > 0)
            {
                IMAGE_BASE_RELOCATION relocation = PointerHelpers.ToStruct <IMAGE_BASE_RELOCATION>(codeBase, directory.VirtualAddress);
                while (relocation.VirtualAddress > 0)
                {
                    unsafe
                    {
                        IntPtr  dest    = (IntPtr)(codeBase.ToInt32() + (int)relocation.VirtualAddress);
                        UInt16 *relInfo = (UInt16 *)(codeBase.ToInt32() + (int)directory.VirtualAddress + sizeOfBase);
                        UInt16  i;
                        for (i = 0; i < ((relocation.SizeOfBlock - Marshal.SizeOf(typeof(IMAGE_BASE_RELOCATION))) / 2); i++, relInfo++)
                        {
                            Int32 type   = *relInfo >> 12;
                            Int32 offset = (*relInfo & 0xfff);
                            switch (type)
                            {
                            case 0x00:
                                break;

                            case 0x03:
                                UInt32 *patchAddrHl  = (UInt32 *)((dest.ToInt32()) + (offset));
                                *       patchAddrHl += delta;
                                break;
                            }
                        }
                    }
                    cnt       += (Int32)relocation.SizeOfBlock;
                    relocation = PointerHelpers.ToStruct <IMAGE_BASE_RELOCATION>(codeBase, (UInt32)(directory.VirtualAddress + cnt));
                }
            }
        }
예제 #10
0
        public UInt32?GetProcAddress(String name)
        {
            unsafe
            {
                IntPtr codeBase = this._module.codeBase;
                Int32? idx      = null;
                IMAGE_DATA_DIRECTORY directory = this._module.headers.OptionalHeader.DataDirectory[0];
                if (directory.Size == 0)
                {
                    return(null);
                }
                IMAGE_EXPORT_DIRECTORY exports = PointerHelpers.ToStruct <IMAGE_EXPORT_DIRECTORY>(codeBase, directory.VirtualAddress);
                UInt32 *nameRef = (UInt32 *)new IntPtr(codeBase.ToInt32() + exports.AddressOfNames);
                UInt16 *ordinal = (UInt16 *)new IntPtr(codeBase.ToInt32() + exports.AddressOfNameOrdinals);

                for (UInt32 i = 0; i < exports.NumberOfNames; i++, nameRef++, ordinal++)
                {
                    IntPtr str = new IntPtr(codeBase.ToInt32() + (Int32)(*nameRef));
                    String tmp = Marshal.PtrToStringAnsi(str);
                    if (tmp == name)
                    {
                        idx = *ordinal;
                        break;
                    }
                }
                if (idx.HasValue)
                {
                    UInt32 *tmpaa = (UInt32 *)(codeBase.ToInt32() + (exports.AddressOfFunctions + (idx.Value * 4)));
                    UInt32  addr  = (UInt32)((codeBase.ToInt32()) + (*tmpaa));
                    return(addr);
                }
                else
                {
                    return(null);
                }
            }
        }
예제 #11
0
        /// <summary>
        /// Allocates memory pages and sets header permissions.
        /// </summary>
        /// <param name="headers">The headers to write to each section of the PE.</param>
        /// <param name="dosHeader">The current header of the PE.</param>
        /// <param name="oldHeaders">The old headers of the PE that have been overwritten.</param>
        public void FinalizeSections(IntPtr headers, IMAGE_DOS_HEADER dosHeader, IMAGE_NT_HEADERS oldHeaders)
        {
            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;

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

            for (int i = 0; i < module.headers.FileHeader.NumberOfSections; i++)
            {
                int executable = (section.Characteristics & 0x20000000) != 0 ? 1 : 0;
                int readable   = (section.Characteristics & 0x40000000) != 0 ? 1 : 0;
                int writeable  = (section.Characteristics & 0x80000000) != 0 ? 1 : 0;

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

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

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

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

                section = PointerHelpers.ToStruct <IMAGE_SECTION_HEADER>(headers, (uint)((24 + dosHeader.e_lfanew + oldHeaders.FileHeader.SizeOfOptionalHeader) + (Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)) * (i + 1))));
            }
        }
예제 #12
0
        /// <summary>
        /// Rebuilds the PE import table after address relocations.
        /// </summary>
        public int BuildImportTable()
        {
            int ucount = GetModuleCount();

            module.modules = Marshal.AllocHGlobal((ucount) * sizeof(int));
            int    pcount   = 0;
            int    result   = 1;
            IntPtr codeBase = module.codeBase;
            IMAGE_DATA_DIRECTORY directory = module.headers.OptionalHeader.DataDirectory[1];

            if (directory.Size > 0)
            {
                var importDesc = PointerHelpers.ToStruct <IMAGE_IMPORT_DESCRIPTOR>(codeBase, directory.VirtualAddress);
                while (importDesc.Name > 0)
                {
                    var    str = codeBase + (int)importDesc.Name;
                    string tmp = Marshal.PtrToStringAnsi(str);
                    unsafe
                    {
                        uint *thunkRef;
                        uint *funcRef;

                        int handle = Win32Imports.LoadLibrary(tmp);

                        if (handle == -1)
                        {
                            result = 0;
                            break;
                        }

                        if (importDesc.CharacteristicsOrOriginalFirstThunk > 0)
                        {
                            IntPtr thunkRefAddr = codeBase + (int)importDesc.CharacteristicsOrOriginalFirstThunk;
                            thunkRef = (uint *)thunkRefAddr;
                            funcRef  = (uint *)(codeBase + (int)importDesc.FirstThunk);
                        }
                        else
                        {
                            thunkRef = (uint *)(codeBase + (int)importDesc.FirstThunk);
                            funcRef  = (uint *)(codeBase + (int)importDesc.FirstThunk);
                        }
                        for (; *thunkRef > 0; thunkRef++, funcRef++)
                        {
                            if ((*thunkRef & 0x80000000) != 0)
                            {
                                *funcRef = (uint)Win32Imports.GetProcAddress(new IntPtr(handle), new IntPtr(*thunkRef & 0xffff));
                            }
                            else
                            {
                                var str2    = codeBase + (int)(*thunkRef) + 2;
                                var tmpaa   = Marshal.PtrToStringAnsi(str2);
                                *   funcRef = Win32Imports.GetProcAddress(new IntPtr(handle), tmpaa);
                            }
                            if (*funcRef == 0)
                            {
                                result = 0;
                                break;
                            }
                        }


                        pcount++;
                        importDesc = PointerHelpers.ToStruct <IMAGE_IMPORT_DESCRIPTOR>(codeBase, directory.VirtualAddress + (uint)(Marshal.SizeOf(typeof(IMAGE_IMPORT_DESCRIPTOR)) * pcount));
                    }
                }
            }
            return(result);
        }
예제 #13
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))));
            }
        }