Last active
September 7, 2021 04:15
-
-
Save MSDN-WhiteKnight/62ef8d733fabbf1dbd01dedf3b43132e to your computer and use it in GitHub Desktop.
LoadLibraryEx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.ComponentModel; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Runtime.InteropServices; | |
namespace ConsoleApp1 | |
{ | |
class Program | |
{ | |
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)] | |
static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName); | |
[Flags] | |
enum LoadLibraryFlags : uint | |
{ | |
None = 0, | |
DONT_RESOLVE_DLL_REFERENCES = 0x00000001, | |
LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010, | |
LOAD_LIBRARY_AS_DATAFILE = 0x00000002, | |
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040, | |
LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020, | |
LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 0x00000200, | |
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000, | |
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x00000100, | |
LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800, | |
LOAD_LIBRARY_SEARCH_USER_DIRS = 0x00000400, | |
LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008 | |
} | |
[DllImport("kernel32.dll", SetLastError = true)] | |
static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags); | |
[StructLayout(LayoutKind.Sequential)] | |
public struct MODULEINFO | |
{ | |
public IntPtr lpBaseOfDll; | |
public uint SizeOfImage; | |
public IntPtr EntryPoint; | |
} | |
[DllImport("psapi.dll", SetLastError = true)] | |
static extern bool GetModuleInformation(IntPtr hProcess, IntPtr hModule, out MODULEINFO lpmodinfo, uint cb); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
static extern bool ReadProcessMemory( | |
IntPtr hProcess, | |
IntPtr lpBaseAddress, | |
[Out] byte[] lpBuffer, | |
int dwSize, | |
out IntPtr lpNumberOfBytesRead); | |
[DllImport("kernel32.dll", SetLastError = true, EntryPoint = "ReadProcessMemory")] | |
static extern bool ReadProcessMemory_Byte( | |
IntPtr hProcess, IntPtr lpBaseAddress, out byte lpBuffer, int dwSize, out IntPtr lpNumberOfBytesRead | |
); | |
[StructLayout(LayoutKind.Sequential)] | |
public struct MEMORY_BASIC_INFORMATION | |
{ | |
public IntPtr BaseAddress; | |
public IntPtr AllocationBase; | |
public uint AllocationProtect; | |
public IntPtr RegionSize; | |
public uint State; | |
public uint Protect; | |
public uint Type; | |
} | |
public enum AllocationProtect : uint | |
{ | |
PAGE_EXECUTE = 0x00000010, | |
PAGE_EXECUTE_READ = 0x00000020, | |
PAGE_EXECUTE_READWRITE = 0x00000040, | |
PAGE_EXECUTE_WRITECOPY = 0x00000080, | |
PAGE_NOACCESS = 0x00000001, | |
PAGE_READONLY = 0x00000002, | |
PAGE_READWRITE = 0x00000004, | |
PAGE_WRITECOPY = 0x00000008, | |
PAGE_GUARD = 0x00000100, | |
PAGE_NOCACHE = 0x00000200, | |
PAGE_WRITECOMBINE = 0x00000400 | |
} | |
const uint MEM_COMMIT = 0x1000; | |
const uint MEM_FREE = 0x10000; | |
const uint MEM_RESERVE = 0x2000; | |
[DllImport("kernel32.dll")] | |
static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength); | |
public struct MemoryRegion | |
{ | |
public long Address { get; set; } | |
public long Size { get; set; } | |
public bool IsReadable { get; set; } | |
} | |
static bool IsReadAccess(uint protectionFlags) | |
{ | |
AllocationProtect ap = (AllocationProtect)protectionFlags; | |
return ap == AllocationProtect.PAGE_EXECUTE_READ || | |
ap == AllocationProtect.PAGE_EXECUTE_READWRITE || | |
ap == AllocationProtect.PAGE_EXECUTE_WRITECOPY || | |
ap == AllocationProtect.PAGE_READONLY || | |
ap == AllocationProtect.PAGE_READWRITE || | |
ap == AllocationProtect.PAGE_WRITECOPY; | |
} | |
public static MemoryRegion[] GetMemoryRegions(IntPtr hProcess, IntPtr address, int size) | |
{ | |
List<MemoryRegion> ret = new List<MemoryRegion>(50); | |
long MaxAddress = (long)address + size; | |
while(true) | |
{ | |
MEMORY_BASIC_INFORMATION m=new MEMORY_BASIC_INFORMATION(); | |
int result = VirtualQueryEx( | |
hProcess, address, out m, (uint)Marshal.SizeOf(m) | |
); | |
if (result==0||m.RegionSize == IntPtr.Zero) break; | |
MemoryRegion reg = new MemoryRegion(); | |
reg.Address = (long)m.BaseAddress; | |
reg.Size = (long)m.RegionSize; | |
if (m.State == MEM_COMMIT && IsReadAccess(m.AllocationProtect)) | |
{ | |
reg.IsReadable = true; | |
} | |
ret.Add(reg); | |
address = (IntPtr)((long)m.BaseAddress + (long)m.RegionSize); | |
if ((long)address > MaxAddress) break; | |
} | |
return ret.ToArray(); | |
} | |
static void EnumMemoryRegions(IntPtr hProcess,IntPtr address, int size) | |
{ | |
MemoryRegion[] regions = GetMemoryRegions(hProcess, address, size); | |
for (int i = 0; i < regions.Length; i++) | |
{ | |
Console.WriteLine("0x{0} : {1} bytes, Readable: {2}", | |
regions[i].Address.ToString("X"), regions[i].Size, regions[i].IsReadable | |
); | |
} | |
} | |
[STAThread] | |
static void Main(string[] args) | |
{ | |
string path = "C:\\Test\\Lib.dll"; | |
//string path = typeof(object).Assembly.Location; | |
IntPtr hModule = LoadLibraryEx(path, IntPtr.Zero, LoadLibraryFlags.None); | |
if (hModule == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error()); | |
IntPtr hProcess = Process.GetCurrentProcess().Handle; | |
MODULEINFO mi = new MODULEINFO(); | |
bool res = GetModuleInformation(hProcess, hModule, out mi, (uint)Marshal.SizeOf(mi)); | |
if (res == false) throw new Win32Exception(Marshal.GetLastWin32Error()); | |
EnumMemoryRegions(hProcess, mi.lpBaseOfDll, (int)mi.SizeOfImage); | |
byte[] data = new byte[mi.SizeOfImage]; | |
IntPtr c; | |
int count_errors = 0; | |
for (int i = 0; i < data.Length; i++) | |
{ | |
byte b = 0; | |
res = ReadProcessMemory_Byte(hProcess, mi.lpBaseOfDll + i, out b, 1, out c); | |
if (res == false || c == IntPtr.Zero) count_errors++; | |
else data[i] = b; | |
} | |
Console.WriteLine(count_errors); | |
; | |
Console.ReadKey(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment