Early Visual Basic program crackers knew that if you put a breakpoint in a right place, you can intercept strings entered into a text/input box. Once you do that, finding the key verification routine is easy as it will refer the memory buffer we can track after data is copied to it.
Around 13 years ago I was asked by an analyst on my team to help him with a WinBatch-compiled malicious sample. At that time there were not many options for analyzing these types of programs and of course, reading producers’ web site one would be discouraged to reverse engineer such executables as they are ‘close to impossible to crack’. After poking around I realized that the code of the ‘compiled’ batch file was actually available in plain text during run-time! It was decrypted and then stored in a memory block on a heap.
I was experimenting a lot with API hooking at that time and this particular experience led me to write a tool that was intercepting calls to a RtlFreeHeap function (HeapFree was forwarded to it), then dumping the content of a memory block the API referenced to a file before releasing the memory. You see, if you are a coder that is taught to free memory buffers after use, it’s only natural you will call these APIs. Even if you don’t really need to, because after process is killed these memory buffer will be killed anyway…
That tool I wrote back in 2008 was essential in handling many ‘script hidden by obfuscation more than anything else’ – it dealt with executables created by perl2exe, winbatch, and many bat2exe converters, and alike. It would literally take seconds to run a suspicious sample through that tool, review the data file it created, and cherry-pick the content that was of interest.
Because of that tool I was probably one of the first analysts being able to systematically dump code of many perl2exe samples targeting POS as well as forensic tools shared by prominent forensic experts e.g. compare rfc.exe vs. its source code, where the dump from my tool shows this (raw data + formatted):
Over next few years I started building a more robust sandbox and I added handling for buffers freed by many memory functions including VirtualFree, RtlFreeHeap, GlobalFree/LocalFree, free, NtFreeVirtualMemory and a few others that I knew contained buffers worth looking at.
Software analysis progressed really a lot since then and we have a gamut of decompilers, sandboxes, emulators, debuggers, plug-ins and both dynamic and static-oriented analysis tools now. It’s a treat.
One thing remains constant – tricks are here to stay.
If you can cut reversing corners – you definitely should.
Check the second part of this series.