Angr Solver
A binary analysis tool in Python to automatically find paths to code
Template
Examples
Last updated
A binary analysis tool in Python to automatically find paths to code
Last updated
import angr
# Change this binary
project = angr.Project("./binary", auto_load_libs=False)
@project.hook(0x401337) # Change this address to your target
def print_flag(state):
print("Valid input:", state.posix.dumps(0))
project.terminate_execution()
project.execute()undefined8 main(void) {
uint uVar1;
int local_10;
int local_c;
printf("Enter the flag: ");
__isoc99_scanf(&DAT_00102015,buf);
for (local_c = 0; local_c < 0x1d; local_c = local_c + 1) {
uVar1 = (uint)(local_c >> 0x1f) >> 0x1e;
buf[local_c] = buf[local_c] ^
*(byte *)((long)&magic + (long)(int)((local_c + uVar1 & 3) - uVar1));
}
local_10 = 0;
while( true ) {
if (0x1c < local_10) { // Hard if statement (computation in the for() loop above)
puts("Correct flag!");
// <--- TARGET Angr right here
// Ghidra shows 0x00101231, and starts by default at 0x00100000, meaning
// we're only 0x1231 into the binary. When Angr runs a program with PIE enabled,
// it starts at 0x00400000. So the final address we target is 0x00401231
return 0;
}
if (buf[local_10] != flag[local_10]) break;
local_10 = local_10 + 1;
}
puts("Wrong flag!");
return 0;
}undefined8 validatePassword(byte *param_1) {
size_t sVar1;
undefined8 uVar2;
sVar1 = strlen((char *)param_1);
// Hard if statement:
if ((((((sVar1 == 0x21) && (*param_1 == (byte)(param_1[6] * '\x02' - 0x1d))) &&
(param_1[1] == (byte)(param_1[0x13] + 5))) &&
(((param_1[2] == (byte)(((char)param_1[8] >> 1) + 0x13U) &&
(param_1[3] == (byte)(param_1[0xf] + 0x35))) &&
((param_1[4] == (byte)(param_1[3] + 0xbc) &&
((param_1[5] == (byte)(param_1[0x11] + 0x28) && (param_1[6] == (char)param_1[0x16] >> 1))))
)))) && (param_1[7] == (param_1[0xb] ^ param_1[0x15]))) &&
(((((((param_1[8] == (param_1[5] ^ 7) && (param_1[9] == (byte)(param_1[0xe] - 0x21))) &&
(param_1[10] == (byte)(param_1[0x1e] + 7))) &&
((param_1[0xb] == (byte)(param_1[0x10] * '\x02') &&
(param_1[0xc] == (byte)(param_1[0x1d] + param_1[9]))))) && (param_1[0xd] == 0x31)) &&
((((param_1[0xe] == (byte)(param_1[0x1d] * '\x02' + 3) && (param_1[0xf] == (*param_1 ^ 5)))
&& (((param_1[0x10] == (byte)(((char)param_1[0x12] >> 1) * '\x02') &&
(((param_1[0x11] == (param_1[0x14] ^ 0x40) && (param_1[0x12] == (param_1[0x17] ^ 10)))
&& (param_1[0x13] == (byte)(param_1[7] - 2))))) &&
(((param_1[0x14] == (param_1[10] ^ param_1[0x1c]) &&
(param_1[0x15] == (char)param_1[0x19] >> 1)) &&
(param_1[0x16] == (byte)((param_1[0x1f] | 0x61) - 2))))))) &&
((param_1[0x17] == 0x39 && (param_1[0x18] == (byte)(param_1[0x12] * '\x02'))))))) &&
(((param_1[0x19] == (byte)(param_1[0x10] + param_1[0x1a]) &&
(((param_1[0x1a] == (byte)((char)param_1[0xb] / '\x02' + 7U) &&
(param_1[0x1b] == (byte)((param_1[4] + 0x7b) * '\x02'))) &&
(param_1[0x1c] == (byte)(param_1[1] - 0x13))))) &&
(((param_1[0x1d] == (byte)(param_1[0x20] + 0xb3) &&
(param_1[0x1e] == (byte)(param_1[0x1f] - param_1[0x10]))) &&
((param_1[0x1f] == (byte)(param_1[0xd] * '\x02' + 1) &&
(param_1[0x20] == (byte)(param_1[4] + param_1[0xf]))))))))))) {
uVar2 = 1; // <--- TARGET Angr here, right after the if statement when
// validatePassword() returns 1
}
else {
uVar2 = 0;
}
return uVar2;
}