[c#(4.5)] Process Handle varies from time to time menu

Shout-Out

User Tag List

Results 1 to 14 of 14
  1. #1
    Threk's Avatar Member
    Reputation
    1
    Join Date
    Oct 2010
    Posts
    23
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [c#(4.5)] Process Handle varies from time to time

    Hey guys,
    I have a simple piece of code which works perfect but the value varies from time to time (which should normally not happen).

    I get the Handle of an Process via the Process.Handle property.
    The Problem is (as stated above) that it varies from time to time (the same instance of the same process).

    It also differs from the Handle that I get when I use OpenProcess(the native/unmanaged function).

    Signature of the OpenProcess function:
    Code:
            [DllImport("kernel32.dll")]
            internal static extern SafeMemoryHandle OpenProcess(
                ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
    Handle from Process.Handle: 532
    Handle from OpenProcess: 528

    Both are IntPtr's.
    There is always a difference of 4.
    I really have no Idea where the Problem is.

    The Handle's are both valid, but why is there a difference of 4 ?
    Last edited by Threk; 12-31-2012 at 10:36 AM.

    [c#(4.5)] Process Handle varies from time to time
  2. #2
    abuckau907's Avatar Active Member
    Reputation
    49
    Join Date
    May 2009
    Posts
    225
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm probably wrong, but I think it's something along the lines of....

    how does each process get it's pid? well..from looking at the task manager, they generally range 0-5000 or whatever..anyway, it's a relatively low range. Why not use the whole Int32 and go up to 2 million or whatever? well...I think it's because Windows(R) keeps track of the handles very careful (scratch that. I know it does), so it's the one who assignes pID when a process starts. <---The OpenProcess() handle is different, because OpenProcess() is basically saying "Windows(R) may I please have ANOTHER handle which is connected to this process" -- the fact that the ID is 4 apart..not really sure. Either coincidence, or something to do with how Windows manages/recycles pid's.


    How do you know the process.id varies? I not quite sure what you mean. Like...on start-up you find the pid, then a few minutes later it's different? I don't think* that's possible (unless you re-start the app ofc) so..are you just keeping a reference to said process like...
    Process _targetProc = ******

    and later when you check _targetProc.Id, the value changes?!?

    or do you mean, on startup, the id is different each time? Because this is normal as described in the Windows(R) part above.


    I just looked at my task manager, never realized --> most of the pID are like.. at least* 30-40 apart from eachother..
    Why is there this space? why doesn't Windows(R) just hand them out in sequential order?
    The Answer: It's something to do with how windows(R) itself manages processes. I think it makes them 40 apart (or whatever) to save space for in-case the Handle gets duplicated...apparently windows decided to keep their values close, not sure the technical reason tho. Something to do with how "windows manages processes/pid and copying it". Windows internals.

    edit: If you wanted a technical answer, sorry. But because you didn't know OpenProcess() was *supposed* to return a different handle, I assume mine is close enough to help?
    apparently OpenProcess() (ie. windows) is designed to keep 'related' pid into a small group (ie. range of values)..not sure of the technical reason tho, I'm sure there are several. -stuff to do with creating/copying/pausing/stopping processes probably, it's a complex subject. Keeping related pid in a specific range apparently makes it easier for windows to manage processes. or it's a coincidence, and you just need to run a bunch of apps *after* starting the target process but *before* calling OpenProcess() to get a new handle. <-- test this maybe, see if it's still 4 apart? if so, it's by Windows' doing.


    Q How are you keeping track of pId and when do you know it's changed?

    Like...
    do you store a reference to the process. Or just declare as Int32 and save it there or ?
    Maybe post a snippet of code and I can try to comment more.



    edit* hypothetically I've never started enough new processes to get to a pid of 2 million :P i probably keep it under 30..5 of which have gui, so, maybe windows pId does go higher than 5000 or whatever, but, obviously windows(r) has to manage them in *some* fashion.

    final-edit: if the original "space between pId" is only 30-40, at 4 bytes each that's only 10 copies of the handle? so..if more than 10 copies are made, the pID's will either be in 2 distinct ranges, or, you can't have more than 10 copies?!? There is a flaw in my logic, someone with more knowledge care to comment?

    final-edit#2 lol: just started a bunch of apps --> some of their pId were much less than 30 apart, so, I think the fact that it was 4 apart is just coincidence, and the handle returned by OpenProcess() is in no way guaranteed to be close to the original process handle. previous statements retracted. ?
    Last edited by abuckau907; 12-31-2012 at 05:07 PM.
    Some things that can be counted, don't matter. And some things that matter, can't be counted.

  3. #3
    Threk's Avatar Member
    Reputation
    1
    Join Date
    Oct 2010
    Posts
    23
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by abuckau907 View Post
    I'm probably wrong, but I think it's something along the lines of....

    how does each process get it's pid? well..from looking at the task manager, they generally range 0-5000 or whatever..anyway, it's a relatively low range. Why not use the whole Int32 and go up to 2 million or whatever? well...I think it's because Windows(R) keeps track of the handles very careful (scratch that. I know it does), so it's the one who assignes pID when a process starts. <---The OpenProcess() handle is different, because OpenProcess() is basically saying "Windows(R) may I please have ANOTHER handle which is connected to this process" -- the fact that the ID is 4 apart..not really sure. Either coincidence, or something to do with how Windows manages/recycles pid's.


    How do you know the process.id varies? I not quite sure what you mean. Like...on start-up you find the pid, then a few minutes later it's different? I don't think* that's possible (unless you re-start the app ofc) so..are you just keeping a reference to said process like...
    Process _targetProc = ******

    and later when you check _targetProc.Id, the value changes?!?

    or do you mean, on startup, the id is different each time? Because this is normal as described in the Windows(R) part above.


    I just looked at my task manager, never realized --> most of the pID are like.. at least* 30-40 apart from eachother..
    Why is there this space? why doesn't Windows(R) just hand them out in sequential order?
    The Answer: It's something to do with how windows(R) itself manages processes. I think it makes them 40 apart (or whatever) to save space for in-case the Handle gets duplicated...apparently windows decided to keep their values close, not sure the technical reason tho. Something to do with how "windows manages processes/pid and copying it". Windows internals.

    edit: If you wanted a technical answer, sorry. But because you didn't know OpenProcess() was *supposed* to return a different handle, I assume mine is close enough to help?
    apparently OpenProcess() (ie. windows) is designed to keep 'related' pid into a small group (ie. range of values)..not sure of the technical reason tho, I'm sure there are several. -stuff to do with creating/copying/pausing/stopping processes probably, it's a complex subject. Keeping related pid in a specific range apparently makes it easier for windows to manage processes. or it's a coincidence, and you just need to run a bunch of apps *after* starting the target process but *before* calling OpenProcess() to get a new handle. <-- test this maybe, see if it's still 4 apart? if so, it's by Windows' doing.


    Q How are you keeping track of pId and when do you know it's changed?

    Like...
    do you store a reference to the process. Or just declare as Int32 and save it there or ?
    Maybe post a snippet of code and I can try to comment more.



    edit* hypothetically I've never started enough new processes to get to a pid of 2 million :P i probably keep it under 30..5 of which have gui, so, maybe windows pId does go higher than 5000 or whatever, but, obviously windows(r) has to manage them in *some* fashion.

    final-edit: if the original "space between pId" is only 30-40, at 4 bytes each that's only 10 copies of the handle? so..if more than 10 copies are made, the pID's will either be in 2 distinct ranges, or, you can't have more than 10 copies?!? There is a flaw in my logic, someone with more knowledge care to comment?

    final-edit#2 lol: just started a bunch of apps --> some of their pId were much less than 30 apart, so, I think the fact that it was 4 apart is just coincidence, and the handle returned by OpenProcess() is in no way guaranteed to be close to the original process handle. previous statements retracted. ?
    Thanks for the answer, but I think you got me wrong
    Not the PID varies, but the Handle.

    I use to different Methods to get the Handle, and both Methods return a value that is always 4 values apart from another.

    The PID is not the Problem, I'm just wondering why there is a difference between the two Handles.

  4. #4
    abuckau907's Avatar Active Member
    Reputation
    49
    Join Date
    May 2009
    Posts
    225
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    haha, you're right, not sure why I went off on pId. At first I meant to say ".handle", looked at task manager, then started rambling about pId.
    I'm not sure I understand?


    OpenProcess() is *supposed* to return a different handle -- it's designed this way. Is that the confusion?

    OpenProcess() gets *a new* handle to the *same process*... 1 process, multiple handles. each 'handle' has security attributes.

    I'm not sure why they are only 4 apart..logically it's either coincidence, or because of how windows manages pId handles.


    edit: I'm pretty sure the only reason you Need* to call OpenProcess() is because the _targetProcess was probably started by the user (ie. non-admin), so it's .Handle has non-admin rights. And you want to ...h4xor it, so you need admin rights (Read/Write processmemory etc) , which you specify in the OpenProcess() argument. Then it returns a new (different), handle with h4xor rights.

    maybe?
    Last edited by abuckau907; 12-31-2012 at 08:45 PM.
    Some things that can be counted, don't matter. And some things that matter, can't be counted.

  5. #5
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Threk View Post
    Hey guys,
    I have a simple piece of code which works perfect but the value varies from time to time (which should normally not happen).

    I get the Handle of an Process via the Process.Handle property.
    The Problem is (as stated above) that it varies from time to time (the same instance of the same process).

    It also differs from the Handle that I get when I use OpenProcess(the native/unmanaged function).

    Signature of the OpenProcess function:
    Code:
            [DllImport("kernel32.dll")]
            internal static extern SafeMemoryHandle OpenProcess(
                ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
    Handle from Process.Handle: 532
    Handle from OpenProcess: 528

    Both are IntPtr's.
    There is always a difference of 4.
    I really have no Idea where the Problem is.

    The Handle's are both valid, but why is there a difference of 4 ?
    Sorry, but umm, who cares? I don't really understand the problem. Handles are opaque by design, you're not meant to rely on an integer representation of them meaning anything special. I don't mean to be rude, I'm just trying to make sure that this is harmless curiosity, and that you're not going to go do something that actually relies on undocumented implementation details.

    Anyway, to answer your question...

    Why are kernel HANDLEs always a multiple of four?

    As for why you get different values for Process.Handle and OpenProcess... OpenProcess opens a new process handle. Just like if you call DuplicateHandle on an existing handle, you'll get a new handle representing the same object (optionally with a different access mask).

    The book "Windows Internals" covers this topic in a lot more depth, I suggest you check it out if you're interested.

  6. #6
    abuckau907's Avatar Active Member
    Reputation
    49
    Join Date
    May 2009
    Posts
    225
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Cypher View Post
    Sorry, but umm, who cares? I don't really understand the problem. Handles are opaque by design, you're not meant to rely on an integer representation of them meaning anything special. I don't mean to be rude, I'm just trying to make sure that this is harmless curiosity, and that you're not going to go do something that actually relies on undocumented implementation details.

    Anyway, to answer your question...

    Why are kernel HANDLEs always a multiple of four?

    As for why you get different values for Process.Handle and OpenProcess... OpenProcess opens a new process handle. Just like if you call DuplicateHandle on an existing handle, you'll get a new handle representing the same object (optionally with a different access mask).

    The book "Windows Internals" covers this topic in a lot more depth, I suggest you check it out if you're interested.
    darn. thought I said that
    btw the link contains the words "opaque values" I guess everyone uses that phrase..
    Last edited by abuckau907; 01-01-2013 at 04:36 PM.
    Some things that can be counted, don't matter. And some things that matter, can't be counted.

  7. #7
    Cromon's Avatar Legendary


    Reputation
    840
    Join Date
    Mar 2008
    Posts
    714
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Handles are just opaque values identifying an object/resource. Mathematically speaking the relation between handle and object is not a bijection (isomorphism) but a surjection (epimorphism) which means every object has at least one handle but is not restricted to have only one handle.

    For this particular situation with OpenProcess and Process.Handle see Cyphers answer. Process.Handle internally calls Process.GetProcessHandle which refers to ProcessManager.OpenProcess which uses NativeMethods.OpenProcess to open the process with all access flags (except PROCESS_QUERY_LIMITED_INFORMATION).

  8. #8
    abuckau907's Avatar Active Member
    Reputation
    49
    Join Date
    May 2009
    Posts
    225
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @Cromon

    " Process.Handle internally calls Process.GetProcessHandle which refers to ProcessManager.OpenProcess which uses NativeMethods.OpenProcess to open the process with all access flags"

    Can you please explain a little, sry. I took that as...any time you check aProcess.Handle it will have All Access :/
    Last edited by abuckau907; 01-01-2013 at 05:20 PM.
    Some things that can be counted, don't matter. And some things that matter, can't be counted.

  9. #9
    Cromon's Avatar Legendary


    Reputation
    840
    Join Date
    Mar 2008
    Posts
    714
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code of Process.Handle's property:
    Code:
    [MonitoringDescription("ProcessHandle"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)]
    public IntPtr Handle
    {
    	get
    	{
    		this.EnsureState(Process.State.Associated);
    		return this.OpenProcessHandle(this.m_processAccess).DangerousGetHandle();
    	}
    }
    Where m_processAccess is assigned only in the constructor(s):
    Code:
    	this.m_processAccess = 2035711;
    2035711 is: 1F0FFF
    PROCESS_ALL_ACCESS is: (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF), STANDARD_RIGHTS_REQUIRED is 0xF0000, SYNCHRONIZE is 0x100000 -> PROCESS_ALL_ACCESS = 0x1FFFFF

    So the difference is obviously only the high nibble of byte 2 which gives us flags 0x1000, 0x2000, 0x4000, 0x8000 where only 0x1000 exists with
    #define PROCESS_QUERY_LIMITED_INFORMATION (0x1000)

  10. #10
    abuckau907's Avatar Active Member
    Reputation
    49
    Join Date
    May 2009
    Posts
    225
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    wow, maybe i should get the windows internals book cypher mentioned Thank you very much .



    So, in .net, calling OpenProcess is pointless ? Well, you can use aProcess.Handle instead ? hmm..never realized.

    and also, if you call aProcess.Handle --> obviously it will fetch a new handle each* time. ? (Not sure if I'm asking or saying )

    edit: I'm sorry if I was an ass to you before (other threads), you obviously know what you're talking about. Genuinely: thank you.
    I will get a Windows book soon.
    Last edited by abuckau907; 01-01-2013 at 05:46 PM.
    Some things that can be counted, don't matter. And some things that matter, can't be counted.

  11. #11
    Cromon's Avatar Legendary


    Reputation
    840
    Join Date
    Mar 2008
    Posts
    714
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It isnt pointless. Process.Handle returns SafeHandle.DangerousGetHandle() where as the SafeHandle which might get released in one of the GC-cycles. Thats why its called "Dangerous". What you get from native OpenProcess stays valid until you call CloseHandle,

  12. #12
    abuckau907's Avatar Active Member
    Reputation
    49
    Join Date
    May 2009
    Posts
    225
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    again, thank you. much appreciated. -- I assumed the opposite: that .Handle would have minimum access and be valid until process.close
    Last edited by abuckau907; 01-01-2013 at 05:55 PM.
    Some things that can be counted, don't matter. And some things that matter, can't be counted.

  13. #13
    Cromon's Avatar Legendary


    Reputation
    840
    Join Date
    Mar 2008
    Posts
    714
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by abuckau907 View Post
    and also, if you call aProcess.Handle --> obviously it will fetch a new handle each* time. ? (Not sure if I'm asking or saying )
    actually the OpenProcessHandle function is somehow like:
    Code:
    if(mHandle == null)
           OpenHandle(accessFlags);
    
    return mHandle;
    So it only opens it once. But its a member of the process class and you do not really have control on what GC does with it unless you store also the process instance (except that you dont know when the process class releases the safehandle).

    and on topic:
    On the MSDN theres a comment on the Process.Handle property:
    This process handle is private to an application--in other words, process handles cannot be shared. A process also has a process Id which, unlike the Handle, is unique and, therefore, valid throughout the system.

  14. #14
    abuckau907's Avatar Active Member
    Reputation
    49
    Join Date
    May 2009
    Posts
    225
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @Threk - I think Cromon's got u covered. -one more time: thnx
    Some things that can be counted, don't matter. And some things that matter, can't be counted.

Similar Threads

  1. [Guide] JhonnyQ's little trick thread - revealing more from time to time
    By JhonnyQ in forum World of Warcraft Guides
    Replies: 1
    Last Post: 01-23-2015, 03:18 AM
  2. [C#] UsePower wrapper crashes from time to time
    By zys924 in forum Diablo 3 Memory Editing
    Replies: 4
    Last Post: 07-06-2012, 07:57 PM
  3. [help] Process Handle and multithreading
    By Myryador in forum WoW Memory Editing
    Replies: 4
    Last Post: 11-03-2011, 12:41 AM
  4. Replies: 21
    Last Post: 10-03-2008, 12:12 AM
  5. Replies: 4
    Last Post: 06-26-2008, 02:20 AM
All times are GMT -5. The time now is 02:57 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search