Sign in to follow this  
Followers 0
tom13

WinAPI OpenProcess returns 0

24 posts in this topic

#1 ·  Posted (edited)

I am trying to open a handle to a process, like so:

#RequireAdmin
#Include <WinAPI.au3>

$processName = "someprocess.exe"
$processId = ProcessExists($processName)
$processHandle = _WinAPI_OpenProcess(0x1f0fff, 0, $processId, True)
MsgBox(4096, "Test", @error & " with " & $processHandle & " and " & $processId, 10)

This works fine when I change processName to eg. chrome.exe. However, when I set it to an other specific process, processId is still valid, @error is still 0 but $processHandle becomes 0 instead of a valid process handle.

When I set debug privileges to False, nothing seems to change.

How come the process handle would return 0 without setting @error to 1 for a certain process while not for others?

I am running this on Windows 7.

Edited by tom13

Share this post


Link to post
Share on other sites



#3 ·  Posted (edited)

Access rights.

Could please attempt to give a slightly more intelligent answer that goes further than the message's subject.

Any such attempt would be highly appreciated.

Eg.:

- what would be the correct access right setting?

- why is the current one not working?

PS. I did try other access rights and also searched for the subject, but it didn't seem to help.

Edited by tom13

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

This is your question:

How come the process handle would return 0 without setting @error to 1 for a certain process while not for others?

And so the answer is "Access rights". Were my answer any more intelligent, it would grow a conscience and subsequently take over the world in a napalm blanketed robot invasion.

But because I am such a nice guy, I'll answer your other question too. (Not the last one though)

- what would be the correct access right setting?

It depends entirely on what you want to do, of course. You could have guessed this and then promptly informed the rest of us what you are trying to achieve. Then we would be able to give you a good idea of which flag you should be using when opening the process.

But because you didn't (maybe something to do with intelligence), I'll just guess what you are trying to do instead.... So: You are trying to get the number of GDI objects that are started under the SYSTEM account. Your code worked under Windows XP but it is failing under Vista and 7 because OpenProcess returns 0. Here is someone that asked the same thing and I answered his question because he provided a good enough background: http://stackoverflow.com/questions/5117739/getgdiobjects-windowsvista

Edited by Manadar

Share this post


Link to post
Share on other sites

This is your question:

And so the answer is "Access rights". Were my answer any more intelligent, it would grow a conscience and subsequently take over the world in a napalm blanketed robot invasion.

But because I am such a nice guy, I'll answer your other question too. (Not the last one though)

It depends entirely on what you want to do, of course. You could have guessed this and then promptly informed the rest of us what you are trying to achieve. Then we would be able to give you a good idea of which flag you should be using when opening the process.

But because you didn't (maybe something to do with intelligence), I'll just guess what you are trying to do instead.... So: You are trying to get the number of GDI objects that are started under the SYSTEM account. Your code worked under Windows XP but it is failing under Vista and 7 because OpenProcess returns 0. Here is someone that asked the same thing and I answered his question because he provided a good enough background: http://stackoverflow.com/questions/5117739/getgdiobjects-windowsvista

That is one very special way of answering that question.

I have told you exactly what I am trying to do. I am trying to open a handle to a process, nothing else.

I am not actually at the process where I use this handle yet, which you assumed.

In any way, the handle that is returned is invalid while @error is not set to 1 as I have said in my original question. This does not make sense to me.

The only valid point you made is that I said nothing about the process involved, which is because I did not know that such thing was related -- the process is just a typical application (nothing system related or anything).

Share this post


Link to post
Share on other sites

Thanks, and that's not a question. Try as described in my previous post:

Const $PROCESS_QUERY_LIMITED_INFORMATION  = 0x1000

If you are anal about why things are happening on the AutoIt inside, then here is the code responsible for returning values assuming that debug priviledges are not enabled:

Local $aResult = DllCall("kernel32.dll", "handle", "OpenProcess", "dword", $iAccess, "bool", $fInherit, "dword", $iProcessID)
If @error Then Return SetError(@error, @extended, 0)
If $aResult[0] Then Return $aResult[0]
If Not $fDebugPriv Then Return 0

Share this post


Link to post
Share on other sites

Thanks, and that's not a question. Try as described in my previous post:

Const $PROCESS_QUERY_LIMITED_INFORMATION  = 0x1000

If you are anal about why things are happening on the AutoIt inside, then here is the code responsible for returning values assuming that debug priviledges are not enabled:

