2024/06/13

A walk down the memory lane: Vol 2

 So, in the first part of the series we pushed out a tool that we used for SpyEye configuration dumping, but it can also be used for other things.

In this part, we'll touch the subject of API name hashing, a technique pretty widely used on both bulk malware and APT malware. I reckon most of the readers are aware of it, but let's do a short introduction.


Commonly when you compile a your code project into an executable, the linker will generate a table of all the system API calls that are used in your program. It can be a handful of system calls like CreateFileW or OpenProcessToken. When analyzing normally compiled binaries the process is a whole lot of smoother when your disassembler/decompiler can tell your straight out of the box which API is being called.

In order to hinder analysis, some malware authors use a technique called API name hashing. Instead of direct calls to various API's, the malware uses "magic" values that are resolved in the runtime by the malware itself. So instead of having a sweet, readable disassembly like this:




you will be getting a much harder to read output, looking something like this:



In order to lessen the impact on analysis time we use a core C project called ApiNameHasher. It has support functionality to hash and print our all API's from a single DLL, or you can choose to dump everything for the whole c:\Windows\System32\*.dll

Now, the API hashing technique changes to one malware to the next. Hence the actual hashing is done in a separate function that receives the API name as parameter. That way when we see a new malware using yet another new way of hashing an API name, we can just do a quick reverse engineering of the hashing function and drop it into the ApiNameHasher.

The C code is available on our Github repo

The original code was a bit cluttered after heavy use, but I left 2 sample functions as an example as they use different approaches in the "style".

The first one is called LazarusHasher:


Sometimes it's faster (for us atleast) to just basically copy and edit the assembly code and then paste it as inline assembly in the ApiNameHasher. This approach works easily for 32-bit code. For 64-bit code you cannot inline the assembly, but you can create an .asm file that holds the code and then add a build dependency for MASM, the Microsoft Assembler. This way is useful especially if there are some compiler semantics at play that you don't have the time to figure out.

The second one is called BlackBubbleHasher. It's an internal name we use for a malware that has not been documented publicly yet, but it's basically a next-generation variant of StealthVector from APT41:


In this function, the whole hashing was reverse engineered into C, and then dropped into the ApiNameHasher.

We absolutely love the tool. We can still see the metadata from it's first uses, when it was compiled using Visual Studio 2008. 16 years already and we bet it has still a lot of love left in it.






No comments:

Post a Comment