Ejemplo n.º 1
0
        public static void InitializeMpAbi()
        {
            // Note: When mapping the abi stub (MpSyscalls.x86), we must
            // map it with writable flag! as we want to resolve the stub's
            // imports
            IoMemory mpPages = IoMemory.MapPhysicalMemory(Platform.MP_ABI_BASE, 4096, true, true);

            mpAbi        = new PEImage(mpPages);
            mpPages      = IoMemory.MapPhysicalMemory(Platform.MP_ABI_BASE, mpAbi.loadedSize, true, true);
            mpAbiExports = mpAbi.GetExportTable(mpPages);

            // Resolve imports in abi shim dll with the kernel exports
            // which are the real stub that will do IPI stuffs
            ImportTable mpAbiIt = mpAbi.GetImportTable(mpPages);

            DebugStub.WriteLine("HSG: ** Resolving Imports");
            mpAbiIt.ResolveImports(kernelExports);
        }
Ejemplo n.º 2
0
        public static PEImage Load(Process process, IoMemory rawMemory,
                                   out IoMemory loadedMemory, bool isForMp,
                                   bool inKernelSpace)
        {
            UIntPtr entryPoint = UIntPtr.Zero;

            loadedMemory = null;

            DiagnosisService.DeferedUpdateNotification();

            if (null == rawMemory || 0 == rawMemory.Length)
            {
                DebugStub.WriteLine("No PXE image to load!");
                return(null);
            }

            //
            // Allocate memory and copy the PXE image from memory to memory
            //
#if verbose
            Tracing.Log(Tracing.Debug, " PXE at {0:x8}, Length ={1:x8}",
                        (uint)rawMemory.VirtualAddress,
                        rawMemory.Length);
#endif

            Kernel.Waypoint(580);
            Tracing.Log(Tracing.Debug, "Loading:");
            PEImage image = new PEImage(rawMemory);
            image.DumpLimitedToStream();

#if verbose
            Tracing.Log(Tracing.Debug, "  Loaded Size={0:x8}", image.loadedSize);
#endif
            Kernel.Waypoint(581);
            if (0 == image.loadedSize)
            {
                throw new BadImageFormatException("Invalid PE, no content");
            }

            try {
                if (inKernelSpace)
                {
                    loadedMemory = IoMemory.AllocateFixed(
                        (UIntPtr)image.loadedSize,
                        process, PageType.System);
                }
                else
                {
                    // Situate the process image in the user range
                    loadedMemory = IoMemory.AllocateUserFixed(
                        (UIntPtr)image.loadedSize,
                        process, PageType.System);
                }

                Kernel.Waypoint(582);


#if verbose
                Tracing.Log(Tracing.Debug, " loaded at {0:x8}, Length ={1:x8}",
                            (uint)loadedMemory.VirtualAddress,
                            loadedMemory.Length);
#endif
                // Copy the header so the debugger can find it.
                IoMemory.Copy(rawMemory, 0, loadedMemory, 0, (int)image.sizeOfHeaders);

#if verbose
                image.DumpLimitedToStream();
#endif

                Kernel.Waypoint(583);
                // load sections into memory where they belong.
                for (int i = 0; i < image.numberOfSections; i++)
                {
                    if (image.sections[i].IsDiscardable ||
                        image.sections[i].sizeOfRawData == 0)
                    {
                        continue;
                    }

                    int  targetOffset = (int)image.sections[i].virtualAddress;
                    int  sourceOffset = (int)image.sections[i].pointerToRawData;
                    uint rawSize      = Math.Min(image.sections[i].sizeOfRawData,
                                                 image.sections[i].virtualSize);
#if verbose
                    Tracing.Log(Tracing.Debug, "section[{0}] source={1:x8}..{2:x8} target={3:x8}..{4:x8}",
                                i,
                                sourceOffset, sourceOffset + rawSize,
                                targetOffset, targetOffset + rawSize);
#endif

                    if (image.sections[i].virtualSize > image.sections[i].sizeOfRawData)
                    {
                        //  The memory allocated for the new image is not zeroed, therefore
                        //  we need to clear the remaining region of a section that is not getting
                        //  copied from the source. NOTE BSS sections rely on this to be zeroed
                        //  This is fixing some random bugs with uninitialized variables in unmanaged code

                        unsafe {
                            byte *dest   = (byte *)loadedMemory.VirtualAddress + targetOffset + image.sections[i].sizeOfRawData;
                            uint  length = image.sections[i].virtualSize - image.sections[i].sizeOfRawData;

                            Buffer.ZeroMemory(dest, length);
                        }
                    }

                    IoMemory.Copy(rawMemory, sourceOffset, loadedMemory, targetOffset, (int)rawSize);
                }
                Kernel.Waypoint(584);

                //
                // Handle Relocations
                //
                int     relocationTableOffset = (int)image.GetRelocationsRaw();
                UIntPtr diff = (UIntPtr)loadedMemory.VirtualAddress - (UIntPtr)image.imageBase;
                image.VirtualAddress = loadedMemory.VirtualAddress;

#if verbose
                Tracing.Log(Tracing.Debug, " Base loaded={0:x8}, relocated ={1:x8} diff={2:x8}",
                            image.imageBase, (uint)loadedMemory.VirtualAddress, diff);

                Tracing.Log(Tracing.Debug, " relocationTableOffset ={0:x8} ", relocationTableOffset);
#endif

                if (relocationTableOffset > 0)
                {
                    Relocations.FixupBlocks(rawMemory, (int)relocationTableOffset,
                                            loadedMemory, diff);
                    // TODO: We should probably zero the relocation table.
                }

                Kernel.Waypoint(585);

                //
                // Resolve Imports
                //
                ImportTable it = image.GetImportTable(loadedMemory);
                Kernel.Waypoint(586);

#if !PAGING
#if GENERATE_ABI_SHIM
                if (it != null)
                {
#endif
                //it.DumpIAT("Import directory");

                // if this is loading for remote processor
                // then solve the imports with abi stub
                if (isForMp)
                {
                    it.ResolveImports(mpAbiExports);
                }
                else
                {
                    it.ResolveImports(kernelExports);
                }

                //DumpIAT(loadedMemory, "Import Address Table",
                // ref image.directory[12]);
#if GENERATE_ABI_SHIM
            }
#endif
#else
                if (it != null)
                {
                    // Ring-3 protection domains come with a set of
                    // stubs that accomplish the ring3-to-ring0 ABI
                    // transitions. Use these when called for.
                    ExportTable abiStubs = process.Domain.ABIStubs;

                    if (abiStubs != null)
                    {
                        it.ResolveImports(abiStubs);
                    }
                    else
                    {
                        it.ResolveImports(kernelExports);
                    }
                }
#endif

                Kernel.Waypoint(587);

                //
                // Dump Exports
                //
                ExportTable et = image.GetExportTable(loadedMemory);
                if (et != null)
                {
                    et.Dump();
                }

                Kernel.Waypoint(588);

                entryPoint = (UIntPtr)loadedMemory.VirtualAddress + image.addressOfEntryPoint;

                Tracing.Log(Tracing.Debug, "  Loaded: {0:x8}..{1:x8}, Entry: {2:x8}",
                            (ulong)loadedMemory.VirtualAddress,
                            (ulong)(loadedMemory.VirtualAddress + loadedMemory.Length),
                            (ulong)(entryPoint));
            }
            finally {
                if (entryPoint == UIntPtr.Zero && loadedMemory != null)
                {
                    // TODO: Need to dispose of target Range.
                    loadedMemory = null;
                }
            }
            return(image);
        }