This post is written for aspiring reverse engineers and will talk about a technique called _API hashing_. The technique is used by malware authors to hinder reverse engineering. We will first discuss the reasons a malware author may even consider using API hashing. Then we will cover the necessary technical details around resolving dynamic imports at load-time and at runtime and finally, will described API hashing and show a Python script that emulates the hashing method used in Sodinokibi/REvil ransomware.
Read on
Earlier this year, I was thrilled to hear that my submission for a talk at this year's [FrOSCon](https://www.froscon.de/) (Free and Open Source Software Conference) was accepted. [The talk](https://programm.froscon.de/2019/events/2350.html) is about Ghidra, the reverse engineering tool which was recently release into open source by the NSA. Since I expected a very heterogeneous audience with people from all kinds of industries with all kinds of backgrounds, I decided to give a long introduction with a lot of motivation for reverse engineering and only use the last quarter or so of the talk to actually show Ghidra's capabilities.
You can find the [slides here](https://blag.nullteilerfrei.de/wp-content/uploads/2019/08/FrOSConTalk2019-Ghidra.pdf), the source [of the slides on github](https://github.com/larsborn/FrOSCon2019-Ghidra-Talk) and a recording at [media.ccc](https://media.ccc.de/v/froscon2019-2350-ghidra_-_an_open_source_reverse_engineering_tool). Based on feedback after and during the talk, I added a bullet point under Motivation: a lot of people at FrOSCon seemed to be in the position where a wild binary blob appeared and they had to deal with it. Some because they found an old service running with source code not available (or readable) anymore and some because they want to re-implement a protocol that is not documented.
A while back [I blawgd about how to get the MSDN library for offline use](https://blag.nullteilerfrei.de/2017/12/21/get-the-msdn-library-for-offline-use/). However, the Help Viewer has its problems. I won't list all of its problems, but it was certainly a bad candidate to integrate Win32 API documentation support to Ghidra. There is [a pretty neat project by Laurence Jackson](http://laurencejackson.com/win32/), but I think I just found something a little better even: Microsoft provides [a download of the MSDN Library for Visual Studio 2008 SP1, stand-alone, offline, as an ISO](https://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=20955) - smell this, Help Viewer:
So this is nice, but the main point of this exercise was to integrate this into Ghidra. If that's something you care about, read on.
After a system crash, Ghidra greeted me with the message
Unsupported file system schema: idata
when I tried to open the project.
Click here to see what happened next!
Say you want to write a C program, but you want to avoid including plain strings within the binary. This is something often done by malware authors, for example, to avoid easy extraction of so called indicators of compromise. I can also imagine a legitimate business that uses string obfuscation to make reverse engineering of their software harder to protect their intellectual property.
This is often called string obfuscation.
I want to use this knowledge to make the world a better place!
Do you ... analyze a lot of malware? Dynamically, too? Or do you just want to launch suspended processes? Well either way, although this is really easy to do, my intense web research did not yield satisfactory results. So here you go, this will just take the entire command line that is passed to it and execute it as a new, suspended process:
#include <Windows.h>
#include <Shlwapi.h>
BOOL ChrIsWhiteSpace(WCHAR x) {
return x == 32 || (x >= 9 && x <= 13);
}
int WinMainCRTStartup() {
int ArgCount = 0;
WCHAR* CommandLine = GetCommandLineW();
WCHAR** ArgList = CommandLineToArgvW(CommandLine, &ArgCount);
if (ArgList && ArgCount > 1) {
WCHAR* PtrRest = StrStrW(CommandLine, ArgList[1]);
if (PtrRest) {
STARTUPINFOW StartupInfo;
PROCESS_INFORMATION ProcessInfo;
while (!ChrIsWhiteSpace(*PtrRest))
PtrRest--;
GetStartupInfoW(&StartupInfo);
CreateProcessW(
NULL,
++PtrRest,
NULL,
NULL,
FALSE,
CREATE_SUSPENDED | INHERIT_PARENT_AFFINITY | DETACHED_PROCESS | CREATE_DEFAULT_ERROR_MODE,
NULL,
NULL,
&StartupInfo,
&ProcessInfo
);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
}
LocalFree(ArgList);
}
ExitProcess(0);
}
Do you want the Base64 encoded binary?
When I open up a file in IDA Pro, I usually want the HexRays decompiler panel to the right of the disassembly. It just so happens that I open up a lot of files in IDA Pro and I have to rearrange the panels every time. Now I finally sat down and wrote a little Python plugin that will rearrange the panels just the way I like them. You may have similar problems and may find it useful. You should be able (with only a small amount of pain) to modify the script according to your own preferred layout:
import idaapi
def runonce(function):
"""
A decorator which makes a function run only once.
"""
function._first_run = True
def wrapper(*args, **kwargs):
if function._first_run:
function._first_run = False
return function(*args, **kwargs)
return wrapper
@runonce
def position_pseudocode():
idaapi.set_dock_pos('Pseudocode-A', None, idaapi.DP_RIGHT)
idaapi.set_dock_pos('Graph overview', 'Output window', idaapi.DP_TAB)
idaapi.set_dock_pos('Functions window', 'Output window', idaapi.DP_TAB)
class PseudoCodeTabRight(idaapi.plugin_t):
flags = idaapi.PLUGIN_HIDE
comment = 'Opens the PseudoCode tab in a spearate pane to the right.'
help = 'The plugin triggers automatically when the decompiler is engaged for the first time.'
wanted_name = 'PseudoCodeTabRight'
wanted_hotkey = ''
def init(self):
def hexrays_event_callback(event, *args):
if event == idaapi.hxe_open_pseudocode:
position_pseudocode()
return 0
if not idaapi.install_hexrays_callback(hexrays_event_callback):
return idaapi.PLUGIN_SKIP
return idaapi.PLUGIN_KEEP
def run(self, arg=0):
pass
def term(self):
pass
def PLUGIN_ENTRY():
return PseudoCodeTabRight()