readme update, bugfix etc.

This commit is contained in:
G0lge
2024-04-07 16:11:47 +03:00
parent e0e552ec1c
commit cb7efb796f
24 changed files with 301 additions and 201 deletions
+31 -32
View File
@@ -13,59 +13,64 @@ This tool is designed for:
### Optimization
## Diagram
![image](https://github.com/loneicewolf/Mergen/assets/68499986/d557b048-9c77-49f2-82b2-ef299bc783c8)
![image](images/graph.png)
## Example
This is our target program
```cpp
int maths(int a, int b, int c) {
return a + b - c;
struct test {
int a;
int b;
int c;
};
int maths(test a, int b, int c) {
return a.a + b - c;
}
```
![image](https://raw.githubusercontent.com/NaC-L/Mergen/main/images/Original_Asm_Code.png)
![image](images/org_disass.png)
VMProtect settings, everything is turned off, we virtualize the function on ultra setting. (Tested versions 3.4.0-3.6.0)
![image](images/org_decomp.png)
![image](https://raw.githubusercontent.com/NaC-L/Mergen/main/images/vmp_settings.png)
VMProtect settings, everything is turned off, we virtualize the function on ultra setting. (Tested versions 3.4.0-3.6.0 3.8.1)
![image](https://raw.githubusercontent.com/NaC-L/Mergen/main/images/vmp_settings2.png)
![image](images/vmp_settings1.png)
This is how it looks after virtualizing.
![image](https://raw.githubusercontent.com/NaC-L/Mergen/main/images/vmp_ultra_asm.png)
![image](images/vmp_settings2.png)
Here, we run mergen. First argument is the name of the file and the second argument is the address of the function. Look how simple it is to run. And we can compile the output so we can explore it using our favorite decompiler.
![image](https://raw.githubusercontent.com/NaC-L/Mergen/main/images/mergen_run.png)
![image](images/run_mergen.png)
```llvm
; ModuleID = 'my_lifting_module'
source_filename = "my_lifting_module"
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
define i64 @main(i64 %rax, i64 %rcx, i64 %rdx, i64 %rbx, i64 %0, i64 %rbp, i64 %rsi, i64 %rdi, i64 %r8, i64 %r9, i64 %r10, i64 %r11, i64 %r12, i64 %r13, i64 %r14, i64 %r15, ptr nocapture readnone %memory) local_unnamed_addr #0 {
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
define i64 @main(i64 %rax, i64 %rcx, i64 %rdx, i64 %rbx, i64 %0, i64 %rbp, i64 %rsi, i64 %rdi, i64 %r8, i64 %r9, i64 %r10, i64 %r11, i64 %r12, i64 %r13, i64 %r14, i64 %r15, ptr nocapture readonly %memory) local_unnamed_addr #0 {
entry:
%stackmemory = alloca i128, i128 20971520, align 8
%stackmemory = alloca i128, i128 13758960, align 8
%1 = trunc i64 %r8 to i32
%2 = trunc i64 %rdx to i32
%3 = trunc i64 %rcx to i32
%realadd-5369234850- = add i32 %2, %3
%not17196 = sub i32 %realadd-5369234850-, %1
%4 = zext i32 %not17196 to i64
ret i64 %4
%GEPLoadxd-5369456437- = getelementptr i8, ptr %memory, i64 %rcx
%3 = load i32, ptr %GEPLoadxd-5369456437-, align 4
%adc-temp-5370242400- = sub i32 %2, %1
%realnot-5369532059- = add i32 %adc-temp-5370242400-, %3
%stackmemory10243.sroa.55.1375304.insert.ext10255 = zext i32 %realnot-5369532059- to i64
ret i64 %stackmemory10243.sroa.55.1375304.insert.ext10255
}
attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
```
After compiling:
![image](https://raw.githubusercontent.com/NaC-L/Mergen/main/images/disass.png)
![image](images/mergen_disass.png)
![image](https://raw.githubusercontent.com/NaC-L/Mergen/main/images/decomp.png)
![image](images/mergen_dec.png)
Now you might notice the registers are a little bit off. This is because of we dont follow the calling conventions, if we were to follow the calling conventions, function signature would look like this:
```llvm
@@ -73,20 +78,14 @@ define i64 @main(i64 %rcx, i64 %rdx, i64 %rdx, i64 %r8, i64 %r9 ...)
```
So, we just adjust the function signature to look normally. If you have more questions about this part, I suggest you research [calling conventions](https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170#parameter-passing) and [ABI](https://learn.microsoft.com/en-us/cpp/build/x64-software-conventions?view=msvc-170&source=recommendations#register-volatility-and-preservation).
![image](https://raw.githubusercontent.com/NaC-L/Mergen/main/images/decomp2.png)
![image](https://raw.githubusercontent.com/NaC-L/Mergen/main/images/adjusted.png)
## Current problems
## What it can/cant do
### Automatically exploring branches and merging two paths into one program
### It can devirtualize some versions of some programs.
### It can figure out if `jcc` is opaque.
### It cant decide which path to follow if `jcc` is not opaque.
### It cant optimize whole binary, only one function at a time.
### Some optimization stuff
### ABI stuff
# Getting in touch
Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

+148 -72
View File
@@ -16,20 +16,42 @@ void initBases2(void* file_base, ZyanU8* data) {
#define TESTFOLDER4
#define TESTFOLDER5
#define TESTFOLDER6
#define TESTFOLDER7
#define TESTFOLDER8
#define TESTFOLDERshl
#define TESTFOLDERshr
#endif
KnownBits analyzeValueKnownBits(llvm::Value* value, const llvm::DataLayout& DL) {
KnownBits knownBits;
KnownBits analyzeValueKnownBits(Value* value, const DataLayout& DL) {
KnownBits knownBits(64);
knownBits.resetAll();
if (value->getType() == Type::getInt128Ty(value->getContext()))
return knownBits;
computeKnownBits(value, knownBits, DL, 0);
return knownBits;
return computeKnownBits(value, DL, 3);
}
Value* simplifyValue(Value* v, const DataLayout& DL) {
if (!isa<Instruction>(v))
return v;
Instruction* inst = cast<Instruction>(v);
SimplifyQuery SQ(DL,inst);
if (auto x = simplifyInstruction(inst, SQ)) {
/*
if (isa<PoisonValue>(x)) // if poison it should be 0 for shifts, can other operations generate poison without a poison value anyways?
return ConstantInt::get(v->getType(), 0);
*/
return x;
}
return v;
}
Value* createSelectFolder(IRBuilder<>& builder, Value* C, Value* True, Value* False, const Twine& Name = "") {
#ifdef TESTFOLDER
@@ -44,8 +66,9 @@ Value* createSelectFolder(IRBuilder<>& builder, Value* C, Value* True, Value* Fa
}
}
}
#endif
return builder.CreateSelect(C, True, False, Name);
#endif
DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
return simplifyValue(builder.CreateSelect(C, True, False, Name), DL);
}
Value* createAddFolder(IRBuilder<>& builder, Value* LHS, Value* RHS, const Twine& Name = "") {
#ifdef TESTFOLDER3
@@ -57,7 +80,8 @@ Value* createAddFolder(IRBuilder<>& builder, Value* LHS, Value* RHS, const Twine
if (RHSConst->isZero()) return LHS;
}
#endif
return builder.CreateAdd(LHS, RHS, Name);
DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
return simplifyValue( builder.CreateAdd(LHS, RHS, Name), DL);
}
Value* createSubFolder(IRBuilder<>& builder, Value* LHS, Value* RHS, const Twine& Name = "") {
@@ -65,8 +89,9 @@ Value* createSubFolder(IRBuilder<>& builder, Value* LHS, Value* RHS, const Twine
if (ConstantInt* RHSConst = dyn_cast<ConstantInt>(RHS)) {
if (RHSConst->isZero()) return LHS;
}
#endif
return builder.CreateSub(LHS, RHS, Name);
#endif
DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
return simplifyValue( builder.CreateSub(LHS, RHS, Name) , DL);
}
Value* foldLShrKnownBits(LLVMContext& context, KnownBits LHS, KnownBits RHS) {
@@ -76,7 +101,20 @@ Value* foldLShrKnownBits(LLVMContext& context, KnownBits LHS, KnownBits RHS) {
if (RHS.hasConflict() || LHS.hasConflict() || !RHS.isConstant() || RHS.getBitWidth() > 64 || LHS.isUnknown() || LHS.getBitWidth() <= 1)
return nullptr;
auto result = KnownBits::lshr(LHS, RHS);
APInt shiftAmount = RHS.getConstant();
unsigned shiftSize = shiftAmount.getZExtValue();
if (shiftSize >= LHS.getBitWidth())
return ConstantInt::get(Type::getIntNTy(context, LHS.getBitWidth()), 0);;
KnownBits result(LHS.getBitWidth());
result.One = LHS.One.lshr(shiftSize);
result.Zero = LHS.Zero.lshr(shiftSize) | APInt::getHighBitsSet(LHS.getBitWidth(), shiftSize);
if (!(result.Zero | result.One).isAllOnes()) {
return nullptr;
}
return ConstantInt::get(Type::getIntNTy(context, LHS.getBitWidth()), result.getConstant());
}
@@ -85,16 +123,30 @@ Value* foldShlKnownBits(LLVMContext& context, KnownBits LHS, KnownBits RHS) {
if (RHS.hasConflict() || LHS.hasConflict() || !RHS.isConstant() || RHS.getBitWidth() > 64 || LHS.isUnknown() || LHS.getBitWidth() <= 1)
return nullptr;
auto result = KnownBits::shl(LHS, RHS);
APInt shiftAmount = RHS.getConstant();
unsigned shiftSize = shiftAmount.getZExtValue();
if (shiftSize >= LHS.getBitWidth())
return ConstantInt::get(Type::getIntNTy(context, LHS.getBitWidth()), 0);
KnownBits result(LHS.getBitWidth());
result.One = LHS.One.shl(shiftSize);
result.Zero = LHS.Zero.shl(shiftSize) | APInt::getLowBitsSet(LHS.getBitWidth(), shiftSize);
if (result.hasConflict() || !result.isConstant()) {
return nullptr;
}
return ConstantInt::get(Type::getIntNTy(context, LHS.getBitWidth()), result.getConstant());
}
Value* createShlFolder(IRBuilder<>& builder, Value* LHS, Value* RHS, const Twine& Name = "") {
DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
#ifdef TESTFOLDERshl
llvm::DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
KnownBits KnownLHS = analyzeValueKnownBits(LHS, DL);
KnownBits KnownRHS = analyzeValueKnownBits(RHS, DL);
@@ -106,15 +158,15 @@ Value* createShlFolder(IRBuilder<>& builder, Value* LHS, Value* RHS, const Twine
#endif
return builder.CreateShl(LHS, RHS, Name);
return simplifyValue( builder.CreateShl(LHS, RHS, Name), DL);
}
Value* createLShrFolder(IRBuilder<>& builder, Value* LHS, Value* RHS, const Twine& Name = "") {
DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
#ifdef TESTFOLDERshr
llvm::DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
KnownBits KnownLHS = analyzeValueKnownBits(LHS, DL);
KnownBits KnownRHS = analyzeValueKnownBits(RHS, DL);
@@ -126,8 +178,7 @@ Value* createLShrFolder(IRBuilder<>& builder, Value* LHS, Value* RHS, const Twin
#endif
return builder.CreateLShr(LHS, RHS, Name);
return simplifyValue(builder.CreateLShr(LHS, RHS, Name),DL);
}
Value* createShlFolder(IRBuilder<>& builder, Value* LHS, uintptr_t RHS, const Twine& Name = "") {
@@ -150,7 +201,7 @@ Value* createLShrFolder(IRBuilder<>& builder, Value* LHS, APInt RHS, const Twine
Value* foldOrKnownBits(LLVMContext& context, KnownBits LHS, KnownBits RHS) {
if (RHS.hasConflict() || LHS.hasConflict() || LHS.isUnknown() || RHS.isUnknown() || LHS.getBitWidth() != RHS.getBitWidth() || !RHS.isConstant() || LHS.getBitWidth() <= 1 || RHS.getBitWidth() <= 1 || RHS.getBitWidth() > 64 || LHS.getBitWidth() > 64) {
if (RHS.hasConflict() || LHS.hasConflict() || LHS.isUnknown() || RHS.isUnknown() || LHS.getBitWidth() != RHS.getBitWidth() || !RHS.isConstant() || LHS.getBitWidth() <= 1 || RHS.getBitWidth() < 1 || RHS.getBitWidth() > 64 || LHS.getBitWidth() > 64) {
return nullptr;
}
@@ -160,7 +211,7 @@ Value* foldOrKnownBits(LLVMContext& context, KnownBits LHS, KnownBits RHS) {
combined.One = LHS.One | RHS.One;
combined.Zero = LHS.Zero & RHS.Zero;
if (!(combined.Zero | combined.One).isAllOnes() || combined.getBitWidth() <= 1) {
if (!combined.isConstant() || combined.hasConflict()) {
return nullptr;
}
@@ -170,6 +221,7 @@ Value* foldOrKnownBits(LLVMContext& context, KnownBits LHS, KnownBits RHS) {
Value* createOrFolder(IRBuilder<>& builder, Value* LHS, Value* RHS, const Twine& Name = "") {
DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
#ifdef TESTFOLDER5
if (ConstantInt* LHSConst = dyn_cast<ConstantInt>(LHS)) {
@@ -178,7 +230,6 @@ Value* createOrFolder(IRBuilder<>& builder, Value* LHS, Value* RHS, const Twine&
if (ConstantInt* RHSConst = dyn_cast<ConstantInt>(RHS)) {
if (RHSConst->isZero()) return LHS;
}
llvm::DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
KnownBits KnownLHS = analyzeValueKnownBits(LHS, DL);
KnownBits KnownRHS = analyzeValueKnownBits(RHS, DL);
@@ -192,11 +243,25 @@ Value* createOrFolder(IRBuilder<>& builder, Value* LHS, Value* RHS, const Twine&
#endif
return builder.CreateOr(LHS, RHS, Name);
return simplifyValue( builder.CreateOr(LHS, RHS, Name),DL );
}
Value* foldXorKnownBits(LLVMContext& context, KnownBits LHS, KnownBits RHS) {
if (RHS.hasConflict() || LHS.hasConflict() || LHS.isUnknown() || RHS.isUnknown() || !RHS.isConstant() || LHS.getBitWidth() != RHS.getBitWidth() || RHS.getBitWidth() <= 1 || LHS.getBitWidth() <= 1 || RHS.getBitWidth() > 64 || LHS.getBitWidth() > 64) {
return nullptr;
}
if (!((LHS.Zero | LHS.One) & RHS.One).eq(RHS.One)) {
return nullptr;
}
APInt resultValue = LHS.One ^ RHS.One;
return ConstantInt::get(Type::getIntNTy(context, LHS.getBitWidth()), resultValue);
}
Value* createXorFolder(IRBuilder<>& builder, Value* LHS, Value* RHS, const Twine& Name = "") {
#ifdef TESTFOLDER6
@@ -206,8 +271,18 @@ Value* createXorFolder(IRBuilder<>& builder, Value* LHS, Value* RHS, const Twine
if (ConstantInt* RHSConst = dyn_cast<ConstantInt>(RHS)) {
if (RHSConst->isZero()) return LHS;
}
#endif
return builder.CreateXor(LHS, RHS, Name);
DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
KnownBits KnownLHS = analyzeValueKnownBits(LHS, DL);
KnownBits KnownRHS = analyzeValueKnownBits(RHS, DL);
if (auto V = foldXorKnownBits(builder.getContext(), KnownLHS, KnownRHS))
return V;
return simplifyValue(builder.CreateXor(LHS, RHS, Name), DL);
}
std::optional<bool> foldKnownBits(CmpInst::Predicate P, KnownBits LHS, KnownBits RHS) {
@@ -239,7 +314,7 @@ std::optional<bool> foldKnownBits(CmpInst::Predicate P, KnownBits LHS, KnownBits
}
Value* createICMPFolder(IRBuilder<>& builder, CmpInst::Predicate P, Value* LHS, Value* RHS, const Twine& Name = "") {
llvm::DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
KnownBits KnownLHS = analyzeValueKnownBits(LHS, DL);
KnownBits KnownRHS = analyzeValueKnownBits(RHS, DL);
@@ -247,7 +322,7 @@ Value* createICMPFolder(IRBuilder<>& builder, CmpInst::Predicate P, Value* LHS,
return ConstantInt::get(Type::getInt1Ty(builder.getContext()), v.value());
}
return builder.CreateICmp(P, LHS, RHS, Name);
return simplifyValue( builder.CreateICmp(P, LHS, RHS, Name), DL);
}
Value* foldAndKnownBits(LLVMContext& context, KnownBits LHS, KnownBits RHS) {
@@ -280,7 +355,7 @@ Value* createAndFolder(IRBuilder<>& builder, Value* LHS, Value* RHS, const Twine
if (RHSConst->isMinusOne()) return LHS;
}
*/
llvm::DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
KnownBits KnownLHS = analyzeValueKnownBits(LHS, DL);
KnownBits KnownRHS = analyzeValueKnownBits(RHS, DL);
@@ -292,38 +367,35 @@ Value* createAndFolder(IRBuilder<>& builder, Value* LHS, Value* RHS, const Twine
}
#endif
return builder.CreateAnd(LHS, RHS, Name);
return simplifyValue( builder.CreateAnd(LHS, RHS, Name), DL);
}
// - probably not needed anymore
Value* createTruncFolder(IRBuilder<>& builder, Value* V, Type* DestTy, const Twine& Name = "") {
Value* resulttrunc = builder.CreateTrunc(V, DestTy, Name);
DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
#ifdef TESTFOLDER7
llvm::DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
KnownBits KnownRHS = analyzeValueKnownBits(resulttrunc, DL);
printvalue(resulttrunc)
printvalue(V)
printvalue2(KnownRHS)
if (!KnownRHS.hasConflict() && KnownRHS.getBitWidth() > 1 && KnownRHS.isConstant())
return ConstantInt::get(DestTy, KnownRHS.getConstant());
#endif
return resulttrunc;
return simplifyValue(resulttrunc, DL);
}
// - probably not needed anymore
Value* createZExtFolder(IRBuilder<>& builder, Value* V, Type* DestTy, const Twine& Name = "") {
Value* createZExtFolder(IRBuilder<>& builder, Value* V, Type* DestTy, const Twine& Name = "") {
auto resultzext = builder.CreateZExt(V, DestTy, Name);
DataLayout DL(builder.GetInsertBlock()->getParent()->getParent());
#ifdef TESTFOLDER8
if (V->getType() == DestTy) {
return V;
}
KnownBits KnownRHS = analyzeValueKnownBits(resultzext, DL);
if (!KnownRHS.hasConflict() && KnownRHS.getBitWidth() > 1 && KnownRHS.isConstant())
return ConstantInt::get(DestTy, KnownRHS.getConstant());
#endif
return builder.CreateZExt(V, DestTy, Name);
return resultzext;
}
@@ -394,30 +466,30 @@ IntegerType* getIntSize(int size, LLVMContext& context) {
switch (size) {
case 1: {
return llvm::Type::getInt1Ty(context);
return Type::getInt1Ty(context);
}
case 8: {
return llvm::Type::getInt8Ty(context);
return Type::getInt8Ty(context);
}
case 16: {
return llvm::Type::getInt16Ty(context);
return Type::getInt16Ty(context);
}
case 32: {
return llvm::Type::getInt32Ty(context);
return Type::getInt32Ty(context);
}
case 64: {
return llvm::Type::getInt64Ty(context);
return Type::getInt64Ty(context);
}
case 128: {
return llvm::Type::getInt128Ty(context);
return Type::getInt128Ty(context);
}
default: {
return llvm::Type::getIntNTy(context, size);
return Type::getIntNTy(context, size);
}
}
@@ -426,8 +498,8 @@ IntegerType* getIntSize(int size, LLVMContext& context) {
void Init_Flags(LLVMContext& context, IRBuilder<>& builder) {
auto zero = ConstantInt::getSigned(llvm::Type::getInt1Ty(context), 0);
auto one = ConstantInt::getSigned(llvm::Type::getInt1Ty(context), 1);
auto zero = ConstantInt::getSigned(Type::getInt1Ty(context), 0);
auto one = ConstantInt::getSigned(Type::getInt1Ty(context), 1);
FlagList[FLAG_CF] = zero;
FlagList[FLAG_PF] = zero;
@@ -445,9 +517,7 @@ void Init_Flags(LLVMContext& context, IRBuilder<>& builder) {
Value* setFlag(LLVMContext& context, IRBuilder<>& builder, Flag flag, Value* newValue = nullptr) {
newValue = createTruncFolder(builder,newValue, Type::getInt1Ty(context));
#ifdef _DEVELOPMENT
outs() << "flag set: " << flag << " "; newValue->print(outs()); outs() << "\n"; outs().flush();
#endif
if (flag == FLAG_RESERVED1
|| flag == FLAG_RESERVED5
|| flag == FLAG_IF
@@ -455,7 +525,7 @@ Value* setFlag(LLVMContext& context, IRBuilder<>& builder, Flag flag, Value* new
)
return nullptr;
auto one = ConstantInt::getSigned(llvm::Type::getInt1Ty(context), 1);
auto one = ConstantInt::getSigned(Type::getInt1Ty(context), 1);
return FlagList[flag] = newValue;
@@ -463,7 +533,7 @@ Value* setFlag(LLVMContext& context, IRBuilder<>& builder, Flag flag, Value* new
Value* getFlag(LLVMContext& context, IRBuilder<>& builder, Flag flag) {
if (FlagList[flag])
return FlagList[flag];
return ConstantInt::getSigned(llvm::Type::getInt1Ty(context), 0);
return ConstantInt::getSigned(Type::getInt1Ty(context), 0);
}
@@ -476,8 +546,8 @@ Value* getFlag(LLVMContext& context, IRBuilder<>& builder, Flag flag) {
void Init_Flags2(LLVMContext& context, IRBuilder<>& builder) {
auto zero = (ConstantInt*)llvm::ConstantInt::getSigned(llvm::Type::getInt64Ty(context), 0);
auto value = (ConstantInt*)llvm::ConstantInt::getSigned(llvm::Type::getInt64Ty(context), 2);
auto zero = (ConstantInt*)ConstantInt::getSigned(Type::getInt64Ty(context), 0);
auto value = (ConstantInt*)ConstantInt::getSigned(Type::getInt64Ty(context), 2);
auto flags = RegisterList[ZYDIS_REGISTER_RFLAGS];
@@ -505,6 +575,7 @@ void initMemoryAlloc(Value* allocArg) {
memoryAlloc = allocArg;
}
// replace it so that we can select we want rcx, rdx, r8, r9 and rest pushed to stack or everything is unknown
unordered_map<int, Value*> InitRegisters(LLVMContext& context, IRBuilder<>& builder,Function* function, ZyanU64 rip) {
int zydisRegister = ZYDIS_REGISTER_RAX;
@@ -518,7 +589,7 @@ unordered_map<int, Value*> InitRegisters(LLVMContext& context, IRBuilder<>& buil
continue;
}
llvm::Argument* arg = &*argIt;
Argument* arg = &*argIt;
arg->setName(ZydisRegisterGetString((ZydisRegister)zydisRegister));
if (std::next(argIt) == argEnd) {
@@ -536,8 +607,8 @@ unordered_map<int, Value*> InitRegisters(LLVMContext& context, IRBuilder<>& buil
auto zero = (ConstantInt*)llvm::ConstantInt::getSigned(llvm::Type::getInt64Ty(context), 0);
auto value = (ConstantInt*)llvm::ConstantInt::getSigned(llvm::Type::getInt64Ty(context), rip);
auto zero = (ConstantInt*)ConstantInt::getSigned(Type::getInt64Ty(context), 0);
auto value = (ConstantInt*)ConstantInt::getSigned(Type::getInt64Ty(context), rip);
auto new_rip = createAddFolder(builder,zero, value);
@@ -546,7 +617,7 @@ unordered_map<int, Value*> InitRegisters(LLVMContext& context, IRBuilder<>& buil
auto stackvalue = (ConstantInt*)llvm::ConstantInt::getSigned(llvm::Type::getInt64Ty(context), STACKP_VALUE);
auto stackvalue = (ConstantInt*)ConstantInt::getSigned(Type::getInt64Ty(context), STACKP_VALUE);
auto new_stack_pointer = createAddFolder(builder,stackvalue, zero);
RegisterList[ZYDIS_REGISTER_RSP] = new_stack_pointer;
@@ -824,8 +895,8 @@ Value* GetEffectiveAddress(LLVMContext& context, IRBuilder<>& builder, ZydisDeco
#include <vector>
#include <cassert>
using namespace llvm;
// replace it with https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/Analysis/MemoryLocation.h#L228 but I think this might be better after build, not while building
class ValueByteReference {
public:
Value* value;
@@ -862,7 +933,8 @@ public:
}
}
Value* retrieveCombinedValue(llvm::IRBuilder<>& builder, unsigned startAddress, unsigned byteCount) {
Value* retrieveCombinedValue(IRBuilder<>& builder, unsigned startAddress, unsigned byteCount) {
LLVMContext& context = builder.getContext();
if (byteCount == 0) return nullptr;
@@ -888,6 +960,10 @@ public:
return firstSource;
}
// supposed to return 0 if never used, wtf?
if (firstSource == nullptr) {
return ConstantInt::get( Type::getIntNTy(context,byteCount), 0);
}
Value* result = nullptr;
@@ -895,12 +971,12 @@ public:
unsigned currentAddress = startAddress + i;
if (currentAddress < buffer.size() && buffer[currentAddress] != nullptr) {
auto* ref = buffer[currentAddress];
llvm::Value* byteValue = extractByte(builder, ref->value, ref->byteOffset);
Value* byteValue = extractByte(builder, ref->value, ref->byteOffset);
if (!result) {
result = createZExtFolder(builder,byteValue, Type::getIntNTy(builder.getContext(), byteCount * 8));
}
else {
llvm::Value* shiftedByteValue = createShlFolder(builder, createZExtFolder(builder,byteValue, Type::getIntNTy(builder.getContext(), byteCount*8) ), llvm::APInt(byteCount * 8, i * 8));
Value* shiftedByteValue = createShlFolder(builder, createZExtFolder(builder,byteValue, Type::getIntNTy(builder.getContext(), byteCount*8) ), APInt(byteCount * 8, i * 8));
result = createAddFolder(builder,result, shiftedByteValue,"extractbytesthing");
}
}
@@ -910,13 +986,13 @@ public:
}
private:
llvm::Value* extractByte(llvm::IRBuilder<>& builder, llvm::Value* value, unsigned byteOffset) {
Value* extractByte(IRBuilder<>& builder, Value* value, unsigned byteOffset) {
if (!value) {
return ConstantInt::get(Type::getInt8Ty(builder.getContext()), 0);
}
unsigned shiftAmount = byteOffset * 8;
llvm::Value* shiftedValue = createLShrFolder(builder,value, llvm::APInt(value->getType()->getIntegerBitWidth(), shiftAmount), "extractbyte");
Value* shiftedValue = createLShrFolder(builder,value, APInt(value->getType()->getIntegerBitWidth(), shiftAmount), "extractbyte");
return createTruncFolder(builder,shiftedValue, Type::getInt8Ty(builder.getContext()));
}
};
@@ -941,10 +1017,10 @@ Value* GetOperandValue(LLVMContext& context, IRBuilder<>& builder, ZydisDecodedO
case ZYDIS_OPERAND_TYPE_IMMEDIATE: {
ConstantInt* val;
if (op.imm.is_signed) {
val = (ConstantInt*)llvm::ConstantInt::getSigned(type, op.imm.value.s);
val = ConstantInt::getSigned(type, op.imm.value.s);
}
else {
val = llvm::ConstantInt::get(context, llvm::APInt(possiblesize, op.imm.value.u));
val = ConstantInt::get(context, APInt(possiblesize, op.imm.value.u));
}
return val;
}
@@ -1097,8 +1173,8 @@ Value* merge(LLVMContext& context, IRBuilder<>& builder, Value* existingValue, V
}
llvm::APInt maskAPInt = llvm::APInt::getHighBitsSet(existingBitWidth, existingBitWidth - newBitWidth);
Value* mask = llvm::ConstantInt::get(context, maskAPInt);
APInt maskAPInt = APInt::getHighBitsSet(existingBitWidth, existingBitWidth - newBitWidth);
Value* mask = ConstantInt::get(context, maskAPInt);
Value* maskedExistingValue = createAndFolder(builder,existingValue, mask, "maskedExistingValue");
+120 -95
View File
@@ -5,45 +5,45 @@
// probably move this stuff somewhere else
Value* computeOverflowFlagAdc(IRBuilder<>& builder, Value* Lvalue, Value* Rvalue, Value* cf, Value* add ) {
auto cfc = builder.CreateZExtOrTrunc(cf, add->getType());
auto ofAdd = builder.CreateAdd(add, cfc);
auto xor0 = builder.CreateXor(Lvalue, ofAdd);
auto xor1 = builder.CreateXor(Rvalue, ofAdd);
auto ofAnd = builder.CreateAnd(xor0, xor1);
return createICMPFolder(builder, CmpInst::ICMP_SLT, ofAnd, llvm::ConstantInt::get(ofAnd->getType(), 0));
auto cfc = createZExtOrTruncFolder(builder,cf, add->getType());
auto ofAdd = createAddFolder(builder,add, cfc);
auto xor0 = createXorFolder(builder,Lvalue, ofAdd);
auto xor1 = createXorFolder(builder,Rvalue, ofAdd);
auto ofAnd = createAndFolder(builder,xor0, xor1);
return createICMPFolder(builder, CmpInst::ICMP_SLT, ofAnd, ConstantInt::get(ofAnd->getType(), 0));
}
Value* computeOverflowFlagAdd(IRBuilder<>& builder, Value* Lvalue, Value* Rvalue, Value* add) {
auto xor0 = builder.CreateXor(Lvalue, add);
auto xor1 = builder.CreateXor(Rvalue, add);
auto ofAnd = builder.CreateAnd(xor0, xor1);
auto xor0 = createXorFolder(builder,Lvalue, add);
auto xor1 = createXorFolder(builder,Rvalue, add);
auto ofAnd = createAndFolder(builder,xor0, xor1);
return createICMPFolder(builder, CmpInst::ICMP_SLT, ofAnd, ConstantInt::get(ofAnd->getType(), 0));
}
llvm::Value* computeOverflowFlagSub(IRBuilder<>& builder, Value* Lvalue, Value* Rvalue, Value* sub) {
auto xor0 = builder.CreateXor(Lvalue, Rvalue);
auto xor1 = builder.CreateXor(Lvalue, sub);
auto ofAnd = builder.CreateAnd(xor0, xor1);
Value* computeOverflowFlagSub(IRBuilder<>& builder, Value* Lvalue, Value* Rvalue, Value* sub) {
auto xor0 = createXorFolder(builder,Lvalue, Rvalue);
auto xor1 = createXorFolder(builder,Lvalue, sub);
auto ofAnd = createAndFolder(builder,xor0, xor1);
return createICMPFolder(builder, CmpInst::ICMP_SLT, ofAnd, ConstantInt::get(ofAnd->getType(), 0));
}
llvm::Value* computeOverflowFlagSbb(IRBuilder<>& builder, Value* Lvalue, Value* Rvalue, Value* cf, Value* sub) {
auto cfc = builder.CreateZExtOrTrunc(cf, sub->getType());
auto ofSub = builder.CreateSub(sub, cfc);
auto xor0 = builder.CreateXor(Lvalue, Rvalue);
auto xor1 = builder.CreateXor(Lvalue, ofSub);
auto ofAnd = builder.CreateAnd(xor0, xor1);
Value* computeOverflowFlagSbb(IRBuilder<>& builder, Value* Lvalue, Value* Rvalue, Value* cf, Value* sub) {
auto cfc = createZExtOrTruncFolder(builder,cf, sub->getType());
auto ofSub = createSubFolder(builder,sub, cfc);
auto xor0 = createXorFolder(builder,Lvalue, Rvalue);
auto xor1 = createXorFolder(builder,Lvalue, ofSub);
auto ofAnd = createAndFolder(builder,xor0, xor1);
return createICMPFolder(builder, CmpInst::ICMP_SLT, ofAnd, ConstantInt::get(ofAnd->getType(), 0));
}
llvm::Value* computeAuxFlagSbb(IRBuilder<>& builder, Value* Lvalue, Value* Rvalue, Value* cf) {
auto ci15 = llvm::ConstantInt::get(Lvalue->getType(), 15);
auto and0 = builder.CreateAnd(Lvalue, ci15);
auto and1 = builder.CreateAnd(Rvalue, ci15);
auto sub = builder.CreateSub(and0, and1);
Value* computeAuxFlagSbb(IRBuilder<>& builder, Value* Lvalue, Value* Rvalue, Value* cf) {
auto ci15 = ConstantInt::get(Lvalue->getType(), 15);
auto and0 = createAndFolder(builder,Lvalue, ci15);
auto and1 = createAndFolder(builder,Rvalue, ci15);
auto sub = createSubFolder(builder,and0, and1);
auto cfc = builder.CreateZExtOrTrunc(cf, sub->getType());
auto add = builder.CreateAdd(sub, cfc);
auto cfc = createZExtOrTruncFolder(builder,cf, sub->getType());
auto add = createAddFolder(builder,sub, cfc);
return createICMPFolder(builder, CmpInst::ICMP_UGT, add, ci15);
}
@@ -112,7 +112,7 @@ void jumpHelper(LLVMContext& context, IRBuilder<>& builder, ZydisDisassembledIns
cout << "Which address do you want do jump?, check output_condition.ll file: ";
long long address;
long long address = 0;
cin >> address;
string block_name = "jumpsomewhere-" + to_string(instruction.runtime_address) + "-";;
@@ -178,8 +178,8 @@ void branchHelper(LLVMContext& context, IRBuilder<>& builder, ZydisDisassembledI
break;
}
case NOT_OPAQUE: {
llvm::ValueToValueMapTy VMap;
llvm::Function* conditionFunction = llvm::CloneFunction(function, VMap);
ValueToValueMapTy VMap;
Function* conditionFunction = CloneFunction(function, VMap);
std::unique_ptr<Module> destinationModule = std::make_unique<Module>("destination_module", function->getContext());
conditionFunction->removeFromParent();
@@ -270,7 +270,7 @@ namespace mov {
auto dest = instruction.operands[0];
auto src = instruction.operands[1];
auto Rvalue = GetOperandValue(context, builder, src, src.size, to_string(instruction.runtime_address));
auto Rvalue = GetOperandValue(context, builder, src, src.size, to_string(instruction.runtime_address));;
if ((dest.type == ZYDIS_OPERAND_TYPE_MEMORY) && (src.type == ZYDIS_OPERAND_TYPE_IMMEDIATE) && (src.size < dest.size)) {
@@ -297,7 +297,7 @@ namespace mov {
printvalue(Rvalue);
#endif
SetOperandValue(context, builder, dest, Rvalue, to_string(instruction.runtime_address));
SetOperandValue(context, builder, dest, Rvalue, to_string(instruction.runtime_address));;
}
@@ -343,7 +343,7 @@ void lift_cmovnbz(LLVMContext& context, IRBuilder<>& builder, ZydisDisassembledI
Value* resultValue = createSelectFolder(builder,nbeCondition, Rvalue, Lvalue, "cmovnbe");
SetOperandValue(context, builder, dest, resultValue);
SetOperandValue(context, builder, dest, resultValue, to_string(instruction.runtime_address));
}
@@ -361,7 +361,7 @@ void lift_cmovz(LLVMContext& context, IRBuilder<>& builder, ZydisDisassembledIns
Value* resultValue = createSelectFolder(builder,zf, Rvalue, Lvalue, "cmovz");
SetOperandValue(context, builder, dest, resultValue);
SetOperandValue(context, builder, dest, resultValue, to_string(instruction.runtime_address));
}
@@ -429,7 +429,7 @@ void lift_cmovnb(LLVMContext& context, IRBuilder<>& builder, ZydisDisassembledIn
Value* resultValue = createSelectFolder(builder,builder.CreateNot(cf), Rvalue, Lvalue, "cmovnb");
SetOperandValue(context, builder, dest, resultValue);
SetOperandValue(context, builder, dest, resultValue, to_string(instruction.runtime_address));
}
@@ -613,11 +613,11 @@ namespace branches {
auto val = ConstantInt::getSigned(Type::getInt64Ty(context), 8); // assuming its x64
auto result = createSubFolder(builder,RspValue, val, "pushing_newrsp");
SetOperandValue(context, builder, rsp, result, to_string(instruction.runtime_address)); // sub rsp 8 first,
SetOperandValue(context, builder, rsp, result, to_string(instruction.runtime_address));; // sub rsp 8 first,
auto push_into_rsp = GetRegisterValue(context, builder, ZYDIS_REGISTER_RIP);
SetOperandValue(context, builder, rsp_memory, push_into_rsp, to_string(instruction.runtime_address)); // sub rsp 8 first,
SetOperandValue(context, builder, rsp_memory, push_into_rsp, to_string(instruction.runtime_address));; // sub rsp 8 first,
string block_name = "jmp-call";
@@ -689,8 +689,8 @@ namespace branches {
if (destination == 0) {
// find first select -> go far back until a lib call/ operand -> print the instruction so we can analyse -> after analysing prompt option to select 0 or 1
llvm::ValueToValueMapTy VMap;
llvm::Function* conditionFunction = llvm::CloneFunction(function, VMap);
ValueToValueMapTy VMap;
Function* conditionFunction = CloneFunction(function, VMap);
std::unique_ptr<Module> destinationModule = std::make_unique<Module>("destination_module", function->getContext());
conditionFunction->removeFromParent();
@@ -830,8 +830,8 @@ namespace branches {
(*run) = 0;
}
if (JOP == JOP_jmp_unsolved) {
llvm::ValueToValueMapTy VMap;
llvm::Function* conditionFunction = llvm::CloneFunction(function, VMap);
ValueToValueMapTy VMap;
Function* conditionFunction = CloneFunction(function, VMap);
std::unique_ptr<Module> destinationModule = std::make_unique<Module>("destination_module", function->getContext());
conditionFunction->removeFromParent();
@@ -1301,6 +1301,8 @@ namespace arithmeticsAndLogical {
ELSE OF is undefined;
FI;
*/
// poison values created here
void lift_rcl(LLVMContext& context, IRBuilder<>& builder, ZydisDisassembledInstruction& instruction) {
auto dest = instruction.operands[0];
auto count = instruction.operands[1];
@@ -1312,7 +1314,8 @@ namespace arithmeticsAndLogical {
auto* actualCount = builder.CreateURem(countValue, ConstantInt::get(countValue->getType(), dest.size), "actualCount");
auto* wideType = Type::getIntNTy(context, dest.size * 2);
auto* wideLvalue = createZExtFolder(builder,Lvalue, wideType);
auto* shiftedInCF = createShlFolder(builder,createZExtFolder(builder,carryFlag, wideType), dest.size,"shiftedincf");
auto cf_extended = createZExtFolder(builder, carryFlag, wideType);
auto* shiftedInCF = createShlFolder(builder,cf_extended, dest.size,"shiftedincf");
wideLvalue = createOrFolder(builder,wideLvalue, createZExtFolder(builder,shiftedInCF, wideType, "shiftedInCFExtended"));
auto* leftShifted = createShlFolder(builder,wideLvalue, createZExtFolder(builder,actualCount, wideType, "actualCountExtended"),"leftshifted");
@@ -1328,6 +1331,18 @@ namespace arithmeticsAndLogical {
auto* msbAfterRotate = createTruncFolder(builder,createLShrFolder(builder,result, dest.size - 1), Type::getInt1Ty(context),"rclmsbafterrotate");
auto* newOF = createSelectFolder(builder,createICMPFolder(builder, CmpInst::ICMP_EQ,actualCount, ConstantInt::get(actualCount->getType(), 1)), createXorFolder(builder,newCF, msbAfterRotate), getFlag(context, builder, FLAG_OF));
printvalue(Lvalue)
printvalue(countValue)
printvalue(carryFlag)
printvalue(cf_extended)
printvalue(shiftedInCF)
printvalue(actualCount)
printvalue(wideLvalue)
printvalue(leftShifted)
printvalue(rightShifted)
printvalue(rotated)
printvalue(result)
SetOperandValue(context, builder, dest, result);
setFlag(context, builder, FLAG_CF, newCF);
setFlag(context, builder, FLAG_OF, newOF);
@@ -1408,7 +1423,7 @@ namespace arithmeticsAndLogical {
auto Rvalue = GetOperandValue(context, builder, dest, dest.size);
Rvalue = builder.CreateNot(Rvalue, "realnot-" + to_string(instruction.runtime_address) + "-");
SetOperandValue(context, builder, dest, Rvalue);
SetOperandValue(context, builder, dest, Rvalue, to_string(instruction.runtime_address));;
printvalue(Rvalue);
// Flags Affected
@@ -1522,14 +1537,14 @@ namespace arithmeticsAndLogical {
Value* clampedCount = createAndFolder(builder, countValue, ConstantInt::get(countValue->getType(), maskC), "shlclamp");
Value* shiftedValue = builder.CreateAShr(Lvalue, clampedCount, "shr-lshr-" + to_string(instruction.runtime_address) + "-");
Value* isZeroed = createICMPFolder(builder, CmpInst::ICMP_UGT, clampedCount, ConstantInt::get(clampedCount->getType(), bitWidth));
Value* isZeroed = createICMPFolder(builder, CmpInst::ICMP_UGT, clampedCount, ConstantInt::get(clampedCount->getType(), bitWidth-1));
shiftedValue = createSelectFolder(builder, isZeroed, zero, shiftedValue);
auto* cfRvalue = builder.CreateSub(clampedCount, llvm::ConstantInt::get(clampedCount->getType(), 1));
auto* cfShl = builder.CreateShl(llvm::ConstantInt::get(cfRvalue->getType(), 1), cfRvalue);
auto* cfAnd = builder.CreateAnd(cfShl, Lvalue);
auto* cfValue = createICMPFolder(builder, CmpInst::ICMP_NE, cfAnd, llvm::ConstantInt::get(cfAnd->getType(), 0));
auto* cfRvalue = createSubFolder(builder,clampedCount, ConstantInt::get(clampedCount->getType(), 1));
auto* cfShl = createShlFolder(builder,ConstantInt::get(cfRvalue->getType(), 1), cfRvalue);
auto* cfAnd = createAndFolder(builder,cfShl, Lvalue);
auto* cfValue = createICMPFolder(builder, CmpInst::ICMP_NE, cfAnd, ConstantInt::get(cfAnd->getType(), 0));
@@ -1541,6 +1556,7 @@ namespace arithmeticsAndLogical {
Value* isNotZero = createICMPFolder(builder, CmpInst::ICMP_NE, clampedCount, zero);
Value* oldcf = getFlag(context, builder, FLAG_CF);
cfValue = createSelectFolder(builder, isNotZero, cfValue, oldcf);
cfValue = createSelectFolder(builder, isZeroed, zero, cfValue);
Value* sf = computeSignFlag(builder, shiftedValue);
Value* zf = computeZeroFlag(builder, shiftedValue);
@@ -1558,7 +1574,7 @@ namespace arithmeticsAndLogical {
setFlag(context, builder, FLAG_ZF, zf);
setFlag(context, builder, FLAG_PF, pf);
SetOperandValue(context, builder, dest, shiftedValue, to_string(instruction.runtime_address));
SetOperandValue(context, builder, dest, shiftedValue, to_string(instruction.runtime_address));;
}
@@ -1579,20 +1595,21 @@ namespace arithmeticsAndLogical {
Value* shiftedValue = createLShrFolder(builder,Lvalue, clampedCount, "shr-lshr-" + to_string(instruction.runtime_address) + "-");
Value* zero = ConstantInt::get(countValue->getType(), 0);
Value* isZeroed = createICMPFolder(builder, CmpInst::ICMP_UGT, clampedCount, ConstantInt::get(clampedCount->getType(), bitWidth));
Value* isZeroed = createICMPFolder(builder, CmpInst::ICMP_UGT, clampedCount, ConstantInt::get(clampedCount->getType(), bitWidth-1));
shiftedValue = createSelectFolder(builder, isZeroed, zero, shiftedValue);
Value* cfValue = createTruncFolder(builder,createLShrFolder(builder,Lvalue, createSubFolder(builder,clampedCount, ConstantInt::get(clampedCount->getType(), 1)),"shrcf"), builder.getInt1Ty());
Value* isCountOne = createICMPFolder(builder, CmpInst::ICMP_EQ,clampedCount, ConstantInt::get(clampedCount->getType(), 1));
Value* of = createICMPFolder(builder, CmpInst::ICMP_SLT, Lvalue, llvm::ConstantInt::get(Lvalue->getType(), 0));
Value* of = createICMPFolder(builder, CmpInst::ICMP_SLT, Lvalue, ConstantInt::get(Lvalue->getType(), 0));
of = createSelectFolder(builder,isCountOne, of, getFlag(context, builder, FLAG_OF));
Value* isNotZero = createICMPFolder(builder, CmpInst::ICMP_NE, clampedCount, zero);
Value* oldcf = getFlag(context, builder, FLAG_CF);
cfValue = createSelectFolder(builder, isNotZero, cfValue, oldcf);
cfValue = createSelectFolder(builder, isZeroed, zero, cfValue);
Value* sf = computeSignFlag(builder, shiftedValue);
Value* zf = computeZeroFlag(builder, shiftedValue);
Value* pf = computeParityFlag(builder, shiftedValue);
@@ -1609,7 +1626,7 @@ namespace arithmeticsAndLogical {
printvalue(isNotZero)
printvalue(oldcf)
printvalue(cfValue)
SetOperandValue(context, builder, dest, shiftedValue, to_string(instruction.runtime_address));
SetOperandValue(context, builder, dest, shiftedValue, to_string(instruction.runtime_address));;
}
@@ -1631,7 +1648,7 @@ namespace arithmeticsAndLogical {
Value* shiftedValue = createShlFolder(builder,Lvalue, clampedCountValue, "shl-shift");
Value* zero = ConstantInt::get(countValue->getType(), 0);
Value* isZeroed = createICMPFolder(builder, CmpInst::ICMP_UGT, clampedCountValue, ConstantInt::get(clampedCountValue->getType(), bitWidth));
Value* isZeroed = createICMPFolder(builder, CmpInst::ICMP_UGT, clampedCountValue, ConstantInt::get(clampedCountValue->getType(), bitWidth-1));
shiftedValue = createSelectFolder(builder, isZeroed, zero, shiftedValue);
Value* cfValue = createLShrFolder(builder,Lvalue, createSubFolder(builder,bitWidthValue, clampedCountValue),"shlcf");
@@ -1641,12 +1658,13 @@ namespace arithmeticsAndLogical {
auto countIsNotZero = createICMPFolder(builder, CmpInst::ICMP_NE, clampedCountValue, ConstantInt::get(clampedCountValue->getType(), 0));
auto cfRvalue = builder.CreateSub(clampedCountValue, llvm::ConstantInt::get(clampedCountValue->getType(), 1));
auto cfShl = builder.CreateShl(Lvalue, cfRvalue);
auto cfIntT = llvm::cast<llvm::IntegerType>(cfShl->getType());
auto cfRightCount = llvm::ConstantInt::get(cfIntT, cfIntT->getBitWidth() - 1);
auto cfLow = builder.CreateLShr(cfShl, cfRightCount);
auto cfRvalue = createSubFolder(builder,clampedCountValue, ConstantInt::get(clampedCountValue->getType(), 1));
auto cfShl = createShlFolder(builder,Lvalue, cfRvalue);
auto cfIntT = cast<IntegerType>(cfShl->getType());
auto cfRightCount = ConstantInt::get(cfIntT, cfIntT->getBitWidth() - 1);
auto cfLow = createLShrFolder(builder,cfShl, cfRightCount);
cfValue = createSelectFolder(builder, countIsNotZero, createTruncFolder(builder,cfLow, Type::getInt1Ty(context)), getFlag(context, builder, FLAG_CF));
cfValue = createSelectFolder(builder, isZeroed, zero, cfValue);
Value* isCountOne = createICMPFolder(builder, CmpInst::ICMP_EQ,clampedCountValue, ConstantInt::get(clampedCountValue->getType(), 1));
@@ -1728,7 +1746,7 @@ namespace arithmeticsAndLogical {
printvalue(Lvalue)
printvalue(Rvalue)
#endif
SetOperandValue(context, builder, dest, Rvalue);
SetOperandValue(context, builder, dest, Rvalue, to_string(instruction.runtime_address));;
SetOperandValue(context, builder, src, Lvalue);
@@ -1767,7 +1785,7 @@ namespace arithmeticsAndLogical {
setFlag(context, builder, FLAG_CF, cf);
setFlag(context, builder, FLAG_OF, of);
SetOperandValue(context, builder, dest, resultValue);
SetOperandValue(context, builder, dest, resultValue, to_string(instruction.runtime_address));
}
@@ -1810,7 +1828,7 @@ namespace arithmeticsAndLogical {
setFlag(context, builder, FLAG_CF, cf);
setFlag(context, builder, FLAG_OF, of);
SetOperandValue(context, builder, dest, resultValue);
SetOperandValue(context, builder, dest, resultValue, to_string(instruction.runtime_address));
}
@@ -1826,7 +1844,7 @@ namespace arithmeticsAndLogical {
#ifdef _DEVELOPMENT
printvalue(Rvalue)
#endif
SetOperandValue(context, builder, dest, Rvalue);
SetOperandValue(context, builder, dest, Rvalue, to_string(instruction.runtime_address));;
}
@@ -2249,10 +2267,10 @@ printvalue(result)
auto val = ConstantInt::getSigned(Type::getInt64Ty(context), 8); // assuming its x64
auto result = createSubFolder(builder,RspValue, val, "pushing_newrsp-" + to_string(instruction.runtime_address) + "-");
SetOperandValue(context, builder, rsp, result, to_string(instruction.runtime_address)); // sub rsp 8 first,
SetOperandValue(context, builder, rsp, result, to_string(instruction.runtime_address));; // sub rsp 8 first,
SetOperandValue(context, builder, dest, Rvalue, to_string(instruction.runtime_address)); // then mov rsp, val
SetOperandValue(context, builder, dest, Rvalue, to_string(instruction.runtime_address));; // then mov rsp, val
}
@@ -2269,10 +2287,10 @@ printvalue(result)
auto val = ConstantInt::get(Type::getInt64Ty(context), 8);
auto result = createSubFolder(builder,RspValue, val);
SetOperandValue(context, builder, rsp, result, to_string(instruction.runtime_address)); // sub rsp 8 first,
SetOperandValue(context, builder, rsp, result, to_string(instruction.runtime_address));; // sub rsp 8 first,
//pushFlags(context, builder, dest, Rvalue, to_string(instruction.runtime_address));
SetOperandValue(context, builder, dest, Rvalue, to_string(instruction.runtime_address)); // then mov rsp, val
//pushFlags(context, builder, dest, Rvalue, to_string(instruction.runtime_address));;
SetOperandValue(context, builder, dest, Rvalue, to_string(instruction.runtime_address));; // then mov rsp, val
}
@@ -2282,15 +2300,15 @@ printvalue(result)
auto src = instruction.operands[2];
auto rsp = instruction.operands[1];
auto Rvalue = GetOperandValue(context, builder, src, dest.size, to_string(instruction.runtime_address));
auto RspValue = GetOperandValue(context, builder, rsp, dest.size, to_string(instruction.runtime_address));
auto Rvalue = GetOperandValue(context, builder, src, dest.size, to_string(instruction.runtime_address));;
auto RspValue = GetOperandValue(context, builder, rsp, dest.size, to_string(instruction.runtime_address));;
auto val = ConstantInt::getSigned(Type::getInt64Ty(context), 8); // assuming its x64
auto result = createAddFolder(builder,RspValue, val, "popping_new_rsp-" + to_string(instruction.runtime_address) + "-");
#ifdef _DEVELOPMENT
printvalue(Rvalue)
#endif
SetOperandValue(context, builder, dest, Rvalue, to_string(instruction.runtime_address)); // mov val, rsp first
SetOperandValue(context, builder, dest, Rvalue, to_string(instruction.runtime_address));; // mov val, rsp first
SetOperandValue(context, builder, rsp, result); // then add rsp 8
@@ -2303,14 +2321,14 @@ printvalue(result)
auto src = instruction.operands[1]; // [rsp]
auto rsp = instruction.operands[0]; // rsp
auto Rvalue = GetOperandValue(context, builder, src, dest.size, to_string(instruction.runtime_address));
auto RspValue = GetOperandValue(context, builder, rsp, dest.size, to_string(instruction.runtime_address));
auto Rvalue = GetOperandValue(context, builder, src, dest.size, to_string(instruction.runtime_address));;
auto RspValue = GetOperandValue(context, builder, rsp, dest.size, to_string(instruction.runtime_address));;
auto val = ConstantInt::getSigned(Type::getInt64Ty(context), 8); // assuming its x64
auto result = createAddFolder(builder,RspValue, val, "popfq-" + to_string(instruction.runtime_address) + "-");
SetOperandValue(context, builder, dest, Rvalue, to_string(instruction.runtime_address)); // mov val, rsp first
SetOperandValue(context, builder, rsp, result, to_string(instruction.runtime_address)); // then add rsp 8
SetOperandValue(context, builder, dest, Rvalue, to_string(instruction.runtime_address));; // mov val, rsp first
SetOperandValue(context, builder, rsp, result, to_string(instruction.runtime_address));; // then add rsp 8
@@ -2377,9 +2395,9 @@ printvalue(result)
Value* sumValue = createAddFolder(builder,Lvalue, Rvalue, "xadd_sum-" + to_string(instruction.runtime_address) + "-");
SetOperandValue(context, builder, dest, sumValue, to_string(instruction.runtime_address));
SetOperandValue(context, builder, dest, sumValue, to_string(instruction.runtime_address));;
SetOperandValue(context, builder, src, Lvalue, to_string(instruction.runtime_address));
SetOperandValue(context, builder, src, Lvalue, to_string(instruction.runtime_address));;
/*
TEMP := SRC + DEST;
SRC := DEST;
@@ -2484,9 +2502,9 @@ printvalue(result)
// TODO: stuff
void lift_rdtsc(LLVMContext& context, IRBuilder<>& builder, ZydisDisassembledInstruction& instruction) {
auto rdtscCall = builder.CreateIntrinsic(llvm::Intrinsic::readcyclecounter, {}, {});
auto rdtscCall = builder.CreateIntrinsic(Intrinsic::readcyclecounter, {}, {});
auto edxPart = createLShrFolder(builder,rdtscCall, 32, "to_edx");
auto eaxPart = createTruncFolder(builder,rdtscCall, llvm::Type::getInt32Ty(context), "to_eax");
auto eaxPart = createTruncFolder(builder,rdtscCall, Type::getInt32Ty(context), "to_eax");
SetRegisterValue(context, builder, ZYDIS_REGISTER_EDX, edxPart);
SetRegisterValue(context, builder, ZYDIS_REGISTER_EAX, eaxPart);
@@ -2622,7 +2640,7 @@ namespace flagOperation {
Value* resultValue = createZExtFolder(builder,builder.CreateNot(pf), Type::getInt8Ty(context));
SetOperandValue(context, builder, dest, resultValue);
SetOperandValue(context, builder, dest, resultValue, to_string(instruction.runtime_address));
}
@@ -2764,17 +2782,17 @@ namespace flagOperation {
auto Lvalue = GetOperandValue(context, builder, dest, dest.size);
auto bitIndexValue = GetOperandValue(context, builder, bitIndex, dest.size);
unsigned LvalueBitW = llvm::cast<llvm::IntegerType>(Lvalue->getType())->getBitWidth();
auto Rvalue = builder.CreateAnd(bitIndexValue, llvm::ConstantInt::get(bitIndexValue->getType(), LvalueBitW - 1));
auto shl = builder.CreateShl(llvm::ConstantInt::get(bitIndexValue->getType(), 1), Rvalue);
auto andd = builder.CreateAnd(shl, bitIndexValue);
auto icmp = createICMPFolder(builder, CmpInst::ICMP_NE, andd, llvm::ConstantInt::get(andd->getType(), 0));
unsigned LvalueBitW = cast<IntegerType>(Lvalue->getType())->getBitWidth();
auto Rvalue = createAndFolder(builder,bitIndexValue, ConstantInt::get(bitIndexValue->getType(), LvalueBitW - 1));
auto shl = createShlFolder(builder,ConstantInt::get(bitIndexValue->getType(), 1), Rvalue);
auto andd = createAndFolder(builder,shl, bitIndexValue);
auto icmp = createICMPFolder(builder, CmpInst::ICMP_NE, andd, ConstantInt::get(andd->getType(), 0));
setFlag(context,builder,FLAG_CF,icmp);
}
// actually this creates the poison
void lift_btr(LLVMContext& context, IRBuilder<>& builder, ZydisDisassembledInstruction& instruction) {
auto dest = instruction.operands[0];
@@ -2786,29 +2804,36 @@ namespace flagOperation {
auto bitIndexValue = GetOperandValue(context, builder, bitIndex, bitIndex.size);
auto adjustedBitIndexValue = builder.CreateURem(bitIndexValue, ConstantInt::get(bitIndexValue->getType(), Lvalue->getType()->getIntegerBitWidth()), "btr-urem");
adjustedBitIndexValue = createZExtOrTruncFolder(builder,adjustedBitIndexValue, Lvalue->getType(), "castedBitIndex");
bitIndexValue = createZExtOrTruncFolder(builder, bitIndexValue, Lvalue->getType(), "castedBitIndex");
unsigned LvalueBitW = llvm::cast<llvm::IntegerType>(Lvalue->getType())->getBitWidth();
auto Rvalue = builder.CreateAnd(bitIndexValue, llvm::ConstantInt::get(bitIndexValue->getType(), LvalueBitW - 1));
auto shl = builder.CreateShl(llvm::ConstantInt::get(bitIndexValue->getType(), 1), Rvalue);
auto andd = builder.CreateAnd(shl, bitIndexValue);
auto icmp = createICMPFolder(builder, CmpInst::ICMP_NE, andd, llvm::ConstantInt::get(andd->getType(), 0));
unsigned LvalueBitW = cast<IntegerType>(Lvalue->getType())->getBitWidth();
auto Rvalue = createAndFolder(builder,bitIndexValue, ConstantInt::get(bitIndexValue->getType(), LvalueBitW - 1));
auto shl = createShlFolder(builder,ConstantInt::get(bitIndexValue->getType(), 1), Rvalue);
auto andd = createAndFolder(builder,shl, bitIndexValue);
auto icmp = createICMPFolder(builder, CmpInst::ICMP_NE, andd, ConstantInt::get(andd->getType(), 0));
setFlag(context, builder, FLAG_CF, icmp);
auto mask = createShlFolder(builder,ConstantInt::get(Lvalue->getType(), 1), adjustedBitIndexValue, "btr-mask");
auto mask = createShlFolder(builder,ConstantInt::get(Lvalue->getType(), 1), bitIndexValue, "btr-mask");
mask = builder.CreateNot(mask, "btr-not");
auto resultValue = createAndFolder(builder,Lvalue, mask, "btr-clear-" + to_string(instruction.runtime_address) + "-");
SetOperandValue(context, builder, dest, resultValue);
SetOperandValue(context, builder, dest, resultValue, to_string(instruction.runtime_address));
printvalue(Lvalue)
printvalue(bitIndexValue)
printvalue(Rvalue)
printvalue(shl)
printvalue(andd)
printvalue(icmp)
printvalue(mask)
printvalue(resultValue)
}
@@ -2920,7 +2945,7 @@ namespace flagOperation {
auto resultValue = createXorFolder(builder,Lvalue, mask, "btc-xor");
SetOperandValue(context, builder, dest, resultValue);
SetOperandValue(context, builder, dest, resultValue, to_string(instruction.runtime_address));
setFlag(context, builder, FLAG_CF, isBitSet);
}
+1 -1
View File
@@ -6,7 +6,7 @@
#define ZYDIS_STATIC_BUILD
#endif // ZYDIS_STATIC_BUILD
#ifndef NDEBUG
#undef NDEBUG
#define NDEBUG
#endif
//#define _DEVELOPMENT
+1 -1
View File
@@ -247,5 +247,5 @@ int main(int argc, char* argv[])
auto elapsed = std::chrono::high_resolution_clock::now() - start;
long long microseconds = std::chrono::duration_cast<std::chrono::microseconds>(
elapsed).count();
cout << "\n" << dec << microseconds << " microsecond has past";
cout << "\n" << dec << microseconds << " microsecond has past" << endl;
}