# Crashing Windows CHM parser in seconds using WinAFL
###### tags: `fuzzing` `bb` `msrc` `chm`
:::info
This article is my submission for https://pagedout.institute #3
:::
One day a friend of mine @xina1i asked on the chat if anyone fuzzed `.hlp` files. I quickly looked at it, and realized that `.hlp` files don’t exist in Windows 10 anymore, but `.chm` files are still here. I’ve double clicked on random `.chm` file and started to look around.
`hh.exe` which is opened by Explorer is very lightweight program it’s only ~16kb, it also takes path to `.chm` file as a parameter, which might be helpful for fuzzing with [WinAFL](https://github.com/googleprojectzero/winafl). For now, I’ll just enumerate reversing takeaways.
* hh.exe just loads and calls `doWinMain()` from `hhctrl.ocx` file which is just a regular `.dll` file.
* `doWinMain()` performs all the job of parsing `.chm` file and it also checks a command line for additional options. We’ll be using `-decompile` option, which is intended to extract data from .chm archive without GUI.
* We could try to patch functionality which is related to writing files to speed up the fuzzing by just targeting `.chm` parsing functionality.
We should be ready to start fuzzing now. Let’s enable full [pageheap](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/gflags-and-pageheap) for the process and pop up a WinAFL. As an input corpus I just placed smallest `.chm` file from my system in the `r:\fuzz\in` directory.
```
afl-fuzz.exe -M 0 -i r:\fuzz\in -o r:\fuzz\out -D r:\dr\bin32 -t 3000 -- -coverage_module hhctrl.ocx -target_module hhctrl.ocx -target_method doWinMain -call_convention stdcall -nargs 2 -fuzz_iterations 5000 -- hh.exe -decompile r:\fuzz\out_cmd_m0\ @@
```

As you can see on the screenshot, the speed is extremely slow (~10execs/sec), but WinAFL was able to find two crashes in 10 minutes!
Here are several patches which you can try to improve the fuzzing speed.
1. Nop `UninitializeSession()` call in `doWinMain()` in order not to call OLE initialization on every fuzzing iteration.
2. Nop `CFSClient::WriteStorageContents()` call inside of hhctrl’s `DeCompile()` which is responsible for writing extracted files to the disk.
By doing so, you should be able to get the first crash in 5 seconds.

Please note, that `hhctrl.ocx` actually calls `itss.dll` to parse file itself. So, in order to discover more paths specify itss.dll as `-coverage_module`.
I’ve reported 4 cases of memory corruption to [msrc](https://msrc.microsoft.com/), but they replied they won’t be fixing it because `.chm` files are generally untrusted and when you open `.chm` file it’s literally the same as when you open `.exe` file. So, beware!
Here is how crash may look like.
```
(5260.483c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0a606f58 ebx=00b8e3d0 ecx=0a60b000 edx=01000000 esi=0a60afe8 edi=00000000
eip=7bf95e9c esp=00b8e3b0 ebp=00b8e3c8 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
itss!CPathManager1::CImpIPathManager::ReadCacheBlock+0x87:
7bf95e9c 8139504d474c cmp dword ptr [ecx],4C474D50h ds:002b:0a60b000=????????
0:000> k
# ChildEBP RetAddr
00 00b8e3d0 7bf962e1 itss!CPathManager1::CImpIPathManager::ReadCacheBlock+0x87
01 00b8e3f0 7bf9687c itss!CPathManager1::CImpIPathManager::FindCacheBlock+0x47
02 00b8e418 7bf94ebe itss!CPathManager1::CImpIPathManager::FindKeyAndLockBlockSet+0xad
03 00b8eeb0 7bf8e69d itss!CPathManager1::CImpIPathManager::FindEntry+0x7e
04 00b8f130 7bf8e9c2 itss!CITFileSystem::CImpITFileSystem::OpenLockBytes+0xbd
05 00b8f158 7bf8d34b itss!CITFileSystem::CImpITFileSystem::OpenStream+0x32
06 00b8f188 7bf8d6ea itss!CITFileSystem::CImpITFileSystem::OpenSpaceNameList+0x2e
07 00b8f1f8 7bf8c6cf itss!CITFileSystem::CImpITFileSystem::InitOpenOnLockBytes+0x233
08 00b8f210 7bf8c64c itss!CITFileSystem::OpenITFSOnLockBytes+0x57
09 00b8f230 7bf9ef23 itss!CITFileSystem::OpenITFileSystem+0x8a
0a 00b8f240 7c154595 itss!CWarehouse::CImpIWarehouse::StgOpenStorage+0x13
0b 00b8f480 7c154dbe hhctrl!CFileSystem::Open+0x81
0c 00b8f4b8 7c15715f hhctrl!CFSClient::Initialize+0x69
0d 00b8f56c 7c156a84 hhctrl!DeCompile+0x39
```