Beispiel #1
0
        private void BuildImportTable32(MEMORYMODULE32 module32)
        {
            int moduleCount = 0;
            IntPtr codeBase = module32.codeBase;
            IMAGE_DATA_DIRECTORY directory = module32.headers.OptionalHeader.ImportTable;

            if (directory.Size > 0)
            {
                //Log.Console("ImportTable.Size: "+ directory.Size);

                uint* nameRef, funcRef;
                IMAGE_IMPORT_DESCRIPTOR importDesc = codeBase.ToStruct<IMAGE_IMPORT_DESCRIPTOR>(directory.VirtualAddress);

                while (importDesc.Name > 0)
                {
                    string moduleName = Marshal.PtrToStringAnsi(codeBase.Add(importDesc.Name));
                    //Log.Console("Import Module: " + moduleName);

                    IntPtr handle = Native.LoadLibrary(moduleName);
                    if (handle == IntPtr.Zero) break;

                    if (importDesc.CharacteristicsOrOriginalFirstThunk > 0)
                    {
                        nameRef = (uint*)codeBase.Add(importDesc.CharacteristicsOrOriginalFirstThunk);
                        funcRef = (uint*)codeBase.Add(importDesc.FirstThunk);
                    }
                    else
                    {
                        nameRef = (uint*)codeBase.Add(importDesc.FirstThunk);
                        funcRef = (uint*)codeBase.Add(importDesc.FirstThunk);
                    }

                    for (; *nameRef > 0; nameRef++, funcRef++)
                    {
                        //Log.Console("Import: " + nameRef->ToString("X16") + ", 0x" + funcRef->ToString("x16"));

                        if ((*nameRef & 0x8000000000000000) != 0)
                        {
                            *funcRef = (uint)Native.GetProcAddress(handle, new IntPtr(*nameRef & 0xffff));
                        }
                        else
                        {
                            string functionName = Marshal.PtrToStringAnsi(codeBase.Add((*nameRef) + 2));
                            *funcRef = (uint)Native.GetProcAddress(handle, functionName);
                            //Log.Console("Import Function: " + functionName + " -> 0x" + funcRef->ToString("x16"));
                        }

                        //Log.Console("Import nameRef: 0x" + nameRef->ToString("X16"));
                        //Log.Console("Import funcRef: 0x" + funcRef->ToString("X16"));                                                

                        if (*funcRef == 0)
                        {
                            break;
                        }
                    }

                    moduleCount++;
                    importDesc = codeBase.ToStruct<IMAGE_IMPORT_DESCRIPTOR>(directory.VirtualAddress + (uint)(Marshal.SizeOf(typeof(IMAGE_IMPORT_DESCRIPTOR)) * moduleCount));
                }
            }
        }
Beispiel #2
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);
        }