Files
obfuscator-llvm-obfuscator/lib/Transforms/Obfuscation/SubstitutionFunction.cpp
T
2013-12-26 14:37:53 +01:00

355 lines
12 KiB
C++

#include "llvm/Transforms/Obfuscation/Substitution.h"
// Implementation of a = b - (-c)
void addNeg(BinaryOperator *bo) {
BinaryOperator *op = NULL;
// Create sub
if(bo->getOpcode() == Instruction::Add) {
op = BinaryOperator::CreateNeg(bo->getOperand(1),"",bo);
op = BinaryOperator::Create(Instruction::Sub,bo->getOperand(0),op,"",bo);
// Check signed wrap
op->setHasNoSignedWrap(bo->hasNoSignedWrap());
op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap());
} else {
op = BinaryOperator::CreateFNeg(bo->getOperand(1),"",bo);
op = BinaryOperator::Create(Instruction::FSub,bo->getOperand(0),op,"",bo);
}
bo->replaceAllUsesWith(op);
}
// Implementation of a = -(-b + (-c))
void addDoubleNeg(BinaryOperator *bo) {
BinaryOperator *op,*op2 = NULL;
if(bo->getOpcode() == Instruction::Add) {
op = BinaryOperator::CreateNeg(bo->getOperand(0),"",bo);
op2 = BinaryOperator::CreateNeg(bo->getOperand(1),"",bo);
op = BinaryOperator::Create(Instruction::Add,op,op2,"",bo);
op = BinaryOperator::CreateNeg(op,"",bo);
// Check signed wrap
op->setHasNoSignedWrap(bo->hasNoSignedWrap());
op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap());
} else {
op = BinaryOperator::CreateFNeg(bo->getOperand(0),"",bo);
op2 = BinaryOperator::CreateFNeg(bo->getOperand(1),"",bo);
op = BinaryOperator::Create(Instruction::FAdd,op,op2,"",bo);
op = BinaryOperator::CreateFNeg(op,"",bo);
}
bo->replaceAllUsesWith(op);
}
// Implementation of r = rand (); a = b + r; a = a + c; a = a - r
void addRand(BinaryOperator *bo) {
BinaryOperator *op = NULL;
if(bo->getOpcode() == Instruction::Add) {
Type *ty = bo->getType();
ConstantInt *co = (ConstantInt*)ConstantInt::get(ty,llvm::cprng->get_uint64_t());
op = BinaryOperator::Create(Instruction::Add,bo->getOperand(0),co,"",bo);
op = BinaryOperator::Create(Instruction::Add,op,bo->getOperand(1),"",bo);
op = BinaryOperator::Create(Instruction::Sub,op,co,"",bo);
// Check signed wrap
op->setHasNoSignedWrap(bo->hasNoSignedWrap());
op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap());
bo->replaceAllUsesWith(op);
}
/* else {
Type *ty = bo->getType();
ConstantFP *co = (ConstantFP*)ConstantFP::get(ty,(float)llvm::cprng->get_uint64_t());
op = BinaryOperator::Create(Instruction::FAdd,bo->getOperand(0),co,"",bo);
op = BinaryOperator::Create(Instruction::FAdd,op,bo->getOperand(1),"",bo);
op = BinaryOperator::Create(Instruction::FSub,op,co,"",bo);
} */
}
// Implementation of r = rand (); a = b - r; a = a + b; a = a + r
void addRand2(BinaryOperator *bo) {
BinaryOperator *op = NULL;
if(bo->getOpcode() == Instruction::Add) {
Type *ty = bo->getType();
ConstantInt *co = (ConstantInt*)ConstantInt::get(ty,llvm::cprng->get_uint64_t());
op = BinaryOperator::Create(Instruction::Sub,bo->getOperand(0),co,"",bo);
op = BinaryOperator::Create(Instruction::Add,op,bo->getOperand(1),"",bo);
op = BinaryOperator::Create(Instruction::Add,op,co,"",bo);
// Check signed wrap
op->setHasNoSignedWrap(bo->hasNoSignedWrap());
op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap());
bo->replaceAllUsesWith(op);
}
/* else {
Type *ty = bo->getType();
ConstantFP *co = (ConstantFP*)ConstantFP::get(ty,(float)llvm::cprng->get_uint64_t());
op = BinaryOperator::Create(Instruction::FAdd,bo->getOperand(0),co,"",bo);
op = BinaryOperator::Create(Instruction::FAdd,op,bo->getOperand(1),"",bo);
op = BinaryOperator::Create(Instruction::FSub,op,co,"",bo);
} */
}
// Implementation of a = b + (-c)
void subNeg(BinaryOperator *bo) {
BinaryOperator *op = NULL;
if(bo->getOpcode() == Instruction::Sub) {
op = BinaryOperator::CreateNeg(bo->getOperand(1),"",bo);
op = BinaryOperator::Create(Instruction::Add,bo->getOperand(0),op,"",bo);
// Check signed wrap
op->setHasNoSignedWrap(bo->hasNoSignedWrap());
op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap());
}
else {
op = BinaryOperator::CreateFNeg(bo->getOperand(1),"",bo);
op = BinaryOperator::Create(Instruction::FAdd,bo->getOperand(0),op,"",bo);
}
bo->replaceAllUsesWith(op);
}
// Implementation of r = rand (); a = b + r; a = a - c; a = a - r
void subRand(BinaryOperator *bo) {
BinaryOperator *op = NULL;
if(bo->getOpcode() == Instruction::Sub) {
Type *ty = bo->getType();
ConstantInt *co = (ConstantInt*)ConstantInt::get(ty,llvm::cprng->get_uint64_t());
op = BinaryOperator::Create(Instruction::Add,bo->getOperand(0),co,"",bo);
op = BinaryOperator::Create(Instruction::Sub,op,bo->getOperand(1),"",bo);
op = BinaryOperator::Create(Instruction::Sub,op,co,"",bo);
// Check signed wrap
op->setHasNoSignedWrap(bo->hasNoSignedWrap());
op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap());
bo->replaceAllUsesWith(op);
}
/* else {
Type *ty = bo->getType();
ConstantFP *co = (ConstantFP*)ConstantFP::get(ty,(float)llvm::cprng->get_uint64_t());
op = BinaryOperator::Create(Instruction::FAdd,bo->getOperand(0),co,"",bo);
op = BinaryOperator::Create(Instruction::FSub,op,bo->getOperand(1),"",bo);
op = BinaryOperator::Create(Instruction::FSub,op,co,"",bo);
} */
}
// Implementation of r = rand (); a = b - r; a = a - c; a = a + r
void subRand2(BinaryOperator *bo) {
BinaryOperator *op = NULL;
if(bo->getOpcode() == Instruction::Sub) {
Type *ty = bo->getType();
ConstantInt *co = (ConstantInt*)ConstantInt::get(ty,llvm::cprng->get_uint64_t());
op = BinaryOperator::Create(Instruction::Sub,bo->getOperand(0),co,"",bo);
op = BinaryOperator::Create(Instruction::Sub,op,bo->getOperand(1),"",bo);
op = BinaryOperator::Create(Instruction::Add,op,co,"",bo);
// Check signed wrap
op->setHasNoSignedWrap(bo->hasNoSignedWrap());
op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap());
bo->replaceAllUsesWith(op);
}
/* else {
Type *ty = bo->getType();
ConstantFP *co = (ConstantFP*)ConstantFP::get(ty,(float)llvm::cprng->get_uint64_t());
op = BinaryOperator::Create(Instruction::FSub,bo->getOperand(0),co,"",bo);
op = BinaryOperator::Create(Instruction::FSub,op,bo->getOperand(1),"",bo);
op = BinaryOperator::Create(Instruction::FAdd,op,co,"",bo);
} */
}
// Implementation of a = b & c => a = (b^~c)& b
void andSubstitution(BinaryOperator *bo) {
BinaryOperator *op = NULL;
// Create NOT on second operand => ~c
op = BinaryOperator::CreateNot(bo->getOperand(1),"",bo);
// Create XOR => (b^~c)
BinaryOperator *op1 = BinaryOperator::Create(Instruction::Xor,bo->getOperand(0),op,"",bo);
// Create AND => (b^~c) & b
op = BinaryOperator::Create(Instruction::And,op1,bo->getOperand(0),"",bo);
bo->replaceAllUsesWith(op);
}
// Implementation of a = a && b <=> !(!a | !b) && (r | !r)
void andSubstitutionRand(BinaryOperator *bo){
// Copy of the BinaryOperator type to create the random number with the
// same type of the operands
Type *ty = bo->getType();
// r (Random number)
ConstantInt *co = (ConstantInt*)ConstantInt::get(ty, llvm::cprng->get_uint64_t());
// !a
BinaryOperator *op = BinaryOperator::CreateNot(bo->getOperand(0),"",bo);
// !b
BinaryOperator *op1 = BinaryOperator::CreateNot(bo->getOperand(1),"",bo);
// !r
BinaryOperator *opr = BinaryOperator::CreateNot(co,"",bo);
// (!a | !b)
BinaryOperator *opa = BinaryOperator::Create(Instruction::Or,op,op1,"",bo);
// (r | !r)
opr = BinaryOperator::Create(Instruction::Or,co,opr,"",bo);
// !(!a | !b)
op = BinaryOperator::CreateNot(opa,"",bo);
// !(!a | !b) && (r | !r)
op = BinaryOperator::Create(Instruction::And,op,opr,"",bo);
// We replace all the old AND operators with the new one transformed
bo->replaceAllUsesWith(op);
}
// Implementation of a = b | c => a = (b & c) | (b ^ c)
void orSubstitutionRand(BinaryOperator *bo){
Type * ty = bo->getType();
ConstantInt *co = (ConstantInt*)ConstantInt::get(ty, llvm::cprng->get_uint64_t());
// !a
BinaryOperator *op = BinaryOperator::CreateNot(bo->getOperand(0),"",bo);
// !b
BinaryOperator *op1 = BinaryOperator::CreateNot(bo->getOperand(1),"",bo);
// !r
BinaryOperator *op2 = BinaryOperator::CreateNot(co,"",bo);
// !a && r
BinaryOperator *op3 = BinaryOperator::Create(Instruction::And,op,co,"",bo);
// a && !r
BinaryOperator *op4 = BinaryOperator::Create(Instruction::And,bo->getOperand(0),op2,"",bo);
// !b && r
BinaryOperator *op5 = BinaryOperator::Create(Instruction::And,op1,co,"",bo);
// b && !r
BinaryOperator *op6 = BinaryOperator::Create(Instruction::And,bo->getOperand(1),op2,"",bo);
// (!a && r) || (a && !r)
op3 = BinaryOperator::Create(Instruction::Or,op3,op4,"",bo);
// (!b && r) ||(b && !r)
op4 = BinaryOperator::Create(Instruction::Or,op5,op6,"",bo);
// (!a && r) || (a && !r) ^ (!b && r) ||(b && !r)
op5 = BinaryOperator::Create(Instruction::Xor,op3,op4,"",bo);
// !a || !b
op3 = BinaryOperator::Create(Instruction::Or,op,op1,"",bo);
// !(!a || !b)
op3 = BinaryOperator::CreateNot(op3,"",bo);
// r || !r
op4 = BinaryOperator::Create(Instruction::Or,co,op2,"",bo);
// !(!a || !b) && (r || !r)
op4 = BinaryOperator::Create(Instruction::And,op3,op4,"",bo);
// [(!a && r) || (a && !r) ^ (!b && r) ||(b && !r) ] || [!(!a || !b) && (r || !r)]
op = BinaryOperator::Create(Instruction::Or,op5,op4,"",bo);
bo->replaceAllUsesWith(op);
}
void orSubstitution(BinaryOperator *bo) {
BinaryOperator *op = NULL;
// Creating first operand (b & c)
op = BinaryOperator::Create(Instruction::And,bo->getOperand(0),bo->getOperand(1),"",bo);
// Creating second operand (b ^ c)
BinaryOperator *op1 = BinaryOperator::Create(Instruction::Xor,bo->getOperand(0),bo->getOperand(1),"",bo);
// final op
op = BinaryOperator::Create(Instruction::Or,op,op1,"",bo);
bo->replaceAllUsesWith(op);
}
// Implementation of a = a ~ b => a = (!a && b) || (a && !b)
void xorSubstitution(BinaryOperator *bo) {
BinaryOperator *op = NULL;
// Create NOT on first operand
op = BinaryOperator::CreateNot(bo->getOperand(0),"",bo); // !a
// Create AND
op = BinaryOperator::Create(Instruction::And,bo->getOperand(1),op,"",bo); // !a && b
// Create NOT on second operand
BinaryOperator *op1 = BinaryOperator::CreateNot(bo->getOperand(1),"",bo); // !b
// Create AND
op1 = BinaryOperator::Create(Instruction::And,bo->getOperand(0),op1,"",bo); // a && !b
// Create OR
op = BinaryOperator::Create(Instruction::Or,op,op1,"",bo); // (!a && b) || (a && !b)
bo->replaceAllUsesWith(op);
}
// implementation of a = a ^ b <=> (a ^ r) ^ (b ^ r) <=> (!a && r || a && !r) ^ (!b && r || b && !r)
// note : r is a random number
void xorSubstitutionRand(BinaryOperator *bo){
BinaryOperator *op = NULL;
Type *ty = bo->getType();
ConstantInt *co = (ConstantInt*)ConstantInt::get(ty, llvm::cprng->get_uint64_t());
// !a
op = BinaryOperator::CreateNot(bo->getOperand(0),"",bo);
// !a && r
op = BinaryOperator::Create(Instruction::And,co,op,"",bo);
// !r
BinaryOperator *opr = BinaryOperator::CreateNot(co,"",bo);
// a && !r
BinaryOperator *op1 = BinaryOperator::Create(Instruction::And,bo->getOperand(0),opr,"",bo);
// !b
BinaryOperator *op2 = BinaryOperator::CreateNot(bo->getOperand(1),"",bo);
// !b && r
op2 = BinaryOperator::Create(Instruction::And,op2,co,"",bo);
// b && !r
BinaryOperator *op3 = BinaryOperator::Create(Instruction::And,bo->getOperand(1),opr,"",bo);
// (!a && r) || (a && !r)
op = BinaryOperator::Create(Instruction::Or,op,op1,"",bo);
// (!b && r) || (b && !r)
op1 = BinaryOperator::Create(Instruction::Or,op2,op3,"",bo);
// (!a && r) || (a && !r) ^ (!b && r) || (b && !r)
op = BinaryOperator::Create(Instruction::Xor,op,op1,"",bo);
bo->replaceAllUsesWith(op);
}