[native] RtlWow64CallFunction64

delphi package - easy access to kernel objects etc.
Nico Bendlin
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

[native] RtlWow64CallFunction64

Post by Nico Bendlin »

This question is not directly related to madKernel,
but the users on this board might be able to answer it :)

Does somebody know which parameters should be passed to RtlWow64CallFunction64 (32-bit) to succeed (call 64-bit RtlpQueryProcessDebugInformationFromWow64)?

Here is a Delphi snippet that tests the 'Nop' function:

Code: Select all

{$MINENUMSIZE 4}

type
  PWow64CallFunction64Function = ^TWow64CallFunction64;
  TWow64CallFunction64 = (
    Wow64CallFunction64Nop,                           // 0
    Wow64CallFunction64QueryProcessDebugInformation,  // 1
    MaxWow64CallFunction64
  );

function RtlWow64CallFunction64(AFunction: TWow64CallFunction64;
  ArgumentFlags, InputBufferLength: LongWord; InputBuffer: Pointer;
  OutputBufferLength: LongWord; OutputBuffer: Pointer;
  out ReturnValue: LongWord): LongInt; stdcall;
  external 'ntdll.dll' name 'RtlWow64CallFunction64';
  // or 'NtWow64CallFunction64'
  // or 'ZwWow64CallFunction64'

procedure TestWow64CallFunction64();
var
  Return: LongWord;
  Status: LongInt;
begin
  // Check DbgPrint outputs while executing RtlWow64CallFunction64.
  Return := $77777777;
  Status := RtlWow64CallFunction64(Wow64CallFunction64Nop, $22222222,
    $33333333, Pointer($44444444), $55555555, Pointer($66666666), Return);
  ShowMessage(
    'Status: $' + IntToHex(Status, 8) + #13#10 +   // $00000000
    'Return: $' + IntToHex(Return, 8));  // Should be $FFFFFFFF
end;
Best regards,
Nico Bendlin
Nico Bendlin
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

Post by Nico Bendlin »

OK, don't care...

The ArgumentFlags must be 0x400 (query CriticalSection owner) and the InputBuffer has the following format:

Code: Select all

type
  PWow64QueryProcessDebugInformationInput = ^TWow64QueryProcessDebugInformationInput;
  TWow64QueryProcessDebugInformationInput = record
    ProcessId  : LongWord;
    Flags      : LongWord;  // = ArgumentFlags
    Information: UInt64;    // PRtlDebugInformation32
  end;
(of course the CriticalSection handle inside the Debug Information must be valid on input)
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Interesting topic... ;)

Have you found a way to list the handles of a process in a 32bit process on a 64bit OS? NtQuerySystemInformation fails listing the handles when run in a 32bit process, unfortunately... :(
Nico Bendlin
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

Post by Nico Bendlin »

madshi wrote:Have you found a way to list the handles of a process in a 32bit process on a 64bit OS?
Not yet.
All attempts - that I have seen and/or tested - to call the native API function (as you already know, the native ntdll/wow64/wow64win/wow64cpu DLLs are loaded in the 32-bit process and accessible are via the native 64-bit TEB/PEB in segment GS) are not stable enough for production systems. For now, the "best workaround" is a native process that provides this information via IPC.

However, my time is limited. If you need some code snippets to get the 64-Bit TEB/PEB, enumerating the native modules, and getting native procedure addresses... drop me a note :]


Best regards,
Nico Bendlin
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Hi Nico,

I'd be happy to receive the code snippets/information you mentioned. I've not yet played around with this kind of 64bit stuff yet. I got madCodeHook working in 64bit without it. But I find it very interesting and it might help me in the future.

Thanks!
Nico Bendlin
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

Post by Nico Bendlin »

I uploaded some Delphi32 units to:
http://www.bendlins.de/nico/delphi/NcxWOW64.zip
(nothing mysterious inside, nearly all informations can be gathered with WinDDK+WinDbg)
Last edited by Nico Bendlin on Tue Nov 04, 2008 2:45 pm, edited 1 time in total.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Cool - thanks much! :)
Nico Bendlin
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

Post by Nico Bendlin »

The units have been ported to FPC (2.2.0, x86 and x86_64).
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Your code just saved me some digging during madCodeHook 3.0 (64bit) development. So thanks again for sharing it... :)

Do you know a way to create a remote thread for a 64bit process from within a 32bit (WOW) process? Can't seem to get that working...
Nico Bendlin
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

Post by Nico Bendlin »

