#ifndef LLVM_SUPPORT_OBFUSCATION_H
#define LLVM_SUPPORT_OBFUSCATION_H
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
namespace llvm {
class Obfuscator {
using MapTy = StringMap<StringRef, BumpPtrAllocator &>;
public:
Obfuscator()
: Alloc(), ForwardMap(64, Alloc), IrreveribleForwardMap(32, Alloc) {}
Obfuscator(const Obfuscator &) = delete;
Obfuscator &operator = (const Obfuscator &) = delete;
StringRef obfuscate(StringRef Src, bool reverse = false);
ErrorOr<StringRef> lookup(StringRef ObfStr) const {
return lookupImpl(ObfStr);
}
void writeReverseMap(raw_ostream &OS) const {
writeReverseMapImpl(OS);
}
void readReverseMap(MemoryBuffer *buf) {
readReverseMapImpl(buf);
}
BumpPtrAllocator &getAllocator() { return Alloc; }
char *copyString(StringRef S) {
auto Ret = allocateString(S.size());
std::copy(S.begin(), S.end(), Ret);
return Ret;
}
ErrorOr<StringRef> lookupForwardMap(StringRef Symbol) const;
protected:
virtual StringRef obfuscateImpl(StringRef, bool) = 0;
virtual ErrorOr<StringRef> lookupImpl(StringRef) const = 0;
virtual void writeReverseMapImpl(raw_ostream &OS) const = 0;
virtual void readReverseMapImpl(MemoryBuffer *buf) = 0;
char *allocateString(unsigned Length) {
assert(Length > 0 && "no length?");
char *P = (char *)Alloc.Allocate(Length + 1, 1);
P[Length] = '\0';
return P;
}
virtual ~Obfuscator() {}
private:
BumpPtrAllocator Alloc;
MapTy ForwardMap;
MapTy IrreveribleForwardMap;
virtual void anchor() = 0;
};
class Rot13Obfuscator : public Obfuscator {
using ReverseMapTy = StringMap<StringRef, BumpPtrAllocator &>;
using Obfuscator::Obfuscator;
public:
Rot13Obfuscator() : Obfuscator(), ReverseMap(16, getAllocator()) {}
protected:
virtual StringRef obfuscateImpl(StringRef, bool) override;
virtual ErrorOr<StringRef> lookupImpl(StringRef) const override;
virtual void writeReverseMapImpl(raw_ostream &OS) const override;
virtual void readReverseMapImpl(MemoryBuffer* buf) override;
private:
ReverseMapTy ReverseMap;
static char rot13(char C) {
if (C >= 'A' && C <= 'Z')
return ((C - 'A' + 13) % 26) + 'A';
if (C >= 'a' && C <= 'z')
return ((C - 'a' + 13) % 26) + 'a';
return C;
}
virtual void anchor() override;
};
class IncrementObfuscator : public Obfuscator {
using ReverseMapTy = std::vector<StringRef>;
using Obfuscator::Obfuscator;
public:
IncrementObfuscator(StringRef Prefix = "__hidden#", StringRef Suffix = "_",
StringRef IrPrefix = "__ir_hidden#")
: Obfuscator(), Pre(copyString(Prefix)),
Suf(copyString(Suffix)), IrPre(IrPrefix)
{
assert(!Prefix.equals(IrPrefix) &&
"Prefix and IrPrefix cannot be the same");
}
protected:
virtual StringRef obfuscateImpl(StringRef, bool) override;
virtual ErrorOr<StringRef> lookupImpl(StringRef) const override;
virtual void writeReverseMapImpl(raw_ostream &OS) const override;
virtual void readReverseMapImpl(MemoryBuffer* buf) override;
private:
StringRef Pre;
StringRef Suf;
StringRef IrPre;
unsigned Num = 0;
unsigned IrNum = 0;
ReverseMapTy ReverseMap;
unsigned findIndex(StringRef Key) const;
virtual void anchor() override;
};
}
#endif // LLVM_SUPPORT_OBFUSCATION_H