IntroductionProbably many programmers, and simply curious people faced with the fact that in some exe / dll / sys and similar files there is incomprehensible data between the MZ and PE header, which ended with the word Rich.
Many did not pay attention to them, but some of them could say that this file was created using the compiler from Microsoft. There were also people who believed that there was hidden some data needed for the program. And this is only one side of this fact.
The other side is that many people know that Microsoft specifically marks executable files created using their compilers (C \ C ++ \ MASM) and that this is supposedly done in order to calculate the creators of malware.
Many believe that when linking fits information about the computer or user.
')
Combining both of these facts, it is safe to say that Rich data is possible and this is the identifier by which you can identify the person / computer where the malware was created. The validity of this fact will be checked.
Rich in detailFrom the main features of these data that could be found by visual inspection, we can distinguish the following:
- They always follow the MZ header, but before the PE header.
- Most often, their position relative to the beginning of the file = 80h = 128.
- A program compiled on the same computer has the same rich data.
Sample RICH data (marked pink):
those. its structure is approximately as follows:
XXXXXXXX - YYYYYYYY - YYYYYYYY - YYYYYYYY
XXXXXXXX - XXXXXXXX - XXXXXXXX - XXXXXXXX
XXXXXXXX - XXXXXXXX - XXXXXXXX - XXXXXXXX
[Rich ] - YYYYYYYY
where YYYYYYYY - Duplicate 32-bit values
XXXXXXXX - Constantly different 32-bit values
[Rich signature] - 4 bytes forming the word Rich
What does Rich hide?It took a lot of time to find out that at least some information and that the data is stored there and eventually a foreign site was found where the article was located (http://ntcore.com/files/richsign.htm) a man named Daniel Pistelli, in which he investigated this signature, as well as how it is formed and still a lot of useful data.
As it was found out in the above article, the number marked by us as YYYYYYYY is the encryption / decryption key. If we talk in more detail about this, then this is just a mask for XOR operation (which is exactly what encryption is)
Decryption:- We take a double word after the signature Rich - this is our key.
- Each double word Rich is decrypted by XOR using the key and so on until we reach the Rich signature (no need to decrypt).
As a result, we get something like this:
DanS-00000000 - 00000000 - 00000000
XXXXXXXX - XXXXXXXX - XXXXXXXX - XXXXXXXX
XXXXXXXX - XXXXXXXX - XXXXXXXX - XXXXXXXX
Rich-YYYYYYYY
where, XXXXXXXX - decrypted data
00000000 - the number of XOR on itself = 0.
The DanS signature was most likely entered in order to verify that this is exactly Rich data and that they are not forged by a simple pseudo-random number generator.
Then the author of that article drove the compiler through IDA in order to study in more detail what is written in Rich data. As it turned out, their format is:
XXXX00YY ZZZZZZZZ XXXX00YY ZZZZZZZZ
XXXX00YY ZZZZZZZZ XXXX00YY ZZZZZZZZ
where XXXX is the older version
YYYY - younger version
ZZZZZZZZ - something like a build version.
From this we can safely say that Rich data is only the versions of libraries and compiler that were used to create the program.
Practical implementation:Everything is good, but it is always better to see with your own eyes what versions there are. Yes, and I would like to automate this process.
Therefore, we will write a small function on Delphi which will display the versions of the libraries sewn into Rich data.
//
procedure PrintRichData(FileName : string);
var
Lib : DWORD; //
Data : DWORD; //
Key : DWORD; //
x : integer;
cnt : integer; // -
MinVer, MajVer : WORD; //
Times : DWORD;// .
Msg : string;
begin
Msg := '';
//
Lib := LoadLibrary(PAnsiChar(FileName));
if Lib <> 0 then //
begin
cnt := 0;
while true do // Rich -
begin
//
Data := DWORD(pointer(Lib + $80 + (cnt shl 2))^);
if Data = 0 then break; //
if Data = $68636952 then break; // - Rich
inc(cnt); //
end;
if cnt <> 0 then // Rich
begin
//
Key := DWORD(pointer(Lib + $80 + ((cnt+1) shl 2))^);
x := 4; // DanS 3 , 4-
while x < cnt-1 do //
begin
Data := DWORD(pointer(Lib + $80 + (x shl 2))^) xor Key; //
MinVer := Data and $FFFF; //
MajVer := (Data shr 16) and $0F; //
inc(x);
Times := DWORD(pointer(Lib + $80 + (x shl 2))^) xor Key; // . .
Msg := Msg + `Ver: ` + inttostr(MajVer) + `.0.` + inttostr(MinVer) + ` Times:` + inttostr(Times) + #13#10;
inc(x); //
end;
MessageBox(0, PAnsiChar(Msg), `INFO`, 0);
end;
FreeLibrary(Lib);
end;
end;
As a result of this function, you can get information about the versions. In my case, the test files had the following library versions.
Ver: 1.0.0 Times:44
Ver: 9.0.9210 Times:5
Ver: 0.0.9210 Times:1
Ver: 12.0.9178 Times:8
Ver: 13.0.9210 Times:1
What it threatens us with:According to the above described data, we can say that there is no important data and more confidential information than Rich data is stored, so you should not worry about the fact that they will be present in your programs.
Although in fact you can identify the following key points:
- You can find out which version of the compiler was used.
- The same version of the compiler on different computers, for the same program will give the same Rich data. So according to this data, it is impossible to prove directly that the program was created on this computer and even more so by you.
- The encryption mask is calculated based on the PE header data, so antiviruses can use it as a signature when analyzing a malware program.
- Deleting this signature may cause more antivirus interest in your program.
- Random values in version data can also attract the attention of antiviruses.
- When writing file protection systems, if completely random random data is used at all, then antiviruses can immediately understand that the file has been changed ie. the second signature check fails (DanS). So it is better if you generate this data yourself, then it is desirable to have a set of the most common versions of libraries.
Literature:1) Daniel Pistelli (http://ntcore.com/files/richsign.htm) - A detailed description of Rich data, a key generation method, and a compiler patch to disable the creation of Rich data.
2) Vovane (http://www.wasm.ru/forum/viewtopic.php?id=8572) - Fake program and validate Rich data.