Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WOW64 Stub for D/Invoke #50

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Fix for WOW64
am0nsec authored Jun 11, 2020
commit 977dd6b8172cee75ccb62740fd2f4ee49964defb
60 changes: 35 additions & 25 deletions SharpSploit/Execution/DynamicInvoke/Generic.cs
Original file line number Diff line number Diff line change
@@ -634,28 +634,19 @@ public static object CallMappedDLLModuleExport(PE.PE_META_DATA PEINFO, IntPtr Mo
/// <summary>
/// Read ntdll from disk, find/copy the appropriate syscall stub and free ntdll.
/// </summary>
/// <author>Ruben Boonen (@FuzzySec)</author>
/// <author>Ruben Boonen (@FuzzySec) and Paul Laîné (@am0nsec)</author>
/// <param name="FunctionName">The name of the function to search for (e.g. "NtAlertResumeThread").</param>
/// <returns>IntPtr, Syscall stub</returns>
public static IntPtr GetSyscallStub(string FunctionName)
{
// Verify process & architecture
bool isWOW64 = Native.NtQueryInformationProcessWow64Information((IntPtr)(-1));
if (IntPtr.Size == 4 && isWOW64)
{
throw new InvalidOperationException("Generating Syscall stubs is not supported for WOW64.");
}
public static IntPtr GetSyscallStub(string FunctionName) {

// Find the path for ntdll by looking at the currently loaded module
string NtdllPath = string.Empty;
ProcessModuleCollection ProcModules = Process.GetCurrentProcess().Modules;
foreach (ProcessModule Mod in ProcModules)
{
if (Mod.FileName.EndsWith("ntdll.dll", StringComparison.OrdinalIgnoreCase))
{
NtdllPath = Mod.FileName;
ProcessModule NativeModule = null;
foreach (ProcessModule _ in Process.GetCurrentProcess().Modules) {
if (_.FileName.EndsWith("ntdll.dll", StringComparison.OrdinalIgnoreCase)) {
NativeModule = _;
}
}
string NtdllPath = NativeModule.FileName;

// Alloc module into memory for parsing
IntPtr pModule = Execute.ManualMap.Map.AllocateFileToMemory(NtdllPath);
@@ -678,24 +669,21 @@ public static IntPtr GetSyscallStub(string FunctionName)
UInt32 BytesWritten = Native.NtWriteVirtualMemory((IntPtr)(-1), pImage, pModule, SizeOfHeaders);

// Write sections to memory
foreach (PE.IMAGE_SECTION_HEADER ish in PEINFO.Sections)
{
foreach (PE.IMAGE_SECTION_HEADER ish in PEINFO.Sections) {
// Calculate offsets
IntPtr pVirtualSectionBase = (IntPtr)((UInt64)pImage + ish.VirtualAddress);
IntPtr pRawSectionBase = (IntPtr)((UInt64)pModule + ish.PointerToRawData);

// Write data
BytesWritten = Native.NtWriteVirtualMemory((IntPtr)(-1), pVirtualSectionBase, pRawSectionBase, ish.SizeOfRawData);
if (BytesWritten != ish.SizeOfRawData)
{
if (BytesWritten != ish.SizeOfRawData) {
throw new InvalidOperationException("Failed to write to memory.");
}
}

// Get Ptr to function
IntPtr pFunc = GetExportAddress(pImage, FunctionName);
if (pFunc == IntPtr.Zero)
{
if (pFunc == IntPtr.Zero) {
throw new InvalidOperationException("Failed to resolve ntdll export.");
}

@@ -710,11 +698,33 @@ public static IntPtr GetSyscallStub(string FunctionName)

// Write call stub
BytesWritten = Native.NtWriteVirtualMemory((IntPtr)(-1), pCallStub, pFunc, 0x50);
if (BytesWritten != 0x50)
{
if (BytesWritten != 0x50) {
throw new InvalidOperationException("Failed to write to memory.");
}

// Verify process & architecture
bool isWOW64 = Native.NtQueryInformationProcessWow64Information((IntPtr)(-1));

// Create custom WOW64 stub
if (IntPtr.Size == 4 && isWOW64) {
IntPtr pNativeWow64Transition = GetExportAddress(NativeModule.BaseAddress, "Wow64Transition");
byte bRetValue = Marshal.ReadByte(pCallStub, 13);

// CALL DWORD PTR ntdll!Wow64SystemServiceCall
Marshal.WriteByte(pCallStub, 5, 0xff);
Marshal.WriteByte(pCallStub, 6, 0x15);
Marshal.WriteInt32(pCallStub, 7, pNativeWow64Transition.ToInt32());

// RET <val>
Marshal.WriteByte(pCallStub, 11, 0xc2);
Marshal.WriteByte(pCallStub, 12, bRetValue);
Marshal.WriteByte(pCallStub, 13, 0x00);

// NOP for alignment
Marshal.WriteByte(pCallStub, 14, 0x90);
Marshal.WriteByte(pCallStub, 15, 0x90);
}

// Change call stub permissions
Native.NtProtectVirtualMemory((IntPtr)(-1), ref pCallStub, ref RegionSize, Execute.Win32.WinNT.PAGE_EXECUTE_READ);

@@ -727,4 +737,4 @@ public static IntPtr GetSyscallStub(string FunctionName)
return pCallStub;
}
}
}
}