Ever watch a detective movie where the hero dusts for fingerprints? They know the clues are there, but they’re invisible to the naked eye. They need a special tool to make them appear.
In the world of malware analysis, we have a similar situation. We often start by running a simple command called strings on a suspicious file. It’s like a quick scan of the crime scene, showing us any readable text hidden inside the code. Sometimes, we get lucky and find a malicious URL or a suspicious command right away.
But here’s the thing: malware authors know we’re going to do that. They’re not just leaving clues out in the open. They’ve gotten incredibly clever at hiding their tracks, scrambling, encoding, and burying the most important pieces of information—the Indicators of Compromise (IOCs)—deep within the executable.
So, what do we do? We pull out our own version of fingerprint powder: a fantastic open-source tool from Mandiant called FLARE-FLOSS. It goes way beyond a simple text scan and helps us reveal the secrets that malware tries so desperately to hide.
Let's walk through what this actually looks like. It’s one thing to talk about it, but it’s another to see it in action.
Setting the Stage: Gearing Up with the Right Tools
Before we can start our investigation, we need our toolkit. In this case, it’s pretty straightforward. We need to get FLOSS installed, which is easily done with Python's package manager, pip.
We also need a cross-compiler called MinGW-w64. Why? Because we’re going to create our own "practice" malware on a Linux machine, but we need to compile it to run on Windows (as a PE file, which is just the technical term for a Windows executable). Think of the compiler as a translator that turns our C code blueprint into a functional Windows program.
Once we’ve got both installed, we’re ready to build our target.
Creating a 'Sparring Partner': Our Fake Malware
To really see what FLOSS can do, we can’t just grab any old malware. For a learning exercise, it’s much safer (and more effective) to build our own harmless sample. This way, we know exactly what secrets are hidden inside and can see if our tool actually finds them.
So, we'll write a small C program that mimics some common malware techniques. We’re not building anything malicious, just a file that uses the same hiding spots.
Here are the tricks we’ll build into our little program:
- Plain Static Strings: This is the easy one. It’s just a regular piece of text stored in the file, like "HELLO_FROM_TUTORIAL". The standard
stringscommand should find this with no problem. - Stack Strings: This is a bit sneakier. Instead of storing a full string, the malware builds it one character at a time in a temporary memory area called the stack. To a simple tool, it doesn't look like a string at all, just a bunch of separate character assignments.
- Tight Strings: This is similar to a stack string, where characters are defined one by one right next to each other in an array. It’s another way to avoid creating an obvious, continuous block of text in the file.
- Encoded Strings: This is the real cloak-and-dagger stuff. We'll take our most sensitive secrets—like a fake command-and-control (C2) server URL, a Windows registry key for persistence, and a suspicious API call—and "scramble" them using a simple XOR cipher. The program only decodes them in memory right before it needs to use them.
With our C code written, we use our MinGW compiler to build sample.exe. Now we have a safe, synthetic piece of malware that’s packed with secrets, ready for analysis.
The First Pass: What the Naked Eye Can See
Okay, let's start with the basics. We run the classic strings utility on our sample.exe. What do we get?
Unsurprisingly, it finds our plain static string right away. No problem there.
But what about the others?
- The stack-built string? Missed.
- The tight string? Missed.
- The XOR-decoded URL, registry key, and API call? Completely missed. All
stringssees is a jumble of meaningless garbage characters.
This is the core problem. If you were an analyst relying only on this first-pass tool, you’d miss every single one of the most important clues. You wouldn't know where the malware was communicating, how it was trying to stay on the system, or what dangerous functions it was planning to call. You’d be flying blind.
Unleashing FLOSS: Time for Some Deep Analysis
Now, it’s time to bring in the specialist. We run FLOSS on the exact same sample.exe file.
FLOSS doesn’t just skim the surface. It performs a much deeper analysis in two key ways:
- Advanced Static Analysis: It meticulously analyzes the program's code without running it, looking for patterns that indicate string decoding routines or other obfuscation techniques.
- Code Emulation: This is the really cool part. FLOSS runs parts of the code in a safe, virtual environment. It watches as the program decodes its own secrets and snatches them right out of memory the moment they become readable. It’s like having a spy inside the program, reporting back on what it’s up to.
The process takes a bit longer than the simple strings command—maybe a minute or so—but the results are well worth the wait. FLOSS saves everything it finds into a nicely structured JSON file, ready for us to examine.
Sifting Through the Evidence: Making Sense of the FLOSS Report
When we open the FLOSS output, it’s like turning on a blacklight at a crime scene. Suddenly, all the hidden messages appear. FLOSS neatly categorizes everything it found:
- Static Strings: Yep, it found the easy one, just like
stringsdid. - Stack Strings: Found! FLOSS’s analysis was smart enough to see us building the string character-by-character and pieced it back together.
- Tight Strings: Found! It recognized this pattern, too.
- Decoded Strings: Jackpot! This is where the magic happens. FLOSS not only found our scrambled secrets but also tells us how and where they were decoded. We get the fully readable text:
- The fake C2 server URL:
https://c2-totally-fake.example/beacon - The registry path for persistence:
SOFTWARE\Microsoft\Run\PersistDemo - The suspicious API call:
kernel32.dll!VirtualAllocEx
- The fake C2 server URL:
This is a night-and-day difference. We went from having almost no actionable intelligence to having a clear map of the malware’s intentions.
Connecting the Dots: From Gibberish to Actionable Intel
With this treasure trove of deobfuscated strings, we can start hunting for specific IOCs. We can automatically scan the results for patterns that match URLs, IP addresses, file names, registry keys, or Windows API calls.
And when we do, we find that all the most critical hits—the URL, the registry path—were found in the "decoded" bucket. These were the clues that were completely invisible before FLOSS did its work. This is the information that allows a security team to block a domain, check other machines for the same registry key, and understand the malware's capabilities.
To make it even clearer, we can even visualize the results. A simple bar chart can show us how many strings were found in each category (static, stack, decoded, etc.). It often highlights just how much critical information is hidden away in those decoded strings, driving home the point that a surface-level analysis is never enough.
So, what’s the big takeaway here?
Modern malware is designed to be evasive. It assumes we’re going to look for the easy clues. But tools like FLARE-FLOSS have changed the game. By combining deep static analysis with clever code emulation, we can peel back the layers of obfuscation and see what’s really going on underneath.
It’s a powerful reminder that in the cat-and-mouse game of cybersecurity, having the right tools and knowing how to go beyond the basics is what separates a missed threat from a successful investigation.




