# Flare-on 11
# Challenge 1
Given an exe and src python code of that exe. Read the src, we see the flag is generated by function GenerateFlagText, which decrypt encrypted flag with simple xor

They key decrypt is x + y * 20 where x and y are the params passed into this function
Follow where this function called, we conclude that x, y will be the 10 for both


Flag: welcom_to_11@flare-on.com
# Challenge2
We're given an executed coded in Go, and lucky that it's not stripped at all. For first part, it requires user to do some math for a random number times (atmost will be 8)



After finish this first part, a checksum is required. This checksum then decoded hex. If input checksum is not a valid checksum (not in hex string format), it prints out "Not a valid checksum...".

Then the decode input will be checked length, if its length is 32, then it passed as key for chacha20poly1305 decrypt, else, it prints out "Maybe it's time to analyze the binary! ;)"


If key is wrong, it also prints out same message as above.
Take a deeper look into binary, the flow of code is kinda weird, cause it pass input checksum as decrypt key but not yet check it, and the check appear after that call the chacha_open(), maybe it's intense of author.
In first, it convert the hexbyte input back to hex string

Then it's passed into main_a, in this function, it xor input with key "FlareOn2024" then encode base64 the output, latter compare with a hardcode base64 string

[Decrypt](https://gchq.github.io/CyberChef/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true,false)XOR(%7B'option':'UTF8','string':'FlareOn2024'%7D,'Standard',false)&input=Y1FvRlJRRXJYMVlBVncxelZRZEZVU3hmQVFOUkJYVU5BeEJTZTE1UUNWUlZKMXBRRXdkL1dGQlVBbEVsQ0ZCRlVubGFCMVVMQnlSZEJFRmRmVnRXVkE9PQ) it, we get the checksum: 7fd7dd1d0e959f74c133c13abb740b9faa61ab06bd0ecd177645e93b1e3825dd
Decrypt flag then stored in UserCacheDir in form of JPG image.


Flag: Th3_M4tH_Do_b3_mAthng@flare-on.com
# Challenge 3:
Given a yara file, we have to find a file that match that yara rule.
Take a look into the yara rule, there are bunch of rules, but just some of them are required to get the flag.

After for a while, i found that only conditions where equal condition appears and the operation can be convert back like (add, sub, mul, xor) that actual help us find the flag. Wickly remove all reduntdant condition, all the left is just kind easy to find.
```python=
uint8(58) + 25 == 122
uint32(52) ^ 425706662 == 1495724241
uint32(17) - 323157430 == 1412131772
hash.crc32(8, 2) == 0x61089c5c
hash.crc32(34, 2) == 0x5888fc1b
uint8(36) + 4 == 72
uint8(27) ^ 21 == 40
uint32(59) ^ 512952669 == 1908304943
uint8(65) - 29 == 70
uint8(45) ^ 9 == 104
uint32(28) - 419186860 == 959764852
uint8(74) + 11 == 116
hash.crc32(63, 2) == 0x66715919
hash.sha256(14, 2) == "403d5f23d149670348b147a15eeb7010914701a7e99aad2e43f90cfa0325c76f"
hash.sha256(56, 2) == "593f2d04aab251f60c9e4b8bbc1e05a34e920980ec08351a18459b2bc7dbf2f6"
uint8(75) - 30 == 86
uint32(66) ^ 310886682 == 849718389
uint32(10) + 383041523 == 2448764514
uint32(37) + 367943707 == 1228527996
uint32(22) ^ 372102464 == 1879700858
uint8(2) + 11 == 119
hash.md5(0, 2) == "89484b14b36a8d5329426a3d944d2983"
uint32(46) - 412326611 == 1503714457
hash.crc32(78, 2) == 0x7cab8d64
uint8(7) - 15 == 82
uint32(70) + 349203301 == 2034162376
hash.md5(76, 2) == "f98ed07a4d5f50f7de1410d905f1477f"
uint32(80) - 473886976 == 69677856
uint32(3) ^ 298697263 == 2108416586
uint8(21) - 21 == 94
uint8(16) ^ 7 == 115
uint32(41) + 404880684 == 1699114335
hash.md5(50, 2) == "657dae0913ee12be6fb2a6f687aae1c7"
uint8(26) - 7 == 25
hash.md5(32, 2) == "738a656e8e8ec272ca17cd51e12f558b"
uint8(84) + 3 == 128
```
For hash check, because it's just two character for each check, so it can be easy crack by bruteforce
The left it just recover back to from add/sub/xor
Flag: 1RuleADayK33p$Malw4r3Aw4y@flare-on.com
# Challenge 4
Given a html file, open it in browser, it's exactly "mememaker"

Take a look into logic javascript code, it's so long and fully obfuscated.

Deobfuscate this code can be done by many tool, for me, i use [this](https://deobfuscate.relative.im/)
The deobfuscated code is pretty simple, in that, a0k function is likely have the flag.
```cpp=
function a0k() {
const a = a0g.alt.split('/').pop()
if (a !== Object.keys(a0e)[5]) {
return
}
const b = a0l.textContent,
c = a0m.textContent,
d = a0n.textContent
if (
a0c.indexOf(b) == 14 &&
a0c.indexOf(c) == a0c.length - 1 &&
a0c.indexOf(d) == 22
) {
var e = new Date().getTime()
while (new Date().getTime() < e + 3000) {}
var f =
d[3] +
'h' +
a[10] +
b[2] +
a[3] +
c[5] +
c[c.length - 1] +
'5' +
a[3] +
'4' +
a[3] +
c[2] +
c[4] +
c[3] +
'3' +
d[2] +
a[3] +
'j4' +
a0c[1][2] +
d[4] +
'5' +
c[2] +
d[5] +
'1' +
c[11] +
'7' +
a0c[21][1] +
b.replace(' ', '-') +
a[11] +
a0c[4].substring(12, 15)
f = f.toLowerCase()
alert(atob('Q29uZ3JhdHVsYXRpb25zISBIZXJlIHlvdSBnbzog') + f)
}
}
```
The decode base64 in alert ("Congratulations! Here you go: ") suggest that f is the flag we have to find.
f is construct from a, b, c, d, a0c variable where:
+ a0c: hardcode array of string
+ a: a0e[5] ==> 'boy_friend0.jpg'
+ b: a0c[14] ==> 'FLARE On'
+ c: a0c[len(a0c) - 1] ==> 'Security Expert'
+ d: a0c[22] ==> 'Malware'
==> f: wh0A_it5_4_cru3l_j4va5cr1p7@FLARE-On.com
flag is in lower form: wh0a_it5_4_cru3l_j4va5cr1p7@flare-on.com
Flag: wh0a_it5_4_cru3l_j4va5cr1p7@flare-on.com
We can also change the js code that always match the condition, so that the brower show the flag for us

# Challenge 5

Given us a copy of a system, with a hint is that server crashed, and it may be related to sshd. As it hints that server is crashed, searching for the coredump file, we found that it's exactly sshd coredump.

Using gdb, we can find where the system has crashed. To make gdb regcognize all shared lib that crashed program load, we need to let gdb know the right libraty folder, not on your own system but the /usr/lib and /usr/lib64 of the given one.
```
set solib-search-path /path/usr/lib:/path/usr/lib64
```
using two commands "info shared libarary" and "info proc mappings" we can find where librarys loaded on mem. Typically, a lib appears as deleted, but combines result of two commands, we can conlude that it's liblzma.so


Using bt command, we can find return address, from that, we can identify where it crashed

The return address is 0x0007f4a18c8f88f which is in range of liblzma.so.5
sshd and liblzma, which lead us into the famous [CVE-2024-3094](https://securelist.com/xz-backdoor-part-3-hooking-ssh/113007/)
According to the blog, it hooks the RSA_public_decrypt function. Take a look into binary liblzma.so.5, we can easy find where the backdoor located

To find key and nonce, the code reveal that it start with '\x48\x7A\x40\xC5', search the sequence bytes in coredump, we can quicky find key and nonce of that

key: 94 3d f6 38 a8 18 13 e2 de 63 18 a5 7 f9 a0 ba 2d bb 8a 7b a6 36 66 d0 8d 11 a6 5e c9 14 d6 6f
nonce: f2 36 83 9f 4d cd 71 1a 52 86 29 55
Decrypt shellcode, we get beautiful code that can F5 easy :))

The logic kinda straight forward, connect socket, receive key, nonce for "salcha20", filename to read, read file, then encrypt "salcha20", send back to server.
All the info may be still on stack, so to find the info, we have to find the stackframe of this backdoor function.
Start of shellcode

The frame contain info is inside the main_backdoor

RBP of main_backdoor = RBP sub_0 - (5(push) + 1(call)) * 8
RBP of sub_0 = (RSP before call backdoor) - (1(push) + 1(call)) * 8
For now, to find key, nonce, and encrypted data is not easy as before, cause no hint or signature to find. We need to lean on the current debug status, find exactly where server crashed and trace back.

RIP = 0, which lead to crash, it maybe due to a call/jmp to 0, from return address find before, we can find RVA of this address, which is 0x988F (0x0007f4a18c8f88f - 0x7f4a18c86000). Follow the return RVA, the call above is call RAX, and RAX in context is exactly 0.

Read the assembly code, we can see that, RSP value we want to find will be plus 8 compare to the current RSP, due to call instruction.
from all above info, RBP of main_backdoor = current_rsp + 8 - 8 * 8 = 0x7ffcc6601e98 - 0x38 = 0x7ffcc6601e60
==> key

==> nonce:

==> file_name:

==> encrypted data

For encrypted data, i take until it meets the null byte (actual only 0x40 bytes from start).
Try decrypt using cyberchef, but it doesn't work :) After for a while, i found that salcha20 is customized a little bit, not "expand 32-byte k" as normal, but "expand 32-byte K" :)
To decrypt, me myself chose to write a program that run that shellcode, with key, nonce, and enc as above.
Flag: supp1y_cha1n_sund4y@flare-on.com
# Challenge 9
Given a x64 executable. Run it, it's absolute Flag checker

At main function

First, it registers an ExceptionFilter but the handler is nothing but an simple error message and exit

Key is copied into an hardcode address, then pass into a shellcode at lpAddress is called. Find reference to lpAddress, it is used in a TLS_Callback

VirtualAlloc a memory range 0x800000 bytes with RXW permission, then copy the same byte from 0x140097AF0 into that address.
Jump to where the shellcode locate, it's kinda weird. First instruction is "hlt", which is an previlege instruction, can only run in kernel mode. If run in userspace, it will generate an EXCEPTION_PRIV_INSTRUCTION

As analyze before, the handler at main function just print out error message and exit, so it have to another mechanism to handle exception and it may enabled even before main function is called.
IDA support to find EntryPoint, after the TLS_Callback, the main entrypoint will be called

At start, it jump to scrt_common_main_seh, and inside this function, we find what we want.
Before main is called, an array of function from First to Last is called


+ sub_140001090: Get ntdll handle
+ sub_140002000: Find RtlInstallFunctionTableCallback address
+ sub_140001030: Call RtlInstallFunctionTableCallback
As [MSDN ](https://learn.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlinstallfunctiontablecallback), the API is used to add a dynamic function table to the dynamic function table list.
Why is it important here ? The [x64 exception handle](https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64?view=msvc-170) mechanism in MSDN and excellent [article](https://codemachine.com/articles/x64_deep_dive.html#exception_handling) on x64 say it all

So when exception occurs, the PGET_RUNTIME_FUNCTION_CALLBACK Callback will be called, it generates a runtime function, which used for handle exception.
The struct of RUNTIME FUNCTION is defined as below:

Let's jump into the callback, we find the logic to generate RUNTIME FUNCTION

```python=
FunctionStart = exception_ocurr offset
FunctionEnd = FunctionStart + 1
UnwindInfo = FunctionEnd + idc.get_wide_byte(base + FunctionEnd) + 1
UnwindInfo += (UnwindInfo & 1)
```
The UnwindInfo hold the infomations that need to handle the exception

At first, with naive thinking, i write a simple script that find the handler and jump immediately from where exception occurs into handler. That give me the flow of that code but still a lot of stubs doesn't make sense, ie: before exception, R8 hold the address of input key, but in the handle, the value of R8 in context no longer hold that value, ..
After for while, reading the the MSDN again, i found that the unwind codes array is the reason i lost the track. It's kinda similar as VM obfuscate, each unwind code is contain info with normal intense to clean the stack, but in this case, it does some "magic" work.
Base on the [ReactOS src](https://doxygen.reactos.org/d8/d2f/unwind_8c_source.html), i write some script that simulate that flow of unwind code (still some bug in this code, but it help me figure out the lost track).
```python=
def handle(base, exception_offset):
start_offset = exception_offset
end_offset = start_offset + 1
unwind_offset = end_offset + get_wide_byte(base + end_offset) + 1
unwind_offset += unwind_offset & 1
unwind_info = base + unwind_offset
#print('UnwindInfo: ' + hex(unwind_info))
flags = (get_wide_byte(unwind_info) & 0xf8) >> 3
#print('FLAG: ' + hex(flags))
sizeofprolog = get_wide_byte(unwind_info + 1)
#print('Size of prolog: ' + hex(sizeofprolog))
countofcode = get_wide_byte(unwind_info + 2)
#print('COUNT OF CODE: ' + hex(countofcode))
frame = get_wide_byte(unwind_info + 3)
fram_reg = frame & 0xf
#print('FRAME REG: ' + hex(fram_reg))
framoffset = (frame & 0xf0) >> 4
#print('FRAME_OFFSET: ' + hex(framoffset))
unwindcode = unwind_info + 4
i = 0
while i < countofcode:
k = 0
#print('Uwincode address: ' + (hex(unwindcode)))
code_offset = get_wide_byte(unwindcode)
code = get_wide_byte(unwindcode + 1)
opcode = (code & 0xf)
#print('OPCODE: ' + hex(opcode) + ': ', end='')
opinfo = (code & 0xf0) >> 4
if opcode == UWOP_PUSH_NONVOL:
insn = 'pop ' + regs[opinfo]
#print(insn)
exception_offset += patch_asm(base + exception_offset, insn)
k = 1
elif opcode == UWOP_ALLOC_LARGE:
if opinfo != 0:
insn = 'add rsp, ' + hex(get_wide_dword(unwindcode + 2))
#print(insn)
exception_offset += patch_asm(base + exception_offset, insn)
k = 3
else:
insn = 'add rsp, ' + hex(get_wide_word(unwindcode + 2) * 8)
#print(insn)
exception_offset += patch_asm(base + exception_offset, insn)
k = 2
elif opcode == UWOP_ALLOC_SMALL:
insn = 'add rsp, ' + hex(8 * (opinfo + 1))
#print(insn)
exception_offset += patch_asm(base + exception_offset, insn)
k = 1
elif opcode == UWOP_SET_FPREG:
reg = regs[fram_reg]
delta = framoffset * 16
if delta:
insn = 'mov rsp, ' + reg + ' - ' + hex(delta) +']'
else:
insn = 'mov rsp, ' + reg
#print(insn)
exception_offset += patch_asm(base + exception_offset, insn)
k = 1
elif opcode == UWOP_SAVE_NONVOL:
reg = regs[opinfo]
offset = get_wide_word(unwindcode + 2)
insn = 'mov ' + reg + ', [rsp + ' + hex(offset) +']'
#print(insn)
exception_offset += patch_asm(base + exception_offset, insn)
k = 2
elif opcode == UWOP_SAVE_NONVOL_FAR:
reg = regs[opinfo]
offset = get_wide_dword(unwindcode + 2)
insn = 'mov ' + reg + ', [rsp + ' + hex(offset) +']'
#print(insn)
exception_offset += patch_asm(base + exception_offset, insn)
k = 3
elif opcode == UWOP_EPILOG:
k = 1
elif opcode == UWOP_SPARE_CODE:
k = 2
elif opcode == UWOP_PUSH_MACHFRAME:
insn = 'add rsp, ' + hex(opinfo * 8)
#print(insn)
exception_offset += patch_asm(base + exception_offset, insn)
insn = 'mov rip, [rsp]'
#print(insn)
insn = 'mov rsp, [rsp + 0x18]'
exception_offset += patch_asm(base + exception_offset, insn)
#print(insn)
k = 1
i += k
unwindcode += k * 2
countofcode *= 2
countofcode += countofcode % 4
handler = base + get_wide_dword(unwind_info + 4 + countofcode)
# delta = handler - base - exception_offset - 5
# patch_byte(base + exception_offset, 0xe9)
# patch_dword(base + exception_offset + 1, delta)
# create_insn(base + exception_offset)
set_cmt(base + start_offset, hex(unwind_info) + ', ' + hex(handler), 0)
return handler
```
Beside that obfuscation x64 exception mechanism, the code at Exception Handler is also obfuscated

The inside the call always has the same logic as below

First, it pop the return address into hardcode address, then it decrypt the real instruction by moving the opcode of real instruction and the then return address is calculated. So each instruction is actual just do one instruction at a time, which is the decrypted code. For deobfuscate the call obfuscate, i use this silly code
```python=
def patch_call(call, start_call, ret):
ea = start_call
create_insn(ea) # pop instruction
poped_addr = get_operand_value(ea, 0)
patch_qword(poped_addr, ret)
ea += 0xe # point to mov
insn_len = create_insn(ea)
ah = get_wide_byte(get_operand_value(ea, 1)) << 8
ea += insn_len # point to lea
insn_len = create_insn(ea)
eax = ah + get_operand_value(ea, 1)
ea += insn_len # point to mov
addr_patch = get_operand_value(ea, 0)
patch_dword(addr_patch, eax)
ea = addr_patch
real_insn = create_insn(ea)
if print_insn_mnem(ea) == 'jmp':
jmp = get_operand_value(ea, 0)
delta = jmp - call - 5
patch_byte(call, 0xe9)
patch_dword(call + 1, delta)
return jmp
#in case it not a jmp to htl
for i in range(real_insn):
patch_byte(call + i, get_wide_byte(ea + i))
create_insn(call)
ea = poped_addr + 8
create_insn(ea)
delta = get_operand_value(ea, 1) # get the real return value
return ret + delta
```
Dump the deobfuscated shellcode to a file, investigate on that code, we can found some key concept below:
+ There' re 32 checks, everytime check fail, it jump into function sub_1400011F0 which print out "Wrong key" message and terminate program.

+ For each check, it is a equation of operation include plus, xor, mul where input key is manage to join in mul operation, each equation take random 8 characters from input key, each character mul with a hardcode number, then xor/add with another hardcode number
+ The hardcode value is not show up clearly in the code but hided by some simple maths (push a number on stack, add/sub a number, the result is the actual value, ...) which can be quickly remove by find the pattern replace with coressponse value of that value.

+ Almost value is manual construct byte by byte (except the value used to mul with input key character), each byte of the value appear in form of array, corresponse to two type of operations xor and add. the final value can be managed to collect with help of idapython script. But compare to actual value we find when debug, some of them are slicely different.
At this point, we decided to debug and log the results of every operation, then convert each result back to the 'actual value' used in the operations. After debugging the first check, we can reimplement it in Python for the first case like this
```python=
def c1():
result = data[0x4] * 0xef7a8c
result = result + 0x9d865d8d
result = result - (data[0x18] * 0x45b53c)
result = result + 0x18baee57
result = result - (data[0x0] * 0xe4cf8b)
result = result + 0x6ec04422
result = result - (data[0x8] * 0xf5c990)
result = result + 0x6bfaa656
result = result ^ (data[0x14] * 0x733178)
result = result ^ 0x61e3db3b
result = result ^ (data[0x10] * 0x9a17b8)
result = result + 0x35d7fb4f
result = result ^ (data[0xc] * 0x773850)
result = result ^ 0x5a6f68be
result = result ^ (data[0x1c] * 0xe21d3d)
result = result ^ 0x5c911c23
result = result + 0x7e9b8687
result &= 0xffffffffffffffff
return result
```
We still have 31 functions like this left, and while debugging each one is possible, it would be extremely time-consuming. I decided to automate the process using IDAPython. My plan is to dump the values of each operation and then back-calculate them to find the hardcoded numbers. I patched the input to `\x00 * 32` to make the calculation easier. With my deobfuscated shellcode dump file, it's easy to locate the offset of any instruction. First, I found that there are only 32 test instructions, each one checking the final value in each function

I’ll set breakpoints at each of these 32 `test` instructions.

Each of the 32 checks will trigger a conditional jump to a Print "Wrong" function if the check fails. To automate the debugging process, you’ll need to ensure that the instruction pointer (RIP) is automatically adjusted after each failed check. To handle this, I’ll also set 32 additional breakpoints on each `cmovnz` instruction. Every time a breakpoint on a `cmovnz` instruction is hit, it will automatically adjust RIP to point to the correct jmp instruction to continue debugging smoothly. Below is my script to dump the values:
```python=
test_array =[0x179fd,0x2f386,0x4751a,0x5d2cd,0x7230b,0x8917b,0xa0de8,0xb7d00,0xd0742,0xe7b7b,0xff3a3,0x1164ea,0x12ce52,0x14492b,0x15ec1e,0x176fbd,0x190732,0x1a5a58,0x1bc75d,0x1d572b,0x1ecdf1,0x205671,0x21b636,0x22f442,0x243e47,0x25a19e,0x26ec62,0x285d0b,0x29e558,0x2b5f19,0x2cd429,0x2e4b8f]
cmove_array = [0x17a07, 0x2f390, 0x47524, 0x5d2d7, 0x72315, 0x89185, 0xa0df2, 0xb7d0a, 0xd074c, 0xe7b85, 0xff3ad, 0x1164f4, 0x12ce5c, 0x144935, 0x15ec28, 0x176fc7, 0x19073c, 0x1a5a62, 0x1bc767, 0x1d5735, 0x1ecdfb, 0x20567b, 0x21b640, 0x22f44c, 0x243e51, 0x25a1a8, 0x26ec6c, 0x285d15, 0x29e562, 0x2b5f23, 0x2cd433, 0x2e4b99]
base = get_qword(0x14089B8E0)
for i in range(len(test_array)):
idaapi.create_insn(base+test_array[i])
add_bpt(base+test_array[i],0,BPT_DEFAULT);
for i in range(len(cmove_array)):
idaapi.create_insn(base + cmove_array[i])
add_bpt(base + cmove_array[i], 0, BPT_DEFAULT)
for i in range(len(test_array)+len(cmove_array)):
ida_dbg.continue_process()
idaapi.wait_for_next_event(WFNE_SUSP, -1)
if(idc.print_insn_mnem(get_reg_value("rip"))=="cmovnz"):
set_reg_value(get_reg_value("rip")+idaapi.create_insn(get_reg_value("rip"))+idaapi.create_insn(get_reg_value("rip")+idaapi.create_insn(get_reg_value("rip"))),"rip")
else:
offset = get_reg_value("rip")-base
value_final = get_reg_value(print_operand(get_reg_value("rip"),0))
print(hex(value_final),end=",")
f.close()
```
We will got 32 final value in mỗi hàm với input is `\x00 * 32` :
```
0x5be3e290,0x62a2a0fb,0x3ade6641,0x18d62e9b4,0xffffffffd01904a1,0xffffffffbbe5233e,0x8478c40,0xffffffffb1b9939b,0xfffffffff31da2f5,0x8c8bc76,0xffffffffd45091a6,0x1a35812a,0xffffffffd8bc839e,0xffffffffe724ad90,0x1a1d901a,0xffffffff81514d31,0xffffffff530d9146,0x5db36e01,0x6c511b62,0xffffffff4f1727a1,0x213022fe,0xfffffffff4d5f043,0xffffffff92a2ef25,0xfffffffedf1a2ab0,0xffffffff750e3b65,0x448addb5,0xfffffffffe691b35,0xffffffffed2a9d03,0x224e42c5,0xfffffffda375005b,0xfffffffe71ef098c,0xffffffffbcc44d66
```
Similarly, I set a breakpoint on the `mul` instruction to dump the factor values in `rsp`

After the first `mul`, the value is pushed to the stack. Starting from the second `mul`, it will use the result of the previous calculation to perform an `xor`, `add`, or `sub` with the newly multiplied result. It's easy to calculate the offsets of these instructions from the mul instruction's address (as they appear just a few instructions after mul) using my deobfuscated shellcode dump file. The output for the first three check functions will look like this.

Now, we have dumped the sign and factors of each multiplication operation. Next, I set a breakpoint on the `ldmxcsr` instruction to dump the hardcoded value used for calculations between the multiplication operations (`mul`).

My dump:

The final piece of data we need is the sign of the operations between the multiplication steps. Through debugging, I found a pattern: if the operation is an `xor`, there is an array containing the xor values, indexed accordingly:

For example, if you want to XOR `0x5` with `0x32`, there is an array pre-calculated with the XOR results. By taking the address of the value `0x32` and adding 5, you get the result of `0x32 ^ 0x5 = 0x37`. The array looks like this:
```asm=
addr: value
0x00: 0x32 //0x32= 0x32 ^ 0x0
0x01: 0x33 //0x33= 0x33 ^ 0x1
0x02: 0x30 //0x30= 0x32 ^ 0x2
0x03: 0x31
0x04: 0x36
0x05: 0x37
0x06: 0x34
0x07: 0x35
0x08: 0x3a
0x09: 0x3b
0x0a: 0x38
0x0b: 0x39
0x0c: 0x3e
0x0d: 0x3f
0x0e: 0x3c
0x0f: 0x3d
...
...
...
```
From all of the above, I was able to reimplement all 32 check functions and use Z3 to find the flag
```python=
from z3 import *
def c1():
result = data[0x4] * 0xef7a8c
result = result + 0x9d865d8d
result = result - (data[0x18] * 0x45b53c)
result = result + 0x18baee57
result = result - (data[0x0] * 0xe4cf8b)
result = result + 0x6ec04422
result = result - (data[0x8] * 0xf5c990)
result = result + 0x6bfaa656
result = result ^ (data[0x14] * 0x733178)
result = result ^ 0x61e3db3b
result = result ^ (data[0x10] * 0x9a17b8)
result = result + 0x35d7fb4f
result = result ^ (data[0xc] * 0x773850)
result = result ^ 0x5a6f68be
result = result ^ (data[0x1c] * 0xe21d3d)
result = result ^ 0x5c911c23
result = result + 0x7e9b8687
result &= 0xffffffffffffffff
return result
def c2():
result = data[0x11] * 0x99aa81
result = result + 0x8b1215af
result = result ^ (data[0x5] * 0x4aba22)
result = result + 0x598015bf
result = result ^ (data[0x15] * 0x91a68a)
result = result ^ 0x6df18e52
result = result ^ (data[0x1] * 0x942fde)
result = result + 0x15c825ee
result = result - (data[0xd] * 0xfe2fbe)
result = result + 0xd5682b64
result = result - (data[0x1d] * 0xd7e52f)
result = result + 0x798bd018
result = result ^ (data[0x19] * 0xe44f6a)
result = result + 0x1992adc2
result = result + (data[0x9] * 0xaf71d6)
result = result + 0x921121d3
result = result + 0x1eeb7552
result &= 0xffffffffffffffff
return result
def c3():
result = data[0xa] * 0x48c500
result = result + 0x70255e44
result = result - (data[0x1e] * 0x152887)
result = result + 0x65f04e48
result = result - (data[0xe] * 0xaa4247)
result = result ^ 0x3d63ec69
result = result ^ (data[0x16] * 0x38d82d)
result = result ^ 0x872eca8f
result = result ^ (data[0x1a] * 0xf120ac)
result = result + 0x803dbdcf
result = result + (data[0x2] * 0x254def)
result = result ^ 0xee380db3
result = result ^ (data[0x12] * 0x9ef3e7)
result = result + 0x921556f5
result = result + (data[0x6] * 0x69c573)
result = result + 0x3653a3a3
result = result + 0xc45c0f3
result &= 0xffffffffffffffff
return result
def c4():
result = data[0xb] * 0x67dda4
result = result + 0xf4753afc
result = result + (data[0x1f] * 0x5bb860)
result = result ^ 0xc1d47fc9
result = result ^ (data[0x17] * 0xab0ce5)
result = result + 0x544ff977
result = result + (data[0x7] * 0x148e94)
result = result + 0x634c1be7
result = result - (data[0xf] * 0x9e06ae)
result = result + 0x5239df9c
result = result ^ (data[0x3] * 0xfb9de1)
result = result ^ 0x4e3633f7
result = result - (data[0x1b] * 0xa8a511)
result = result ^ 0xa61f9208
result = result + (data[0x13] * 0xd3468d)
result = result + 0x4a5d7a48
result = result + 0x109bee5e
result &= 0xffffffffffffffff
return result
def c5():
result = data[0xc] * 0x640ba9
result = result + 0x516c7a5c
result = result - (data[0x0] * 0xf1d9e5)
result = result + 0x8b424d6b
result = result + (data[0x1c] * 0xd3e2f8)
result = result + 0x3802be78
result = result + (data[0x18] * 0xb558ce)
result = result + 0xccbe7372
result = result - (data[0x8] * 0x2f03a7)
result = result ^ 0xe050b170
result = result + (data[0x10] * 0xb8fa61)
result = result ^ 0x1fc22df6
result = result - (data[0x14] * 0xe0c507)
result = result ^ 0xd8376e57
result = result + (data[0x4] * 0x8e354e)
result = result + 0x2d34cdf8
result = result + 0xff187080
result &= 0xffffffffffffffff
return result
def c6():
result = data[0x11] * 0xa9b448
result = result ^ 0x9f938499
result = result + (data[0x5] * 0x906550)
result = result + 0x407021af
result = result ^ (data[0xd] * 0xaa5ad2)
result = result ^ 0x77cf83a7
result = result ^ (data[0x1d] * 0xc49349)
result = result ^ 0x3067f4e7
result = result + (data[0x9] * 0x314f8e)
result = result + 0xcd975f3b
result = result ^ (data[0x15] * 0x81968b)
result = result + 0x893d2e0b
result = result - (data[0x19] * 0x5ffbac)
result = result ^ 0xf3378e3a
result = result - (data[0x1] * 0xf63c8e)
result = result + 0xe3e276d5
result = result + 0x71a14c73
result &= 0xffffffffffffffff
return result
def c7():
result = data[0x16] * 0xa6edf9
result = result ^ 0x77c58017
result = result - (data[0x12] * 0xe87bf4)
result = result + 0x666428c0
result = result - (data[0x2] * 0x19864d)
result = result + 0xbe77b413
result = result + (data[0x6] * 0x901524)
result = result ^ 0x247bf095
result = result ^ (data[0xa] * 0xc897cc)
result = result ^ 0xeff7eea8
result = result ^ (data[0xe] * 0x731197)
result = result + 0x67a0d262
result = result + (data[0x1e] * 0x5f591c)
result = result + 0x316661f9
result = result + (data[0x1a] * 0x579d0e)
result = result + 0xcbd804e4
result = result + 0x6ff28cb5
result &= 0xffffffffffffffff
return result
def c8():
result = data[0x17] * 0x9afaf6
result = result ^ 0xdb895413
result = result + (data[0x13] * 0x7d1a12)
result = result + 0x398603bc
result = result + (data[0xb] * 0x4d84b1)
result = result + 0xa30387dc
result = result - (data[0xf] * 0x552b78)
result = result ^ 0xf54a725e
result = result ^ (data[0x7] * 0xf372a1)
result = result + 0xb3aefc53
result = result + (data[0x1f] * 0xb40eb5)
result = result ^ 0x16fa70d2
result = result ^ (data[0x3] * 0x9e5c18)
result = result + 0x38784353
result = result ^ (data[0x1b] * 0xf2513b)
result = result + 0xa1fc09f0
result = result + 0xfe291bf8
result &= 0xffffffffffffffff
return result
def c9():
result = data[0x1c] * 0xac70b9
result = result + 0xdae0a932
result = result ^ (data[0x4] * 0xc42b6f)
result = result ^ 0xbc03104c
result = result - (data[0x0] * 0x867193)
result = result + 0xdc48c63a
result = result - (data[0xc] * 0x6d31fe)
result = result ^ 0x4baeb6d0
result = result - (data[0x10] * 0xaaae58)
result = result + 0x328ede08
result = result + (data[0x14] * 0x9faa7a)
result = result + 0xbe0a2c9c
result = result + (data[0x18] * 0x354ac6)
result = result ^ 0xd8ad17f1
result = result - (data[0x8] * 0x3f2acb)
result = result + 0x74948177
result = result + 0x9c3ec96d
result &= 0xffffffffffffffff
return result
def c10():
result = data[0x1d] * 0xe9d18a
result = result ^ 0xcb5557ea
result = result ^ (data[0x19] * 0x8aa5b9)
result = result ^ 0x9125a906
result = result - (data[0x11] * 0x241997)
result = result + 0x6e46fcb8
result = result + (data[0x5] * 0xe3da0f)
result = result + 0x442800ec
result = result + (data[0xd] * 0xa5f9eb)
result = result + 0xbde8f9af
result = result + (data[0x15] * 0xd6e0fb)
result = result + 0x36268dbd
result = result + (data[0x1] * 0x8dc36e)
result = result + 0xc54b7d21
result = result ^ (data[0x9] * 0xb072ee)
result = result + 0xd5e54e3f
result = result + 0x40dfbc25
result &= 0xffffffffffffffff
return result
def c11():
result = data[0x1e] * 0xd14f3e
result = result ^ 0xa06c215b
result = result - (data[0x1a] * 0xc5ecbf)
result = result + 0xb197c5c0
result = result ^ (data[0x6] * 0x19ff9c)
result = result ^ 0x66e7d06c
result = result + (data[0x2] * 0xe3288b)
result = result ^ 0x80af4325
result = result ^ (data[0xa] * 0xcfb18c)
result = result + 0x1ec37c6d
result = result ^ (data[0x12] * 0xd208e5)
result = result + 0xf96d2b51
result = result + (data[0xe] * 0x42240f)
result = result + 0x78cdd8c3
result = result - (data[0x16] * 0x1c6098)
result = result + 0x2c2ba3a6
result = result + 0xf4c281a5
result &= 0xffffffffffffffff
return result
def c12():
result = data[0xb] * 0x3768cc
result = result ^ 0x19f61419
result = result - (data[0x3] * 0x43be16)
result = result + 0x566cc6a8
result = result ^ (data[0xf] * 0xb7cca5)
result = result + 0x6db0599e
result = result + (data[0x1b] * 0xf6419f)
result = result ^ 0xbd613538
result = result ^ (data[0x13] * 0xae52fc)
result = result + 0x717a44dd
result = result - (data[0x17] * 0x5eeb81)
result = result + 0xdd02182d
result = result ^ (data[0x7] * 0xec1845)
result = result ^ 0xef8e5416
result = result + (data[0x1f] * 0x61a3be)
result = result ^ 0x9288d4fa
result = result + 0x7e4241fb
result &= 0xffffffffffffffff
return result
def c13():
result = data[0x10] * 0x336e91
result = result + 0xa1eb20e3
result = result - (data[0x4] * 0xd45de9)
result = result + 0xc7e538e6
result = result + (data[0x8] * 0x76c8f8)
result = result ^ 0xd8caa2cd
result = result - (data[0x14] * 0x945339)
result = result + 0x524d7efa
result = result + (data[0xc] * 0x4474ec)
result = result + 0x1b817d33
result = result ^ (data[0x0] * 0x51054f)
result = result ^ 0x3321c9b1
result = result - (data[0x18] * 0xd7eb3b)
result = result + 0x36f6829d
result = result - (data[0x1c] * 0xad52e1)
result = result ^ 0x6ce2191a
result = result + 0xc64bcbd
result &= 0xffffffffffffffff
return result
def c14():
result = data[0x1d] * 0x725059
result = result ^ 0xa8b69f6b
result = result + (data[0x11] * 0x6dcfe7)
result = result ^ 0x653c249a
result = result + (data[0x1] * 0x8f4c44)
result = result ^ 0x68e87685
result = result - (data[0x9] * 0xd2f4ce)
result = result + 0x78dc723b
result = result ^ (data[0xd] * 0xe99d3f)
result = result + 0xed16797a
result = result + (data[0x5] * 0xada536)
result = result + 0x6a5fa557
result = result - (data[0x19] * 0xe0b352)
result = result ^ 0x43c00020
result = result + (data[0x15] * 0x8675b6)
result = result + 0x34a29213
result = result + 0xdfe69582
result &= 0xffffffffffffffff
return result
def c15():
result = data[0x2] * 0x4a5e95
result = result + 0x5ed7a1f1
result = result + (data[0x16] * 0x3a7b49)
result = result ^ 0x87a91310
result = result - (data[0x6] * 0xf27038)
result = result ^ 0xf64a0f19
result = result + (data[0x1e] * 0xa187d0)
result = result + 0x44338ca3
result = result - (data[0x12] * 0xfc991a)
result = result ^ 0xf9ddd08f
result = result - (data[0x1a] * 0x4e947a)
result = result + 0xa656e8d2
result = result ^ (data[0xe] * 0x324ead)
result = result + 0x6965859c
result = result - (data[0xa] * 0x656b1b)
result = result + 0x8c112443
result = result + 0x3e24bb39
result &= 0xffffffffffffffff
return result
def c16():
result = data[0xb] * 0x251b86
result = result + 0xa751192c
result = result - (data[0x7] * 0x743927)
result = result ^ 0xf851da43
result = result ^ (data[0x1f] * 0x9a3479)
result = result ^ 0x335087a5
result = result ^ (data[0x3] * 0x778a0d)
result = result ^ 0x4bfd30d3
result = result - (data[0x1b] * 0x7e04b5)
result = result + 0xa2abfb6b
result = result ^ (data[0x13] * 0xf1c3ee)
result = result + 0x460c48a6
result = result + (data[0xf] * 0x883b8a)
result = result + 0x7b2ffbdc
result = result + (data[0x17] * 0x993db1)
result = result + 0xa98b27fa
result = result + 0xddf7842c
result &= 0xffffffffffffffff
return result
def c17():
result = data[0x10] * 0xbae081
result = result + 0x2359766f
result = result ^ (data[0x18] * 0xc2483b)
result = result + 0xea986a57
result = result - (data[0x1c] * 0x520ee2)
result = result ^ 0xa6ff8114
result = result + (data[0x8] * 0x9864ba)
result = result + 0x42833507
result = result - (data[0x0] * 0x7cd278)
result = result ^ 0x360be811
result = result ^ (data[0x4] * 0xbe6605)
result = result + 0xb36d8573
result = result + (data[0x14] * 0x3bd2e8)
result = result + 0xb790cfd3
result = result - (data[0xc] * 0x548c2b)
result = result + 0x2a0e04cc
result = result + 0xdecd786e
result &= 0xffffffffffffffff
return result
def c18():
result = data[0x11] * 0xfb213b
result = result + 0x988c29bd
result = result ^ (data[0x9] * 0xde6876)
result = result ^ 0x8649fde3
result = result ^ (data[0x1d] * 0x629ff7)
result = result ^ 0xa0eeb203
result = result - (data[0x19] * 0xdbb107)
result = result ^ 0x94aa6b62
result = result - (data[0x1] * 0x262675)
result = result + 0x2030ab78
result = result + (data[0x5] * 0xd691c5)
result = result + 0xa4c118ba
result = result - (data[0xd] * 0xcafc93)
result = result + 0xeee421de
result = result - (data[0x15] * 0x81f945)
result = result + 0x6ffcc3f8
result = result + 0x9cb62931
result &= 0xffffffffffffffff
return result
def c19():
result = data[0xa] * 0x52f44d
result = result ^ 0x33b3d0e4
result = result ^ (data[0x1e] * 0xe6e66e)
result = result + 0xd8a28650
result = result - (data[0x6] * 0xf98017)
result = result ^ 0x456e6c1d
result = result - (data[0xe] * 0x34fcb0)
result = result ^ 0x28709cd8
result = result ^ (data[0x2] * 0x4d8ba9)
result = result + 0xb5482f53
result = result ^ (data[0x12] * 0x6c7e92)
result = result + 0x2af1d741
result = result + (data[0x16] * 0xa4711e)
result = result ^ 0x22e79af6
result = result + (data[0x1a] * 0x33d374)
result = result + 0xee8102f2
result = result + 0x6c86bd72
result &= 0xffffffffffffffff
return result
def c20():
result = data[0x1b] * 0x65ac37
result = result + 0x15e586b0
result = result ^ (data[0x1f] * 0xc6dde0)
result = result ^ 0x2354cad4
result = result ^ (data[0xf] * 0x154abd)
result = result ^ 0xfee57fd5
result = result ^ (data[0x13] * 0xa5e467)
result = result + 0x315624ef
result = result ^ (data[0x17] * 0xb6bed6)
result = result + 0xad7a4f5b
result = result - (data[0x7] * 0x832ae7)
result = result + 0xe961bedd
result = result + (data[0xb] * 0xc46330)
result = result + 0xb561e29b
result = result ^ (data[0x3] * 0x3f8467)
result = result ^ 0x95a6a1c4
result = result + 0xeef1cae7
result &= 0xffffffffffffffff
return result
def c21():
result = data[0x18] * 0xb74a52
result = result ^ 0x8354d4e8
result = result ^ (data[0x4] * 0xf22ecd)
result = result + 0xcb340dc5
result = result + (data[0x14] * 0xbef4be)
result = result ^ 0x60a6c39a
result = result ^ (data[0x8] * 0x7fe215)
result = result + 0xb14a7317
result = result - (data[0x10] * 0xdb9f48)
result = result + 0x4356fa0e
result = result - (data[0x1c] * 0xbb4276)
result = result + 0x6df1ddb8
result = result ^ (data[0x0] * 0xa3fbef)
result = result + 0x4c22d2d3
result = result ^ (data[0xc] * 0xc5e883)
result = result ^ 0x50a6e4c9
result = result + 0x271a433a
result &= 0xffffffffffffffff
return result
def c22():
result = data[0xd] * 0x4b2d02
result = result ^ 0x4b59b93a
result = result - (data[0x9] * 0x84bb2c)
result = result ^ 0x42d5652c
result = result ^ (data[0x19] * 0x6f2d21)
result = result + 0x1020133a
result = result + (data[0x1d] * 0x5fe38f)
result = result + 0x9d7f84e0
result = result + (data[0x15] * 0xea20a5)
result = result ^ 0x60779ceb
result = result ^ (data[0x11] * 0x5c17aa)
result = result ^ 0x1aaf8a2d
result = result - (data[0x5] * 0xb9feb0)
result = result + 0x5241fd05
result = result - (data[0x1] * 0x782f79)
result = result + 0x303ed7ca
result = result + 0xb77294fa
result &= 0xffffffffffffffff
return result
def c23():
result = data[0x6] * 0x608d19
result = result + 0xd1119d14
result = result - (data[0xe] * 0xbe18f4)
result = result ^ 0xb86f9b72
result = result ^ (data[0x1e] * 0x88dec9)
result = result + 0xaf5cd797
result = result ^ (data[0x12] * 0xb68150)
result = result + 0xc2f8c45b
result = result + (data[0x16] * 0x4d166c)
result = result + 0xbb1e1039
result = result - (data[0x2] * 0x495e3f)
result = result + 0xe727b98e
result = result - (data[0xa] * 0x5caba1)
result = result + 0xe5c3093f
result = result + (data[0x1a] * 0x183a4d)
result = result + 0x35fc681f
result = result + 0x997b5ce3
result &= 0xffffffffffffffff
return result
def c24():
result = data[0xb] * 0xffd0ca
result = result + 0x70d93118
result = result ^ (data[0x7] * 0xbf2b59)
result = result + 0xc76bad6e
result = result + (data[0x17] * 0x29df01)
result = result + 0xeef034a2
result = result ^ (data[0x1b] * 0xbbda1d)
result = result + 0x5923194e
result = result - (data[0x1f] * 0x5d24a5)
result = result + 0x7eeff867
result = result + (data[0xf] * 0x3dc505)
result = result + 0x9645116f
result = result ^ (data[0x13] * 0x4e25a6)
result = result + 0x2468b30a
result = result - (data[0x3] * 0xae1920)
result = result ^ 0xd3db6142
result = result + 0x44850ff1
result &= 0xffffffffffffffff
return result
def c25():
result = data[0x4] * 0xf56c62
result = result ^ 0x6c7d1f41
result = result + (data[0x10] * 0x615605)
result = result + 0x5b52f6ee
result = result + (data[0x14] * 0x828456)
result = result ^ 0x6f059759
result = result - (data[0x1c] * 0x50484b)
result = result + 0x84e222af
result = result ^ (data[0x8] * 0x89d640)
result = result + 0xfd21345b
result = result - (data[0x18] * 0xe4b191)
result = result + 0xfe15a789
result = result ^ (data[0x0] * 0x8c58c1)
result = result ^ 0x4c49099f
result = result + (data[0xc] * 0xa13c4c)
result = result ^ 0x27c5288e
result = result + 0xff6724f5
result &= 0xffffffffffffffff
return result
def c26():
result = data[0x1] * 0x73aaf0
result = result ^ 0xa04e34f1
result = result + (data[0x1d] * 0xf61e43)
result = result + 0xd09b66f3
result = result + (data[0x19] * 0x8cb5f0)
result = result + 0xc11c9b4b
result = result ^ (data[0x11] * 0x4f53a8)
result = result + 0x9b9a98d2
result = result + (data[0x9] * 0xb2e1fa)
result = result ^ 0x77c07fd8
result = result - (data[0x15] * 0xb8b7b3)
result = result + 0x77d3eadf
result = result + (data[0xd] * 0x13b807)
result = result ^ 0x758dd142
result = result ^ (data[0x5] * 0xdd40c4)
result = result + 0xbb68781a
result = result + 0x4fa227c4
result &= 0xffffffffffffffff
return result
def c27():
result = data[0xe] * 0xca894b
result = result + 0xa34fe406
result = result + (data[0x12] * 0x11552b)
result = result + 0x3764ecd4
result = result ^ (data[0x16] * 0x7dc36b)
result = result + 0xb45e777b
result = result ^ (data[0x1a] * 0xcec5a6)
result = result ^ 0x2d59bc15
result = result + (data[0x1e] * 0xb6e30d)
result = result ^ 0xfab9788c
result = result ^ (data[0xa] * 0x859c14)
result = result + 0x41868e54
result = result + (data[0x6] * 0xd178d3)
result = result + 0x958b0be3
result = result ^ (data[0x2] * 0x61645c)
result = result + 0x9dc814cf
result = result + 0x847feabe
result &= 0xffffffffffffffff
return result
def c28():
result = data[0x1b] * 0x7239e9
result = result + 0x89f1a526
result = result - (data[0x3] * 0xf1c3d1)
result = result + 0x10d75f98
result = result ^ (data[0xb] * 0x1b1367)
result = result ^ 0x31e00d5a
result = result ^ (data[0x13] * 0x8038b3)
result = result + 0xb5163447
result = result + (data[0x1f] * 0x65fac9)
result = result + 0xe04a889a
result = result - (data[0x17] * 0xd845ca)
result = result + 0x5482e3a8
result = result + (data[0xf] * 0xb2bbbc)
result = result ^ 0x3a017b92
result = result ^ (data[0x7] * 0x33c8bd)
result = result + 0x540376e3
result = result + 0x4f17f36d
result &= 0xffffffffffffffff
return result
def c29():
result = data[0x0] * 0x53a4e0
result = result + 0x9f9e7fc2
result = result - (data[0x10] * 0x9bbfda)
result = result + 0x69b383f1
result = result - (data[0x18] * 0x6b38aa)
result = result + 0x68ece860
result = result + (data[0x14] * 0x5d266f)
result = result + 0x5a4b0e60
result = result - (data[0x8] * 0xedc3d3)
result = result ^ 0x93e59af6
result = result - (data[0x4] * 0xb1f16c)
result = result ^ 0xe8d2b9a9
result = result + (data[0xc] * 0x1c8e5b)
result = result + 0x977c6d7d
result = result + (data[0x1c] * 0x78f67b)
result = result + 0xac22677
result = result + 0xb154dea3
result &= 0xffffffffffffffff
return result
def c30():
result = data[0x11] * 0x87184c
result = result + 0x8d5ea528
result = result ^ (data[0x19] * 0xf6372e)
result = result + 0x16ad4f89
result = result - (data[0x15] * 0xd7355c)
result = result + 0x44df01cb
result = result ^ (data[0x5] * 0x471dc1)
result = result ^ 0x572c95f4
result = result - (data[0x1] * 0x8c4d98)
result = result + 0x6b9af38c
result = result - (data[0xd] * 0x5ceea1)
result = result ^ 0xf703dcc1
result = result - (data[0x1d] * 0xeb0863)
result = result + 0xad3bc09d
result = result ^ (data[0x9] * 0xb6227f)
result = result + 0xb95195e9
result = result + 0xcea17ee8
result &= 0xffffffffffffffff
return result
def c31():
result = data[0x1e] * 0x8c6412
result = result ^ 0xc08c361c
result = result ^ (data[0xe] * 0xb253c4)
result = result + 0x21bb1147
result = result + (data[0x2] * 0x8f0579)
result = result + 0x596ee7a
result = result - (data[0x16] * 0x7ac48a)
result = result + 0xbb787dd5
result = result + (data[0xa] * 0x2737e6)
result = result ^ 0xa2bb7683
result = result - (data[0x12] * 0x4363b9)
result = result ^ 0x88c45378
result = result ^ (data[0x6] * 0xb38449)
result = result + 0xdf623f88
result = result + (data[0x1a] * 0x6e1316)
result = result + 0x1343dee9
result = result + 0x1c966ad9
result &= 0xffffffffffffffff
return result
def c32():
result = data[0x13] * 0x390b78
result = result + 0x7d5deea4
result = result - (data[0xf] * 0x70e6c8)
result = result + 0x915cc61e
result = result ^ (data[0x1b] * 0xd8a292)
result = result + 0xd772913b
result = result - (data[0x17] * 0x978c71)
result = result + 0x1a27a128
result = result + (data[0x1f] * 0x9a14d4)
result = result + 0x49698f34
result = result ^ (data[0x7] * 0x995144)
result = result + 0x2d188cbe
result = result ^ (data[0xb] * 0x811c39)
result = result + 0xd22fca9b
result = result ^ (data[0x3] * 0x9953d7)
result = result ^ 0x80877669
result = result + 0x6bddb88
result &= 0xffffffffffffffff
return result
data = [BitVec(f'data{i}', 8) for i in range(32)]
s = Solver()
s.add(c1() == 0)
s.add(c2() == 0)
s.add(c4() == 0)
s.add(c3() == 0)
s.add(c5() == 0)
s.add(c6() == 0)
s.add(c7() == 0)
s.add(c8() == 0)
s.add(c9() == 0)
s.add(c10() == 0)
s.add(c11() == 0)
s.add(c12() == 0)
s.add(c13() == 0)
s.add(c14() == 0)
s.add(c15() == 0)
s.add(c16() == 0)
s.add(c17() == 0)
s.add(c18() == 0)
s.add(c19() == 0)
s.add(c20() == 0)
s.add(c21() == 0)
s.add(c22() == 0)
s.add(c23() == 0)
s.add(c24() == 0)
s.add(c25() == 0)
s.add(c26() == 0)
s.add(c27() == 0)
s.add(c28() == 0)
s.add(c29() == 0)
s.add(c30() == 0)
s.add(c31() == 0)
s.add(c32() == 0)
def print_all_sat(solver):
solutions = []
while solver.check() == sat:
model = solver.model()
result = ''.join(chr(model[byte].as_long()) for byte in data)
print("SAT Solution:")
print(result)
exclusion = Or([byte != model[byte] for byte in data])
solver.add(exclusion)
print_all_sat(s)
```
Flag: `$$_4lway5_k3ep_mov1ng_and_m0ving@flare-on.com`