Author: Matt Bergin (@thatguylevel)
This paper details a cryptographic solution to the .eas file encryption used by Cellebrite to prevent review of the forensic methodologies implemented in their software.
This is the second cipher written by Cellebrite I have decided to release a solution to. The previous research I published detailed how to recover the plaintext for code used by their tools to elevate privilege on target devices and to collect raw bytes needed for forensic analysis. These findings were presented at BlackHat 2021 Asia and much of my code can be found on my public GitHub. In both my previous work and now the algorithms discussed are affected by CWE-321, CWE-326, and CWE-327.
I would also like to show an appreciation for the book Cryptanalysis: A study of ciphers and their solutions by Helen-Fouche Gaines. It was valuable to this research and I came across it randomly while visiting a local library, go visit yours and walk around for a bit.
In my previous research, I found out too late about solutions for previous versions that had already been made available by others. When starting to look at this cipher I knew of a previous solution that was made public by cellebrited. The source code for their solution can be found below:
import os
import sys
import random
class CellebriteEas(object):
def __init__(self):
self._box = bytearray(256)
self.KEY_SIZE = 16 #Decodieren
self.BOX_SIZE = 256
self._encryptionKey=None
def setKey(self,Key):
self._encryptionKey=Key
for index in range(256):
self._box[index] = index;
index1 = 0
keylength = len(self._encryptionKey)
for index2 in range(256):
index1 = (index1 + self._box[index2] + self._encryptionKey[index2 % keylength]) % 256
num = self._box[index2]
self._box[index2] = self._box[index1]
self._box[index1] = num
def crypto(self,data):
index1 = 0
index2 = 0
numArray1 = bytearray(len(data))
numArray2 = bytearray()
numArray2+=self._box
for index3 in range(len(data)):
index1 = (index1 + 1) % 256
index2 = (index2 + numArray2[index1]) % 256
num1 = numArray2[index1]
numArray2[index1] = numArray2[index2]
numArray2[index2] = num1
num2 = data[index3]
num3 = numArray2[( numArray2[index1] + numArray2[index2]) % 256]
numArray1[index3] = ( num2 ^ num3)&0xff
return numArray1
def decrypt(self,filename):
buffer=bytearray()
with open(filename,"rb") as file:
file_data=file.read()
Key=bytearray(file_data[-16:])
Data=bytearray(file_data[:-16])
self.setKey(Key)
return self.crypto(Data)
def decrypt_file(filename):
enc = CellebriteEas()
with open(filename+".dll","wb") as file:
file.write(enc.decrypt(filename))
def do_decrypt(basedir,hash):
print("Im {0} running".format(basedir))
for root, dirs, files in os.walk(basedir):
for name in files:
if ".eas"==name[-4:]:
print("{0} processing".format(name))
filename=os.path.join(root,name)
decrypt_file(filename)
decrypt_file("bb_whatsapp.eas")
In this version of the .eas file encryption algorithm, the key to unlock the file exists within the file. The first byte is not only an encrypted byte, but also acts as part of an offset to the location within the ciphertext where the key resides. I don't think this is a subtle attempt at a concealment cipher but it certainly felt a bit like a variation of a grille cipher. Looking at an example we see this:
$ hexdump -C Apple.eas | more
00000000 c3 5c 44 89 c4 4f 3a 60 59 66 af cd d3 2d 33 f3 |.\D..O:`Yf...-3.|
00000010 37 fd 71 ed a7 8f 23 04 12 28 13 b5 2a f6 84 5b |7.q...#..(..*..[|
...
000000c0 31 f0 40 81 14 c1 70 01 08 1e d9 f9 f6 ed c6 5c |1.@...p........\|
000000d0 c6 13 70 0f 54 6f 78 70 6e 6b 78 07 0f 59 71 61 |..p.Toxpnkx..Yqa|
000000e0 59 3f fe 4c df 7c e9 55 39 76 55 e2 14 08 78 01 |Y?.L.|.U9vU...x.|
...
The offset to the key is calculated using the following formula:
The output of the formula shown above is 0xd2 and this is the location of the key material needed to unlock the file. Here is the key from this example:
000000d0 XX XX 70 0f 54 6f 78 70 6e 6b 78 07 0f 59 71 61 |..p.Toxpnkx..Yqa|
000000e0 59 3f XX XX XX XX XX XX XX XX XX XX XX XX XX XX |Y?..............|
This sixteen byte key is removed from the ciphertext to be decrypted and is used to initialize two substitution boxes. To begin, a 256 byte 2D matrix is generated and populated with 0x0 through 0xff. Below is a matrix showing what this looks like:
Next we calculate the new value for the first of two indices. A for loop is then used to perform the necessary transpositions in order to finish the initialization of this substitution box. This is done using the following forumla, where index1 is initially set to 0 and i is a range from 0 through 256.
The second index is the value within the box at the position of the value for i.
The value within the box at the position of i is replaced with the value within the box at the position index1.
The value within the box at the position of index1 is replaced with the value within the box at the position of index2.
Below is an example showing the log output of the transposition for the first substitution box:
TRANSPOSE SBOX1[0] was 0x0 now 0x70. SBOX1[112] was 0x70 now 0x0
TRANSPOSE SBOX1[1] was 0x1 now 0x80. SBOX1[128] was 0x80 now 0x1
TRANSPOSE SBOX1[2] was 0x2 now 0xd6. SBOX1[214] was 0xd6 now 0x2
TRANSPOSE SBOX1[3] was 0x3 now 0x48. SBOX1[72] was 0x48 now 0x3
Below is an example of the first substition box after it has been initialized:
The second byte of the sixteen byte key is then used to initialize the second substitution box. This byte is first made the only byte in a 624 byte 2D matrix. The remainder of the matrix is populated in a for loop using the following formula where i is the value of the last byte in the matrix:
The next value is then appended to the matrix. The value for i in the subsequent operation then becomes 0x3 and this formula is repeated. The first 256 bytes of the second substitution box in this case is:
Two copies of substitution box two should be kept in memory. One which is transposed earlier in the decryption process and another which is transposed mid-way through the overall decryption process.
Prior to attempting to decrypt an encrypted byte, the two substitution boxes go through a set of transposition operations which mutate the boxes based on the given formulas and box content. It is important to note that these transpositions are applied for every byte to be decrypted. The first substitution box undergoes one transpostition while the second undergoes three. Before these transpositions take place a check is performed to see if we are decrypting byte number 0x26f, and if so, then to restore the original content of the second substitution box before beginning the transposition and decryption operation within the loop.
The transposition operation for the first substitution box is very similar to what is used during its initialization. The main difference is that in this case we are not mixing in bytes from a key when calculating new values and positions. Before we enter the for loop for the first time, we set two variables, index1 and index2, to zero. We calculate the first position (index1) using the following:
We need to also store the old index1 value for later use.
Next we calculate the second position (index2) using the following:
The values at these positions are then swapped.
No transposition is performed on the second substitution box for bytes before 0x26e. Instead, we then select the bytes needed from each of the two boxes and also the previous value at index1 from substitution box 1. When decrypting the first byte, the previous value is also the current value.
To decrypt an encrypted byte we plug in our variables to the following (simplified) equation:
Going back to our example from Apple.eas, the first encrypted byte is 0xc3. We expect to get back 0x4d (ASCII: M) as it is the first character in the file magic for the Portable Executable (PE) file format. In our equation below, we do not get that result. I chose Apple.eas on purpose because it is one of a handful of encrypted files that were stubborn.
(((((0xf << 0xb & 0xff) >> 0x7) >> 0x12 ^ 0xf) ^ 0xca) ^ 0xc3) ^ 0xcb = 0xcd
The above equation works for most files. In the case where it fails (which you should check using the same technique described above) a simple fix can be applied to substitution box 2 that will address the issue and allow for the file to be decrypted. The fix is to re-initialize the second substitution box using a different value. We start by setting i to the value of the second byte of the encryption key and then add 0x80.
The first 256 bytes of substitution box 2 in this case are:
Now, in applying the same equation as before we can successfully decrypt the first byte.
(((((0x8f << 0xb & 0xff) >> 0x7) >> 0x12 ^ 0x8f) ^ 0xca) ^ 0xc3) ^ 0xcb = 0x4d
This approach will work for the first 0x26f bytes by design, but will also work through 0x273 due to insufficient transposition in substitution box 2 during each loop.
After byte 0x26f, three additional transposition operations take place when decrypting, totaling four transpositions per byte.
In the first twist we iterate over substitution box two 0xe3 times. At the start of each iteration, we select byte i+1 and right shift it by 1 then and it by 1.
From here if b2 is 0 then c will be 0, otherwise c is 0xdf.
In the second twist we iterate over substitution box two 0x18c times. At the start of each iteration, we select byte i+0xe3 and right shift it by 1 then and it by 1.
From here if b2 is 0 then c will be 0, otherwise c is 0xdf.
In the third twist there is no loop.
From here if b2 is 0 then c will be 0, otherwise c is 0xdf.
Now that all of the substitution box transpositions have been completed for the next byte, we can select values from the boxes and plug them into an equation which will return a plaintext byte.
c = encrypted[pos]
Finally..
$ python3 ./decrypt-eas --file Apple.eas --verbose
[+] Decrypting: Apple.eas
[*] OFFSET 0xd2
[*] IV 0x700f546f78706e6b78070f597161593f
SBOX1 0x100
0x70 0x07 0x59 0x86 0xc4 0x39 0x20 0x5f 0x9f 0x69 0xfd 0x2c 0xa9 0x00 0xd9 0xcc
0x56 0x19 0xd2 0x49 0x4f 0x43 0xe9 0xcd 0xf1 0xd5 0x3a 0x62 0x64 0xb9 0x30 0x76
0xad 0x2f 0xb1 0xf5 0x6a 0x08 0x48 0x58 0xb2 0xd1 0x5c 0x44 0x2d 0x3d 0xd8 0x36
0x09 0xef 0x75 0x37 0x05 0x5b 0x1a 0x21 0x3c 0xa3 0xa7 0x4e 0x8f 0xaa 0xce 0x4d
0x63 0xe7 0x8e 0x25 0xac 0xd3 0x47 0x32 0x34 0x8d 0x11 0x4c 0xcf 0x66 0x2e 0x74
0x88 0x96 0x71 0x97 0x87 0xa4 0x8a 0x12 0xa2 0xf9 0xe1 0x67 0x1d 0x77 0xb4 0x0f
0x6d 0xfe 0xbf 0x98 0xbe 0xb5 0x89 0x93 0xe6 0xab 0x45 0x40 0x92 0x9c 0xae 0x9d
0x17 0x06 0x53 0x28 0x78 0x0d 0xbc 0x84 0xa5 0x0b 0x7d 0xa1 0x0a 0x6c 0x01 0x7c
0x80 0x55 0xc6 0xe0 0x23 0x73 0x0e 0xf6 0x13 0x42 0x29 0x52 0xdd 0xd0 0xb7 0x5e
0x38 0xd4 0xeb 0xed 0xb6 0x10 0x7b 0x5a 0xd7 0x26 0x22 0xf0 0xea 0x65 0xf4 0xc0
0xcb 0xe8 0x41 0x03 0xf2 0x83 0xdc 0x8b 0x6b 0x16 0xc1 0xff 0x72 0x60 0xee 0xbd
0x04 0x82 0xa6 0xc5 0x18 0xdf 0x54 0x1e 0xc7 0x9e 0xf3 0x1f 0x57 0x27 0x79 0xb0
0xc2 0x2a 0x24 0x50 0x6e 0x1c 0x2b 0xfa 0x0c 0xfb 0x6f 0x7a 0x5d 0xba 0x7f 0xc9
0x51 0x15 0x99 0x14 0x95 0x02 0x9b 0x85 0x90 0x7e 0x4a 0xd6 0x35 0xe4 0xfc 0x4b
0xda 0xa8 0x1b 0x8c 0xe2 0x61 0x31 0x3f 0x46 0xf7 0xe3 0xca 0xde 0xec 0xe5 0x68
0xa0 0xb3 0x91 0x33 0x3b 0x3e 0xc3 0xbb 0xdb 0xf8 0x94 0x81 0xc8 0x9a 0xb8 0xaf
SBOX2 0x270
0x0f 0x03 0x67 0x7b 0x7f 0xb3 0x57 0xab 0xef 0x63 0x47 0xdb 0x5f 0x13 0x37 0x0b
0xcf 0xc3 0x27 0x3b 0x3f 0x73 0x17 0x6b 0xaf 0x23 0x07 0x9b 0x1f 0xd3 0xf7 0xcb
0x8f 0x83 0xe7 0xfb 0xff 0x33 0xd7 0x2b 0x6f 0xe3 0xc7 0x5b 0xdf 0x93 0xb7 0x8b
0x4f 0x43 0xa7 0xbb 0xbf 0xf3 0x97 0xeb 0x2f 0xa3 0x87 0x1b 0x9f 0x53 0x77 0x4b
0x0f 0x03 0x67 0x7b 0x7f 0xb3 0x57 0xab 0xef 0x63 0x47 0xdb 0x5f 0x13 0x37 0x0b
0xcf 0xc3 0x27 0x3b 0x3f 0x73 0x17 0x6b 0xaf 0x23 0x07 0x9b 0x1f 0xd3 0xf7 0xcb
0x8f 0x83 0xe7 0xfb 0xff 0x33 0xd7 0x2b 0x6f 0xe3 0xc7 0x5b 0xdf 0x93 0xb7 0x8b
0x4f 0x43 0xa7 0xbb 0xbf 0xf3 0x97 0xeb 0x2f 0xa3 0x87 0x1b 0x9f 0x53 0x77 0x4b
0x0f 0x03 0x67 0x7b 0x7f 0xb3 0x57 0xab 0xef 0x63 0x47 0xdb 0x5f 0x13 0x37 0x0b
0xcf 0xc3 0x27 0x3b 0x3f 0x73 0x17 0x6b 0xaf 0x23 0x07 0x9b 0x1f 0xd3 0xf7 0xcb
0x8f 0x83 0xe7 0xfb 0xff 0x33 0xd7 0x2b 0x6f 0xe3 0xc7 0x5b 0xdf 0x93 0xb7 0x8b
0x4f 0x43 0xa7 0xbb 0xbf 0xf3 0x97 0xeb 0x2f 0xa3 0x87 0x1b 0x9f 0x53 0x77 0x4b
0x0f 0x03 0x67 0x7b 0x7f 0xb3 0x57 0xab 0xef 0x63 0x47 0xdb 0x5f 0x13 0x37 0x0b
0xcf 0xc3 0x27 0x3b 0x3f 0x73 0x17 0x6b 0xaf 0x23 0x07 0x9b 0x1f 0xd3 0xf7 0xcb
0x8f 0x83 0xe7 0xfb 0xff 0x33 0xd7 0x2b 0x6f 0xe3 0xc7 0x5b 0xdf 0x93 0xb7 0x8b
0x4f 0x43 0xa7 0xbb 0xbf 0xf3 0x97 0xeb 0x2f 0xa3 0x87 0x1b 0x9f 0x53 0x77 0x4b
0x0f 0x03 0x67 0x7b 0x7f 0xb3 0x57 0xab 0xef 0x63 0x47 0xdb 0x5f 0x13 0x37 0x0b
0xcf 0xc3 0x27 0x3b 0x3f 0x73 0x17 0x6b 0xaf 0x23 0x07 0x9b 0x1f 0xd3 0xf7 0xcb
0x8f 0x83 0xe7 0xfb 0xff 0x33 0xd7 0x2b 0x6f 0xe3 0xc7 0x5b 0xdf 0x93 0xb7 0x8b
0x4f 0x43 0xa7 0xbb 0xbf 0xf3 0x97 0xeb 0x2f 0xa3 0x87 0x1b 0x9f 0x53 0x77 0x4b
0x0f 0x03 0x67 0x7b 0x7f 0xb3 0x57 0xab 0xef 0x63 0x47 0xdb 0x5f 0x13 0x37 0x0b
0xcf 0xc3 0x27 0x3b 0x3f 0x73 0x17 0x6b 0xaf 0x23 0x07 0x9b 0x1f 0xd3 0xf7 0xcb
0x8f 0x83 0xe7 0xfb 0xff 0x33 0xd7 0x2b 0x6f 0xe3 0xc7 0x5b 0xdf 0x93 0xb7 0x8b
0x4f 0x43 0xa7 0xbb 0xbf 0xf3 0x97 0xeb 0x2f 0xa3 0x87 0x1b 0x9f 0x53 0x77 0x4b
0x0f 0x03 0x67 0x7b 0x7f 0xb3 0x57 0xab 0xef 0x63 0x47 0xdb 0x5f 0x13 0x37 0x0b
0xcf 0xc3 0x27 0x3b 0x3f 0x73 0x17 0x6b 0xaf 0x23 0x07 0x9b 0x1f 0xd3 0xf7 0xcb
0x8f 0x83 0xe7 0xfb 0xff 0x33 0xd7 0x2b 0x6f 0xe3 0xc7 0x5b 0xdf 0x93 0xb7 0x8b
0x4f 0x43 0xa7 0xbb 0xbf 0xf3 0x97 0xeb 0x2f 0xa3 0x87 0x1b 0x9f 0x53 0x77 0x4b
0x0f 0x03 0x67 0x7b 0x7f 0xb3 0x57 0xab 0xef 0x63 0x47 0xdb 0x5f 0x13 0x37 0x0b
0xcf 0xc3 0x27 0x3b 0x3f 0x73 0x17 0x6b 0xaf 0x23 0x07 0x9b 0x1f 0xd3 0xf7 0xcb
0x8f 0x83 0xe7 0xfb 0xff 0x33 0xd7 0x2b 0x6f 0xe3 0xc7 0x5b 0xdf 0x93 0xb7 0x8b
0x4f 0x43 0xa7 0xbb 0xbf 0xf3 0x97 0xeb 0x2f 0xa3 0x87 0x1b 0x9f 0x53 0x77 0x4b
0x0f 0x03 0x67 0x7b 0x7f 0xb3 0x57 0xab 0xef 0x63 0x47 0xdb 0x5f 0x13 0x37 0x0b
0xcf 0xc3 0x27 0x3b 0x3f 0x73 0x17 0x6b 0xaf 0x23 0x07 0x9b 0x1f 0xd3 0xf7 0xcb
0x8f 0x83 0xe7 0xfb 0xff 0x33 0xd7 0x2b 0x6f 0xe3 0xc7 0x5b 0xdf 0x93 0xb7 0x8b
0x4f 0x43 0xa7 0xbb 0xbf 0xf3 0x97 0xeb 0x2f 0xa3 0x87 0x1b 0x9f 0x53 0x77 0x4b
0x0f 0x03 0x67 0x7b 0x7f 0xb3 0x57 0xab 0xef 0x63 0x47 0xdb 0x5f 0x13 0x37 0x0b
0xcf 0xc3 0x27 0x3b 0x3f 0x73 0x17 0x6b 0xaf 0x23 0x07 0x9b 0x1f 0xd3 0xf7 0xcb
0x8f 0x83 0xe7 0xfb 0xff 0x33 0xd7 0x2b 0x6f 0xe3 0xc7 0x5b 0xdf 0x93 0xb7 0x8b
(((((0xf << 0xb & 0xff) >> 0x7) >> 0x12 ^ 0xf) ^ 0xca) ^ 0xc3) ^ 0xcb == 0xcd
[!] The first byte has failed to decrypt. Do you want to try a experimental fix? (y/n) y
[-] Fix applied, trying again.
(((((0x8f << 0xb & 0xff) >> 0x7) >> 0x12 ^ 0x8f) ^ 0xca) ^ 0xc3) ^ 0xcb == 0x4d
Do you want to keep going? (y/n/q/s/t) t
...
...
...
SBOX1 0x100
0x9a 0x8c 0x7c 0xaf 0x57 0x69 0x2a 0x31 0xbf 0x43 0x27 0x4a 0xf4 0x36 0x09 0x72
0x15 0xc7 0xe8 0x33 0xe7 0x8d 0xf7 0x34 0x03 0x54 0x10 0x14 0x4f 0xd4 0x46 0x3b
0xaa 0x52 0xad 0xcf 0x35 0x9b 0x18 0x61 0xeb 0xd3 0xea 0x9f 0x39 0xbc 0xda 0xa1
0xff 0x84 0xe6 0x4d 0xd1 0xf6 0xba 0x6a 0x6c 0x00 0xa2 0x48 0x23 0xcb 0x1d 0x2c
0xfc 0xcc 0x0f 0x29 0x07 0x44 0xb6 0x88 0xc3 0xdf 0x65 0x08 0x98 0x38 0x4c 0x99
0xfa 0xb2 0xa7 0x67 0x40 0x74 0xa4 0x58 0x0b 0x5b 0x7a 0x95 0x62 0x92 0xfd 0xac
0xb8 0xd8 0x2b 0x3e 0x75 0xf3 0xfb 0xf2 0x5a 0x71 0x22 0x82 0x60 0xc6 0x89 0x5e
0xe3 0x30 0x47 0x87 0x1f 0xa6 0xb7 0x6b 0x76 0x45 0xc8 0xa3 0xd2 0x42 0x8e 0x7b
0x3f 0x16 0x53 0x78 0x24 0x77 0x8f 0x6f 0xec 0xdd 0x28 0xe2 0x86 0x55 0x41 0xb3
0x05 0xd7 0x11 0x20 0x1b 0x5d 0xf9 0x26 0xa9 0x2e 0xc9 0x1e 0xc5 0xb4 0xa8 0xa0
0xfe 0x50 0x79 0xbd 0xdc 0x7f 0x37 0x04 0x81 0x0e 0x06 0x66 0x7e 0x59 0x8b 0x5f
0xe4 0x17 0x9d 0xde 0xd5 0xf8 0x2f 0x49 0x21 0xce 0x91 0x73 0x8a 0x80 0x6e 0x19
0x83 0x51 0x02 0xbe 0xc0 0xae 0x93 0xf5 0x90 0xc1 0xb0 0xb9 0xf1 0x32 0xbb 0x7d
0x5c 0xe0 0x0c 0xe5 0xc4 0x3a 0x13 0xab 0xcd 0xca 0x94 0xc2 0x3d 0x0d 0xdb 0x3c
0x6d 0xef 0xe9 0x0a 0xb1 0x97 0x1a 0xed 0x12 0xee 0x9c 0xa5 0x1c 0x4b 0x2d 0xb5
0x56 0x63 0xd0 0x68 0x01 0x64 0x70 0xd6 0xe1 0xf0 0x4e 0xd9 0x96 0x85 0x25 0x9e
SBOX2 0x270
0xcd 0xdb 0xe9 0x2f 0x45 0xd3 0xb1 0x97 0x9d 0xeb 0xd9 0x5f 0xf5 0xc3 0x41 0xa7
0x6d 0x3b 0x09 0x4f 0x65 0x33 0x11 0x77 0xfd 0x0b 0xb9 0xbf 0x55 0x63 0xe1 0x47
0x0d 0x1b 0x29 0xef 0x85 0x13 0x71 0x57 0x5d 0x2b 0x19 0x9f 0x35 0x03 0x81 0x67
0xad 0xfb 0xc9 0x8f 0xa5 0xf3 0xd1 0xb7 0x3d 0xcb 0x79 0x7f 0x95 0xa3 0x21 0x87
0xcd 0xdb 0xe9 0x2f 0x45 0xd3 0xb1 0x97 0x9d 0xeb 0xd9 0x5f 0xf5 0xc3 0x41 0xa7
0x6d 0x3b 0x09 0x4f 0x65 0x33 0x11 0x77 0xfd 0x0b 0xb9 0xbf 0x55 0x63 0xe1 0x47
0x0d 0x1b 0x29 0xef 0x85 0x13 0x71 0x57 0x5d 0x2b 0x19 0x9f 0x35 0x03 0x81 0x67
0xad 0xfb 0xc9 0x8f 0xa5 0xf3 0xd1 0xb7 0x3d 0xcb 0x79 0x7f 0x95 0xa3 0x21 0x87
0xcd 0xdb 0xe9 0x2f 0x45 0xd3 0xb1 0x97 0x9d 0xeb 0xd9 0x5f 0xf5 0xc3 0x41 0xa7
0x6d 0x3b 0x09 0x4f 0x65 0x33 0x11 0x77 0xfd 0x0b 0xb9 0xbf 0x55 0x63 0xe1 0x47
0x0d 0x1b 0x29 0xef 0x85 0x13 0x71 0x57 0x5d 0x2b 0x19 0x9f 0x35 0x03 0x81 0x67
0xad 0xfb 0xc9 0x8f 0xa5 0xf3 0xd1 0xb7 0x3d 0xcb 0x79 0x7f 0x95 0xa3 0x21 0x87
0xcd 0xdb 0xe9 0x2f 0x45 0xd3 0xb1 0x97 0x9d 0xeb 0xd9 0x5f 0xf5 0xc3 0x41 0xa7
0x6d 0x3b 0x09 0x4f 0x65 0x33 0x11 0x77 0xfd 0x0b 0xb9 0xbf 0x55 0x63 0xe1 0x47
0x0d 0x1b 0x29 0x6d 0x1d 0x5d 0xe5 0xad 0x7d 0x0d 0x65 0x2d 0x7d 0x5d 0xc5 0x0d
0x3d 0xcd 0x25 0xed 0x9d 0x9d 0xe5 0xad 0xbd 0x8d 0xa5 0x6d 0xfd 0x5d 0x45 0x8d
0xbd 0x0d 0xa5 0xed 0x9d 0xdd 0x65 0x2d 0xfd 0x8d 0xe5 0xad 0xfd 0xdd 0x45 0x8d
0xbd 0x4d 0xa5 0x6d 0x1d 0x1d 0x65 0x2d 0x3d 0x0d 0x25 0xed 0x7d 0xdd 0xc5 0x0d
0x3d 0x8d 0x25 0x6d 0x1d 0x5d 0xe5 0xad 0x7d 0x0d 0x65 0x2d 0x7d 0x5d 0xc5 0x0d
0x3d 0xcd 0x25 0xed 0x9d 0x9d 0xe5 0xad 0xbd 0x8d 0xa5 0x6d 0xfd 0x5d 0x45 0x8d
0xbd 0x0d 0xa5 0xed 0x9d 0xdd 0x65 0x2d 0xfd 0x8d 0xe5 0xad 0xfd 0xdd 0x45 0x8d
0xbd 0x4d 0xa5 0x6d 0x1d 0x1d 0x65 0x2d 0x3d 0x0d 0x25 0xed 0x7d 0xdd 0xc5 0x0d
0x3d 0x8d 0x25 0x6d 0x1d 0x5d 0xe5 0xad 0x7d 0x0d 0x65 0x2d 0x7d 0x5d 0xc5 0x0d
0x3d 0xcd 0x25 0xed 0x9d 0x9d 0xe5 0xad 0xbd 0x8d 0xa5 0x6d 0xfd 0x5d 0x45 0x8d
0xbd 0x0d 0xa5 0xed 0x9d 0xdd 0x65 0x2d 0xfd 0x8d 0xe5 0xad 0xfd 0xdd 0x45 0x8d
0xbd 0x4d 0xa5 0x6d 0x1d 0x1d 0x65 0x2d 0x3d 0x0d 0x25 0xed 0x7d 0xdd 0xc5 0x0d
0x3d 0x8d 0x25 0x6d 0x1d 0x5d 0xe5 0xad 0x7d 0x0d 0x65 0x2d 0x7d 0x5d 0xc5 0x0d
0x3d 0xcd 0x25 0xed 0x9d 0x9d 0xe5 0xad 0xbd 0x8d 0xa5 0x6d 0xfd 0x5d 0x45 0x8d
0xbd 0x0d 0xa5 0xed 0x9d 0xdd 0xe7 0xb5 0xb3 0x19 0x1f 0x8d 0xdb 0xa1 0xf7 0xc5
0xe3 0x09 0xcf 0xfd 0x2b 0xf1 0x07 0x15 0x53 0x39 0x3f 0x6d 0x3b 0x01 0xd7 0x65
0xc3 0xe9 0x2f 0x1d 0xcb 0x11 0x27 0x75 0x73 0xd9 0xdf 0x4d 0x1b 0x61 0x37 0x05
0x23 0xc9 0x0f 0x3d 0xeb 0x31 0xc7 0xd5 0x93 0xf9 0xff 0xad 0xfb 0xc1 0x17 0xa5
0x03 0x29 0xef 0xdd 0x0b 0xd1 0xe7 0xb5 0xb3 0x19 0x1f 0x8d 0xdb 0xa1 0xf7 0xc5
0xe3 0x09 0xcf 0xfd 0x2b 0xf1 0x07 0x15 0x53 0x39 0x3f 0x6d 0x3b 0x01 0xd7 0x65
0xc3 0xe9 0x2f 0x1d 0xcb 0x11 0x27 0x75 0x73 0xd9 0xdf 0x4d 0x1b 0x61 0x37 0x05
0x23 0xc9 0x0f 0x3d 0xeb 0x31 0xc7 0xd5 0x93 0xf9 0xff 0xad 0xfb 0xc1 0x17 0xa5
0x03 0x29 0xef 0xdd 0x0b 0xd1 0xe7 0xb5 0xb3 0x19 0x1f 0x8d 0xdb 0xa1 0xf7 0xc5
0xe3 0x09 0xcf 0xfd 0x2b 0xf1 0x07 0x15 0x53 0x39 0x3f 0x6d 0x3b 0x01 0xd7 0x65
0xc3 0xe9 0x2f 0x1d 0xcb 0x11 0x27 0x75 0x73 0xd9 0xdf 0x4d 0x1b 0x61 0x37 0x44
(((((((0xcd << 0x7 & 0xff) ^ 0xcd) >> 0x12 & 0xff) ^ (((0xcd << 0x7 & 0xff) ^ 0xcd))) ^ 0xd9) ^ 0x5e) ^ 0xcb) == 0x1
Do you want to keep going? (y/n/q/s) y
...
...
...
$ file Apple.dll
Apple.dll: PE32 executable (DLL) (console) Intel 80386 Mono/.Net assembly, for MS Windows