[Dailydave] Mutating to avoid structural analysis

Halvar Flake halvar at gmx.de
Tue Dec 18 19:05:26 EST 2007


Hey Dave, all,

I am kinda busy at the moment, so replies will be late / brief.

1. Obfuscation on the callgraph alone will break _some_ part of the
diffing, without rendering it useless -- you still have a ton of
structure on the flowgraphs.
2. Breaking structural comparison is possible, but requires more than
inserting 4 lines of C code into your existing codebase (which is
sufficient for breaking behavioral classification).
3. Even for a 'modest' obfuscation such as the one proposed, one needs
to go through some binary rewriting or at least major preprocessing voodoo.
4. You should make your dispatcher NP-hard to analyze. And quick to
dispatch. Constant table lookups are likely to be optimized away.

So I guess what I am saying is: I think that in order to break
structural classification, you have to do some 'real' work -- rewrite
your binary, build an obfuscating compiler back-end or something along
the lines. Which is more than for most other approahces.

Cheers,
Halvar

> So flying home from JFK I was wondering this...
> 
> Given that avoiding "behavioral signatures" is a matter of calling
> random NOP-like API calls (i.e. CreateFile + CloseHandle == 1 NOP),
> Halvar's program classification techniques involve a structural
> differencing engine. This has advantages (see his talk for details) in
> that program structure closely reflects the semantic meaning of a
> program, as interpreted by a compiler.
> 
> So the obvious way, from what I can tell, to defeat a structural
> differencing algorithm would be to do a static or dynamic analysis of
> your target program, and for each CALL opcode, change the destination
> to a dispatcher function. This dispatcher function can then be built
> to do a O(1) table lookup to find the true destination of the call.
> 
> So now all your functions call one function D. Your call graph is
> meaningless without reverse engineering the dispatcher function and
> reconstructing it, or doing dynamic analysis of the whole program
> (assuming you can get decent code coverage).
> 
> For bonus points you could mutate your dispatcher function by putting
> it as a never-used basic block in lots of other functions. You'd
> probably also want to do some other easy obfuscation.
> 
> So my question is this: is defeating a structural based fingerprint of
> a program more difficult to do than defeating behavioral based
> fingerprints.
> 
> -dave

_______________________________________________
Dailydave mailing list
Dailydave at lists.immunitysec.com
http://lists.immunitysec.com/mailman/listinfo/dailydave



More information about the Dailydave mailing list