Introduction #
In this article, we will explore the fundamental differences between dynamic and static analysis. We will also discuss the advantages and disadvantages each type of analysis offers the reverse engineer. Hopefully the information provided within this blog will afford newer analysts to the field, some exposure to the tools of the trade, the thought process of analysis and a basic understanding of the reverse engineering lifecycle.
What is Static Analysis? #
Static analysis is analysis without execution. Typically, you analyse a binary through a disassembler (such as Ghidra) and requires a working knowledge and understanding of assembly or the language used. The goals of static analysis, as always, are completely dependent upon the point of what you are trying to achieve. This is why it is so incredibly important to leverage the scientific process to define your objectives. Not only does this ensure that you have a clear path forward, but it has the added benefit of serving as a reminder of what you are trying to achieve when you invariably get pulled down a rabbit hole when analysing a sample.
Uses #
Static analysis has many uses within the reverse engineering lifecycle. Most notably, it provides a platform to understand the logic involved in binary execution as well as the functions within a binary. Viewing a binary through a disassembler allows you to rename variables and functions, effectively deobfuscating the code (making it easier for you, the analyst, to read).
By perusing the sample within a disassembler, you can go beyond simply understanding execution flow. This view allows you to identify encryption or compression algorithms used by the binary (if they are present). You can look for the tell-tale signs of encryption such as the presence of constants and inspect the assembly code. Additionally, this thorough inspection of functions can reveal (accidentally) compiled information inside the binary, which could help with sample attribution (as many threat actors leverage the same build info in designing their malware).
This process also allows you to identify and inspect the strings present within a binary. It can also be achieved within the disassembler, or alternatively via command-line tools (conveniently called strings). This is important because the presence of some strings (such as C2 addresses, created files and persistence mechanisms) allow you to quickly identify some capability of the sample you are inspecting.
When performing static analysis, the typical workflow I leverage is:
- Create a project within a disassembler (for me, this is Ghidra)
- Perform auto analysis of the executable using the disassembler (this prompt is provided when you are entering into the sample for the first time)
- Peruse the defined strings list within the binary and identify any items of interest (C2s, domain names, interesting commands, error codes, etc.)
- Work from the main function onwards — determine what this is and use it as a pivot point to understand other functions that are called by main
Where this can come undone is if the malware has a config which is held within C2 infrastructure. This can impact your ability to perform static analysis and you are forced into performing dynamic analysis to retrieve the information (if the C2 is still live and can be retrieved from) to further enable your analysis.
Advantages and Disadvantages #
Advantages | Disadvantages |
---|---|
Do not execute the binary | Cannot read information stored in memory |
Understand execution flow | A lot more effort to understand something statically than dynamically |
Typically you get a greater understanding through taking the time to walk through the flow of execution | Can be impeded by malware that hold additional stages and configurations within C2 infrastructure |
The bottom line really is, static analysis should be used in concert with dynamic analysis.
Tools #
Below is a list of the typical tools that can be leveraged to perform static analysis. I have also included what type of operating system they are used for, where this is appropriate/applicable.
Note that this is not a complete list of tooling available. There are many more tools you can leverage to perform static analysis and every reverse engineer has their favourites. This list will be updated and changed in accordance to my continued growth and exposure to RE.
Tool | Operating System | Type | Notes |
---|---|---|---|
Ghidra | Agnostic | Disassembler | Open source and freely available. This is the ideal disassembler for people who are trying out reverse engineering to see whether they want to jump into the profession. |
IDA Pro | Agnostic | Disassembler | Very expensive licencing involved. This disassembler is typically leveraged by companies who hold a commercial licence. Home licences are restrictive. There is a free version but it is exceptionally limited. |
Binary Ninja | Agnostic | Disassembler | Can be expensive to licence. Like IDA, licences are annually renewed. Also typically used by companies who hold a commercial licence. |
dnSpy | Windows .NET | Disassembler/Debugger | A great disassembler for looking at Windows code. Has the added benefit of including a debugger as well, which allows you to perform dynamic analysis on .NET executables. |
PEStudio | Windows | PE Header Inspector, file hashes, libraries and strings | The free version of this tool is great for analysis, but interestingly, they also have a paid version (basically allowing batch mode for analysis). This program is typically used to inspect the PE header of Windows executables. It provides some great information about what is going on in the binary, including information on whether the binary is packed. Also has VirusTotal integration. |
Resource Hacker | Windows | Windows resources (.rc files) | Both a resource compiler and decompiler where you can edit and view resources in executables. It has a GUI (this is the primary way to interact with it), but also contains many command line resources. |
What is Dynamic Analysis? #
If static analysis is analysis without execution, dynamic analysis is analysis through execution of a binary. Here, you can monitor changes to the network, file system, running process, file handles etc. Dynamic analysis can be anything from double-clicking the binary and allowing the malware to run on an endpoint, to working through the executable using a debugger. It allows you to coax a sample into performing its malicious actions on the endpoint, which then allows you to confirm or disprove your assumptions from previous analysis.
Uses #
The most interesting (and scary) aspect of dynamic analysis is actually allowing the malware to achieve its objectives through running the application on your virtual machine. There are of course risks that come with performing this analysis (and sometimes you might get a robust enough signature through pure static analysis, if you’re lucky) because you are literally infecting your computer (and risking VM escapes in more crafty samples). Assumptions compound in static analysis, so running it dynamically actually validates them.
Network connections can be viewed and established using this form of analysis, which can grant you access to additional payloads and thus, enables the analyst to develop a deeper knowledge and understanding of the sample in question (is this a dropper? Does the malware rely on a config to operate successfully?). It provides intriguing and concrete clues as to what malware type you are dealing with, and additionally, potentially the threat actor. The tooling is also significantly different and allows you to packet capture these network connections, which can be information that is unavailable in static analysis, particularly where significant obfuscation is in play.
This form of analysis also provides an alternative way to analyse packed binaries — identifying the tail jump to find the original entry point, unpacking the binary for you (which can be dumped via memory) and reconstructing the import table. Additionally, you can inspect the impact the malware is having on memory addresses as you load it into a debugger and step through each function as the sample calls it.
As always, it is incredibly important to ensure that you have robust notes as you step through the program. Most debuggers, like our disassemblers, will allow you to make notes via comments in the code (or have a setting in them that basically turns on comments for each instruction made by the malware, looking at you x64dbg).
The ‘standard operating procedure’ for dynamic analysis will depend on what platform and malware type you are dealing with. This form of analysis will require the use of many more tools (typically) than static, as you are interested in understanding impact on the endpoint and network. Typically, no less than 3 tools will be employed in any given dynamic analysis:
- Packet capturing application or command line tool to understand network connections and activities
- Debugger to step through and into functions, to understand their impact on disk and again network activities
- RegShot or something similar for Windows, to determine whether there are persistence mechanisms in the registry
- Sysinternal suite to look at spawned processes on a Windows endpoint, and any installed applications/programs by the malware (the impact it has on disk)
- Glancesis a good alternative for MacOS systems to perform a similar function to the sysinternal suite
Advantages and Disadvantages #
Advantages | Disadvantages |
---|---|
You can extract information that is not available during static analysis from memory | Execution of the malware requires a safe operating environment |
You can access network activity and create robust signatures from that information | You are infecting the machine you are running the sample on |
You can potentially find additional malware called by the sample | There could be a risk of VM escape, depending on the malware you are analysing |
You can determine what functions are actually being used by the malware by stepping through the program | Where you cannot reconstruct the import table, it makes it quite hard to actually perform dynamic analysis |
Tools #
Just like the static analysis tool set, this table is not exhaustive.
Tool | Operating System | Type | Notes |
---|---|---|---|
Ollydbg | Windows | Debugger | An older debugger that has frozen development, unfortunately. There are still aspects and plugins to this that are deeply helpful and great. Its a fantastic little debugger. |
Windbg | Windows | Debugger | Microsofts answer to debugging. This has quite a steep learning curve (jn my opinion), but once you get used to it, its deeply powerful for Windows malware analysis. |
x32/x64dbg | Windows | Debugger | A go to set of debuggers for most programs. Its designed to mirror some aspects of IDA to make it more friendly and easier to use for folks that leverage that more. Its open source, and generally a great debugger. Interestingly, this program also contains a mnemonic summary setting that basically turns on comments, telling you what is happening with each instruction in the program. |
Sysinternal Suite | Windows | Debugger | A whole host of useful tools provided by Microsoft. There is some significant overlap here between reverse engineering and forensic analysis in terms of use. Stand out is definitely procmon, but it also includes other applications that analyse network traffic and other aspects of executables. Definitely worth installing if you are analysing Windows executables. Check out the link to learn more about all of the goodies included or simply install Flare on your VM. |
Wireshark | Agnostic | Packet Capture | Operating system agnostic, this program is perhaps one of the most famous of the lot and needs no introduction. A great and powerful GUI is included that enables you to do all sorts of filtering for network traffic and inspection. |
DNS Server | Agnostic | DNS Server | Now I have placed this here as a tool because it helps perform network analysis in a closed off, safe space. By setting one of these up, you can pretend the malware can access the internet, to determine whether network connections are made. This can be a nice, safe way to assess whether the malware has multiple stages before you just open it to the internet and download additional items. |
GDB | *Nix/Windows | Debugger | A classic debugger available on the commandline on most nix distributions (else easily able to install). Last I heard this had not been ported to ARM and is not available on Apple Silicon devices. |
LLDB | MacOS | Debugger | Next generation, high-performance debugger that is the default debugger in Xcode on MacOS. It supports debugging C, Objective-C and C++ on the desktop and iOS devices (or similar). |
Glances | MacOS/Linux | Monitoring Tool | Open source and written in python, this program is a nice way to get similar functionality to the sysinternal suite on MacOS and Nix systems. |
RegShot | Windows | Registry Monitoring | An open source tool that allows you to take a snapshot of registry changes in Windows operating systems. A before and after snapshot is taken and the program compares the two, highlighting newly created registry information. There can be a lot of information to sift through, particularly in modern Windows OS where a lot of registry information is dynamically created. Still a very powerful and useful tool for malware analysis. |
Summary #
At the end of the day, both static and dynamic analysis make up two critical components of the reverse engineering lifecycle. Both come with their own advantages and disadvantages, which is why it is so critical that they are used in conjunction with one another to perform your analysis. Generally speaking, static analysis is performed before dynamic to ensure that at least a high-level understanding of the executable is established in order to minimise risk when running it dynamically.
In all instances of reversing a sample, it is critical to maintain a safe operating environment on the platform of your choice, and to employ the scientific process (hypothesis, aims, objectives, analysis and summary) to ensure that you have clear, repeatable objectives and results when performing your analysis.
As always, remember you are not infallible. Reverse engineering, particularly malware, is all about making and learning from your mistakes as you stumble through analysis and slowly grow in exposure to different coding languages, malware authors and families. If you find yourself overwhelmed, that is completely fine, just walk away, make yourself a cup of tea/coffee and try again later! You are looking at the same information over and over again with the same set of eyeballs (I hope), so you can and will miss things. Go back to the basics when you are refreshed and try to enjoy getting lost and learning the art of reversing!