How does powercfg -energy detect the requested timer resolution - winapi

How does "powercfg -energy" command detect the requested timer resolution of each individual program running at the time?
I imagine one way would be injecting into each of running processes and inside that process calling timeEndPeriod for each increased resolution (values 1-15) in a loop over these resolutions and checking whether the timeEndPeriod call for a current resolution returns TIMERR_NOCANDO or TIMERR_NOERROR (note: these return values are NOT correspondingly false and true). And if it returns TIMERR_NOERROR then concluding that the program is using that frequency, and then calling again timeBeginPeriod. But this method seems cumbersome. Moreover, it is a bit intrusive since it modifies the state of the process, and also assumes that powercfg is able to inject into all processes.
Is there instead some documented or undocumented system API that enables requesting that information for foreign processes? At least I would like to know how it works, even if that API remains a secret...
A related (but not the main) question is, how to get the maximum timer resolution (minimum interval) that is currently in effect in the system in case I am not interested in the requests of individual applications? I imagine that maybe GetSystemTimeAdjustment()'s lpTimeIncrement helps with that, but I am not too sure. Please confirm me or propose an alternate method.

You may use the undocumented API of NtQueryTimerResolution().
NTSTATUS NtQueryTimerResolution(OUT PULONGMinimumResolution,
OUT LONGMaximumResolution,
OUT PULONGActualResolution);
See this post for an example on how to use it. But it will only give the ActualResolution as configured by any process. It does not give the information which process has configured which multimedia timer resolution.
You wouldn't want to change each processes mutimedia setting to find out which process has aquired which resolution. It would only be needed to obtain information on which process has requested ActualResolution.
Note: powercfg /energy is only available from Windows 7 / Windows Server 2008 R2 upwards.

Related

Guarding against system changes between function calls in Windows

Given some code like this...
auto res = GetScreenResolution();
// Can windows change the screen resolution between these calls?
// How do you guard against it?
DoSomething(res);
Can the resolution of the screen be changed between the function calls? Say from the user adjusting display settings. I assume it can but I'll ask for certainty.
If the resolution is changed between calls, then the function DoSomething might not work correctly, or cause a major problem depending on the code.
Is there any way at all of making sure the system (or particular settings) cannot be changed during the execution of a piece of code?
The same concept could be applied to various things, like checking if a network is up or checking the status of a file.
The probability of something happening is so small that it's not worth bothering with, but I was curious.
Some overnight thoughts...
Call GetScreenResolution() again after DoSomething() to check for a match. This would also allow you to undo changes you've made and correct them. It's still possible for a problem to occur, but it's much much lower still.
With exceptions, DoSomething() may throw a software exception with out of date data. You can then do whatever is necessary.
If you have to do a lot of processing between GetScreenResolution and DoSomething, say for a minute, then it may be worth checking for changes to the system. If you receive a message that resolution changed, you can also reset the processing if you're architecture allows for that.
You just have to prepare for failure and/or make sure you are notified about any changes.
Even if there was a lock you could take to prevent another application from changing the display settings there is nothing you can do to prevent me from pulling out my monitor cable and Windows reacting to that and making my laptop screen the primary monitor.
If you look at ChangeDisplaySettings for example you will see this on MSDN:
When the display mode is changed dynamically, the WM_DISPLAYCHANGE message is sent to all running applications with the following message parameters.
The only thing you can do to prevent something is to use a job object to restrict a specific process/processes under your control from calling certain functions (JOB_OBJECT_UILIMIT_DISPLAYSETTINGS etc.).

How to identify a process in Windows? Kernel and User mode

In Windows, what is the formal way of identifying a process uniquely? I am not talking about PID, which is allocated dynamically, but a unique ID or a name which is permanent to that process. I know that every program/process has a security descriptor but it seems to hold SIDs for loggedin user and group (not the process). We cannot use the path and name of executable from where the process starts as that can change.
My aim is to identify a process in the kernel mode and allow it to perform certain operation. What is the easiest and best way of doing this?
Your question is too vague to answer properly. For example how could the path possibly change (without poking around in kernel memory) after creation of a process? And yes, I am aware that one could hook into the memory-mapping process during process creation to replace the image originally destined to be loaded with another. Point is that a process is merely one instance of running a given executable. And it's not clear what exact tampering attempts you want to counter here.
But from kernel mode you do have the ability to simply use the pointer to the EPROCESS structure. No need to use the PID, although that will be unique while the process is still alive.
So assuming your process uses an IRP to communicate to the driver (whether it be WriteFile, ReadFile, DeviceIoControl or something more exotic), in order to register itself, you can use IoGetCurrentProcess to get the PEPROCESS value which will be unique to the process.
While the structure itself is not officially documented, hints can be gleaned from the "Windows Internals" book (in its various incarnations), the dt (Display Type) command in WinDbg (and friends) as well as from third-party resources on the internet (e.g. here, specific to Vista).
The process objects are kept in several linked lists. So if you know the (officially undocumented!!!) layout for a particular OS version, you may traverse the lists to get from one to the next process object (i.e. EPROCESS structure).
Cautionary notes
Make sure to reference the object of the process, by using the respective object manager routines. Otherwise you cannot be certain it's safe to both reach into these structures (which is anyway unsafe, since you cannot rely on their layout across OS versions) or to pass it to functions that expect a PEPROCESS.
As a side-note: Harry Johnston is of course right to assert that a privileged user can insert arbitrary (well almost arbitrary) code into the TCB in order to thwart your protective measures. In the end it is going to be an arms race.
Also keep in mind that similar to PIDs, theoretically the value of the PEPROCESS may be recycled. But in both cases you can simply counter this by invalidating whatever internal state you keep in your driver that allows the process to do its magic, whenever the process goes down. Using something like PsSetCreateProcessNotifyRoutine would seem to be a good method here. In order to translate your process handle from the callback to a PEPROCESS value, use ObReferenceObjectByHandle.
An alternative of countering recycling of the PID/PEPROCESS is by keeping a reference to the process object and thus keeping it in a kind of undead state (similar to not closing a handle in user mode), although the main thread may have finished.

