private static bool UnMapAndLoad(ref LoadedImage loadedImage)
 {
     if (NativeMethods.UnmapViewOfFile(loadedImage.MappedAddress))
     {
         loadedImage = new LoadedImage();
         return(true);
     }
     return(false);
 }
        private static void ParsePeFile(string executable, ILogger logger, Action <LoadedImage> action)
        {
            LoadedImage image  = new LoadedImage();
            bool        loaded = false;

            try
            {
                loaded = MapAndLoad(executable, out image);
                if (loaded)
                {
                    action(image);
                }
            }
            finally
            {
                if (loaded && !UnMapAndLoad(ref image))
                {
                    logger.LogError(Resources.UnMapLoad);
                }
            }
        }
        private static string GetString(LoadedImage image, uint offset)
        {
            IntPtr stringPtr = NativeMethods.ImageRvaToVa(image.FileHeader, image.MappedAddress, offset, IntPtr.Zero);

            return(PtrToStringUtf8(stringPtr));
        }
        private static bool MapAndLoad(string imageName, out LoadedImage loadedImage)
        {
            loadedImage = new LoadedImage();

            long   fileSize;
            IntPtr mapAddr;

            using (var hFile = NativeMethods.CreateFile(imageName, NativeMethods.GENERIC_READ,
                                                        NativeMethods.FILE_SHARE_READ, IntPtr.Zero, NativeMethods.OPEN_EXISTING, 0, IntPtr.Zero))
            {
                if (hFile.IsInvalid)
                {
                    return(false);
                }

                if (!NativeMethods.GetFileSizeEx(hFile, out fileSize))
                {
                    return(false);
                }

                using (var hMapping = NativeMethods.CreateFileMapping(hFile, IntPtr.Zero, NativeMethods.PAGE_READONLY, 0, 0, null))
                {
                    if (hMapping.IsInvalid)
                    {
                        return(false);
                    }

                    mapAddr = NativeMethods.MapViewOfFile(hMapping, NativeMethods.FILE_MAP_READ, 0, 0, UIntPtr.Zero);
                    if (mapAddr == IntPtr.Zero)
                    {
                        return(false);
                    }
                }
            }

            unsafe
            {
                if (fileSize < Marshal.SizeOf <IMAGE_DOS_HEADER>())
                {
                    return(false);
                }

                var dosHeader = (IMAGE_DOS_HEADER *)mapAddr;
                IMAGE_NT_HEADERS *rawFileHeader;
                if (dosHeader->e_magic == NativeMethods.IMAGE_DOS_SIGNATURE)
                {
                    if (dosHeader->e_lfanew <= 0 ||
                        fileSize < dosHeader->e_lfanew + Marshal.SizeOf <IMAGE_NT_HEADERS>())
                    {
                        return(false);
                    }

                    rawFileHeader = (IMAGE_NT_HEADERS *)((byte *)mapAddr + dosHeader->e_lfanew);
                }
                else if (dosHeader->e_magic == NativeMethods.IMAGE_NT_SIGNATURE)
                {
                    if (fileSize < Marshal.SizeOf <IMAGE_NT_HEADERS>())
                    {
                        return(false);
                    }

                    rawFileHeader = (IMAGE_NT_HEADERS *)mapAddr;
                }
                else
                {
                    return(false);
                }

                if (rawFileHeader->Signature != NativeMethods.IMAGE_NT_SIGNATURE)
                {
                    return(false);
                }

                loadedImage.MappedAddress = mapAddr;
                loadedImage.FileHeader    = (IntPtr)rawFileHeader;
                return(true);
            }
        }