Created
December 10, 2020 03:59
-
-
Save invokethreatguy/5fa79de2dff636c7c380983514e3bae3 to your computer and use it in GitHub Desktop.
Get PEB64 without using P/Invoke
This file contains hidden or 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.Reflection; | |
using System.Runtime.CompilerServices; | |
using System.Text; | |
namespace ConsoleApp1 | |
{ | |
unsafe class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var methodHandle = typeof(Program).GetMethod(nameof(GetPebPtr), BindingFlags.Static | BindingFlags.NonPublic).MethodHandle; | |
RuntimeHelpers.PrepareMethod(methodHandle); | |
var methodPointer = methodHandle.GetFunctionPointer().ToPointer(); | |
var patchStub = stackalloc byte[] | |
{ | |
0x48, 0x31, 0xC0, // xor rax,rax | |
0x65, 0x48, 0xA1, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rax, gs:[60h] | |
0xC3 // ret | |
}; | |
var jitJmpToPreStubOffset = *(int*)((byte*)methodPointer + 1); | |
var patchAddress = (byte*)methodPointer + 5 /*jmp offset counted starting from next instruction, so skip jmp 5-bytes sequence*/ + jitJmpToPreStubOffset; | |
Unsafe.CopyBlock(patchAddress, patchStub, 15); // copy patch stub bytes to the begining of method's pre-stub (there must be enough space for that in case of using as method body "throw new NotImplementedException()") | |
var pPeb = GetPebPtr(); | |
var peb = *(PEB*)pPeb; | |
var pPebEntry = (LDR_DATA_TABLE_ENTRY*)peb.Ldr->InMemoryOrderModuleList.Flink; | |
var pebEntry = *pPebEntry; | |
var pHeadEntry = pPebEntry; | |
while (true) | |
{ | |
pPebEntry = (LDR_DATA_TABLE_ENTRY*)pebEntry.InMemoryOrderLinks.Flink; //pebEntry.InMemoryOrderLinks.Flink.ReinterpretAs<LDR_DATA_TABLE_ENTRY>(); | |
pebEntry = *pPebEntry; | |
if (pPebEntry != pHeadEntry && pebEntry.DllBase != IntPtr.Zero) | |
{ | |
var dllName = Encoding.Unicode.GetString((byte*)pebEntry.BaseDllName.Buffer, pebEntry.BaseDllName.Length); | |
var dllImageBase = pebEntry.DllBase; | |
var dllPath = Encoding.Unicode.GetString((byte*)pebEntry.FullDllName.Buffer, pebEntry.FullDllName.Length); | |
continue; | |
} | |
break; | |
} | |
Console.ReadKey(); | |
} | |
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] | |
private static IntPtr GetPebPtr() | |
{ | |
throw new NotImplementedException(); | |
} | |
} | |
unsafe struct LIST_ENTRY | |
{ | |
public byte* Flink; | |
public byte* Blink; | |
} | |
struct PEB_LDR_DATA | |
{ | |
private byte Reserved1a; | |
private byte Reserved1b; | |
private byte Reserved1c; | |
private byte Reserved1d; | |
private byte Reserved1e; | |
private byte Reserved1f; | |
private byte Reserved1g; | |
private byte Reserved1h; | |
private IntPtr Reserved2a; | |
private IntPtr Reserved2b; | |
private IntPtr Reserved2c; | |
public LIST_ENTRY InMemoryOrderModuleList; | |
} | |
unsafe struct PEB | |
{ | |
private byte Reserved1a; | |
private byte Reserved1b; | |
private byte BeingDebugged; | |
private byte Reserved2a; | |
private byte Reserved2b; | |
private IntPtr Reserved3a; | |
private IntPtr Reserved3b; | |
public PEB_LDR_DATA* Ldr; | |
} | |
unsafe struct UNICODE_STRING | |
{ | |
public ushort Length; | |
public ushort MaximumLength; | |
public char* Buffer; | |
} | |
struct LDR_DATA_TABLE_ENTRY | |
{ | |
public LIST_ENTRY InMemoryOrderLinks; | |
public LIST_ENTRY InInitializationOrderList; | |
public IntPtr DllBase; | |
public IntPtr EntryPoint; | |
private IntPtr Reserved3; | |
public UNICODE_STRING FullDllName; | |
public UNICODE_STRING BaseDllName; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment