Provide blocking of access and hiding of the system registry keys depending on the context of user in the current application.
Such task occurs in Corporate Security System implementation in particular in Data Protection components and some others.
Blocking of access to the keys and values of registry comes to the interception of key opening APIs. In accordance with the rules our handler should redirect control the original one or return status with an error (namely access_denied).
Hiding of registry keys differs from hiding of other objects in the system (files, processes etc.): the interface of API for access to the list of keys is based on the request for each key in the list by its index directly.
Different groups of programmers worked on APIs, and it is a reason of their wide difference. For example access to the list of directory files or system task list at the kernel level comes to the buffer filling. In this case the solution of the task would be as trivial as buffer modification. The interface of access to the registry lies in the receipt of information by the index for each key or value in the list. Only interception of the kernel API allows to define a user in the process context and resolve our task.
Problems of hiding registry keys and variants of possible solution
Exactly API for access to the registry presents the most problems at the interception and modification of values. They can’t be solved trivially.
Our handler will be called for value search repeatedly and one of its parameters is an index. Each time handler has to make the decision about the replacement of index. It’s no need to correct the buffer returned by system for the hiding of certain element, it is enough to replace the value of index that is transferred to the original API handler.
For example, in one key of registry there are a few values (reg value) which will be looked over. To hide a value handler should modify indexes of all requests for values and set them to index+Number of hidden keys. It is obvious that the complexity will increase exponentially if the handler looks over all registry keys for each of such requests to determine the number of keys hidden before the current index.
Registry API is rapid but key search with such simple handler can take seconds. It would influence the performance dramatically.
We can also store all of indexes in the kernel memory to save time, but this memory is very important and critical resource. So we face with well-known performance optimization task: to use minimal memory volume and ensure maximal functioning speed.
Implementation of finite-state machine would be great solution for the handler. For correct implementation one should understand that requests to the system registry are multithreaded. Our handler will process requests for values from different processes in the system and even from different threads of one process. It should be taken into account when associating current status of the key to the thread.
When request for the first key or value comes hidden indexes for the current registry key are defined according to the rules. From here our handler won’t need to work with the registry already. Handler functioning in the case when the context of finite state machine is found for the current key will come to the simple verification of number of the hidden elements before the current one (inclusive).
Described method gives double time even for the biggest registry keys. Finite state machine with the states for the sorted out keys is a good variant and it can be improved only by introduction of cache to obtain the states of every key. In this case search of the key won’t be performed if content of the keys and rules is not changed. In such way we will get the saving of time that will make the processing time of the most requests close to the original.
However, the size of cache should be limited as Windows kernel memory is a very precious resource. So the most optimal approach is to use cash only with those registry keys that are frequently requested.
Tools and technologies
Interception of ZwOpenKey, ZwEnumerateKey, ZwEnumerateValue, ZwCloseKey functions in ServiceDesctriptorTable;
Tools: Windbg, RegMon.
Learn more about Corporate Security tasks that we solve at Corporate Security System Components page