How to use windbg to find the specified characters in the memory? A friend in the group gave me a dump the day before yesterday and asked me to help identify whether some sensitive information is also encrypted in the memory.
Now data security is very important. Not only the information in the database must be encrypted, but the data after being poured into the memory is also encrypted. Need to store the ciphertext, decrypt it as you use it, and strive for maximum security 😄, this is the background, next is my fuck, how can I find the character?? 😂😂😂
Windbg to find the specified characters
How to identify
After thinking for a few seconds, I calm down and think that there is still a solution. Let me simplify the problem first.
Determine whether there is a plaintext character in the memory with a string of znlive or Znlive.com or znlive.net.
Determine whether the ciphertext corresponding to the respective plaintext exists in the memory.
By searching the above two points, you can basically determine whether the sensitive information is encrypted.
A managed language like C# has the advantage that all managed objects are stored on the managed heap. The implication is that strings are also on the managed heap, so the next question is how to retrieve string=znlive strings on the heap .
Here comes the question. Many times the number of strings on the managed heap is massive. I have seen the highest number of tens of millions. The strings are vast. When will I find my most beautiful cub? 😤😤😤, the theoretical time is over, and then I will start playing strange.
Case presentation
In order to continue the conversation, I use a simple example to demonstrate how to manually search for string=znlive, first look at the code.
class Program { static List<string> strList = new List<string>(); static void Main(string[] args) { strList.Add("fake"); strList.Add("znlive"); Console.ReadLine(); } }
windbg to find the specified characters
Next use windbg.
Use !dumpheap -type System.String -min 8 -max 15 to find all strings in the range of 10-15 bytes.
0:000> !dumpheap -type System.String -min 8 -max 15 Address MT Size 026f1228 652224e4 14 026f164c 652224e4 16 026f230c 65222d74 12 ... Statistics: MT Count TotalSize Class Name 65225468 1 12 System.Collections.Generic.GenericEqualityComparer`1[[System.String, mscorlib]] 65222d74 10 156 System.String[] 652224e4 65 1168 System.String Total 76 objects
windbg to find the specified characters
It can be seen from the output that there are 1168 strings in the current size range. It is also found that this size is not particularly accurate. Don’t worry about it. Although there are a lot of strings, they can still be searched manually. Use !do xxx to view them one by one.
0:000> !do 026f2354 Name: System.String MethodTable: 652224e4 EEClass: 65327690 Size: 18(0x12) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: znlive Fields: MT Field Offset Type VT Attr Value Name 652242a8 4000283 4 System.Int32 1 instance 2 m_stringLength 65222c9c 4000284 8 System.Char 1 instance 5f20 m_firstChar 652224e4 4000288 70 System.String 0 shared static Empty >> Domain:Value 00a22530:NotInit <<
windbg to find the specified characters
Do you see it? The String: znlive above is the result I want, and the real hammer is stored in plain text.
Can the article end here? 🙃🙃🙃, there is no actual combat experience. As I just said, many times the filtered string may be as high as tens of thousands and hundreds of thousands. It is impossible to use manual labor. . .
Is there any alternative to manual scripts? 😜😜😜, hey, there is really. . .
Use automated scripts
The current windbg preview supports javascript as a script extension. Next, I am going to write the manual steps just now into a script. It seems that the professional name is the playbook. My script is as follows:
"use strict"; function RunCommands() { var ctl = host.namespace.Debugger.Utility.Control; var str_address_list = ctl.ExecuteCommand("!dumpheap -type System.String -min 8 -max 15 -short"); for (var str_address of str_address_list) { var str_dump = ctl.ExecuteCommand("!do -nofields "+ str_address); var str = str_dump.Last(); var isContains = str.indexOf("znlive")> 0; if(isContains) host.diagnostics.debugLog(str+" "+str_address +"\n"); } }
windbg to find the specified characters
The logic of the script is still very simple. It simulates the human flesh just now, and finally judges whether there is a znlive string in the output content. If so, print it out together with the address address. After the script is saved, use the dx command to execute RunCommands() function.
0:000> dx Debugger.State.Scripts.RunCommands.Contents.RunCommands() String: znlive 026f2354 Debugger.State.Scripts.RunCommands.Contents.RunCommands()
windbg to find the specified characters
See if the plaintext znlive is displayed. If you don’t believe it, I will cut a picture to prove that I did not lie to you 🤭🤭🤭.
Conclusion
In this case, the js script is used to get it easily. It can be seen that the script gives windbg unlimited mining possibilities. It is really too powerful. If you are interested, please refer to MSDN: https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/javascript-debugger-scripting