Challenge Description

As a bird soaring through the sky, you seek the perfect language, and then… you find this

Analysis

When we examine the challenge file, we immediately notice that it has a .db3 extension and is quite large. Opening it with a text editor reveals a strange-looking language that initially appears obfuscated. Our first step is to determine what language this is.

Given the .db3 file extension and the challenge description, which mentions the perfect language and emphasizes the word bird, we perform a quick search. This leads us to conclude that the language in question is DreamBerd, an eso-lang.

Static Analysis

After reviewing DreamBerd’s specifics, we realize that there is no way to execute the program directly, so we opt for static analysis instead.

Examining the code, we observe that the variable 42 is used as an index for m. The declaration of m appears at the end of the file (line 34434) as an array of numbers: [205, 242, 231, 208, 235, 150, 5, 14, 162, 115, 134, 81, 118, 138, 49, 16, 54, 142, 80, 102, 139, 35, 127, 83, 52, 106, 200, 185, 153, 203, 34, 66, 62, 12, 7, 166, 34, 81, 250] The next line of the code prints this array, suggesting that myabe represents the flag for the challenge. Upon further analysis, we see that the rest of the code repeatedly executes the same operation inside an if statement that is always True:

if (;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42) {
    const var v = m[a-1]!!
    const var w = ((42 ^ v) % 256) ^ 0x89!!!
	m[a-1] = w!!!!
	const var a<-3> = 42 % 39!!
	42 += 1!
}

We simplify this snippet by renaming 42 as i and removing the redundant ! symbols:

const var v = m[a-1]
const var w = ((i ^ v) % 256) ^ 0x89
m[a-1] = w
const var a<-3> = i % 39
i += 1

Rearranging the instructions for better readability and removing unnecessary keywords (const and var), we obtain:

a = i % 39
v = m[a-1]
w = ((i ^ v) % 256) ^ 0x89
m[a-1] = w
i += 1

Since DreamBerd indexes arrays in an unusual way, we account for the -1 offset and rewrite the logic in Python:

index = i % 39
value = m[index]
result = ((i ^ value) % 256) ^ 0x89
m[index] = result
i += 1

Writing the Solve Script

To extract and decode the flag, we implement the following approach:

  • Read the file, remove ! symbols, and strip unnecessary whitespace:
file = "chall.db3"

with open(file, "r") as f:
	code = f.read().split("\n")
code = [c.strip().replace('!', '') for c in code]
  • Extract the m array (or copy it directly):
mem = list(map(int, code[-4].split('[')[1][:-1].split(', ')))
  • Extract the lines containing hardcoded values:
start = 'const var w = '
operations = [c[len(start):] for c in code if c.startswith(start)]
  • Implement the original code logic:
for i, op in enumerate(operations):
	num = int(op.split(' ^ ')[2], 16)
	addr = i % len(mem)
	mem[addr] = ((i ^ mem[addr]) % 256) ^ num
  • Cast and print the flag:
flag = bytes(mem).decode()
print(flag)

Final Solve Script

file = "chall.db3"

with open(file, "r") as f:
	code = f.read().split("\n")
code = [c.strip().replace('!', '') for c in code]

mem = list(map(int, code[-4].split('[')[1][:-1].split(', ')))

start = 'const var w = '
operations = [c[len(start):] for c in code if c.startswith(start)]

for i, op in enumerate(operations):
	num = int(op.split(' ^ ')[2], 16)
	addr = i % len(mem)
	mem[addr] = ((i ^ mem[addr]) % 256) ^ num

flag = bytes(mem).decode()
print(flag)

Flag

TRX{tHi5_I5_th3_P3rf3ct_l4nGU4g3!!!!!!}