khchen / winim

Windows API, COM, and CLR Module for Nim

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Problem with DuplicateTokenEx

rafale0n opened this issue · comments

Hello, I am trying to write token duplication program using your library. I tried my best for few days but it seems like I cannot figure out the right values for DuplicateTokenEx. Here is what I have tried so far:

import winim
import strutils

proc toString(chars: openArray[WCHAR]): string =
    result = ""
    for c in chars:
        if cast[char](c) == '\0':
            break
        result.add(cast[char](c))

proc GetLsassPid(name: string): int =
    var 
        entry: PROCESSENTRY32
        hSnapshot: HANDLE

    entry.dwSize = cast[DWORD](sizeof(PROCESSENTRY32))
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
    defer: CloseHandle(hSnapshot)

    if Process32First(hSnapshot, addr entry):
        while Process32Next(hSnapshot, addr entry):
            if entry.szExeFile.toString == name:
                return int(entry.th32ProcessID)

    return 0

when isMainModule:
    var name: string = readLine(stdin)
    let processId: int = GetLsassPid(name)
    if not bool(processId):
        echo "[X] Unable to find: ", name, " process"
        quit(1)
    else:
        echo "Found: ", name, " with PID: ", processId

    var
      process_token: HANDLE
      duplicateTokenHandle: HANDLE

    var hProcess: HANDLE = OpenProcess(MAXIMUM_ALLOWED, false, cast[DWORD](processId));
    if not (bool)hProcess:
      raise newException(Exception, "Cannot open process ($1)" % [$GetLastError()])
    else:
      echo "Succeded opening handle on: ", name, " ", (bool)hProcess
      echo "    \\-- Handle ID is: ", hProcess  

    var getToken: HANDLE = OpenProcessToken(hProcess, MAXIMUM_ALLOWED, cast[PHANDLE](addr(process_token)))
    if not bool(getToken):
      raise newException(Exception, "Cannot query tokens ($1)" % [$GetLastError()])
    else:
      echo "Succeded opening process token: ", (bool)getToken
      echo "    \\-- Handle ID is: ", getToken  
      echo "    \\-- Process Token ID is: ", process_token  

    # This is failing with error 1346: Either a required impersonation level was not provided, or the provided impersonation level is invalid.
    var tokenDuplication = DuplicateTokenEx(process_token, cast[DWORD](MAXIMUM_ALLOWED), NULL, SecurityImpersonation, cast[TOKEN_TYPE](tokenPrimary), &duplicateTokenHandle)
    if not bool(tokenDuplication):
      raise newException(Exception, "Cannot duplicate tokens ($1)" % [$GetLastError()])
    else:
      echo "TokenDuplciation status: ", bool(tokenDuplication)

I was wondering if you could point me in the right direction. Thanks for all your work on winim.

I should mentioned, that I executed following program with Administrative privileges.

Never mind, problem solved with changing SecurityImpersonation to securityImpersonation :). Case closed.