This cheat sheet presents tips for analyzing and reverse-engineering malware. It outlines the steps for performing behavioral and code-level analysis of malicious software. To print it, use the one-page PDF version; you can also edit the Word version to customize it for you own needs.
Overview of the Malware Analysis Process
- Use automated analysis sandbox tools for an initial assessment of the suspicious file.
- Set up a controlled, isolated laboratory in which to examine the malware specimen.
- Examine static properties and meta-data of the specimen for triage and early theories.
- Emulate code execution to identify malicious capabilities and contemplate next steps.
- Perform behavioral analysis to examine the specimen's interactions with its environment.
- Analyze relevant aspects of the code statically with a disassembler and decompiler.
- Perform dynamic code analysis to understand the more difficult aspects of the code.
- If necessary, unpack the specimen.
- Repeat steps 4-8 above as necessary (the order may vary) until analysis objectives are met.
- Augment your analysis using other methods, such as memory forensics and threat intel.
- Document findings, save analysis artifacts and clean-up the laboratory for future analysis.
- Be ready to revert to good state via virtualization snapshots, Clonezilla, dd, FOG, PXE booting, etc.
- Monitor local interactions (Process Hacker, Process Monitor, ProcDOT, Noriben).
- Detect major local changes (RegShot, Autoruns).
- Monitor network interactions (Wireshark, Fiddler).
- Redirect network traffic (fakedns, accept-all-ips).
- Activate services (INetSim or actual services) requested by malware and reinfect the system.
- Adjust the runtime environment for the specimen as it requests additional local or network resources.
Ghidra for Static Code Analysis
|Go to specific destination||g|
|Show references to selected instruction||Ctrl+Shift+f|
|Insert a comment||;|
|Follow jump or call||Enter|
|Return to previous location||Alt+Left|
|Go to next view||Alt+Right|
|Define data type||t|
|Add a bookmark||Ctrl+d|
|Add or edit a label||l|
|Disassemble selected values||d|
x64dbg/x32dbg for Dynamic Code Analysis
|Run the code||F9|
|Step into/over instruction||F7 / F8|
|Execute until selected instruction||F4|
|Execute untill next return||Ctrl+F9|
|Show previous/next executed instruction||- / +|
|Return to previous view||*|
|Go to specific expression||Ctrl+g|
|Insert comment/label||; / :|
|Show current function as a graph||g|
|Set software breakpoint on specific instruction||Select instruction » F2|
|Set software breakpoint on API||Go to Command prompt » SetBPX API Name|
|Highlight all occurrences of the keyword in disassembler||h » Click on keyword|
|Assemble instruction in place of selected one||Select instruction » Spacebar|
|Edit data in memory or instruction opcode||Select data or instruction » Ctrl+e|
|Extract API call references||Right-click in disassembler » Search for » Current module » Intermodular calls|
Unpacking Malicious Code
- Determine whether the specimen is packed by using Detect It Easy, Exeinfo PE, Bytehist, peframe, etc.
- To try unpacking the specimen quickly, infect the lab system and dump from memory using Scylla.
- For more precision, find the Original Entry Point (OEP) in a debugger and dump with OllyDumpEx.
- To find the OEP, anticipate the condition close to the end of the unpacker and set the breakpoint.
- Try setting a memory breakpoint on the stack in the unpacker's beginning to catch it during cleanup.
- To get closer to the OEP, set breakpoints on APIs such as LoadLibrary, VirtualAlloc, etc.
- To intercept process injection set breakpoints on VirtualAllocEx, WriteProcessMemory, etc.
- If cannot dump cleanly, examine the packed specimen via dynamic code analysis while it runs.
- Rebuild imports and other aspects of the dumped file using Scylla and pe_unmapper.
Bypassing Other Analysis Defenses
- Decode obfuscated strings statically using FLOSS, xorsearch, Balbuzard, etc.
- Decode data in a debugger by setting a breakpoint after the decoding function and examining results.
- Conceal x64dbg/x32dbg via the ScyllaHide plugin.
- To disable anti-analysis functionality, locate and patch the defensive code using a debugger.
- Look out for tricky jumps via TLS, SEH, RET, CALL, etc. when stepping through the code in a debugger.
- If analyzing shellcode, use scdbg and runsc
- Disable ASLR via setdllcharacteristics and CFF Explorer.
If you have suggestions for improving this cheat sheet, please let me know. Creative Commons v3 "Attribution" License for this cheat sheet version 2.2.
Updated July 20, 2021