1

I've been translating a powershell script into python, mostly to learn how to do it. I've gotten stuck on these lines here:

$lpTargetHandle = [IntPtr]::Zero
$CallResult = [Kernel32]::DuplicateHandle(
              $ProcessInfo.hProcess, 0x4,
              [Kernel32]::GetCurrentProcess(),
              [ref]$lpTargetHandle, 0, $false, 0x00000002)

echo $lpTargetHandle

This is what I have in python:

lpTargetHandle = HANDLE()
CallResult = kernel32.DuplicateHandle(ProcessInfo.hProcess, 0x4,
             kernel32.GetCurrentProcess(),byref(lpTargetHandle), 0, False, 0x00000002)

print(lpTargetHandle)

Here is the output I am getting:

>>> lpTargetHandle = HANDLE()
>>> CallResult = kernel32.DuplicateHandle(ProcessInfo.hProcess, 0x4, kernel32.GetCurrentProcess(),byref(lpTargetHandle), 0, False, 0x00000002)
>>>
>>> print(lpTargetHandle)
c_void_p(None)
>>> lpTargetHandle.value
>>> type(lpTargetHandle.value)
<type 'NoneType'>

What is supposed to happen, is the lpTargetHandle pointer should return back the Thread ID number, but I'm just getting Nones. I've seen that IntPtr's are handled in IronPython, but my goal is to learn vanilla python. My includes are:
from ctypes import * from ctypes.wintypes import *

How do you duplicate an IntPtr in normal Python (CPython)?

Specifically, how do you write $var = [IntPtr]::Zero in python?

I've also tried this, but it did not work:

tid = POINTER(c_int)
num = c_int(0)
addr = addressof(num)
ptr = cast(addr,tid)
CallResult = = kernel32.DuplicateHandle(ProcessInfo.hProcess, 0x4,
         kernel32.GetCurrentProcess(),ptr, 0, False, 0x00000002)

Here is a pastebin of the full python code I have
Here is a pastebin of the powershell function I am working on duplicating.

Edit: Here is the relevant function that I am trying to duplicate in C

 HANDLE hThread = nullptr;  
 DuplicateHandle(procInfo.hProcess, (HANDLE)0x4, 
     GetCurrentProcess(), &hThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
 return hThread;
MikeTGW
  • 395
  • 2
  • 10
  • Where/how are you defining `ProcessInfo.hProcess` in the Python examples? – Kev Jul 10 '16 at 01:25
  • The full code is a little lengthy to put in the post: http://pastebin.com/GzftL7Rh – MikeTGW Jul 10 '16 at 02:41
  • 1
    Can you explain a bit more about what you're trying to do. What's the magic number `0x4`? – Kev Jul 10 '16 at 03:25
  • @Kev It's probably [this](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724251(v=vs.85).aspx). – Bacon Bits Jul 10 '16 at 03:29
  • @BaconBits - yeah I got that, but was wondering what the `0x4` handle number represented passed in `hSourceHandle` – Kev Jul 10 '16 at 03:32
  • I think the problem might be that when you create the powershell process it terminates right away. When I watch task manager I don't see a new `powershell.exe` or `cmd.exe` process being created and staying resident in memory. – Kev Jul 10 '16 at 03:35
  • Per your pastebin code, when you call `advapi32.CreateProcessWithLogonW()` check to see if `CallResult` is non-zero or not. If it's zero then the call failed, if so then make a call to `GetLastError()` and let us know what the value is. It'll be one of these error codes: https://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx I suspect `CreateProcessWithLogonW` is probably failing. – Kev Jul 10 '16 at 04:28
  • No failure there. Both CallResults are returning 0. – MikeTGW Jul 10 '16 at 04:54
  • 1
    That means something is broken. "If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError." - https://msdn.microsoft.com/en-us/library/windows/desktop/ms682431(v=vs.85).aspx – Kev Jul 10 '16 at 05:06

1 Answers1

1

According to the Windows documentation, this is the function prototype:

BOOL WINAPI DuplicateHandle(
  _In_  HANDLE   hSourceProcessHandle,
  _In_  HANDLE   hSourceHandle,
  _In_  HANDLE   hTargetProcessHandle,
  _Out_ LPHANDLE lpTargetHandle,
  _In_  DWORD    dwDesiredAccess,
  _In_  BOOL     bInheritHandle,
  _In_  DWORD    dwOptions
);

The equivalent in python for the LPHANDLE type would be wintypes.LPHANDLE

Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
  • Thats what the HANDLE() fills (or any 4 bytes really, I've even tried putting a cast((c_byte*4)(),pointer(c_int)) style pointer. The problem I'm having is reading the (memory location)? (value)? of lpTargetHandle after I call DuplicateHandle. – MikeTGW Jul 10 '16 at 15:56
  • @MikeTGW Here is a ready answer for your DuplicateHandle function: http://stackoverflow.com/a/29737399/2230844 – denfromufa Aug 18 '16 at 04:12