readme update, bugfix etc.
@@ -13,59 +13,64 @@ This tool is designed for:
|
||||
### Optimization
|
||||
|
||||
## Diagram
|
||||

|
||||

|
||||
|
||||
## 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;
|
||||
}
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
VMProtect settings, everything is turned off, we virtualize the function on ultra setting. (Tested versions 3.4.0-3.6.0)
|
||||

|
||||
|
||||

|
||||
VMProtect settings, everything is turned off, we virtualize the function on ultra setting. (Tested versions 3.4.0-3.6.0 3.8.1)
|
||||
|
||||

|
||||

|
||||
|
||||
This is how it looks after virtualizing.
|
||||
|
||||

|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||

|
||||
|
||||
```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:
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
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).
|
||||
|
||||

|
||||
|
||||

|
||||
## 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
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 9.6 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 18 KiB |
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#define ZYDIS_STATIC_BUILD
|
||||
#endif // ZYDIS_STATIC_BUILD
|
||||
#ifndef NDEBUG
|
||||
#undef NDEBUG
|
||||
#define NDEBUG
|
||||
#endif
|
||||
//#define _DEVELOPMENT
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||