Is it possible to associate data with a running process?

As the title says, I want to associate a random bit of data (ULONG) with a running process on the local machine. I want that data persisted with the process it's associated with, not the process thats reading & writing the data. Is this possible in Win32?
Yes but it can be tricky. You can't access an arbitrary memory address of another process and you can't count on shared memory because you want to do it with an arbitrary process.
The tricky way
What you can do is to create a window (with a special and known name) inside the process you want to decorate. See the end of the post for an alternative solution without windows.
First of all you have to get a handle to the process with OpenProcess.
Allocate memory with VirtualAllocEx in the other process to hold a short method that will create a (hidden) window with a special known name.
Copy that function from your own code with WriteProcessMemory.
Execute it with CreateRemoteThread.
Now you need a way to identify and read back this memory from another process other than the one that created that. For this you simply can find the window with that known name and you have your holder for a small chunk of data.
Please note that this technique may be used to inject code in another process so some Antivirus may warn about it.
Final notes
If Address Space Randomization is disabled you may not need to inject code in the process memory, you can call CreateRemoteThread with the address of a Windows kernel function with the same parameters (for example LoadLibrary). You can't do this with native applications (not linked to kernel32.dll).
You can't inject into system processes unless you have debug privileges for your process (with AdjustTokenPrivileges).
As alternative to the fake window you may create a suspended thread with a local variable, a TLS or stack entry used as data chunk. To find this thread you have to give it a name using, for example, this (but it's seldom applicable).
The naive way
A poor man solution (but probably much more easy to implement and somehow even more robust) can be to use ADS to hide a small data file for each process you want to monitor (of course an ADS associated with its image then it's not applicable for services and rundll'ed processes unless you make it much more complicated).
Iterate all processes and for each one create an ADS with a known name (and the process ID).
Inside it you have to store the system startup time and all the data you need.
To read back that informations:
Iterate all processes and check for that ADS, read it and compare the system startup time (if they mismatch then it means you found a widow ADS and it should be deleted.
Of course you have to take care of these widows so periodically you may need to check for them. Of course you can avoid this storing ALL these small chunk of data into a well-known location, your "reader" may check them all each time, deleting files no longer associated to a running process.

How can I find out how many GDI objects my process is allowed to create?

There's a registry key where I can check (& set) the currently set GDI object quota for processes. However, if a user changes that registry key, the value remains the old value until a reboot occurs. In my program, I need to know if there's a way to determine, programatically, how many more GDI objects I can create. Is there an API for getting GDI information for the current process? What about at the system level?
Always hard to prove the definite absence of an API, but this one is a 95% no-go. Lots of system settings are configured through the registry without an API to tweak it afterward.
Raymond Chen's typical response to questions like these is "if you want to know then you are doing something wrong". It applies here, the default quota of 10,000 handles is enormous.
If you want to find the current quota that matters to you, create GDI objects until that fails. Record that number. Then, destroy all of them.
If you feel like doing this on a regular basis to get an accurate number, you can do so. It's probably going to be fairly expensive though.
Since Hans mentioned Raymond already, we should play his "Imagine if this were true" game. If this API - GetGDIObjectLimit or whatever - existed, what would it return? If the object count limit is 10000, then you expect it to return that right? So what happens when the system is low on memory? The API tells you a value which has no actual meaning. If you're getting close to 10000 GDI objects, you are doing something wrong and you should concentrate on fixing that.

How to get job handle if I have HANDLE to one of the windows of the job

My application tried to scrape IE8, here we somehow obtain HANDLE to Internet Explorer Window/UI. Now I want to get the job handle for IE8.
One Idea is to -
Determine first the process id using the IE Window HANDLE using GetWindowThreadProcessId() but after this I am stuck.
There is new implementation in IE8, here every tab opened is a process within a job. Thus IE8 we see is managed as a job.
I couldn't find any documented way to get the job to which a process is bound; also, I couldn't find any documented way to enumerate all the jobs in the system, except the WMI way that however works only from XP onwards (which I don't think it's a problem since you're targeting IE8) and only with named jobs (which may actually be a problem if IE8 uses anonymous job objects).
If IE's jobs are in this list, then the road is downhill: just use OpenJobObject on each job name you can get (or, if you manage to narrow down your work with some heuristic on the job names, even better) and use the IsProcessInJob to check if your process handle (which you get with OpenProcess + GetWindowThreadProcessId) belongs to the job; once you get a match, you're set. Remember to close all those handles! :)
In the unfortunate event that the job objects used by IE8 are unnamed, then the whole thing becomes more difficult. You probably need to resort to almost-undocumented (by Microsoft, but widely documented on the net) handle-enumeration techniques to enumerate all the handles relative to your target process. You can then filter out just the job objects handles, and use the technique described above to get the right one.
By the way, why do you need to access the job objects used by IE8?

Resources