madshi wrote:So thanks again for sharing it...
You're welcome.
madshi wrote:Do you know a way to create a remote thread for a 64bit process from within a 32bit (WOW) process?
I have no need for this feature, because all my remote-thread-targets are native processes (read: I never cared about it and never tried it). Sorry.
Nico Bendlin
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

Post by Nico Bendlin »

madshi wrote:Have you found a way to list the handles of a process in a 32bit process on a 64bit OS? NtQuerySystemInformation fails listing the handles when run in a 32bit process, unfortunately... :(
In the meantime I had some spare time to investigate it further...
There is a quite simple (of course undocumented) way to call native system calls (with up to 4 parameters) directly - without emulation.
Just send me an e-mail if you still need a workaround for NtQuerySystemInformation.
Nico Bendlin
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

Post by Nico Bendlin »

FYI: SystemExtendedHandleInformation is correctly emulated by WOW64 (at least on Windows Vista). However, the pointers are (of course) truncated to 32-bit (you need external 64-bit code or have to use Turbo Dispatching to retrieve the native pointers).

Code: Select all

//
// SystemExtendedHandleInformation (64)
//

type
  PSystemHandleTableEntryInfoEx32 = ^TSystemHandleTableEntryInfoEx32;
  TSystemHandleTableEntryInfoEx32 = packed record
    Object_              : TPtr32;  // 0x00
    UniqueProcessId      : UInt32;  // 0x04
    HandleValue          : UInt32;  // 0x08
    GrantedAccess        : UInt32;  // 0x0C
    CreatorBackTraceIndex: UInt16;  // 0x10
    ObjectTypeIndex      : UInt16;  // 0x12
    HandleAttributes     : UInt32;  // 0x14
    Reserved             : UInt32;  // 0x18
  end;                              // 0x1C

  PSystemHandleTableEntryInfoEx64 = ^TSystemHandleTableEntryInfoEx64;
  TSystemHandleTableEntryInfoEx64 = packed record
    Object_              : TPtr64;  // 0x00
    UniqueProcessId      : UInt64;  // 0x08
    HandleValue          : UInt64;  // 0x10
    GrantedAccess        : UInt32;  // 0x18
    CreatorBackTraceIndex: UInt16;  // 0x1C
    ObjectTypeIndex      : UInt16;  // 0x1E
    HandleAttributes     : UInt32;  // 0x20
    Reserved             : UInt32;  // 0x24
  end;                              // 0x28

  PSystemHandleTableEntryInfoEx = ^TSystemHandleTableEntryInfoEx;
  TSystemHandleTableEntryInfoEx = record
    Object_              : Pointer;
    UniqueProcessId      : TSizeT;
    HandleValue          : TSizeT;
    GrantedAccess        : UInt32;
    CreatorBackTraceIndex: UInt16;
    ObjectTypeIndex      : UInt16;
    HandleAttributes     : UInt32;
    Reserved             : UInt32;
  end;

type
  PSystemHandleInformationEx32 = ^TSystemHandleInformationEx32;
  TSystemHandleInformationEx32 = packed record
    NumberOfHandles: UInt32;                                                   // 0x00
    Reserved       : UInt32;                                                   // 0x04
    Handles        : array [AnySizeArray] of TSystemHandleTableEntryInfoEx32;  // 0x08
  end;                                                                         // 0x24

  PSystemHandleInformationEx64 = ^TSystemHandleInformationEx64;
  TSystemHandleInformationEx64 = packed record
    NumberOfHandles: UInt64;                                                   // 0x00
    Reserved       : UInt64;                                                   // 0x08
    Handles        : array [AnySizeArray] of TSystemHandleTableEntryInfoEx64;  // 0x10
  end;                                                                         // 0x38

  PSystemHandleInformationEx = ^TSystemHandleInformationEx;
  TSystemHandleInformationEx = record
    NumberOfHandles: TSizeT;
    Reserved       : TSizeT;
    Handles        : array [AnySizeArray] of TSystemHandleTableEntryInfoEx;
  end;
ps: TSizeT is ULONG_PTR and AnySizeArray is defined as:

Code: Select all

type
  AnySizeArray = (AnySizeArrayLow{ = 0, AnySizeArrayHigh = NumberOfXxx - 1});
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Thank you!

What is "turbo dispatching"?
Nico Bendlin
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

Post by Nico Bendlin »

madshi wrote:What is "turbo dispatching"?
Have a look at NcxNtApi.NtWow64QueryNativeSystemInformation in the NcxWOW64 project (link above).

edit: I'll update the workaround for NtQuerySystemInformation(SystemHandleInformation) in the NcxWOW64 project this weekend.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Ah, thanks!
Post Reply