Hi All, my name is Ron Riddle and I’m an Escalation Engineer on the core Windows team. I worked an issue recently wherein a svchost.exe was crashing due to heap corruption; so, after enabling Page Heap and breaking out the services as needed, I received a user-mode dump that would show me the culprit. I was expecting to find a legitimate bug either in our code or a third-party module; but, much to my surprise, I found that malware had caused a buffer overrun and the subsequent crash. With that, I would like to share the simple approach I took in identifying the malware within the dump file.
1. I start by dumping out the offending call stack. Notice that the debugger wasn’t able to map the code addresses to a loaded or unloaded module.
0:003> kbn
# ChildEBP RetAddr Args to Child
WARNING: Frame IP not in any known module. Following frames may be wrong.
00 02bcfdcc 7c81a35f 02b7ae40 7c81a3ab 00000004 0x2b685b0
01 02bcfde4 02b68bfe 02b7ae40 00000000 77e424ee ntdll!LdrpCallInitRoutine+0x21
02 02bcfde8 02b7ae40 00000000 77e424ee 02b7ae10 0x2b68bfe
03 02bcfdec 00000000 77e424ee 02b7ae10 00000000 0x2b7ae40
2. Next, I try to learn more about the mystery address, such as what larger allocation it was a part of.
0:003> !address 0x2b685b0
Usage: <unclassified>
Allocation Base: 02b60000
Base Address: 02b61000
End Address: 02b81000
Region Size: 00020000
Type: 00020000 MEM_PRIVATE
State: 00001000 MEM_COMMIT
Protect: 00000040 PAGE_EXECUTE_READWRITE
3. By now, I am suspicious of a rogue module, so I proceed in searching the aforementioned address range for a DOS Signature(i.e. 0x5A4D or “MZ”) that I know any Portable Executable file must contain. I start with the Base Address from the above output and use the Region Size to specify my range.
0:003> s -a 02b61000 l20000/4 "MZ"
02b615d8 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ..............
02b61bd0 4d 5a 75 f4 5f 83 c4 08-c2 04 00 55 8d 44 24 0c MZu._......U.D$.
02b67cd0 4d 5a 0f 85 69 01 00 00-8b 4d 7c 8b 46 3c 81 c1 MZ..i....M|.F<..
02b681bf 4d 5a 74 07 33 c0 e9 c9-01 00 00 8b 45 0c 56 8b MZt.3.......E.V.
4. Now that I have some hits, I’ll start with the first one and verify whether it’s a valid module. Bingo!
0:003> !dh -a 02b615d8
File Type: DLL
FILE HEADER VALUES
14C machine (i386)
5 number of sections
37304740 time date stamp Wed May 05 08:27:28 1999
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
2102 characteristics
Executable
32 bit word machine
DLL
OPTIONAL HEADER VALUES
10B magic #
7.00 linker version
Read more: Ntdebugging Blog
1. I start by dumping out the offending call stack. Notice that the debugger wasn’t able to map the code addresses to a loaded or unloaded module.
0:003> kbn
# ChildEBP RetAddr Args to Child
WARNING: Frame IP not in any known module. Following frames may be wrong.
00 02bcfdcc 7c81a35f 02b7ae40 7c81a3ab 00000004 0x2b685b0
01 02bcfde4 02b68bfe 02b7ae40 00000000 77e424ee ntdll!LdrpCallInitRoutine+0x21
02 02bcfde8 02b7ae40 00000000 77e424ee 02b7ae10 0x2b68bfe
03 02bcfdec 00000000 77e424ee 02b7ae10 00000000 0x2b7ae40
2. Next, I try to learn more about the mystery address, such as what larger allocation it was a part of.
0:003> !address 0x2b685b0
Usage: <unclassified>
Allocation Base: 02b60000
Base Address: 02b61000
End Address: 02b81000
Region Size: 00020000
Type: 00020000 MEM_PRIVATE
State: 00001000 MEM_COMMIT
Protect: 00000040 PAGE_EXECUTE_READWRITE
3. By now, I am suspicious of a rogue module, so I proceed in searching the aforementioned address range for a DOS Signature(i.e. 0x5A4D or “MZ”) that I know any Portable Executable file must contain. I start with the Base Address from the above output and use the Region Size to specify my range.
0:003> s -a 02b61000 l20000/4 "MZ"
02b615d8 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ..............
02b61bd0 4d 5a 75 f4 5f 83 c4 08-c2 04 00 55 8d 44 24 0c MZu._......U.D$.
02b67cd0 4d 5a 0f 85 69 01 00 00-8b 4d 7c 8b 46 3c 81 c1 MZ..i....M|.F<..
02b681bf 4d 5a 74 07 33 c0 e9 c9-01 00 00 8b 45 0c 56 8b MZt.3.......E.V.
4. Now that I have some hits, I’ll start with the first one and verify whether it’s a valid module. Bingo!
0:003> !dh -a 02b615d8
File Type: DLL
FILE HEADER VALUES
14C machine (i386)
5 number of sections
37304740 time date stamp Wed May 05 08:27:28 1999
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
2102 characteristics
Executable
32 bit word machine
DLL
OPTIONAL HEADER VALUES
10B magic #
7.00 linker version
Read more: Ntdebugging Blog