The cat and the prince change ---- wear others' shoes and follow your own path (the alternative thinking achieves ring0 to hide files)
On the 10th, I received a programming order from my friend and asked me to write a lite version of remote control software from the beginning. Other functions were not mentioned, mainly because I needed to set file access permissions, you can set four types (accessible, writable, deletable, and visible)
It is easy to understand according to the literal meaning, that can be accessed is whether it can be read (in other words, if it cannot be accessed, it certainly cannot be written). If it is visible, it is whether it can be seen, deletable indicates whether the object can be deleted;
The first idea is to use ssdt hook, but it is quite time-consuming to start writing a driver again, and debugging is time-consuming; A friend told me that he wanted this function because there was a free software, easy file locker, on the Internet, which was very convenient. So he came up with an idea.
Can we reverse the easy file locker and see how it is implemented?
So I downloaded the software and the interface was very simple;
Supports file locking and folder locking, which can be accessed, written, and deleted from left to right;
After a simple look, this program has no shelling and no anti-debugging protection measures (onlookers: No, didn't you say it was a free software, I am also doing a fart anti-debugging)
Now, let's start a reverse journey from this OK button event. There is not much to say about searching for button events and so on. I believe that the good friends in the team are more powerful than me;
After a trail, I came to the 00410c35 function. The reason why it is locked here is that... I used f8. after I checked which call, the file was locked, so F7 went in. After so many times, I finally found that it was the two API functions fltlib in 00410c35. filterconnectcommunicationport and fltlib. filtersendmessage implements the file locking function (what, two API functions can implement file locking, which is impossible)
Baidu looks at the information about these two functions to see what they are used,
Http://technet.microsoft.com/zh-cn/ff540460 (V = vs.85)
Introduction:FilterconnectcommunicationportOpens a new connection to a communication server port that is created by a file system minifilter.
I cannot understand English. Baidu Translation
FilterconnectcommunicationportIt opens up a new port connecting to the Communication Server and creates a new framework through the file system.
Although... The translation from Baidu is hard to understand by Chinese and foreigners, but we can still understand it. filterconnectcommunicationport opens a new port to connect to the communication server; it is not hard to understand that filtersendmessage transmits data through the communication server port. Let's take a look at the parameters:
Hresult filterconnectcommunicationport (
_ In _ lpcwstr lpportname, // "\ xlkfsport"
_ In _ DWORD dwoptions, // null
_ In_opt _ lpcvoid lpcontext, // null
_ In _ word dwsizeofcontext, // null
_ In_opt _ lpsecurity_attributes lpsecurityattributes, // null
_ Out _ HANDLE * hport // buffer pointer of the return handle
);
Hresult filtersendmessage (
_ In _ HANDLE hport, // communication port handle
_ In_opt _ lpvoid lpinbuffer, // input buffer
_ In _ DWORD dwinbuffersize, // input buffer size
_ Out _ lpvoid lpoutbuffer, // output buffer (can be null)
_ In _ DWORD dwoutbuffersize, // output buffer size (can be null)
_ Out _ lpdword lpbytesreturned // actual data written
);
Therefore, the filterconnectcommunicationport function does not need to be detailed. You only need to know its lpportname parameter, because it is a connection function. In other words, if we want to focus on file operations, therefore, we should pay attention to writefile and readfile. For createfile, we only need to care about filename;
In this case, the filtersendmessage is disconnected at the ff25 position and we find that this function is executed to retn from the beginning. This function has been called twice, and the data of the two times is:
First time (because the file format is tmpxxx. tmp ~ 1, so name it tmp0_1)
009847c8 58 66 73 53 03 00 00 00 5C 00 3f 00 3f 00 5C 00 xfss
...\.?.?. \.
009847d8 43 00 3A 00 5C 00 44 00 4f 00 43 00 55 00 4D 00 C .. \. D. o.c. U. M.
009847e8 45 00 7E 00 31 00 5C 00 41 00 44 00 4D 00 49 00 E .~. 1. \. a.d.m. I.
009847f8 4E 00 49 00 7E 00 31 00 5C 00 4C 00 4f 00 43 00 n. I .~. 1. \. L. o.c.
00984808 41 00 4C 00 53 00 7E 00 31 00 5C 00 54 00 65 00 A. L. S .~. 1. \. T. E.
00984818 6D 00 70 00 5C 00 74 00 6D 00 70 00 37 00 45 00 m. p. \. T. M. p.7.e.
00984828 2E 00 74 00 6D 00 70 00 7E 00 31 00 00 00 00 .. t. m. p .~. 1 .....
Second time (because the file format is tmpxxx. tmp ~ 0, so name it tmp0_0)
009847c8 58 66 73 53 05 00 00 00 5C 00 3f 00 3f 00 5C 00 xfss ...\.?.?. \.
009847d8 43 00 3A 00 5C 00 44 00 4f 00 43 00 55 00 4D 00 C .. \. D. o.c. U. M.
009847e8 45 00 7E 00 31 00 5C 00 41 00 44 00 4D 00 49 00 E .~. 1. \. a.d.m. I.
009847f8 4E 00 49 00 7E 00 31 00 5C 00 4C 00 4f 00 43 00 n. I .~. 1. \. L. o.c.
00984808 41 00 4C 00 53 00 7E 00 31 00 5C 00 54 00 65 00 A. L. S .~. 1. \. T. E.
00984818 6D 00 70 00 5C 00 74 00 6D 00 70 00 32 00 30 00 m. p. \. T. M. p.2.0.
00984828 46 00 2E 00 74 00 6D 00 70 00 7E 00 30 00 00 00 f... T. M. P .~. 0...
So it is obvious that the name of a temporary file is transferred. Who is it? Of course it is for the driver. Let's take a brief look at the two TMP and find that the names of the files we want to lock and some other data appear in the two TMP to make a small experiment:
Modify the file name and find that the locked file has changed. We can roughly guess the structure of the program:
The ring3 program obtains some information from the user, such as "the file path to be locked", "What attributes to lock", and "whether to lock files or folders; then combine the tmp file and transmit the path of the tmp file to ring0. The ring0 kernel module locks the file;
Then, hey, we will consider whether the two TMP data structures can be analyzed, and two TMP data structures can be constructed by ourselves, and then transmitted to the kernel module using filterconnectcommunicationport and filtersendmessage, from this, we can achieve what we said at the beginning: "The cat is a prince." Oh, of course, yes, because I have already done it well;
For detailed analysis, I believe everyone will. Here we will post an analysis result:
The first is the data structure of tmp0_1.
Typedef struct _ DATA
{
DWORD count; // fixed to 1
Byte [80] pathvoluemename; // drive letter of the disk where the easy file locker is located, which can be obtained through getvolumenameforvolumemountpoint. Note:
Here is a unicode string
DWORD voluenamecheck; // convert volumename to uppercase, for example, {0171e958-db33-11e2-8658-806d6172696f}, and then add each
ASCII value of a character, for example, 0x089d
DWORD zero; // fixed to 0
DWORD zero; // fixed to 0
DWORD zero; // fixed to 0
DWORD relativerouteendoffset; // The offset between the end position of the relativeroute data and the start address of the data.
// Calculation method: strlenw (relativeroute) + 0x64 (size of all data before relativeroute) + 0x02
(Length of the end character of relativeroute, 2 0x00)
Byte [?] Relativeroute; // relative path of easy file locker + \ *, but note that all must be in uppercase and must be a unicode string
// For example, if easy file locker is stored in c: \ AAAA, the value is Unicode "\ AAAA \*"
Word strend; // 0x0000, Unicode string Terminator
Byte [96] Zero; // 0x60 (96) bytes 0x00
DWORD recylebinendoffset; // The offset between the end position of recyclebin data and the end position of relativeroute;
// Calculation method: 2 * strlenw (recyclebin) + 0x02 (end character length) + 0x60 (zero data length) +
0x04 (recylebinendoffset length );
Byte [?] Recyclebin; // fixed to Unicode "\ $ recycle. bin \*"
Word strend; // 0x0000, Unicode string Terminator
Byte [96] Zero; // 0x60 (96) bytes 0x00
DWORD buffer3endoffset; // The offset between (the end position of the buffer3 data) and (the end position of the recyclebin ).
// Calculation method: 2 * strlenw (buffer3) + 0x02 (end character length) + 0x60 (zero data length) +
0x04 (buffer3endoffset length );
Byte [?] Buffer3; // It is fixed to Unicode "\ recycler \ *". The specific meaning is unknown.
Word strend; // 0x0000, Unicode string Terminator
Byte [96] Zero; // 0x60 (96) bytes 0x00
DWORD buffer4endoffset; // (buffer4 data end position) offset relative to (buffer3 end position)
// Calculation method: 2 * strlenw (buffer4) + 0x02 (end character length) + 0x60 (zero data length) +
0x04 (buffer4endoffset length );
Byte [?] Buffer4; // It is fixed to Unicode "\ system volume information \ *". The specific meaning is unknown.
Word strend; // 0x00, Unicode string Terminator
Byte [80] pathvoluemename1; // The drive letter of the file to be locked, which can be obtained through getvolumenameforvolumemountpoint. Note that
Is a unicode string
DWORD voluename1check; // converts volumename1 to uppercase, for example, {0171e958-db33-11e2-8658-806d6172696f}, and then accumulates each
ASCII value, for example, 0x089d
DWORD zero; // fixed to 0
DWORD zero; // fixed to 0
DWORD access; // In fact, only four binary digits are allowed, that is, half a byte. The four binary digits represent: deletable
Visible and accessible. "0" indicates that the check box is selected, and "1" indicates that the check box is not selected.
DWORD filenameendoffset; // The offset between the end position of the filename data and the end position of buffer4 data.
// Calculation method: strlenw (filename) * 2 + 2 + 0x50 (pathvoluemename1 length) + 5*4 (5
DWORD length)
Byte [?] Filename; // The relative path of the object to be locked. For example, to lock E: \ YY \ delphi7example .exe, the value is
Unicode "\ YY \ Delphi7 example. EXE"
} Data, * pdata;
Then there is the data structure of tmp0_0:
[Common]
Count = locker file count; // The total number of locked files
[X] // file X, counted from 0
Path = lock file path
Type = bool (file = 0, folder = 1)
Access = writable, visible, and accessible
1 0 1 0
Then we only need to construct two TMP data based on this structure, and then transmit it to ring0;
Next, we know how to load its driver, because we know that its main implementation is the driver code. If we want to use filterconnectcommunicationport and filtersendmessage, we must first load its driver, otherwise, everything is free of discussion;
At first, I thought it was an NT-type driver. I had to take the loader for a long time. All of them failed .. after analyzing what the installer did, I found that it was a WDM driver. During installation, a xlkfs will be generated in the temp folder. INF, which is the driver installation INF;
This INF is not enough. After debugging and analysis, it is found that two items need to be added to the registry before you right-click INF-> install. One item can be added under ring3, the other item requires the ring0 permission, because the second item is located in the locked permission; it can only be read at ordinary times and cannot be written; then Baidu finally found the code for modifying the permission, please refer to the source code for details.
The general process is: generate a tmp0_0 file based on the user's operation (lock or unlock) and parameters (path, access), generate the tmp0_1 File Based on the tmp0_0 file, and then connect to the driver
Tmp0_0 (Actually an INI file) is generated as follows:
(1) first copy c: \ windows \ xlkfs. ini to any disk for temporary storage (I copied it to c)
(2). Retrieve the Count subitem under its common primary item (this subitem indicates the total number of locked files)
(3). If the object is locked, add the access, type, and path Attributes Based on the Count value.
(4). If the file is unlocked, The INI file will be traversed Based on the path value of the file to be unlocked and the corresponding items will be deleted.
Then generate a copy of tmp0_1 according to tmp0_0. The specific structure is written in the source code and in the article.
Note::Source codeOninitdialogThe function contains the code for loading the driver.,If you need to uninstall,Please installEasy file locker,Then execute the uninstall program,The source code does not contain the uninstall code.!