Fixture 131
obfuscated composite
C · 2 functions · 4 lanes · 8 of 8 function-lanes behave identically
All 4 lanes recompile and return the same results as the original.
An IOCCC-flavoured composition of everything this batch covers: a function-pointer table indexed by a bit trick, a comma-operator loop header, a statement expression, reversed subscripts, and a nested conditional. Dense on purpose, and fully defined throughout.
#include <stdint.h>
/* An IOCCC-flavoured composition of everything this batch covers: a
* function-pointer table indexed by a bit trick, a comma-operator loop header,
* a statement expression, reversed subscripts, and a nested conditional. Dense
* on purpose, and fully defined throughout. */
static int32_t twist(int32_t v) { return (int32_t)(((uint32_t)v << 3) ^ 0x9E37u); }
static int32_t fold(int32_t v) { return (int32_t)(((uint32_t)v >> 2) + 0x1234u); }
typedef int32_t (*Stage)(int32_t);
static Stage const STAGES[2] = {twist, fold};
#define PICK(v) ({ int32_t _v = (v); STAGES[(_v & 1)](_v); })
__attribute__((noinline)) int32_t
obfuscated_pipeline(int32_t *state, int32_t count, int32_t seed) {
int32_t i;
int32_t acc = seed;
int32_t last = 0;
if (state == 0 || count < 0 || count > 16) {
return -1;
}
for (i = 0; i < count; last = acc, acc = PICK(acc), i[state] = acc, ++i) {
acc ^= (i & 3) ? (i << 1) : ~i;
}
return count ? ((count - 1)[state] ^ last) : acc;
}
__attribute__((noinline)) int32_t
nested_conditional_matrix(int32_t a, int32_t b, int32_t c, int32_t d) {
return (a < b) ? ((c < d) ? ((a < c) ? a : c) : ((a < d) ? a : d))
: ((c < d) ? ((b < c) ? b : c) : ((b < d) ? b : d));
} Recovered C
Generated by glaurung decompile --style decbench at b47f6b43.
baseline.json records the result after recompiling the C and calling it beside the
original with seeded inputs.
clang -O0
2/2nested_conditional_matrix pass 25 lines
// glaurung: nested_conditional_matrix @ 0x1220
int32_t nested_conditional_matrix(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3) {
int local_14;
int local_1c;
int local_24;
int local_2c;
// x86-64 prologue: save rbp
if ((arg1 <= arg0)) {
if ((arg3 <= arg2)) {
local_2c = ((arg3 <= arg1) ? (unsigned long)((unsigned int)(arg3)) : (unsigned long)((unsigned int)(arg1)));
return (unsigned int)(local_2c);
} else {
local_24 = ((arg2 <= arg1) ? (unsigned long)((unsigned int)(arg2)) : (unsigned long)((unsigned int)(arg1)));
return (unsigned int)(local_24);
}
} else {
if ((arg3 <= arg2)) {
local_1c = ((arg3 <= arg0) ? (unsigned long)((unsigned int)(arg3)) : (unsigned long)((unsigned int)(arg0)));
return (unsigned int)(local_1c);
} else {
local_14 = ((arg2 <= arg0) ? (unsigned long)((unsigned int)(arg2)) : (unsigned long)((unsigned int)(arg0)));
return (unsigned int)(local_14);
}
}
} obfuscated_pipeline pass 50 lines
// glaurung: obfuscated_pipeline @ 0x1100
int32_t obfuscated_pipeline(int32_t * arg0, int32_t arg1, int32_t arg2) {
extern void fold(void);
extern void twist(void);
static void (*STAGES[2])(void) = {
(void (*)(void))twist,
(void (*)(void))fold,
};
int acc;
int last;
int i;
int _v;
int local_2c;
int local_30;
int local_34;
int local_4;
long var23;
// x86-64 prologue: save rbp, frame 64 bytes
acc = arg2;
last = 0;
if ((arg0 == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((long)(arg1) < 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
for (i = 0; (i < arg1); i++) {
local_30 = (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) & 3))) == 0) ? ((unsigned long)((unsigned int)(i)) ^ -1) : ((unsigned long)((unsigned int)(i)) << 1));
acc = ((unsigned int)(local_30) ^ acc);
last = acc;
_v = acc;
var23 = ((long (*)(long))(STAGES[(long)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(_v)) & 1)))))]))((unsigned long)((unsigned int)(_v)));
local_2c = var23;
acc = local_2c;
arg0[(long)(i)] = acc;
}
local_34 = (((unsigned long)((unsigned int)(arg1)) == 0) ? (unsigned long)((unsigned int)(acc)) : ((unsigned long)((unsigned int)(arg0[(long)((int)(((unsigned long)((unsigned int)(arg1)) - 1)))])) ^ (unsigned long)((unsigned int)(last))));
local_4 = local_34;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} clang -O2
2/2nested_conditional_matrix pass 15 lines
// glaurung: nested_conditional_matrix @ 0x11a0
int32_t nested_conditional_matrix(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3) {
long var0;
var0 = (unsigned long)((unsigned int)(arg2));
if ((arg0 < arg1)) {
if (((long)(arg3) <= (long)((int)(var0)))) {
return (unsigned int)((arg0 < arg3) ? arg0 : arg3);
}
return (((long)(arg0) < (long)((int)(var0))) ? arg0 : var0);
}
if (((long)(arg3) <= (long)((int)(var0)))) {
return (unsigned int)((arg1 < arg3) ? arg1 : arg3);
}
return (((long)(arg1) < (long)((int)(var0))) ? arg1 : var0);
} obfuscated_pipeline pass 73 lines
// glaurung: obfuscated_pipeline @ 0x1100
__attribute__((no_stack_protector)) int32_t obfuscated_pipeline(int32_t * arg0, int32_t arg1, int32_t arg2) {
extern void fold(void);
extern void twist(void);
static void (*STAGES[2])(void) = {
(void (*)(void))twist,
(void (*)(void))fold,
};
int i;
int _v;
int acc;
int last;
unsigned char local_38[56];
long rbp;
long ret;
long var0;
long var1;
long var12;
long var13;
long var14;
long var16;
long var17;
long var2;
long var21;
long var25;
long var3;
long var30;
long var4;
long var5;
*(long *)((&local_38[0] + 48)) = rbp;
*(long *)((&local_38[0] + 40)) = var0;
*(long *)((&local_38[0] + 32)) = var1;
*(long *)((&local_38[0] + 24)) = var2;
*(long *)((&local_38[0] + 16)) = var3;
*(long *)((&local_38[0] + 8)) = var4;
*(long *)(&local_38[0]) = ret;
var5 = 0xffffffff;
if ((arg0 == 0)) {
ret = (unsigned long)((unsigned int)(var5));
// x86-64 epilogue: tear down frame
return (unsigned int)(var5);
}
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
ret = (unsigned long)((unsigned int)(var5));
// x86-64 epilogue: tear down frame
return (unsigned int)(var5);
}
var12 = (unsigned long)((unsigned int)(arg2));
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
var5 = (unsigned long)((unsigned int)(var12));
} else {
var13 = (long)arg0;
*(long *)(&local_38[0]) = (unsigned long)((unsigned int)(arg1));
var14 = (unsigned long)((unsigned int)(arg1));
var16 = 0;
var17 = 0xffffffff;
i = 0;
var21 = var12;
do {
var25 = (unsigned long)((unsigned int)(((((unsigned long)((unsigned char)((i & 3))) == 0) ? var17 : (unsigned long)((unsigned int)(var16))) ^ var21)));
var30 = ((long (*)(long))(STAGES[(unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var25)) & 1)))]))((unsigned long)((unsigned int)(var25)));
*(int *)((var13 + i * 4)) = var30;
i = (i + 1);
var16 = (unsigned long)((unsigned int)((var16 + 2)));
var17 = (unsigned long)((unsigned int)((var17 - 1)));
var21 = var30;
} while ((var14 != i));
var5 = (unsigned long)((unsigned int)((var25 ^ *(int *)((var13 + ((unsigned long)((unsigned int)((*(long *)(&local_38[0]) - 1))) * 4))))));
}
ret = (unsigned long)((unsigned int)(var5));
// x86-64 epilogue: tear down frame
return (unsigned int)(var5);
} gcc -O0
2/2nested_conditional_matrix pass 17 lines
// glaurung: nested_conditional_matrix @ 0x1207
int32_t nested_conditional_matrix(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3) {
// x86-64 prologue: save rbp
if ((arg1 <= arg0)) {
if ((arg3 <= arg2)) {
return ((((unsigned int)(arg3) == (unsigned int)(arg1)) | (arg3 < arg1)) ? (unsigned long)((unsigned int)(arg3)) : (unsigned long)((unsigned int)(arg1)));
} else {
return ((((unsigned int)(arg2) == (unsigned int)(arg1)) | (arg2 < arg1)) ? (unsigned long)((unsigned int)(arg2)) : (unsigned long)((unsigned int)(arg1)));
}
} else {
if ((arg3 <= arg2)) {
return ((((unsigned int)(arg3) == (unsigned int)(arg0)) | (arg3 < arg0)) ? (unsigned long)((unsigned int)(arg3)) : (unsigned long)((unsigned int)(arg0)));
} else {
return ((((unsigned int)(arg2) == (unsigned int)(arg0)) | (arg2 < arg0)) ? (unsigned long)((unsigned int)(arg2)) : (unsigned long)((unsigned int)(arg0)));
}
}
} obfuscated_pipeline pass 42 lines
// glaurung: obfuscated_pipeline @ 0x1129
int32_t obfuscated_pipeline(int32_t * arg0, int32_t arg1, int32_t arg2) {
extern void fold(void);
extern void twist(void);
static void (*STAGES[2])(void) = {
(void (*)(void))twist,
(void (*)(void))fold,
};
int acc;
int last;
int i;
int _v;
long var21;
// x86-64 prologue: save rbp, frame 32 bytes
acc = arg2;
last = 0;
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((long)(arg1) < 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
for (i = 0; (i < arg1); i++) {
acc = (acc ^ (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) & 3))) == 0) ? (~(unsigned long)((unsigned int)(i))) : (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) + (unsigned long)((unsigned int)(i)))))));
last = acc;
_v = acc;
var21 = ((long (*)(long))(STAGES[(long)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(_v)) & 1)))))]))((unsigned long)((unsigned int)(_v)));
acc = var21;
arg0[(long)(i)] = acc;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return (unsigned int)(acc);
} else {
return (unsigned int)(((unsigned long)((unsigned int)(*(int *)(((long)arg0 + (((long)(arg1) << 2) - 4))))) ^ last));
}
} gcc -O2
2/2nested_conditional_matrix pass 7 lines
// glaurung: nested_conditional_matrix @ 0x11c0
int32_t nested_conditional_matrix(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3) {
if ((arg1 <= arg0)) {
return ((arg3 <= arg2) ? (((((unsigned int)(arg1) == (unsigned int)(arg3)) | (arg1 < arg3)) == 0) ? arg3 : arg1) : ((((unsigned int)(arg1) == (unsigned int)(arg2)) | (arg1 < arg2)) ? arg1 : (unsigned long)((unsigned int)(arg2))));
}
return ((arg3 <= arg2) ? (((((unsigned int)(arg0) == (unsigned int)(arg3)) | (arg0 < arg3)) == 0) ? arg3 : arg0) : ((((unsigned int)(arg0) == (unsigned int)(arg2)) | (arg0 < arg2)) ? arg0 : (unsigned long)((unsigned int)(arg2))));
} obfuscated_pipeline pass 53 lines
// glaurung: obfuscated_pipeline @ 0x1130
int32_t obfuscated_pipeline(int32_t * arg0, int32_t arg1, int32_t arg2) {
extern void fold(void);
extern void twist(void);
static void (*STAGES[2])(void) = {
(void (*)(void))twist,
(void (*)(void))fold,
};
int i;
int _v;
int acc;
long ret;
long var0;
long var1;
long var19;
long var2;
long var7;
long var9;
if ((arg0 == 0)) {
return (unsigned int)(-1);
}
var0 = (long)(arg1);
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
goto L_11b4;
}
ret = (unsigned long)((unsigned int)(arg2));
if (((unsigned long)((unsigned int)(var0)) == 0)) {
goto L_11a5;
}
var1 = (long)arg0;
var2 = (unsigned long)((unsigned int)((var0 - 1)));
i = 0;
var7 = ret;
goto L_1173;
L_1170: ;
i = var9;
L_1173: ;
_v = (unsigned long)((unsigned int)(((((unsigned long)((unsigned char)((i & 3))) != 0) ? (unsigned long)((unsigned int)((i + i))) : (~(unsigned long)((unsigned int)(i)))) ^ var7)));
var19 = ((long (*)(long))(STAGES[(unsigned long)((unsigned int)(((unsigned long)((unsigned int)(_v)) & 1)))]))((unsigned long)((unsigned int)(_v)));
var7 = var19;
var9 = ((unsigned long)((unsigned int)(i)) + 1);
*(int *)((var1 + i * 4)) = var19;
if ((i != var2)) {
goto L_1170;
}
ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)((var1 + var0 * 4 - 0x4)))) ^ _v)));
L_11a5: ;
// x86-64 epilogue: tear down frame
return ret;
L_11b4: ;
ret = 0xffffffff;
goto L_11a5;
}