Dynamically reconstruct control flow #53
Replies: 2 comments
-
A couple of months ago I added the rearrangeSwitches module that does a similar thing to switch cases, in a first attempt to flatten a flow. I would love to be able to solve a case such as your present but I'm having trouble coming up with a generalized algorithm to solve that. I don't think it's impossible though, just requires a lot of thought as to not accidentally flatten flows which shouldn't be flattened. I think this is a great point for discussion so thanks for bringing this up! :) |
Beta Was this translation helpful? Give feedback.
-
Nice to see there are already some modules touching this. With this particular code I haven't had any luck yet due to the errors mentioned in a previous issue. I should make some smaller POCs to check what's already working.
That's important yeah. Although an initial experimental module doesn't need to be perfect yet I think the problem I am describing would come down to two modules;
1. content encodingThis code examples uses a byte string which contains encoded variable values. I believe it is jsvmp, as I found out through this article, not 100% sure. This whole block could I think be replaced by the static values it eventually produces. var e = "484e4f4a403f52430038121cfc403b70000000f9685f239b000001241102004a1200000700014301140001033011000115000203101100011500031100014a12000407000543011400020700061100021500071100024a1200080700090302030c430349030211000215000a030111000215000b07000c11000215000d1100024a12000e030803080308030003024305491100024a12000f4300491100014a1200104300140003021102011100034301423e001f1400031100024a1200110d1100030e00120700130e001443014903011d42413d00251101024700041101024211000112001547000403011d420211010143001401021101024241084211010247000411010242021101010600164301140102084205000000003b0014000105000000953b0214010205000000e13b001401030300140002110102140104084200170d534255514455755c555d555e440653515e465143054759544458065855595758440a575544735f5e445548440202540a0104404810435542595604565f5e440856595c5c6455484404c09fa88e218e10c0ac8d0a435851545f47725c45420b43585f477f565643554468045c595d550943585f47735f5c5f4203514253064344425f5b5509445f7451445165627c04404543580355424203536f53044449405504405542560a03070305090208050509";
var r = {
get 0() {
return document;
},
get 1() {
return _0x3ca110;
},
get 2() {
return _0x319a4c;
},
set 2(e) {
_0x319a4c = e;
},
get 3() {
return _0x1939e2;
},
set 3(e) {
_0x1939e2 = e;
},
get 4() {
return _0x589ee9;
},
set 4(e) {
_0x589ee9 = e;
}
};
var t = void(0);
function _0xb0d8b3(e, r, t) {
function a(e, r) {
var t = parseInt(e.slice(r, r + 2), 16);
return t >>> 7 == 0 ? [1, t] : t >>> 6 == 2 ? (t = (63 & t) << 8, [2, t += parseInt(e.slice(r + 2, r + 4), 16)]) : (t = (63 & t) << 16,
[3, t += parseInt(e.slice(r + 2, r + 6), 16)]);
}
var n, f = 0,
i = [],
c = [],
o = parseInt(e.slice(0, 8), 16),
s = parseInt(e.slice(8, 16), 16);
if (1213091658 !== o || 1077891651 !== s) {
throw new Error("mhe");
}
if (0 !== parseInt(e.slice(16, 18), 16)) {
throw new Error("ve");
}
for (n = 0; n < 4; ++n) {
f += (3 & parseInt(e.slice(24 + 2 * n, 26 + 2 * n), 16)) << 2 * n;
}
var d = parseInt(e.slice(32, 40), 16),
l = 2 * parseInt(e.slice(48, 56), 16);
for (n = 56; n < l + 56; n += 2) {
i.push(parseInt(e.slice(n, n + 2), 16));
}
var u = l + 56,
b = parseInt(e.slice(u, u + 4), 16);
for (u += 4, n = 0; n < b; ++n) {
var p = a(e, u);
u += 2 * p[0];
for (var h = "", _ = 0; _ < p[1]; ++_) {
var x = a(e, u);
h += String.fromCharCode(f ^ x[1]), u += 2 * x[0];
}
c.push(h);
}
// business logic
// ...
} 2. control flowBesides what I mentioned in the previous comment, it's also good to note that in this example the outcome depends on the initial starting point. The final flow changes depending on at which index of the sequence you start at |
Beta Was this translation helpful? Give feedback.
-
I wanted to create a discussion for this but I can't seem to open a discussion, so feel free to convert this to a discussion.
I am running into an RE challenge and wondered whether it would be possible to create a module for this lib to tackle this.
The code I am trying to RE, uses a lot of small if statements to obfuscate the control flow. It uses a large array with numbers as a sequence of when to execute which if blocks.
Currently, I have been reverse engineering this by manually stepping through it in a debugger and keeping track of the logic, which works, but gets very tedious for bigger operations. So I was wondering if it would be possible to dynamically analyze the control flow and simplify it.
Simplified example:
Each block here performs a small and simple task, and currently, my RE process entails keeping track of what data is modified in which way. Which as you can imagine gets very labor-intensive for a large sequence of operations.
I was thinking it could perhaps theoretically be possible to simplify the control flow by executing the code and dynamically keeping track of what happens, and then reconstructing that logic.
I understand it's not a simple thing, but I am no expert on the topic so I am curious to hear others' perspectives on this.
So.. Any ideas on if it's possible to create a module for this, or other tips to RE code like this?
Beta Was this translation helpful? Give feedback.
All reactions