andrivet / ADVobfuscator

Obfuscation library based on C++11/14 and metaprogramming
1.39k stars 238 forks source link

MetaFSM.h: Predicate and Return value positions are swapped in function template #39

Open PeteHemery opened 3 weeks ago

PeteHemery commented 3 weeks ago

While playing with ObfuscatedCalls and DetectDebugger, I noticed a bug with the macro for returning the result of the function with a predicate.

In ObfuscatedCallWithPredicate.h, these lines:

#define OBFUSCATED_CALL_RET_P0(R, P, f) andrivet::ADVobfuscator::ObfuscatedCallRetP<andrivet::ADVobfuscator::Machine2::Machine, P, R>(MakeObfuscatedAddress(f, andrivet::ADVobfuscator::MetaRandom<__COUNTER__, 400>::value + 278))

#define OBFUSCATED_CALL_RET_P(R, P, f, ...) andrivet::ADVobfuscator::ObfuscatedCallRetP<andrivet::ADVobfuscator::Machine2::Machine, P, R>(MakeObfuscatedAddress(f, andrivet::ADVobfuscator::MetaRandom<__COUNTER__, 400>::value + 278), ##__VA_ARGS__)

define the call to ObfuscatedCallRetP with (machine, P, R) as parameters.

In MetaFSM.h, the template is in the form (machine, R, P):

    // When function F is returning a value
    // FSM: Finite State Machine
    // R: Type of the returned value
    // P: Predicate (functor)
    // F: Function (target)
    // Args: Arguments of target
    template<template<typename, typename, typename> class FSM, typename R, typename P, typename F, typename... Args>
    inline R ObfuscatedCallRetP(F f, Args&&... args)

This was causing strange behaviour, so I first swapped the values in the macros, and then reverted it and changed the underlying template. In using this, I noticed the predicateCounter_ in the FSM isn't initialized to 0, causing very weird behaviour, so added these changes and it seems to be working now.

 $ git diff master -U1
diff --git a/Lib/MetaFSM.h b/Lib/MetaFSM.h
index 8df957a..e9730b3 100644
--- a/Lib/MetaFSM.h
+++ b/Lib/MetaFSM.h
@@ -117,7 +117,7 @@ namespace andrivet { namespace ADVobfuscator {
     // FSM: Finite State Machine
-    // R: Type of the returned value
     // P: Predicate (functor)
+    // R: Type of the returned value
     // F: Function (target)
     // Args: Arguments of target
-    template<template<typename, typename, typename> class FSM, typename R, typename P, typename F, typename... Args>
+    template<template<typename, typename, typename> class FSM, typename P, typename R, typename F, typename... Args>
     inline R ObfuscatedCallRetP(F f, Args&&... args)
@@ -129,2 +129,3 @@ namespace andrivet { namespace ADVobfuscator {
         M machine;
+        machine.predicateCounter_ = 0;
         Run::run(machine, f, std::forward<Args>(args)...);
@@ -146,2 +147,3 @@ namespace andrivet { namespace ADVobfuscator {
         M machine;
+        machine.predicateCounter_ = 0;
         Run::run(machine, f, std::forward<Args>(args)...);

Was wondering if it was worth the faff to create a pull request with forking and what-not, but thought I'd just mention it here, hope it gets fixed on master.

I've been exploring ways of trying to make a proprietary library I'm working on "harder to crack". Thanks for the excellent base from which to build obfuscated code. I added a couple of other methods of detecting debuggers in Linux and Window too. Let me know if you think that's worth a PR.

Thanks again, Pete