Tommy

The Trace · Episode 75

Code Style Attribution

1,924 words

Tommy The Hamburger here, following the trace. One hair, one login, one smear, one weird little inconsistency, that's all it takes to bury a lie. Most motherfuckers look at the big mess. I look at the stubborn little detail that refuses to shut the fuck up. Listen close, because every fucking cover up sheds something, and every scrap of residue can rat that shit out. The trace is repeated coding style inside malware and public code. I am in a malware lab with decompiled source on one screen and old public repository snapshots on another, the room smelling like hot dust, old coffee, and plastic warmed by too many monitors. The banking trojan in front of me is nasty enough, but the first thing that catches my eye is not what it steals. It is how it was written. The same weird little fucking naming habit keeps surfacing. The same kind of comments. The same way the coder handles errors. That is the clue, and it is fucking louder than the obfuscation wrapped around it. People outside software think code is pure logic, like math poured into a machine. It is not. Code has habits in it. Some coders name things one way and stick to it. Some mix styles without noticing. Some leave comments that explain why they did something instead of what it does. Some build the same shape of helper function over and over because that shape feels natural in their hands. That is what makes coding style a trace. Not one choice. Repeated choices that hang together like a personality. The malware sample keeps mixing naming styles in a way that should not be there if the author were cleanly following one language culture. One variable reads like polished camel case. Another looks flattened and rushed. Then the error handling kicks in with the same little structure I see in a public code repository tied to one freelance developer. Same kind of custom exception wrapper. Same kind of comment dropped right above a risky branch. Same kind of neat little preference for readability over elegance. One match would be cute. A cluster is a problem. That is how the trace got there. The malware author wrote malicious code with the same hands they used for ordinary work. People imagine a criminal coder transforms into some separate species once the code turns evil. Bullshit. Most of the time they drag their old habits straight into the bad work. Same fingers. Same muscle memory. Same private sense of what clear code looks like. Obfuscation can scramble the surface, but it often leaves the deeper structure and recurring habits behind. That is also why the trace survives. The coder has to make hundreds of tiny decisions while building the thing. How big should this function be. How do I name this helper. Do I explain this ugly section or leave it naked. What do I call the wrapper around a failure. Those decisions pile up faster than a person can consciously sanitize them. Even if they remember to rename the loud obvious pieces, they usually keep solving problems in the same shape they always do. That shape is what I am following. So I pull public code samples from the suspected developer and compare them at the human level first. Not fake wizard math. Not instant destiny. Just repeated habits. Mixed naming conventions. Similar comment rhythm. Similar logic decomposition. Similar ways of guarding dangerous operations. The public code and the malware do not need to be identical line for line to smell like the same author. They just need to keep making the same kinds of choices when choices did not have to be made that way. That is why this trace matters. Malware can be packed, renamed, and shuffled through layers of crap to hide what it does. But the coder still has to solve problems as they go. They still choose how to break up functions. They still choose whether to comment and where. They still choose how to name the ugly temporary variable they think nobody will care about. Those small choices keep adding up until the code starts sounding like a voice instead of a machine. I line the malware against the public repository over multiple sections, not just one lucky overlap. Credential handling. Input validation. Logging decisions. Failure recovery. The same hand seems to keep showing itself. A habit of writing explanatory comments before messy logic. A habit of wrapping lower level failure in one more named layer instead of letting it fall raw. A habit of mixing a polished style in one block with a sloppier one in the next because the coder lives in more than one programming culture and never fully cleans the border between them. That is not proof from heaven, but it is one hell of a narrowing trace. And once the narrowing starts, other things that looked ordinary stop looking ordinary. A helper pattern from the public repo shows up wearing different clothes in the malware. A familiar arrangement of validation and retry logic reappears where it did not have to. The code is not copying one big public chunk like a complete idiot. It is doing something more human than that. It is reusing taste. Reusing reflex. Reusing the same internal sense of how to build a solution when the pressure is on. Then I check what everybody else missed. Security analysts were staring at indicators of compromise, command channels, network behavior, all the loud obvious machine level stuff. Good. They should. But they were not reading the code like authored work. They were reading it like a hostile object only. That is the mistake. A program is also a piece of writing. Somebody built it. Somebody made choices in it. If you ignore the authorship layer, you throw away one of the nastiest little clues in the whole file. There is a negative trace here too. The malware does not show the marks you would expect from heavily automated code generation or a big shared criminal development team sanding every surface smooth. Too many personal little quirks survive. Too much internal consistency in the habits. Too much repeated preference in places where a committee or generator would usually flatten things out. That missing flattening matters because it narrows the field toward one primary author path instead of a faceless code mill. It also rules out a lot of lazy alternate stories. This does not read like a one off copy paste job by a low skill criminal stitching together stolen snippets from ten different sources. It does not read like an outsourced rush job passed through too many hands. It does not read like fully machine generated sludge where every section feels equally bland and equally dead. The same living preferences keep surfacing in too many important places. That matters because ruling out the wrong kinds of authors is part of how the trace earns its weight. That narrowing is the whole payoff. The trace does not have to scream this exact person beyond all doubt all by itself. It only has to do honest work. It cuts the field from countless anonymous coders down to a real source path with public samples, repeatable habits, and testable overlap. That is enough to justify looking harder at build history, machine use, repository timelines, and all the boring records that become a lot more interesting once one likely author starts standing under the light. Once the style trace points at one developer, the rest of the work becomes testable instead of dreamy. Build times can be checked. Local repository history can be checked. Old snippets can be checked. Public commits can be checked. The trace does not need to solve the whole case alone. It just needs to cut the search space down to a real path. That is what it does here. It turns anonymous malware into authored behavior. And that authored behavior survives for the same reason handwriting survives. Habit is cheap for the brain and expensive to break. A coder under deadline or stress reaches for familiar patterns. A motherfucker can change the variable names in a hurry and still leave the same structure underneath. They can rip comments out of one file and still build helper functions the same way in the next. They can hide their IP address better than they can stop being themselves in code. That is what people missed while they were hypnotized by malware capability. They saw what the code could do and forgot to ask who would naturally write it that way. They treated the sample like an evil appliance that had simply appeared on earth. It did not. A human built it. A human left preferences all through it. A human kept choosing the same little solutions they had already chosen in cleaner public work. The code was carrying the author's habits like lint on a black shirt. That is also why obfuscation did not save the author here. Obfuscation can tangle names, shuffle flow, and make the file uglier to read. It does not always erase taste. The coder still tends to arrange logic in familiar layers. They still tend to guard risky operations in familiar ways. They still tend to prefer one kind of readability over another. If the sample is rich enough, that old self keeps showing through the camouflage, and that is exactly what happened here. When I brief the team, I keep it plain. This malware was not just built by someone skilled. It was built by someone whose coding habits already existed in the open. The public code was the clean shirt. The malware was the bloody one. Same shoulders underneath. Once you see that, the rest of the case stops feeling abstract. That is why this clue mattered more than any one malicious feature inside the sample. Features can be bought, copied, or borrowed. Style is harder to fake across a whole body of work. The trojan could steal credentials all day and still tell you less about the author than the repeated little ways its builder thought through a problem. That is the ugly beauty of this trace. The code kept confessing authorship even while the malware was trying to hide intent. Fuck me sideways, the code read like the same motherfucker trying to wear gloves over handwriting he never learned to disguise. That is where the polite version goes to shit and the trace starts fucking up the pattern. Once the behavior line holds, every polished explanation sounds like bullshit and every clean persona looks half fucked. That is why I trust the ugly habit scrap more than the official script, because the trace does not give a shit who rehearsed the story and it will fuck the cover self anyway. After that, the case is not subtle, it is just a shit wrapped performance with one fucked routine still telling the truth. What the repeated coding style proved was that the malware was not just a floating criminal tool with no human trail behind it. It carried the same structural and stylistic habits found in a specific developer's public code, which narrowed authorship to a real source path worth testing. It mattered because the style trace turned decompiled malware from a technical artifact into a piece of authored behavior tied to one likely coder instead of a faceless attacker myth. That's the trace for today. Now you know what happened. Every residue tells a story if you're willing to follow it.