Skip to content

Commit

Permalink
fix(obf): fix #47
Browse files Browse the repository at this point in the history
  • Loading branch information
terminalsin committed Dec 4, 2023
1 parent 184ed6a commit 8c14ee5
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 18 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,9 @@ dev.skidfuscator.obfuscator/src/test/resources/test.jar.compressed.skid
skidfuscator.log

calculations.txt

dev.skidfuscator.obfuscator/out/test/resources/test.jar.compressed.skid

dev.skidfuscator.obfuscator/out/test/resources/test.jar.compressed.json

dev.skidfuscator.obfuscator/out/test/resources/test.jar.compressed
20 changes: 20 additions & 0 deletions dev.skidfuscator.obfuscator/out/test/resources/config/config.hocon
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
exempt: [
"class{^dev\\/skidfuscator\\/test}"
]

driver: {
enabled: true
}

classRenamer {
enabled: true
}

methodRenamer {
enabled: false
}

flowException {
enabled: true
exempt: []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
exempt: [
"class{^dev\\/skidfuscator\\/test}"
]

driver: {
enabled: true
}

fileCrasher: {
enabled: false
}

stringEncryption {
type: STANDARD
enabled: true
exempt: []
}

exceptionReturn {
enabled: true
exempt: []
}

classRenamer {
enabled: false
type: CUSTOM
prefix: "skido/"
chars: [
"K"
"oO",
"o0"
]
depth: 3
}

methodRenamer {
enabled: false
type: CUSTOM
chars: [
"K"
"oO",
"o0"
]
depth: 3
}

fieldRenamer {
enabled: false
type: ALPHABETICAL
}

flowException {
enabled: true
strength: AGGRESSIVE
exempt: []
}

64 changes: 64 additions & 0 deletions dev.skidfuscator.obfuscator/out/test/resources/config/test.hocon
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
exempt: [
"class{^dev\\/skidfuscator\\/test}"
]

driver: {
enabled: true
}

fileCrasher: {
enabled: false
}

stringEncryption {
type: STANDARD
enabled: true
exempt: []
}

reference {
enabled: true
}

exceptionReturn {

enabled: true
exempt: []
}

classRenamer {
enabled: false
type: CUSTOM
prefix: "skido/"
chars: [
"K"
"oO",
"o0"
]
depth: 3
}

methodRenamer {
enabled: true
type: CUSTOM
chars: [
"K"
"oO",
"o0"
]
depth: 3
}

fieldRenamer {
enabled: false
type: ALPHABETICAL
}

flowException {
enabled: true
exempt: []
}

outliner {
enable: false
}
1 change: 1 addition & 0 deletions dev.skidfuscator.obfuscator/out/test/resources/exempt.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
method{main}
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ private BoissinotDestructor(ControlFlowGraph cfg) {

coalescePhis();
coalesceCopies();

remapLocals();
applyRemapping();

Expand Down Expand Up @@ -353,9 +353,36 @@ private void coalesceCopies() {
if (!copy.isSynthetic() && copy.getExpression() instanceof VarExpr) {
Local lhs = copy.getVariable().getLocal();
Local rhs = ((VarExpr) copy.getExpression()).getLocal();
if (!isReservedRegister((VersionedLocal) rhs)) {

/*
* Fix 4th December 2023
* right and left must be both of same type to coalesce, or else
* variables initialized with null and overriden in one branch
* will have that one branch value propagated to the other branch
*
* eg:
* var = nullconst
* for (i in [0, 10)) {
* if (cond) {
* var = i
* }
* }
* print(var)
*
* would become:
*
* var = nullconst
* for (i in [0, 10)) {
* var = i;
* if (cond) {
* }
* }
* print(var)
*
*/
if (!isReservedRegister((VersionedLocal) rhs) && lhs.isStack() == rhs.isStack()) {
if (tryCoalesceCopyValue(lhs, rhs)) {
// System.out.println("COPYKILL(1) " + lhs + " == " + rhs);
//System.out.println("COPYKILL(1) " + lhs + " == " + rhs);
it.remove();
}

Expand Down Expand Up @@ -398,32 +425,32 @@ private boolean isReservedRegister(VersionedLocal l) {

// Process the copy a = b. Returns true if a and b can be coalesced via value.
private boolean tryCoalesceCopyValue(Local a, Local b) {
// System.out.println("Enter COPY");
//System.out.println("Enter COPY");
CongruenceClass conClassA = getCongruenceClass(a);
CongruenceClass conClassB = getCongruenceClass(b);

// System.out.println(" A: " + conClassA);
// System.out.println(" B: " + conClassB);
//System.out.println(" A: " + conClassA);
//System.out.println(" B: " + conClassB);

// System.out.println(" same=" + (conClassA == conClassB));
//System.out.println(" same=" + (conClassA == conClassB));
if (conClassA == conClassB)
return true;

if (conClassA.size() == 1 && conClassB.size() == 1) {
boolean r = checkInterfereSingle(conClassA, conClassB);
// System.out.println(" single=" + r);
//System.out.println(" single=" + r);
return r;
}

boolean r2 = checkInterfere(conClassA, conClassB);
// System.out.println(" both=" + r2);
//System.out.println(" both=" + r2);
if (r2) {
return false;
}

// merge congruence classes
merge(conClassA, conClassB);
// System.out.println("Exit COPY");
//System.out.println("Exit COPY");
return true;
}

Expand Down Expand Up @@ -570,21 +597,49 @@ private boolean dominates(Local a, Local b) {
}
}

/**
* Purpose: The checkInterfere method determines if there is any interference
* between two congruence classes, red and blue, in the context of SSA variable
* coalescence.
* <br/>
* Process:
* The method uses dominator tree traversal to compare elements from each class.
* It maintains two stacks: one for the elements (dom) and one for their corresponding class (domClasses).
* The method iterates through each class, comparing elements based on their dominance relationship.
* If any pair of elements from different classes interfere, the method returns true.
* Return Value: Returns true if there is interference between the two classes, otherwise false.
*
* Note: This method assumes that the CongruenceClass type and related methods like dominates, interference, and checkPreDomOrder are correctly implemented and available in the context.
* @param red The first congruence class to check for interference.
* @param blue The second congruence class to check for interference.
* @return Returns true if there is interference between the two classes, otherwise false.
*/
private boolean checkInterfere(CongruenceClass red, CongruenceClass blue) {
// System.out.println("Enter interfere: " + red + " vs " + blue);
Stack<Local> dom = new Stack<>(); // dominator tree traversal stack
Stack<Integer> domClasses = new Stack<>(); // 0=red, 1=blue
int nr = 0, nb = 0; // from the paper
Local ir = red.first(), ib = blue.first(); // iteration pointers
Local lr = red.last(), lb = blue.last(); // end sentinels
// Initialize stacks for dominator tree traversal and class tracking
Stack<Local> dom = new Stack<>();
Stack<Integer> domClasses = new Stack<>();

// Initialize counters for red and blue classes
int nr = 0, nb = 0;

// Initialize iteration pointers and end sentinels for both classes
Local ir = red.first(), ib = blue.first();
Local lr = red.last(), lb = blue.last();

// Flags to track if there are more elements in each class
boolean redHasNext = true, blueHasNext = true;
equalAncOut.put(ir, null); // these have no parents so we have to manually init them

// Manually initialize for elements with no parents
equalAncOut.put(ir, null);
equalAncOut.put(ib, null);

do {
// System.out.println("\n ir, ib, lr, lb: " + ir + " " + ib + " " + lr + " " + lb);
// System.out.println(" dom: " + dom);
Local current;
int currentClass;

// Determine which class to process next based on pre-dominator order
if (!blueHasNext || (redHasNext && checkPreDomOrder(ir, ib))) {
// current = red[ir++] (Red case)
current = ir;
Expand All @@ -601,6 +656,7 @@ private boolean checkInterfere(CongruenceClass red, CongruenceClass blue) {
ib = blue.higher(ib);
}

// Pop elements from stack that do not dominate the current element
while (!dom.isEmpty() && !dominates(dom.peek(), current)) {
if (domClasses.peek() == 0)
nr--;
Expand All @@ -611,13 +667,20 @@ else if (domClasses.peek() == 1)
dom.pop();
domClasses.pop();
}

// Check for interference
if (!dom.isEmpty() && interference(current, dom.peek(), currentClass == domClasses.peek())) {
return true;
}

// Push current element and its class onto the stacks
dom.push(current);
domClasses.push(currentClass);
} while ((redHasNext && nb > 0) || (blueHasNext && nr > 0) || (redHasNext && blueHasNext));
}
// Continue while there are elements in either class and unprocessed dominators in the stack
while ((redHasNext && nb > 0) || (blueHasNext && nr > 0) || (redHasNext && blueHasNext));

// No interference detected
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ public static void main(String[] args) throws Exception {

BoissinotDestructor.leaveSSA(cfg);



// CFGUtils.easyDumpCFG(cfg, "pre-reaalloc");
LocalsReallocator.realloc(cfg);
// CFGUtils.easyDumpCFG(cfg, "post-reaalloc");
Expand Down

0 comments on commit 8c14ee5

Please sign in to comment.