It seems like half a year has passed since I published the Win32k.SYS system call table list on the net. During this time (well, it didn’t take so long ;)) I managed to gather enough information to release yet another API list – this time, concerning an user-mode application – CSRSS (Client/Server Runtime SubSystem). As a relatively common research subject, I think a table of this kind can make things easier for lots of people.
Before presenting the table itself, I would like to gently introduce the mechanism in consideration to the reader. As the name itself states, CSRSS is a part of the Windows Environment Subsystem, running in user-mode. It is a single process (having the highest possible – SYSTEM – privileges), which mostly takes advantage of three dynamic libraries – basesrv.dll, csrsrv.dll and winsrv.dll. These files provide support for certain parts of the subsystem functionality, such as:
- Updating the list of processes / threads running on the system
- Handling the Console Window (i.e. special text-mode window) events
- Implementing parts of the Virtual DOS Machine support
- Supplying miscellaneous functions, such as ExitWindowsEx
Every Windows process running on the system does (or, at least, should) have an open connection with CSRSS, through the LPC / ALPC mechanism (depending on the system version) – which in turn stands for (Advanced) Local Procedure Calls. The ntdll.dll module provides multiple functions dedicated to the data exchange between user processes and CSRSS. Some of the examplary, exported names include, but are not limited to:
Out of all the Csr~ wrapper functions, CsrClientCallServer is the most commonly used. One can find it’s references in kernel32.CreateProcess, kernel32.AllocConsole, kernel32.FreeConsole, user32.EndTask and tens of other documented API functions. At a closer look, it is easy to notice that each time a call is made to CsrClientCallServer, an unique number is pushed on the stack, differing from routine to routine. An example code snippet follows:
.text:77E96D55 push 4 .text:77E96D57 push 20225h <---------- HERE .text:77E96D5C mov [ebp+var_7C], eax .text:77E96D5F push 0 .text:77E96D61 lea eax, [ebp+var_A4] .text:77E96D67 push eax .text:77E96D68 call ds:__imp__CsrClientCallServer@16 ; CsrClientCallServer(x,x,x,x)
As it turns out, these numbers are in fact indexes into special function pointer tables defined by the aforementioned libraries used by CSRSS. More specifically, a special routine – internally called CsrApiRequestThread – running in the context of a separate csrss.exe thread, is responsible for receiving user requests (that is – the CsrApi ID value together with the input buffer), handling it through appropriate dispatch tables, and returning the results. This scheme is slightly different on Windows 7, but the general idea remains the same.
In order to give the reader a better view of how many and what functions are supported on a specific OS version, as well as make cross-version comparisons easier, I’ve created two versions of the CsrAPI table:
- A complete list of the functions present in the dispatch tables for most likely every NT-series system can be found @ https://j00ru.vexillium.org/csrss_list/api_list.html.
- A cross-version compatibility table, for the same system version set can be found @ https://j00ru.vexillium.org/csrss_list/api_table.html.
I have done my best to make sure that the presented materials are correct and up-to-date. If, however, a mistake of any kinds is noticed, please let me know about this fact asap ;) It is possible that I will manage to fill the red-green table with corresponding api-numbers soon – I cannot guarantee this, though.
From this point, I would like to thank all people who showed their interest and helped my with this tiny project – thank You! Also, please drop me a line on whether you like the idea or not ;-)