Full Code of revsic/cpp-obfuscator for AI

master 3dd832715270 cached
29 files
41.0 KB
11.6k tokens
112 symbols
1 requests
Download .txt
Repository: revsic/cpp-obfuscator
Branch: master
Commit: 3dd832715270
Files: 29
Total size: 41.0 KB

Directory structure:
gitextract_9t2uq1pg/

├── .gitignore
├── .gitmodules
├── 3RD-PARTY.md
├── LICENSE
├── README.md
├── azure-pipelines.yml
├── obfuscator/
│   ├── obfs/
│   │   ├── fsm.hpp
│   │   ├── random.hpp
│   │   ├── sequence.hpp
│   │   └── string.hpp
│   └── obfuscator.hpp
├── obfuscator.hpp
├── sample/
│   ├── CMakeLists.txt
│   ├── random.cpp
│   ├── state_machine.cpp
│   └── string_obfs.cpp
├── script/
│   ├── Dockerfile.bionic
│   ├── __init__.py
│   ├── azure-pipelines-template-mac.yml
│   ├── azure-pipelines-template-unix.yml
│   ├── azure-pipelines-template-win.yml
│   ├── merge.py
│   └── string_obfs_tester.py
└── test/
    ├── CMakeLists.txt
    ├── impl/
    │   ├── fsm.cpp
    │   ├── random.cpp
    │   ├── sequence.cpp
    │   └── string.cpp
    └── main.cpp

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# editor
.vscode

# build
build

# cl with debug option
*.ilk
*.obj
*.pdb

# sample program
*.exe

# python cache
__pycache__

================================================
FILE: .gitmodules
================================================
[submodule "external/Catch2"]
	path = external/Catch2
	url = https://github.com/catchorg/Catch2


================================================
FILE: 3RD-PARTY.md
================================================
cpp-obfuscator uses Catch2 for testing obfuscator modules

Boost Software License - Version 1.0 - August 17th, 2003

Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:

The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