Local $aResult = DllCall("kernel32.dll", "handle", "OpenProcess", "dword", $iAccess, "bool", $fInherit, "dword", $iProcessID)
If @error Then Return SetError(@error, @extended, 0)
If $aResult[0] Then Return $aResult[0]
If Not $fDebugPriv Then Return 0

Thanks for trying to help.

Unfortunately I am still getting a handle of 0 when executing the following code, the processId is valid (tested):

$processHandle = _WinAPI_OpenProcess(0x1000, False, $processId)

Share this post


Link to post
Share on other sites

There are strict rules about what and who can do something or anything with processes on newer windows systems. It's all explained at MSDN's OpenProcess function description page.

There are no mysteries.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

There are strict rules about what and who can do something or anything with processes on newer windows systems. It's all explained at MSDN's OpenProcess function description page.

There are no mysteries.

Well, it's great to hear that there are no mysteries and all, but I did read the MSDN and cannot find myself a solution (which explains why I would ask the question here).

Share this post


Link to post
Share on other sites

Well, it's great to hear that there are no mysteries and all, but I did read the MSDN and cannot find myself a solution (which explains why I would ask the question here).

In that case the most obvious (since you like pointing the obvious) thing to do is to show the exact code you run for others to test.

Of course that "someprocess.exe" will be something that's normally run on normal machines by normal users.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

In that case the most obvious (since you like pointing the obvious) thing to do is to show the exact code you run for others to test.

Of course that "someprocess.exe" will be something that's normally run on normal machines by normal users.

Hi Trancexx,

The exact code I run is in my original question. I did not paste a snippet.

I will repeat it:

#RequireAdmin
#Include <WinAPI.au3>

$processName = "someprocess.exe"
$processId = ProcessExists($processName)
$processHandle = _WinAPI_OpenProcess(0x1f0fff, 0, $processId, True)
MsgBox(4096, "Test", @error & " with " & $processHandle & " and " & $processId, 1)

It works for some processes (like chrome.exe) but returns a handle of 0 for others (just non-system applications, aka normal ones), as I already mentioned.

Share this post


Link to post
Share on other sites

Hi Trancexx,

The exact code I run is in my original question. I did not paste a snippet.

I will repeat it:

#RequireAdmin
#Include <WinAPI.au3>

$processName = "someprocess.exe"
$processId = ProcessExists($processName)
$processHandle = _WinAPI_OpenProcess(0x1f0fff, 0, $processId, True)
MsgBox(4096, "Test", @error & " with " & $processHandle & " and " & $processId, 1)

It works for some processes (like chrome.exe) but returns a handle of 0 for others (just non-system applications, aka normal ones), as I already mentioned.

What others? That's the whole thing. What others?

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

It's a java runtime environment process.

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

It's a java runtime environment process.

To resolve one mystery, what do you get when you run this:

#RequireAdmin
#Include <WinAPI.au3>

$processName = "someprocess.exe"
$processId = ProcessExists($processName)
$processHandle = _WinAPI_OpenProcess(0x1000, 0, $processId, True)
MsgBox(4096, "Test", @error & " with " & $processHandle & " and " & $processId)

Fair and honest answer, please.

As for the other thing, enable more privileges to your process. Enable all, for example and then remove redundant.

I'll show you how to do it if you would have troubles.

Edited by trancexx

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Eh, I already told you what it returns with 0x1000, exactly the same. Aka error 0, handle 0 and process id 4217 (or something, cannot check at the moment).

My original access setting is already to allow everything.

Share this post


Link to post
Share on other sites

Eh, I already told you what it returns with 0x1000, exactly the same. Aka error 0, handle 0 and process id 4217 (or something, cannot check at the moment).

No, you haven't. Just run the freaking code and post the result when you would be able to.

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

No, you haven't. Just run the freaking code and post the result when you would be able to.

I'm afraid you did not read the entire thread.

I did run exactly that code, and I also said that it returned the same results.

Just to please you I did it once again, and the results are the same.

This time it returned:

0 with 0 and 3060, like I said earlier.

Edit: although I did not explicitly mention that in the specific 0x1000 case I also tested it with the debug privileges enabled, but this is the case.

Edited by tom13

Share this post


Link to post
Share on other sites

I'm afraid you did not read the entire thread.

I did run exactly that code, and I also said that it returned the same results.

Just to please you I did it once again, and the results are the same.

This time it returned:

0 with 0 and 3060, like I said earlier.

Edit: although I did not explicitly mention that in the specific 0x1000 case I also tested it with the debug privileges enabled, but this is the case.

I don't care about your fears.

Did you try enabling all of the privileges and then running the code?


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

I'm able to reproduce this on server 2008 as well (running as admin).

