Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save hypeartist/d52ef1196e2f19a7b36367d95a123c3a to your computer and use it in GitHub Desktop.
Save hypeartist/d52ef1196e2f19a7b36367d95a123c3a to your computer and use it in GitHub Desktop.
Get PEB64 without using P/Invoke
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