---

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2019 YoungJoong Kim

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# cpp-obfuscator
[![License](https://img.shields.io/badge/Licence-MIT-blue.svg)](https://github.com/revsic/cpp-obfuscator/blob/master/LICENSE)
[![Build Status](https://dev.azure.com/revsic99/cpp-obfuscator/_apis/build/status/revsic.cpp-obfuscator?branchName=master)](https://dev.azure.com/revsic99/cpp-obfuscator/_build/latest?definitionId=3&branchName=master)

C++ implementation of compile time obfuscator

## Compiler Support
| Compiler | Version |
| -- | -- |
| Visual Studio | 2019 |
| Clang++ | 8.0 |
| g++ | 7.3 |
| Apple Clang | Mojave |

## Usage

Use existing single header [obfuscator.hpp](./obfuscator.hpp) or run [script](./script/merge.py) to merge multiple headers in directory [obfuscator](./obfuscator).

```bash
python -m script.merge
```

Include [obfuscator.hpp](./obfuscator.hpp) to use it.
```C++
#include "../obfuscator.hpp"

template <char key>
constexpr char xor_(char c) {
    return c ^ key;
}

std::cout << obfs::make_string<xor_<0x50>, xor_<0x50>>("Hello World !\n").decode();
```

## String

Compile time string obfuscator. No more raw string in binary, sample [string_obfuscator](./sample/string_obfs.cpp).

0. Sample encoder, decoder
```C++
template <char key>
constexpr char xor_(char c) {
    return c ^ key;
}

template <char Key>
constexpr char add(char c) {
    return c + Key;
}

template <char(*f)(char), char(*g)(char)>
constexpr char comp(char c) {
    return f(g(c));
}
```

1. Single encoder, decoder.
```C++
std::cout << obfs::make_string<xor_<0x50>, xor_<0x50>>("Hello World !\n").decode();
```

2. Multiple encoder, decoder and random selection.
```C++
using table = obfs::make_table<
    obfs::encoder_seq<xor_<0x50>, add<10>, comp<xor_<0x50>, add<10>>>,
    obfs::decoder_seq<xor_<0x50>, add<-10>, comp<add<-10>, xor_<0x50>>>>;

std::cout << obfs::make_string<table>("Hello World !\n").decode();
```

3. Multiple encoder, decoder as pair.
```C++
using table = obfs::make_pair_table<
    obfs::encoder_pair<xor_<0x50>, xor_<0x50>>,
    obfs::encoder_pair<add<10>, add<-10>>,
    obfs::encoder_pair<comp<xor_<0x50>, add<10>>, comp<add<-10>, xor_<0x50>>>
>;

std::cout << obfs::make_string<table>("Hello World !\n").decode();
```

4. String obfuscator macro.
```C++
MAKE_STRING(str, "Hello World !\n", table);
std::cout << str.decode();
```

## Finite state machine

Compile time finite state machine based routine obfuscator, sample [state_machine](./sample/state_machine.cpp).

0. Make state table.
```C++
using namespace obfs;
using machine = StateMachine<
    Stage<state1, Next<event5 , state2, Dummy::dummy1>,
                  Next<event1 , state3, Dummy::dummy3>>,
    Stage<state2, Next<event2 , state4>>,
    Stage<state3, Next<None   , state3>>,
    Stage<state4, Next<event4 , state1>,
                  Next<event3 , state5, Dummy::dummy2>>,
    Stage<state5, Next<Trigger, Final, Action::action>>>;
```

1. Run state machine, each execution returns next state.
```C++
auto next1 = machine::run(state1{}, event5{}); // dummy1 executed
auto next2 = machine::run(next1, event2{});
auto next3 = machine::run(next2, event3{});    // dummy2 executed
auto next4 = machine::run(next3, Trigger{});   // action executed
```

================================================
FILE: azure-pipelines.yml
================================================
jobs:
- template: script/azure-pipelines-template-mac.yml
  parameters:
    name: macOS
    vmImage: macOS-10.14

- template: script/azure-pipelines-template-unix.yml
  parameters:
    name: Linux
    vmImage: ubuntu-16.04

- template: script/azure-pipelines-template-win.yml
  parameters:
    name: Windows
    vmImage: windows-2019


================================================
FILE: obfuscator/obfs/fsm.hpp
================================================
#ifndef OBFS_FINITE_STATE_MACHINE
#define OBFS_FINITE_STATE_MACHINE

#include "sequence.hpp"

#include <type_traits>

namespace obfs {
    void FreeAction() {}

    template <typename Event, typename State, void(*Action)() = FreeAction>
    struct Next {
        using event = Event;
        using state = State;
        constexpr static void(*action)() = Action;
    };

    struct None {};

    template <typename State, typename... Nexts>
    struct Stage {
        using state = State;

        template <typename NextInfo, typename Event>
        using act = std::conditional_t<
            std::is_same_v<typename NextInfo::event, Event>, NextInfo, Pass>;

        template <typename Event>
        using next = typename First<None, act<Nexts, Event>...>::type;
    };

    template <typename Stage_, typename Event>
    struct next_stage {
        using type = typename Stage_::template next<Event>;
    };

    template <typename Event>
    struct next_stage<None, Event> {
        using type = None;
    };

    template <typename State>
    struct action_invoker {
        static auto action() {
            State::action();
            return typename State::state{};
        }
    };

    template <>
    struct action_invoker<None> {
        static auto action() {
            return None{};
        }
    };

    template <typename... Specs>
    struct StateMachine {
        template <typename State, typename StageT>
        using filter = std::conditional_t<
            std::is_same_v<typename StageT::state, State>, StageT, Pass>;

        template <typename State>
        using find = typename First<None, filter<State, Specs>...>::type;

        template <typename State, typename Event>
        using next_t = typename next_stage<find<State>, Event>::type;

        template <typename State, typename Event>
        static auto run(State state, Event event) {
            using next_state = next_t<std::decay_t<State>, std::decay_t<Event>>;
            return action_invoker<next_state>::action();
        }
    };
}

#endif

================================================
FILE: obfuscator/obfs/random.hpp
================================================
#ifndef COMPILE_TIME_RANDOM
#define COMPILE_TIME_RANDOM

namespace obfs {
    using size_t = decltype(sizeof(void*));

    constexpr char TIME[] = __TIME__;
    constexpr int digit(char c) {
        return c - '0';
    }
    constexpr size_t SEED = digit(TIME[7]) +
                         digit(TIME[6]) * 10 +
                         digit(TIME[4]) * 60 +
                         digit(TIME[3]) * 600 +
                         digit(TIME[1]) * 3600 +
                         digit(TIME[0]) * 36000;

    template <size_t Seed, size_t Idx>
    struct Xorshiftplus {
        using prev = Xorshiftplus<Seed, Idx - 1>;

        constexpr static size_t update() {
            constexpr size_t x = prev::state0 ^ (prev::state0 << 23);
            constexpr size_t y = prev::state1;
            return x ^ y ^ (x >> 17) ^ (y >> 26);
        }

        constexpr static size_t state0 = prev::state1;
        constexpr static size_t state1 = update();

        constexpr static size_t value = state0 + state1;
    };

    template <size_t Seed>
    struct Xorshiftplus<Seed, 0> {
        constexpr static size_t state0 = Seed;
        constexpr static size_t state1 = Seed << 1;
        constexpr static size_t value = state0 + state1;
    };

    template <size_t Idx, size_t Mod>
    constexpr size_t RAND_VAL = Xorshiftplus<SEED, Idx>::value % Mod;
}

#define MAKE_RAND_VAL(MOD) obfs::RAND_VAL<__LINE__, MOD>

#endif

================================================
FILE: obfuscator/obfs/sequence.hpp
================================================
#ifndef COMPILE_TIME_SEQUENCE
#define COMPILE_TIME_SEQUENCE

#include <type_traits>

namespace obfs {
    template <typename T, T Val>
    struct TypeVal {
        using value_type = T;
        constexpr static T value = Val;
    };

    struct Nothing {};

    template <typename T, T Val, T... Others>
    struct Sequence {
        using value = TypeVal<T, Val>;
        using next = Sequence<T, Others...>;

        constexpr static std::size_t size = 1 + sizeof...(Others);

        template <std::size_t Idx>
        using index = std::conditional_t<Idx == 0, value, typename next::template index<Idx - 1>>;
    };

    template <typename T, T Val>
    struct Sequence<T, Val> {
        using value = TypeVal<T, Val>;

        constexpr static std::size_t size = 1;

        template <std::size_t Idx>
        using index = std::conditional_t<Idx == 0, value, Nothing>;
    };

    template <typename T, typename... Ts>
    struct TypeSeq {
        using type = T;
        using next = TypeSeq<Ts...>;

        constexpr static std::size_t size = 1 + sizeof...(Ts);

        template <std::size_t Idx>
        using index = std::conditional_t<Idx == 0, type, typename next::template index<Idx - 1>>;
    };

    template <typename T>
    struct TypeSeq<T> {
        using type = T;

        constexpr static std::size_t size = 1;

        template <std::size_t Idx>
        using index = std::conditional_t<Idx == 0, type, Nothing>;
    };

    template <std::size_t Val, std::size_t... Others>
    struct MinVal {
        constexpr static std::size_t value = 
            Val < MinVal<Others...>::value ? Val : MinVal<Others...>::value;
    };

    template <std::size_t Val>
    struct MinVal<Val> {
        constexpr static std::size_t value = Val;
    };

    template <typename... T>
    struct SeqPack {
        constexpr static std::size_t size = MinVal<T::size...>::value;

        template <std::size_t Idx, typename U>
        using getter = typename U::template index<Idx>;

        template <std::size_t Idx>
        using index = TypeSeq<getter<Idx, T>...>;
    };

    struct Pass {};

    template <typename IfAllPass, typename T, typename... Ts>
    struct First {
        using type = std::conditional_t<
            std::is_same_v<T, Pass>,
            typename First<IfAllPass, Ts...>::type,
            T>;
    };

    template <typename IfAllPass, typename T>
    struct First<IfAllPass, T> {
        using type = std::conditional_t<
            std::is_same_v<T, Pass>,
            IfAllPass,
            T>;
    };
}

#endif

================================================
FILE: obfuscator/obfs/string.hpp
================================================
#ifndef OBFS_STRING
#define OBFS_STRING

#include "random.hpp"
#include "sequence.hpp"

#include <utility>

namespace obfs {
    using Encoder = char(*)(char);
    using Decoder = char(*)(char);

    template <std::size_t size, Encoder encoder, Decoder decoder>
    class String {
    public:
        template <std::size_t... Idx>
        constexpr String(char const* str,
                         std::index_sequence<Idx...>):
            str{ encoder(str[Idx])... } {
            // Do Nothing
        }

        inline char const* decode() const {
            for (char& chr : str) {
                chr = decoder(chr);
            }
            return str;
        }

    private:
        mutable char str[size];
    };

    template <Encoder encoder, Decoder decoder, std::size_t size>
    constexpr auto make_string(char const (&str)[size]) {
        return String<size, encoder, decoder>(str, std::make_index_sequence<size>());
    }

    template <Encoder... encoders>
    using encoder_seq = Sequence<Encoder, encoders...>;

    template <Decoder... decoders>
    using decoder_seq = Sequence<Decoder, decoders...>;

    template <typename EncoderSeq, typename DecoderSeq>
    using make_table = SeqPack<EncoderSeq, DecoderSeq>;

    template <Encoder encoder, Decoder decoder>
    using encoder_pair = Sequence<Encoder, encoder, decoder>;

    template <typename... Seq>
    using make_pair_table = TypeSeq<Seq...>;

    template <typename Table, std::size_t size>
    constexpr auto make_string(char const(&str)[size]) {
        using pair = typename Table::template index<MAKE_RAND_VAL(Table::size)>;
        constexpr Encoder encoder = pair::template index<0>::value;
        constexpr Decoder decoder = pair::template index<1>::value;

        return make_string<encoder, decoder>(str);
    }
}

#define MAKE_STRING(Var, String, ...) constexpr auto Var = obfs::make_string<__VA_ARGS__>(String);

#endif

================================================
FILE: obfuscator/obfuscator.hpp
================================================
#ifndef OBFUSCATOR
#define OBFUSCATOR

#include "obfs/fsm.hpp"
#include "obfs/random.hpp"
#include "obfs/sequence.hpp"
#include "obfs/string.hpp"

#endif

================================================
FILE: obfuscator.hpp
================================================
#ifndef OBFUSCATOR_HPP
#define OBFUSCATOR_HPP

#include <type_traits>
#include <utility>

#define COMPILE_TIME_SEQUENCE
#define OBFS_FINITE_STATE_MACHINE
#define COMPILE_TIME_RANDOM
#define MAKE_RAND_VAL(MOD) obfs::RAND_VAL<__LINE__, MOD>
#define OBFS_STRING
#define MAKE_STRING(Var, String, ...) constexpr auto Var = obfs::make_string<__VA_ARGS__>(String);


namespace obfs {
    template <typename T, T Val>
    struct TypeVal {
        using value_type = T;
        constexpr static T value = Val;
    };

    struct Nothing {};

    template <typename T, T Val, T... Others>
    struct Sequence {
        using value = TypeVal<T, Val>;
        using next = Sequence<T, Others...>;

        constexpr static std::size_t size = 1 + sizeof...(Others);

        template <std::size_t Idx>
        using index = std::conditional_t<Idx == 0, value, typename next::template index<Idx - 1>>;
    };

    template <typename T, T Val>
    struct Sequence<T, Val> {
        using value = TypeVal<T, Val>;

        constexpr static std::size_t size = 1;

        template <std::size_t Idx>
        using index = std::conditional_t<Idx == 0, value, Nothing>;
    };

    template <typename T, typename... Ts>
    struct TypeSeq {
        using type = T;
        using next = TypeSeq<Ts...>;

        constexpr static std::size_t size = 1 + sizeof...(Ts);

        template <std::size_t Idx>
        using index = std::conditional_t<Idx == 0, type, typename next::template index<Idx - 1>>;
    };

    template <typename T>
    struct TypeSeq<T> {
        using type = T;

        constexpr static std::size_t size = 1;

        template <std::size_t Idx>
        using index = std::conditional_t<Idx == 0, type, Nothing>;
    };

    template <std::size_t Val, std::size_t... Others>
    struct MinVal {
        constexpr static std::size_t value = 
            Val < MinVal<Others...>::value ? Val : MinVal<Others...>::value;
    };

    template <std::size_t Val>
    struct MinVal<Val> {
        constexpr static std::size_t value = Val;
    };

    template <typename... T>
    struct SeqPack {
        constexpr static std::size_t size = MinVal<T::size...>::value;

        template <std::size_t Idx, typename U>
        using getter = typename U::template index<Idx>;

        template <std::size_t Idx>
        using index = TypeSeq<getter<Idx, T>...>;
    };

    struct Pass {};

    template <typename IfAllPass, typename T, typename... Ts>
    struct First {
        using type = std::conditional_t<
            std::is_same_v<T, Pass>,
            typename First<IfAllPass, Ts...>::type,
            T>;
    };

    template <typename IfAllPass, typename T>
    struct First<IfAllPass, T> {
        using type = std::conditional_t<
            std::is_same_v<T, Pass>,
            IfAllPass,
            T>;
    };
}


namespace obfs {
    void FreeAction() {}

    template <typename Event, typename State, void(*Action)() = FreeAction>
    struct Next {
        using event = Event;
        using state = State;
        constexpr static void(*action)() = Action;
    };

    struct None {};

    template <typename State, typename... Nexts>
    struct Stage {
        using state = State;

        template <typename NextInfo, typename Event>
        using act = std::conditional_t<
            std::is_same_v<typename NextInfo::event, Event>, NextInfo, Pass>;

        template <typename Event>
        using next = typename First<None, act<Nexts, Event>...>::type;
    };

    template <typename Stage_, typename Event>
    struct next_stage {
        using type = typename Stage_::template next<Event>;
    };

    template <typename Event>
    struct next_stage<None, Event> {
        using type = None;
    };

    template <typename State>
    struct action_invoker {
        static auto action() {
            State::action();
            return typename State::state{};
        }
    };

    template <>
    struct action_invoker<None> {
        static auto action() {
            return None{};
        }
    };

    template <typename... Specs>
    struct StateMachine {
        template <typename State, typename StageT>
        using filter = std::conditional_t<
            std::is_same_v<typename StageT::state, State>, StageT, Pass>;

        template <typename State>
        using find = typename First<None, filter<State, Specs>...>::type;

        template <typename State, typename Event>
        using next_t = typename next_stage<find<State>, Event>::type;

        template <typename State, typename Event>
        static auto run(State state, Event event) {
            using next_state = next_t<std::decay_t<State>, std::decay_t<Event>>;
            return action_invoker<next_state>::action();
        }
    };
}


namespace obfs {
    using size_t = decltype(sizeof(void*));

    constexpr char TIME[] = __TIME__;
    constexpr int digit(char c) {
        return c - '0';
    }
    constexpr size_t SEED = digit(TIME[7]) +
                         digit(TIME[6]) * 10 +
                         digit(TIME[4]) * 60 +
                         digit(TIME[3]) * 600 +
                         digit(TIME[1]) * 3600 +
                         digit(TIME[0]) * 36000;

    template <size_t Seed, size_t Idx>
    struct Xorshiftplus {
        using prev = Xorshiftplus<Seed, Idx - 1>;

        constexpr static size_t update() {
            constexpr size_t x = prev::state0 ^ (prev::state0 << 23);
            constexpr size_t y = prev::state1;
            return x ^ y ^ (x >> 17) ^ (y >> 26);
        }

        constexpr static size_t state0 = prev::state1;
        constexpr static size_t state1 = update();

        constexpr static size_t value = state0 + state1;
    };

    template <size_t Seed>
    struct Xorshiftplus<Seed, 0> {
        constexpr static size_t state0 = Seed;
        constexpr static size_t state1 = Seed << 1;
        constexpr static size_t value = state0 + state1;
    };

    template <size_t Idx, size_t Mod>
    constexpr size_t RAND_VAL = Xorshiftplus<SEED, Idx>::value % Mod;
}


namespace obfs {
    using Encoder = char(*)(char);
    using Decoder = char(*)(char);

    template <std::size_t size, Encoder encoder, Decoder decoder>
    class String {
    public:
        template <std::size_t... Idx>
        constexpr String(char const* str,
                         std::index_sequence<Idx...>):
            str{ encoder(str[Idx])... } {
            // Do Nothing
        }

        inline char const* decode() const {
            for (char& chr : str) {
                chr = decoder(chr);
            }
            return str;
        }

    private:
        mutable char str[size];
    };

    template <Encoder encoder, Decoder decoder, std::size_t size>
    constexpr auto make_string(char const (&str)[size]) {
        return String<size, encoder, decoder>(str, std::make_index_sequence<size>());
    }

    template <Encoder... encoders>
    using encoder_seq = Sequence<Encoder, encoders...>;

    template <Decoder... decoders>
    using decoder_seq = Sequence<Decoder, decoders...>;

    template <typename EncoderSeq, typename DecoderSeq>
    using make_table = SeqPack<EncoderSeq, DecoderSeq>;

    template <Encoder encoder, Decoder decoder>
    using encoder_pair = Sequence<Encoder, encoder, decoder>;

    template <typename... Seq>
    using make_pair_table = TypeSeq<Seq...>;

    template <typename Table, std::size_t size>
    constexpr auto make_string(char const(&str)[size]) {
        using pair = typename Table::template index<MAKE_RAND_VAL(Table::size)>;
        constexpr Encoder encoder = pair::template index<0>::value;
        constexpr Decoder decoder = pair::template index<1>::value;

        return make_string<encoder, decoder>(str);
    }
}


#endif


================================================
FILE: sample/CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.10)
project(sample)

set(CMAKE_CXX_STANDARD 17)
add_executable(string_obfs string_obfs.cpp)
add_executable(state_machine state_machine.cpp)
add_executable(random random.cpp)


================================================
FILE: sample/random.cpp
================================================
#include "../obfuscator.hpp"

#include <iostream>

int main() {
    std::cout << MAKE_RAND_VAL(100) << std::endl;
    return 0;
}

================================================
FILE: sample/state_machine.cpp
================================================
#include "../obfuscator.hpp"

#include <iostream>

#define STATE(Name) struct Name {};
#define EVENT(Name) struct Name {};

STATE(Final);
EVENT(Trigger);

STATE(state1); STATE(state2); STATE(state3); STATE(state4); STATE(state5);
EVENT(event1); EVENT(event2); EVENT(event3); EVENT(event4); EVENT(event5);

struct Action {
    static bool trigged;
    static void action() {
        trigged = true;
        std::cout << "Trigged" << std::endl;
    }
};
bool Action::trigged = true;

struct Dummy {
    static int dummy;
    static void dummy1() {
        dummy += 10;
        std::cout << "Dummy1" << std::endl;
    }
    static void dummy2() {
        dummy *= 20;
        std::cout << "Dummy2" << std::endl;
    }
    static void dummy3() {
        std::exit(1);
    }
};
int Dummy::dummy = 0;

int main() {
    using namespace obfs;
    using machine = StateMachine<
        Stage<state1, Next<event5 , state2, Dummy::dummy1>,
                      Next<event1 , state3, Dummy::dummy3>>,
        Stage<state2, Next<event2 , state4>>,
        Stage<state3, Next<None   , state3>>,
        Stage<state4, Next<event4 , state1>,
                      Next<event3 , state5, Dummy::dummy2>>,
        Stage<state5, Next<Trigger, Final, Action::action>>>;

    auto next1 = machine::run(state1{}, event5{});
    auto next2 = machine::run(next1, event2{});
    auto next3 = machine::run(next2, event3{});
    auto next4 = machine::run(next3, Trigger{});

    return 0;
}

================================================
FILE: sample/string_obfs.cpp
================================================
#include "../obfuscator.hpp"

#include <iostream>

template <char key>
constexpr char xor_(char c) {
    return c ^ key;
}

template <char Key>
constexpr char add(char c) {
    return c + Key;
}

template <char(*f)(char), char(*g)(char)>
constexpr char comp(char c) {
    return f(g(c));
}

int main() {
    using table = obfs::make_table<
        obfs::encoder_seq<xor_<0x50>, add<10>, comp<xor_<0x50>, add<10>>>,
        obfs::decoder_seq<xor_<0x50>, add<-10>, comp<add<-10>, xor_<0x50>>>>;

    MAKE_STRING(str, "Hello World !", table);
    std::cout << str.decode() << std::endl;
}

================================================
FILE: script/Dockerfile.bionic
================================================
FROM ubuntu:18.04

RUN apt-get update -yq && apt-get install -yq build-essential cmake python3.6 python3.6-dev python3-pip python3-setuptools python3-wheel
RUN echo `g++ --version`

ADD . /app

# Run UnitTest
WORKDIR /app/test/build
RUN cmake .. && \
    make -j `nproc` && \
    ./unittest

# Run Additional Test
WORKDIR /app/sample/build
RUN cmake .. && \
    make -j `nproc`

WORKDIR /app
RUN python3 -m script.merge && \
    python3 -m script.string_obfs_tester ./sample/build/string_obfs "Hello World !"


================================================
FILE: script/__init__.py
================================================


================================================
FILE: script/azure-pipelines-template-mac.yml
================================================
jobs:
- job: ${{ parameters.name }}
  pool:
    vmImage: ${{ parameters.vmImage }}
  steps:
# Initialize
  - script: git submodule update --init
    displayName: Initialize submodule
# UnitTest
  - task: CMake@1
    inputs:
      workingDirectory: ./test/build
      cmakeArgs: ../
    displayName: CMake unittest

  - script: cd ./test/build && make;
    displayName: GNU Make unittest

  - script: ./test/build/unittest
    displayName: Run unittest
# Additional tests
  - task: UsePythonVersion@0
    inputs:
      versionSpec: 3.6
      architecture: 'x64'

  - script: python -m script.merge
    displayName: Remerge obfuscator.hpp

  - task: CMake@1
    inputs:
      workingDirectory: ./sample/build
      cmakeArgs: ../
    displayName: CMake sample

  - script: cd ./sample/build && make;
    displayName: GNU Make sample

  - script: python -m script.string_obfs_tester ./sample/build/string_obfs "Hello World !"
    displayName: String OBFS test


================================================
FILE: script/azure-pipelines-template-unix.yml
================================================
jobs:
- job: ${{ parameters.name }}
  pool:
    vmImage: ${{ parameters.vmImage }}
  steps:
  - script: git submodule update --init
    displayName: initialize submodule

  - script: docker build -f script/Dockerfile.bionic -t cpp_obfuscator .
    displayName: run docker-bionic


================================================
FILE: script/azure-pipelines-template-win.yml
================================================
jobs:
- job: ${{ parameters.name }}
  pool:
    vmImage: ${{ parameters.vmImage }}
  steps:
# Initialize
  - script: git submodule update --init
    displayName: Initialize submodule
# UnitTest
  - task: CMake@1
    inputs:
      workingDirectory: .\test\build
      cmakeArgs: ..\
    displayName: CMake unittest

  - task: MSBuild@1
    inputs: 
      solution: .\test\build\unittest.sln
    displayName: MSBuild unittest

  - script: .\test\build\Debug\unittest.exe
    displayName: Start unittest
# Additional tests
  - task: UsePythonVersion@0
    inputs:
      versionSpec: 3.6
      architecture: 'x64'
  
  - script: python -m script.merge
    displayName: Remerge obfuscator.hpp

  - task: CMake@1
    inputs:
      workingDirectory: .\sample\build
      cmakeArgs: ..\
    displayName: CMake sample

  - task: MSBuild@1
    inputs:
      solution: .\sample\build\sample.sln
    displayName: MSBuild sample
  
  - script: python -m script.string_obfs_tester .\sample\build\Debug\string_obfs.exe "Hello World !"
    displayName: String OBFS test
  

================================================
FILE: script/merge.py
================================================
import os
import re
import sys


class Format(object):
    hpp = '''\
#ifndef {0}
#define {0}

{1}
{2}
{3}
#endif'''

    @classmethod
    def hpp_beutifier(cls, source):
        out = ''
        n_blank = 0
        for line in source.split('\n'):
            if line == '' or line.isspace():
                n_blank += 1
            else:
                if n_blank > 2:
                    n_blank = 2

                out += '\n' * n_blank
                n_blank = 0

                out += line + '\n'
        return out


class ReSupport(object):
    r_guard = re.compile(r'(#ifndef|#endif)')
    r_include_dep = re.compile(r'#include "(.+?)"')
    r_include = re.compile(r'#include <(.+?)>')
    r_define = re.compile(r'#define (.+)')

    @classmethod
    def guard(cls, inp):
        return cls.r_guard.findall(inp)

    @classmethod
    def include_dep(cls, inp):
        return cls.r_include_dep.findall(inp)

    @classmethod
    def include(cls, inp):
        return cls.r_include.findall(inp)

    @classmethod
    def define(cls, inp):
        return cls.r_define.findall(inp)


class SourceInfo(object):
    def __init__(self):
        self.out = ''
        self.deps = []
        self.includes = []
        self.defines = []

    @classmethod
    def set_with(cls, out, deps, includes, defines):
        obj = cls()
        obj.out = out
        obj.deps = deps
        obj.includes = includes
        obj.defines = defines
        return obj

    @classmethod
    def read_file(cls, path):
        obj = cls()
        with open(path) as f:
            for line in f.readlines():
                if len(ReSupport.guard(line)) > 0:
                    continue

                include_name = ReSupport.include_dep(line)
                if len(include_name) > 0:
                    obj.deps.append(include_name[0])
                    continue

                include_name = ReSupport.include(line)
                if len(include_name) > 0:
                    obj.includes.append(include_name[0])
                    continue

                define_name = ReSupport.define(line)
                if len(define_name) > 0:
                    obj.defines.append(define_name[0])
                    continue

                obj.out += line
        return obj

    def __add__(self, other):
        out = self.out + other.out
        deps = self.deps + other.deps
        includes = self.includes + other.includes
        defines = self.defines + other.defines
        return SourceInfo.set_with(out, deps, includes, defines)


def file_list(dirname, ban_dir=[]):
    files = []
    if isinstance(ban_dir, str):
        ban_dir = [ban_dir]

    for name in os.listdir(dirname):
        full_path = os.path.join(dirname, name)
        if os.path.isfile(full_path):
            files.append(full_path)
        elif os.path.isdir(full_path) and name not in ban_dir:
            files += file_list(full_path)
    return files


def in_endswith(name, files):
    for f in files:
        if f.endswith(name):
            return f
    return None


def order_dep(deps, files, done):
    info = SourceInfo()
    for dep in deps:
        if in_endswith(dep, done) is None:
            path = in_endswith(dep.split('/')[-1], files)

            if path is not None:
                new = SourceInfo.read_file(path)
                dep_new = order_dep(new.deps, files, done)

                info += dep_new + new
                done.append(path)

    return info


def none_preproc(dirname):
    if not os.path.exists(dirname):
        return [], ''
    
    dep = []
    out = ''
    includes = ''
    for files in os.listdir(dirname):
        with open(os.path.join(dirname, files)) as f:
            lines = f.readlines()
        
        if lines[0].startswith('#ifndef') \
            and lines[1].startswith('#define') \
            and lines[-1].startswith('#endif'):
            lines = lines[2:-1]
        
        data = ''.join(lines)

        include_idx = data.find('// merge:np_include')
        if include_idx != -1:
            start_idx = include_idx + len('// merge:np_include')
            end_idx = data.find('// merge:end', include_idx)
            
            includes += data[start_idx:end_idx]
            data = data[end_idx + len('// merge:end'):]

        include_idx = data.find('// merge:include')
        if include_idx != -1:
            start_idx = include_idx + len('// merge:include')
            end_idx = data.find('// merge:end', include_idx)

            for line in data[start_idx:end_idx].split('\n'):
                res = ReSupport.include(line)
                if len(res) > 0:
                    dep += res
                    includes += line + '\n'

            data = data[end_idx + len('// merge:end'):]

        dep.append(files)
        out += data

    return dep, includes + out


def merge(dirname):
    done = []
    info = SourceInfo()
    files = file_list(dirname, 'platform')

    preproc_dep, info.out = \
        none_preproc(os.path.join(dirname, 'platform'))

    for full_path in files:
        if full_path not in done:
            source = SourceInfo.read_file(full_path)
            dep = order_dep(source.deps, files, done)

            info += dep + source
            done.append(full_path)

    return info, preproc_dep


def write_hpp(outfile, merged):
    info, preproc_dep = merged
    dep_check = lambda file: not any(file.endswith(dep) for dep in preproc_dep)

    idx = outfile.rfind('/')
    if idx > -1:
        outfile = outfile[idx+1:]
    guard_name = outfile.upper().replace('.', '_')

    unique_include = []

    for include in info.includes:
        if include not in unique_include and dep_check(include):
            unique_include.append(include)

    includes = '\n'.join(
        '#include <{}>'.format(x) for x in sorted(unique_include)) + '\n'
    defines = '\n'.join(
        '#define {}'.format(x) for x in info.defines) + '\n'

    out = Format.hpp.format(guard_name, includes, defines, info.out)
    out = Format.hpp_beutifier(out)

    with open(outfile, 'w') as f:
        f.write(out)

if __name__ == "__main__":
    if len(sys.argv) > 1:
        outfile = sys.argv[1]
    else:
        outfile = './obfuscator.hpp'

    if len(sys.argv) > 2:
        dirname = sys.argv[2]
    else:
        dirname = './obfuscator/obfs'

    merged = merge(dirname)
    write_hpp(outfile, merged)


================================================
FILE: script/string_obfs_tester.py
================================================
import sys

def main(argc, argv):
    if argc < 3:
        print('USAGE: python string_obfs_tester.py [STRING_OBFS.EXE] [TARGET_STRING]')
        return 1
    
    path = argv[1]
    with open(path, 'rb') as f:
        data = f.read()
    
    if data.find(str.encode(argv[2])) == -1:
        print('Cannot find string "{}" from "{}"'.format(argv[2], argv[1]))
        return 0
    else:
        print('Find string "{}" from "{}"'.format(argv[2], argv[1]))
        return 1

if __name__ == '__main__':
    retn = main(len(sys.argv), sys.argv)
    sys.exit(retn)


================================================
FILE: test/CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.10)
project(unittest)

set(CMAKE_CXX_STANDARD 17)

file(GLOB test_files 
        "impl/*.cpp"
)

add_executable(unittest main.cpp ${test_files})
target_include_directories(unittest PRIVATE ../obfuscator)

add_subdirectory(../external/Catch2 external)
target_link_libraries(unittest Catch2::Catch2)


================================================
FILE: test/impl/fsm.cpp
================================================
#include <obfs/fsm.hpp>
#include <catch2/catch.hpp>

#define STATE(Name) struct Name {};
#define EVENT(Name) struct Name {};

STATE(Final);
EVENT(Trigger);

STATE(state1); STATE(state2); STATE(state3); STATE(state4); STATE(state5);
EVENT(event1); EVENT(event2); EVENT(event3); EVENT(event4); EVENT(event5);

struct Action {
    static bool trigged;
    static void action() {
        trigged = true;
    }
};
bool Action::trigged = true;

struct Dummy {
    static int dummy;
    static void dummy1() {
        dummy += 10;
    }
    static void dummy2() {
        dummy *= 20;
    }
};
int Dummy::dummy = 0;

TEST_CASE("Next", "[obfs::StateMachine]") {
    using next = obfs::Next<event1, state1>;
    static_assert(std::is_same_v<event1, typename next::event>);
    static_assert(std::is_same_v<state1, typename next::state>);
    static_assert(next::action == obfs::FreeAction);

    using next2 = obfs::Next<event2, state2, Action::action>;
    static_assert(next2::action == Action::action);
}

TEST_CASE("Stage", "[obfs::StateMachine]") {
    using stage = obfs::Stage<
        state1,
        obfs::Next<event5, state2, Dummy::dummy1>,
        obfs::Next<event1, state3>>;
    
    static_assert(std::is_same_v<
        obfs::Next<event5, state2, Dummy::dummy1>,
        typename stage::template next<event5>>);

    static_assert(std::is_same_v<
        obfs::Next<event5, state2, Dummy::dummy1>,
        typename obfs::next_stage<stage, event5>::type>);

    static_assert(std::is_same_v<
        obfs::Next<event1, state3>,
        typename stage::template next<event1>>);

    static_assert(std::is_same_v<
        obfs::Next<event1, state3>,
        typename obfs::next_stage<stage, event1>::type>);

    static_assert(std::is_same_v<obfs::None, typename stage::template next<event3>>);

    static_assert(std::is_same_v<obfs::None, typename obfs::next_stage<stage, event3>::type>);

    static_assert(std::is_same_v<obfs::None, typename obfs::next_stage<obfs::None, event1>::type>);
}

TEST_CASE("StateMachine", "[obfs::StateMachine]") {
    using namespace obfs;
    using machine = StateMachine<
        Stage<state1, Next<event5 , state2, Dummy::dummy1>,
                      Next<event1 , state3>>,
        Stage<state2, Next<event2 , state4>>,
        Stage<state3, Next<None   , state3>>,
        Stage<state4, Next<event4 , state1>,
                      Next<event3 , state5, Dummy::dummy2>>,
        Stage<state5, Next<Trigger, Final, Action::action>>>;

    auto failure = machine::run(obfs::None{}, event5{});
    static_assert(std::is_same_v<decltype(failure), obfs::None>);

    auto next1 = machine::run(state1{}, event5{});
    static_assert(std::is_same_v<decltype(next1), state2>);
    REQUIRE(Dummy::dummy == 10);

    auto next2 = machine::run(next1, event2{});
    static_assert(std::is_same_v<decltype(next2), state4>);

    auto failure2 = machine::run(next2, event1{});
    static_assert(std::is_same_v<decltype(failure2), obfs::None>);
    
    auto next3 = machine::run(next2, event3{});
    static_assert(std::is_same_v<decltype(next3), state5>);
    REQUIRE(Dummy::dummy == 200);

    auto next4 = machine::run(next3, Trigger{});
    static_assert(std::is_same_v<decltype(next4), Final>);
    REQUIRE(Action::trigged);
}


================================================
FILE: test/impl/random.cpp
================================================
#include <obfs/random.hpp>
#include <catch2/catch.hpp>

using ull = unsigned long long;

// https://en.wikipedia.org/wiki/Xorshift
ull xorshift128plus(ull state[2]) {
	ull t = state[0];
	ull const s = state[1];
	state[0] = s;
	t ^= t << 23;		// a
	t ^= t >> 17;		// b
	t ^= s ^ (s >> 26);	// c
	state[1] = t;
	return t + s;
}

TEST_CASE("Random case", "[obfs::Xorshift+]") {
    constexpr size_t val = MAKE_RAND_VAL(100);
    ull state[2] = { val, val << 1 };

    REQUIRE(obfs::Xorshiftplus<val, 1>::value == xorshift128plus(state));
    REQUIRE(obfs::Xorshiftplus<val, 2>::value == xorshift128plus(state));
    REQUIRE(obfs::Xorshiftplus<val, 3>::value == xorshift128plus(state));
}


================================================
FILE: test/impl/sequence.cpp
================================================
#include <obfs/sequence.hpp>
#include <catch2/catch.hpp>

TEST_CASE("TypeVal", "[obfs::Sequence]") {
    using val = obfs::TypeVal<int, 10>;
    
    static_assert(std::is_same_v<int, typename val::value_type>);
    static_assert(val::value == 10);
}

TEST_CASE("Sequence", "[obfs::Sequence]") {
    using seq = obfs::Sequence<int, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9>;

    static_assert(std::is_same_v<int, typename seq::value::value_type>);
    static_assert(seq::size == 10);
    static_assert(seq::index<0>::value == 0);
    static_assert(seq::index<5>::value == 5);
    static_assert(seq::index<9>::value == 9);
    static_assert(std::is_same_v<seq::index<10>, obfs::Nothing>);
}

TEST_CASE("TypeSeq", "[obfs::Sequence]") {
    using namespace obfs;
    using seq = TypeSeq<TypeVal<int, 0>, TypeVal<int, 1>, TypeVal<int, 2>, TypeVal<int, 3>>;
    
    static_assert(seq::size == 4);
    static_assert(seq::index<0>::value == 0);
    static_assert(seq::index<2>::value == 2);
    static_assert(seq::index<3>::value == 3);
    static_assert(std::is_same_v<seq::index<4>, Nothing>);
}

TEST_CASE("MinVal", "[obfs::Sequence]") {
    using min = obfs::MinVal<1, 3, 2, 4, 9, 5, 6, 0, 7, 8>;
    static_assert(min::value == 0);
}

TEST_CASE("SeqPack", "[obfs::Sequence]") {
    using pack = obfs::SeqPack<
        obfs::Sequence<int, 0, 1, 2, 3, 4>,
        obfs::Sequence<int, 1, 2, 3, 4, 5, 6>,
        obfs::Sequence<int, 2, 3, 4, 5>
    >;

    static_assert(pack::size == 4);

    using item = pack::index<2>;
    static_assert(item::size == 3);
    static_assert(item::index<0>::value == 2);
    static_assert(item::index<1>::value == 3);
    static_assert(item::index<2>::value == 4);
}

template <typename Val>
using condition = std::conditional_t<(Val::value > 3), Val, obfs::Pass>;

template <typename... Values>
using first = typename obfs::First<obfs::Nothing, condition<Values>...>::type;

TEST_CASE("First", "[obfs::Sequence]") {
    using result = first<
        obfs::TypeVal<int, 0>,
        obfs::TypeVal<int, 3>,
        obfs::TypeVal<int, 2>,
        obfs::TypeVal<int, 5>,
        obfs::TypeVal<int, 1>,
        obfs::TypeVal<int, 4>>;

    static_assert(result::value == 5);
}

================================================
FILE: test/impl/string.cpp
================================================
#include <obfs/string.hpp>
#include <catch2/catch.hpp>

template <char Key>
constexpr char enc_xor(char value) {
    return value ^ Key;
}

template <char Key>
constexpr char add(char c) {
    return c + Key;
}

template <char(*f)(char), char(*g)(char)>
constexpr char comp(char c) {
    return f(g(c));
}

TEST_CASE("Single encoder, decoder", "[obfs::String]") {
    REQUIRE(
        obfs::make_string<enc_xor<0x50>, enc_xor<0x50>>("Hello World !").decode()
        == std::string_view("Hello World !"));
}

TEST_CASE("Multiple encoder, decoder", "[obfs::String]") {
    using table = obfs::make_table<
        obfs::encoder_seq<enc_xor<0x50>, add<10>, comp<enc_xor<0x50>, add<10>>>,
        obfs::decoder_seq<enc_xor<0x50>, add<-10>, comp<add<-10>, enc_xor<0x50>>>>;

    MAKE_STRING(str, "Hello World !", table);
    REQUIRE(str.decode() == std::string_view("Hello World !"));
}

TEST_CASE("Multiple encoder, decoder pair", "[obfs::String]") {
    using table = obfs::make_pair_table<
        obfs::encoder_pair<enc_xor<0x50>, enc_xor<0x50>>,
        obfs::encoder_pair<add<10>, add<-10>>,
        obfs::encoder_pair<comp<enc_xor<0x50>, add<10>>, comp<add<-10>, enc_xor<0x50>>>
    >;

    MAKE_STRING(str, "Hello World !", table);
    REQUIRE(str.decode() == std::string_view("Hello World !"));
}


================================================
FILE: test/main.cpp
================================================
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
Download .txt
gitextract_9t2uq1pg/

├── .gitignore
├── .gitmodules
├── 3RD-PARTY.md
├── LICENSE
├── README.md
├── azure-pipelines.yml
├── obfuscator/
│   ├── obfs/
│   │   ├── fsm.hpp
│   │   ├── random.hpp
│   │   ├── sequence.hpp
│   │   └── string.hpp
│   └── obfuscator.hpp
├── obfuscator.hpp
├── sample/
│   ├── CMakeLists.txt
│   ├── random.cpp
│   ├── state_machine.cpp
│   └── string_obfs.cpp
├── script/
│   ├── Dockerfile.bionic
│   ├── __init__.py
│   ├── azure-pipelines-template-mac.yml
│   ├── azure-pipelines-template-unix.yml
│   ├── azure-pipelines-template-win.yml
│   ├── merge.py
│   └── string_obfs_tester.py
└── test/
    ├── CMakeLists.txt
    ├── impl/
    │   ├── fsm.cpp
    │   ├── random.cpp
    │   ├── sequence.cpp
    │   └── string.cpp
    └── main.cpp
Download .txt
SYMBOL INDEX (112 symbols across 13 files)

FILE: obfuscator.hpp
  type obfs (line 15) | namespace obfs {
    type TypeVal (line 17) | struct TypeVal {
    type Nothing (line 22) | struct Nothing {}
    type Sequence (line 25) | struct Sequence {
    type Sequence<T, Val> (line 36) | struct Sequence<T, Val> {
    type TypeSeq (line 46) | struct TypeSeq {
    type TypeSeq<T> (line 57) | struct TypeSeq<T> {
    type MinVal (line 67) | struct MinVal {
    type MinVal<Val> (line 73) | struct MinVal<Val> {
    type SeqPack (line 78) | struct SeqPack {
    type Pass (line 88) | struct Pass {}
    type First (line 91) | struct First {
    type First<IfAllPass, T> (line 99) | struct First<IfAllPass, T> {
    function FreeAction (line 109) | void FreeAction() {}
    type Next (line 112) | struct Next {
    type None (line 118) | struct None {}
    type Stage (line 121) | struct Stage {
    type next_stage (line 133) | struct next_stage {
    type next_stage<None, Event> (line 138) | struct next_stage<None, Event> {
    type action_invoker (line 143) | struct action_invoker {
      method action (line 144) | static auto action() {
    type action_invoker<None> (line 151) | struct action_invoker<None> {
      method action (line 152) | static auto action() {
    type StateMachine (line 158) | struct StateMachine {
      method run (line 170) | static auto run(State state, Event event) {
    function digit (line 182) | constexpr int digit(char c) {
    type Xorshiftplus (line 193) | struct Xorshiftplus {
      method update (line 196) | constexpr static size_t update() {
    type Xorshiftplus<Seed, 0> (line 209) | struct Xorshiftplus<Seed, 0> {
    class String (line 225) | class String {
      method String (line 228) | constexpr String(char const* str,
    function make_string (line 246) | constexpr auto make_string(char const (&str)[size]) {
    function make_string (line 266) | constexpr auto make_string(char const(&str)[size]) {
  type obfs (line 108) | namespace obfs {
    type TypeVal (line 17) | struct TypeVal {
    type Nothing (line 22) | struct Nothing {}
    type Sequence (line 25) | struct Sequence {
    type Sequence<T, Val> (line 36) | struct Sequence<T, Val> {
    type TypeSeq (line 46) | struct TypeSeq {
    type TypeSeq<T> (line 57) | struct TypeSeq<T> {
    type MinVal (line 67) | struct MinVal {
    type MinVal<Val> (line 73) | struct MinVal<Val> {
    type SeqPack (line 78) | struct SeqPack {
    type Pass (line 88) | struct Pass {}
    type First (line 91) | struct First {
    type First<IfAllPass, T> (line 99) | struct First<IfAllPass, T> {
    function FreeAction (line 109) | void FreeAction() {}
    type Next (line 112) | struct Next {
    type None (line 118) | struct None {}
    type Stage (line 121) | struct Stage {
    type next_stage (line 133) | struct next_stage {
    type next_stage<None, Event> (line 138) | struct next_stage<None, Event> {
    type action_invoker (line 143) | struct action_invoker {
      method action (line 144) | static auto action() {
    type action_invoker<None> (line 151) | struct action_invoker<None> {
      method action (line 152) | static auto action() {
    type StateMachine (line 158) | struct StateMachine {
      method run (line 170) | static auto run(State state, Event event) {
    function digit (line 182) | constexpr int digit(char c) {
    type Xorshiftplus (line 193) | struct Xorshiftplus {
      method update (line 196) | constexpr static size_t update() {
    type Xorshiftplus<Seed, 0> (line 209) | struct Xorshiftplus<Seed, 0> {
    class String (line 225) | class String {
      method String (line 228) | constexpr String(char const* str,
    function make_string (line 246) | constexpr auto make_string(char const (&str)[size]) {
    function make_string (line 266) | constexpr auto make_string(char const(&str)[size]) {
  type obfs (line 178) | namespace obfs {
    type TypeVal (line 17) | struct TypeVal {
    type Nothing (line 22) | struct Nothing {}
    type Sequence (line 25) | struct Sequence {
    type Sequence<T, Val> (line 36) | struct Sequence<T, Val> {
    type TypeSeq (line 46) | struct TypeSeq {
    type TypeSeq<T> (line 57) | struct TypeSeq<T> {
    type MinVal (line 67) | struct MinVal {
    type MinVal<Val> (line 73) | struct MinVal<Val> {
    type SeqPack (line 78) | struct SeqPack {
    type Pass (line 88) | struct Pass {}
    type First (line 91) | struct First {
    type First<IfAllPass, T> (line 99) | struct First<IfAllPass, T> {
    function FreeAction (line 109) | void FreeAction() {}
    type Next (line 112) | struct Next {
    type None (line 118) | struct None {}
    type Stage (line 121) | struct Stage {
    type next_stage (line 133) | struct next_stage {
    type next_stage<None, Event> (line 138) | struct next_stage<None, Event> {
    type action_invoker (line 143) | struct action_invoker {
      method action (line 144) | static auto action() {
    type action_invoker<None> (line 151) | struct action_invoker<None> {
      method action (line 152) | static auto action() {
    type StateMachine (line 158) | struct StateMachine {
      method run (line 170) | static auto run(State state, Event event) {
    function digit (line 182) | constexpr int digit(char c) {
    type Xorshiftplus (line 193) | struct Xorshiftplus {
      method update (line 196) | constexpr static size_t update() {
    type Xorshiftplus<Seed, 0> (line 209) | struct Xorshiftplus<Seed, 0> {
    class String (line 225) | class String {
      method String (line 228) | constexpr String(char const* str,
    function make_string (line 246) | constexpr auto make_string(char const (&str)[size]) {
    function make_string (line 266) | constexpr auto make_string(char const(&str)[size]) {
  type obfs (line 220) | namespace obfs {
    type TypeVal (line 17) | struct TypeVal {
    type Nothing (line 22) | struct Nothing {}
    type Sequence (line 25) | struct Sequence {
    type Sequence<T, Val> (line 36) | struct Sequence<T, Val> {
    type TypeSeq (line 46) | struct TypeSeq {
    type TypeSeq<T> (line 57) | struct TypeSeq<T> {
    type MinVal (line 67) | struct MinVal {
    type MinVal<Val> (line 73) | struct MinVal<Val> {
    type SeqPack (line 78) | struct SeqPack {
    type Pass (line 88) | struct Pass {}
    type First (line 91) | struct First {
    type First<IfAllPass, T> (line 99) | struct First<IfAllPass, T> {
    function FreeAction (line 109) | void FreeAction() {}
    type Next (line 112) | struct Next {
    type None (line 118) | struct None {}
    type Stage (line 121) | struct Stage {
    type next_stage (line 133) | struct next_stage {
    type next_stage<None, Event> (line 138) | struct next_stage<None, Event> {
    type action_invoker (line 143) | struct action_invoker {
      method action (line 144) | static auto action() {
    type action_invoker<None> (line 151) | struct action_invoker<None> {
      method action (line 152) | static auto action() {
    type StateMachine (line 158) | struct StateMachine {
      method run (line 170) | static auto run(State state, Event event) {
    function digit (line 182) | constexpr int digit(char c) {
    type Xorshiftplus (line 193) | struct Xorshiftplus {
      method update (line 196) | constexpr static size_t update() {
    type Xorshiftplus<Seed, 0> (line 209) | struct Xorshiftplus<Seed, 0> {
    class String (line 225) | class String {
      method String (line 228) | constexpr String(char const* str,
    function make_string (line 246) | constexpr auto make_string(char const (&str)[size]) {
    function make_string (line 266) | constexpr auto make_string(char const(&str)[size]) {

FILE: obfuscator/obfs/fsm.hpp
  type obfs (line 8) | namespace obfs {
    function FreeAction (line 9) | void FreeAction() {}
    type Next (line 12) | struct Next {
    type None (line 18) | struct None {}
    type Stage (line 21) | struct Stage {
    type next_stage (line 33) | struct next_stage {
    type next_stage<None, Event> (line 38) | struct next_stage<None, Event> {
    type action_invoker (line 43) | struct action_invoker {
      method action (line 44) | static auto action() {
    type action_invoker<None> (line 51) | struct action_invoker<None> {
      method action (line 52) | static auto action() {
    type StateMachine (line 58) | struct StateMachine {
      method run (line 70) | static auto run(State state, Event event) {

FILE: obfuscator/obfs/random.hpp
  type obfs (line 4) | namespace obfs {
    function digit (line 8) | constexpr int digit(char c) {
    type Xorshiftplus (line 19) | struct Xorshiftplus {
      method update (line 22) | constexpr static size_t update() {
    type Xorshiftplus<Seed, 0> (line 35) | struct Xorshiftplus<Seed, 0> {

FILE: obfuscator/obfs/sequence.hpp
  type obfs (line 6) | namespace obfs {
    type TypeVal (line 8) | struct TypeVal {
    type Nothing (line 13) | struct Nothing {}
    type Sequence (line 16) | struct Sequence {
    type Sequence<T, Val> (line 27) | struct Sequence<T, Val> {
    type TypeSeq (line 37) | struct TypeSeq {
    type TypeSeq<T> (line 48) | struct TypeSeq<T> {
    type MinVal (line 58) | struct MinVal {
    type MinVal<Val> (line 64) | struct MinVal<Val> {
    type SeqPack (line 69) | struct SeqPack {
    type Pass (line 79) | struct Pass {}
    type First (line 82) | struct First {
    type First<IfAllPass, T> (line 90) | struct First<IfAllPass, T> {

FILE: obfuscator/obfs/string.hpp
  type obfs (line 9) | namespace obfs {
    class String (line 14) | class String {
      method String (line 17) | constexpr String(char const* str,
    function make_string (line 35) | constexpr auto make_string(char const (&str)[size]) {
    function make_string (line 55) | constexpr auto make_string(char const(&str)[size]) {

FILE: sample/random.cpp
  function main (line 5) | int main() {

FILE: sample/state_machine.cpp
  type Action (line 14) | struct Action {
    method action (line 16) | static void action() {
  type Dummy (line 23) | struct Dummy {
    method dummy1 (line 25) | static void dummy1() {
    method dummy2 (line 29) | static void dummy2() {
    method dummy3 (line 33) | static void dummy3() {
  function main (line 39) | int main() {

FILE: sample/string_obfs.cpp
  function xor_ (line 6) | constexpr char xor_(char c) {
  function add (line 11) | constexpr char add(char c) {
  function comp (line 16) | constexpr char comp(char c) {
  function main (line 20) | int main() {

FILE: script/merge.py
  class Format (line 6) | class Format(object):
    method hpp_beutifier (line 17) | def hpp_beutifier(cls, source):
  class ReSupport (line 34) | class ReSupport(object):
    method guard (line 41) | def guard(cls, inp):
    method include_dep (line 45) | def include_dep(cls, inp):
    method include (line 49) | def include(cls, inp):
    method define (line 53) | def define(cls, inp):
  class SourceInfo (line 57) | class SourceInfo(object):
    method __init__ (line 58) | def __init__(self):
    method set_with (line 65) | def set_with(cls, out, deps, includes, defines):
    method read_file (line 74) | def read_file(cls, path):
    method __add__ (line 99) | def __add__(self, other):
  function file_list (line 107) | def file_list(dirname, ban_dir=[]):
  function in_endswith (line 121) | def in_endswith(name, files):
  function order_dep (line 128) | def order_dep(deps, files, done):
  function none_preproc (line 144) | def none_preproc(dirname):
  function merge (line 189) | def merge(dirname):
  function write_hpp (line 208) | def write_hpp(outfile, merged):

FILE: script/string_obfs_tester.py
  function main (line 3) | def main(argc, argv):

FILE: test/impl/fsm.cpp
  type Action (line 13) | struct Action {
    method action (line 15) | static void action() {
  type Dummy (line 21) | struct Dummy {
    method dummy1 (line 23) | static void dummy1() {
    method dummy2 (line 26) | static void dummy2() {

FILE: test/impl/random.cpp
  function ull (line 7) | ull xorshift128plus(ull state[2]) {

FILE: test/impl/string.cpp
  function enc_xor (line 5) | constexpr char enc_xor(char value) {
  function add (line 10) | constexpr char add(char c) {
  function comp (line 15) | constexpr char comp(char c) {
Condensed preview — 29 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (45K chars).
[
  {
    "path": ".gitignore",
    "chars": 125,
    "preview": "# editor\n.vscode\n\n# build\nbuild\n\n# cl with debug option\n*.ilk\n*.obj\n*.pdb\n\n# sample program\n*.exe\n\n# python cache\n__pyca"
  },
  {
    "path": ".gitmodules",
    "chars": 96,
    "preview": "[submodule \"external/Catch2\"]\n\tpath = external/Catch2\n\turl = https://github.com/catchorg/Catch2\n"
  },
  {
    "path": "3RD-PARTY.md",
    "chars": 1401,
    "preview": "cpp-obfuscator uses Catch2 for testing obfuscator modules\n\nBoost Software License - Version 1.0 - August 17th, 2003\n\nPer"
  },
  {
    "path": "LICENSE",
    "chars": 1071,
    "preview": "MIT License\n\nCopyright (c) 2019 YoungJoong Kim\n\nPermission is hereby granted, free of charge, to any person obtaining a "
  },
  {
    "path": "README.md",
    "chars": 3172,
    "preview": "# cpp-obfuscator\n[![License](https://img.shields.io/badge/Licence-MIT-blue.svg)](https://github.com/revsic/cpp-obfuscato"
  },
  {
    "path": "azure-pipelines.yml",
    "chars": 334,
    "preview": "jobs:\n- template: script/azure-pipelines-template-mac.yml\n  parameters:\n    name: macOS\n    vmImage: macOS-10.14\n\n- temp"
  },
  {
    "path": "obfuscator/obfs/fsm.hpp",
    "chars": 2047,
    "preview": "#ifndef OBFS_FINITE_STATE_MACHINE\n#define OBFS_FINITE_STATE_MACHINE\n\n#include \"sequence.hpp\"\n\n#include <type_traits>\n\nna"
  },
  {
    "path": "obfuscator/obfs/random.hpp",
    "chars": 1417,
    "preview": "#ifndef COMPILE_TIME_RANDOM\n#define COMPILE_TIME_RANDOM\n\nnamespace obfs {\n    using size_t = decltype(sizeof(void*));\n\n "
  },
  {
    "path": "obfuscator/obfs/sequence.hpp",
    "chars": 2552,
    "preview": "#ifndef COMPILE_TIME_SEQUENCE\n#define COMPILE_TIME_SEQUENCE\n\n#include <type_traits>\n\nnamespace obfs {\n    template <type"
  },
  {
    "path": "obfuscator/obfs/string.hpp",
    "chars": 1916,
    "preview": "#ifndef OBFS_STRING\n#define OBFS_STRING\n\n#include \"random.hpp\"\n#include \"sequence.hpp\"\n\n#include <utility>\n\nnamespace ob"
  },
  {
    "path": "obfuscator/obfuscator.hpp",
    "chars": 153,
    "preview": "#ifndef OBFUSCATOR\n#define OBFUSCATOR\n\n#include \"obfs/fsm.hpp\"\n#include \"obfs/random.hpp\"\n#include \"obfs/sequence.hpp\"\n#"
  },
  {
    "path": "obfuscator.hpp",
    "chars": 7753,
    "preview": "#ifndef OBFUSCATOR_HPP\n#define OBFUSCATOR_HPP\n\n#include <type_traits>\n#include <utility>\n\n#define COMPILE_TIME_SEQUENCE\n"
  },
  {
    "path": "sample/CMakeLists.txt",
    "chars": 207,
    "preview": "cmake_minimum_required(VERSION 3.10)\nproject(sample)\n\nset(CMAKE_CXX_STANDARD 17)\nadd_executable(string_obfs string_obfs."
  },
  {
    "path": "sample/random.cpp",
    "chars": 129,
    "preview": "#include \"../obfuscator.hpp\"\n\n#include <iostream>\n\nint main() {\n    std::cout << MAKE_RAND_VAL(100) << std::endl;\n    re"
  },
  {
    "path": "sample/state_machine.cpp",
    "chars": 1463,
    "preview": "#include \"../obfuscator.hpp\"\n\n#include <iostream>\n\n#define STATE(Name) struct Name {};\n#define EVENT(Name) struct Name {"
  },
  {
    "path": "sample/string_obfs.cpp",
    "chars": 585,
    "preview": "#include \"../obfuscator.hpp\"\n\n#include <iostream>\n\ntemplate <char key>\nconstexpr char xor_(char c) {\n    return c ^ key;"
  },
  {
    "path": "script/Dockerfile.bionic",
    "chars": 509,
    "preview": "FROM ubuntu:18.04\n\nRUN apt-get update -yq && apt-get install -yq build-essential cmake python3.6 python3.6-dev python3-p"
  },
  {
    "path": "script/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "script/azure-pipelines-template-mac.yml",
    "chars": 957,
    "preview": "jobs:\n- job: ${{ parameters.name }}\n  pool:\n    vmImage: ${{ parameters.vmImage }}\n  steps:\n# Initialize\n  - script: git"
  },
  {
    "path": "script/azure-pipelines-template-unix.yml",
    "chars": 279,
    "preview": "jobs:\n- job: ${{ parameters.name }}\n  pool:\n    vmImage: ${{ parameters.vmImage }}\n  steps:\n  - script: git submodule up"
  },
  {
    "path": "script/azure-pipelines-template-win.yml",
    "chars": 1056,
    "preview": "jobs:\n- job: ${{ parameters.name }}\n  pool:\n    vmImage: ${{ parameters.vmImage }}\n  steps:\n# Initialize\n  - script: git"
  },
  {
    "path": "script/merge.py",
    "chars": 6389,
    "preview": "import os\nimport re\nimport sys\n\n\nclass Format(object):\n    hpp = '''\\\n#ifndef {0}\n#define {0}\n\n{1}\n{2}\n{3}\n#endif'''\n\n  "
  },
  {
    "path": "script/string_obfs_tester.py",
    "chars": 562,
    "preview": "import sys\n\ndef main(argc, argv):\n    if argc < 3:\n        print('USAGE: python string_obfs_tester.py [STRING_OBFS.EXE] "
  },
  {
    "path": "test/CMakeLists.txt",
    "chars": 331,
    "preview": "cmake_minimum_required(VERSION 3.10)\nproject(unittest)\n\nset(CMAKE_CXX_STANDARD 17)\n\nfile(GLOB test_files \n        \"impl/"
  },
  {
    "path": "test/impl/fsm.cpp",
    "chars": 3262,
    "preview": "#include <obfs/fsm.hpp>\n#include <catch2/catch.hpp>\n\n#define STATE(Name) struct Name {};\n#define EVENT(Name) struct Name"
  },
  {
    "path": "test/impl/random.cpp",
    "chars": 685,
    "preview": "#include <obfs/random.hpp>\n#include <catch2/catch.hpp>\n\nusing ull = unsigned long long;\n\n// https://en.wikipedia.org/wik"
  },
  {
    "path": "test/impl/sequence.cpp",
    "chars": 2190,
    "preview": "#include <obfs/sequence.hpp>\n#include <catch2/catch.hpp>\n\nTEST_CASE(\"TypeVal\", \"[obfs::Sequence]\") {\n    using val = obf"
  },
  {
    "path": "test/impl/string.cpp",
    "chars": 1301,
    "preview": "#include <obfs/string.hpp>\n#include <catch2/catch.hpp>\n\ntemplate <char Key>\nconstexpr char enc_xor(char value) {\n    ret"
  },
  {
    "path": "test/main.cpp",
    "chars": 53,
    "preview": "#define CATCH_CONFIG_MAIN\n#include <catch2/catch.hpp>"
  }
]

About this extraction

This page contains the full source code of the revsic/cpp-obfuscator GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 29 files (41.0 KB), approximately 11.6k tokens, and a symbol index with 112 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!