Originally, there were about 50 of 80 processes that returned 0.

Changing to 0x1000 reduced this to 6 (mostly system processes).

To get the rest I used this:

#RequireAdmin
#Include <WinAPI.au3>
setprivilege("sedebugprivilege", 1)
$procs = ProcessList()
$count = 0
for $a =1 to $procs[0][0]
    $processId = ProcessExists($procs[$a][0])
    $processHandle = _WinAPI_OpenProcess(0x1000, 0, $processId, True)
    if ($processHandle=0) then $count+=1
Next
MsgBox(0,"",$count)

Func setprivilege($PRIVILEGE, $BENABLE)
    Const $MY_TOKEN_ADJUST_PRIVILEGES = 32
    Const $MY_TOKEN_QUERY = 8
    Const $MY_SE_PRIVILEGE_ENABLED = 2
    Local $HTOKEN, $SP_AUXRET, $SP_RET, $HCURRPROCESS, $NTOKENS, $NTOKENINDEX, $PRIV
    $NTOKENS = 1
    $LUID = DllStructCreate("dword;int")
    If IsArray($PRIVILEGE) Then $NTOKENS = UBound($PRIVILEGE)
    $TOKEN_PRIVILEGES = DllStructCreate("dword;dword[" & (3 * $NTOKENS) & "]")
    $NEWTOKEN_PRIVILEGES = DllStructCreate("dword;dword[" & (3 * $NTOKENS) & "]")
    $HCURRPROCESS = DllCall("kernel32.dll", "hwnd", "GetCurrentProcess")
    $SP_AUXRET = DllCall("advapi32.dll", "int", "OpenProcessToken", "hwnd", $HCURRPROCESS[0], "int", BitOR($MY_TOKEN_ADJUST_PRIVILEGES, $MY_TOKEN_QUERY), "int*", 0)
    If $SP_AUXRET[0] Then
    $HTOKEN = $SP_AUXRET[3]
    DllStructSetData($TOKEN_PRIVILEGES, 1, 1)
    $NTOKENINDEX = 1
    While $NTOKENINDEX <= $NTOKENS
    If IsArray($PRIVILEGE) Then
    $PRIV = $PRIVILEGE[$NTOKENINDEX - 1]
    Else
    $PRIV = $PRIVILEGE
    EndIf
    $RET = DllCall("advapi32.dll", "int", "LookupPrivilegeValue", "str", "", "str", $PRIV, "ptr", DllStructGetPtr($LUID))
    If $RET[0] Then
    If $BENABLE Then
    DllStructSetData($TOKEN_PRIVILEGES, 2, $MY_SE_PRIVILEGE_ENABLED, (3 * $NTOKENINDEX))
    Else
    DllStructSetData($TOKEN_PRIVILEGES, 2, 0, (3 * $NTOKENINDEX))
    EndIf
    DllStructSetData($TOKEN_PRIVILEGES, 2, DllStructGetData($LUID, 1), (3 * ($NTOKENINDEX - 1)) + 1)
    DllStructSetData($TOKEN_PRIVILEGES, 2, DllStructGetData($LUID, 2), (3 * ($NTOKENINDEX - 1)) + 2)
    DllStructSetData($LUID, 1, 0)
    DllStructSetData($LUID, 2, 0)
    EndIf
    $NTOKENINDEX += 1
    WEnd
    $RET = DllCall("advapi32.dll", "int", "AdjustTokenPrivileges", "hwnd", $HTOKEN, "int", 0, "ptr", DllStructGetPtr($TOKEN_PRIVILEGES), "int", DllStructGetSize($NEWTOKEN_PRIVILEGES), "ptr", DllStructGetPtr($NEWTOKEN_PRIVILEGES), "int*", 0)
    $F = DllCall("kernel32.dll", "int", "GetLastError")
    EndIf
    $NEWTOKEN_PRIVILEGES = 0
    $TOKEN_PRIVILEGES = 0
    $LUID = 0
    If $SP_AUXRET[0] = 0 Then Return 0
    $SP_AUXRET = DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $HTOKEN)
    If Not $RET[0] And Not $SP_AUXRET[0] Then Return 0
    Return $RET[0]
EndFunc ;==>SETPRIVILEGE

SetPrivilege was taken from nomads memory UDF.

I'm not sure the full implications of doing it this way but it worked for me.

Share this post


Link to post
Share on other sites

I don't care about your fears.

Did you try enabling all of the privileges and then running the code?

Yes of course, that is actually the access code in my original post.

I'm able to reproduce this on server 2008 as well (running as admin).

Originally, there were about 50 of 80 processes that returned 0.

Changing to 0x1000 reduced this to 6 (mostly system processes).

To get the rest I used this:

#RequireAdmin
#Include <WinAPI.au3>
setprivilege("sedebugprivilege", 1)
$procs = ProcessList()
$count = 0
for $a =1 to $procs[0][0]
    $processId = ProcessExists($procs[$a][0])
    $processHandle = _WinAPI_OpenProcess(0x1000, 0, $processId, True)
    if ($processHandle=0) then $count+=1
Next
MsgBox(0,"",$count)

Func setprivilege($PRIVILEGE, $BENABLE)
    Const $MY_TOKEN_ADJUST_PRIVILEGES = 32
    Const $MY_TOKEN_QUERY = 8
    Const $MY_SE_PRIVILEGE_ENABLED = 2
    Local $HTOKEN, $SP_AUXRET, $SP_RET, $HCURRPROCESS, $NTOKENS, $NTOKENINDEX, $PRIV
    $NTOKENS = 1
    $LUID = DllStructCreate("dword;int")
    If IsArray($PRIVILEGE) Then $NTOKENS = UBound($PRIVILEGE)
    $TOKEN_PRIVILEGES = DllStructCreate("dword;dword[" & (3 * $NTOKENS) & "]")
    $NEWTOKEN_PRIVILEGES = DllStructCreate("dword;dword[" & (3 * $NTOKENS) & "]")
    $HCURRPROCESS = DllCall("kernel32.dll", "hwnd", "GetCurrentProcess")
    $SP_AUXRET = DllCall("advapi32.dll", "int", "OpenProcessToken", "hwnd", $HCURRPROCESS[0], "int", BitOR($MY_TOKEN_ADJUST_PRIVILEGES, $MY_TOKEN_QUERY), "int*", 0)
    If $SP_AUXRET[0] Then
    $HTOKEN = $SP_AUXRET[3]
    DllStructSetData($TOKEN_PRIVILEGES, 1, 1)
    $NTOKENINDEX = 1
    While $NTOKENINDEX <= $NTOKENS
    If IsArray($PRIVILEGE) Then
    $PRIV = $PRIVILEGE[$NTOKENINDEX - 1]
    Else
    $PRIV = $PRIVILEGE
    EndIf
    $RET = DllCall("advapi32.dll", "int", "LookupPrivilegeValue", "str", "", "str", $PRIV, "ptr", DllStructGetPtr($LUID))
    If $RET[0] Then
    If $BENABLE Then
    DllStructSetData($TOKEN_PRIVILEGES, 2, $MY_SE_PRIVILEGE_ENABLED, (3 * $NTOKENINDEX))
    Else
    DllStructSetData($TOKEN_PRIVILEGES, 2, 0, (3 * $NTOKENINDEX))
    EndIf
    DllStructSetData($TOKEN_PRIVILEGES, 2, DllStructGetData($LUID, 1), (3 * ($NTOKENINDEX - 1)) + 1)
    DllStructSetData($TOKEN_PRIVILEGES, 2, DllStructGetData($LUID, 2), (3 * ($NTOKENINDEX - 1)) + 2)
    DllStructSetData($LUID, 1, 0)
    DllStructSetData($LUID, 2, 0)
    EndIf
    $NTOKENINDEX += 1
    WEnd
    $RET = DllCall("advapi32.dll", "int", "AdjustTokenPrivileges", "hwnd", $HTOKEN, "int", 0, "ptr", DllStructGetPtr($TOKEN_PRIVILEGES), "int", DllStructGetSize($NEWTOKEN_PRIVILEGES), "ptr", DllStructGetPtr($NEWTOKEN_PRIVILEGES), "int*", 0)
    $F = DllCall("kernel32.dll", "int", "GetLastError")
    EndIf
    $NEWTOKEN_PRIVILEGES = 0
    $TOKEN_PRIVILEGES = 0
    $LUID = 0
    If $SP_AUXRET[0] = 0 Then Return 0
    $SP_AUXRET = DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $HTOKEN)
    If Not $RET[0] And Not $SP_AUXRET[0] Then Return 0
    Return $RET[0]
EndFunc ;==>SETPRIVILEGE

SetPrivilege was taken from nomads memory UDF.

I'm not sure the full implications of doing it this way but it worked for me.

Great, someone who believes that I am capable of running the 5 lines of code correctly. :)

This indeed fixed it. I am not sure why the inbuild debug privileges does not seem to function properly, but this certainly solves it.

Thanks a lot !

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0