Doubts, help and support about QuickBMS and other game research tools
chrrox
Posts: 388 Joined: Thu Aug 07, 2014 10:28 pm
Post
by chrrox » Sun Oct 13, 2019 1:21 pm
How would you translate this to a quickbms function
Code: Select all
$constKeys = [ 0x3039, // 12345 0x10932,// 67890 0x7AB7 // 31415 ]; $keys = [ $constKeys[0] ^ KEY0, $constKeys[1] ^ KEY1, $constKeys[2] ^ KEY2, ]; for ($j=0; $j<strlen($data); $j++) { $data[$j] = $data[$j] ^ chr((($keys[1] ^ $keys[0] ^ $keys[2]) >> 24) & 0xff); $keys[0] = (0x343fd * $keys[0] + 0x269ec3) & 0xFFFFFFFF; $keys[1] = (0x343fd * $keys[1] + 0x269ec3) & 0xFFFFFFFF; $keys[2] = (0x343fd * $keys[2] + 0x269ec3) & 0xFFFFFFFF; }
and for an example
set KEY0 2000205869
set KEY1 1453860051
set KEY2 55406356
and
the original data
set MEMORY_FILE binary "\xCE\x8E\x8A\x67"
and the correct output should be
"\xEC\x7D\x07\x7C"
the way it should work is
so when you xor them you get 12345 ^ 2000205869 = 0x77388814 67890 ^ 1453860051 = 0x56A92DE1 31415 ^ 55406356 = 0x34D15A3 then you xor those 3 together and get 22DCB056 and you right shift that by 24 so you get 0x22 that is the xor key for the first byte of the file.
aluigi
Site Admin
Posts: 12984 Joined: Wed Jul 30, 2014 9:32 pm
Post
by aluigi » Sun Oct 13, 2019 7:51 pm
Code: Select all
set MEMORY_FILE binary "\xCE\x8E\x8A\x67" math KEY0 = 2000205869 math KEY1 = 1453860051 math KEY2 = 55406356 math constKeys_0 = 0x3039, // 12345 math constKeys_1 = 0x10932,// 67890 math constKeys_2 = 0x7AB7 // 31415 xmath keys_0 "constKeys_0 ^ KEY0" xmath keys_1 "constKeys_1 ^ KEY1" xmath keys_2 "constKeys_2 ^ KEY2" get MEM_SIZE asize MEMORY_FILE for j = 0 < MEM_SIZE getvarchr data MEMORY_FILE j xmath data "data ^ (((keys_1 ^ keys_0 ^ keys_2) >> 24) & 0xff)" putvarchr MEMORY_FILE j data xmath keys_0 "(0x343fd * keys_0 + 0x269ec3) & 0xFFFFFFFF" xmath keys_1 "(0x343fd * keys_1 + 0x269ec3) & 0xFFFFFFFF" xmath keys_2 "(0x343fd * keys_2 + 0x269ec3) & 0xFFFFFFFF" next j
chrrox
Posts: 388 Joined: Thu Aug 07, 2014 10:28 pm
Post
by chrrox » Sun Oct 13, 2019 8:32 pm
This worked perfectly is there any way to speed up this function?
It took 44 seconds to decrypt a 1593287 byte file.
This is the file.
This is the script I tried.
Code: Select all
get SIZE asize log MEMORY_FILE 0 SIZE math KEY0 = 2000205869 math KEY1 = 1453860051 math KEY2 = 55406356 math constKeys_0 = 0x3039, // 12345 math constKeys_1 = 0x10932,// 67890 math constKeys_2 = 0x7AB7 // 31415 xmath keys_0 "constKeys_0 ^ KEY0" xmath keys_1 "constKeys_1 ^ KEY1" xmath keys_2 "constKeys_2 ^ KEY2" get MEM_SIZE asize MEMORY_FILE for j = 0 < MEM_SIZE getvarchr data MEMORY_FILE j xmath data "data ^ (((keys_1 ^ keys_0 ^ keys_2) >> 24) & 0xff)" putvarchr MEMORY_FILE j data xmath keys_0 "(0x343fd * keys_0 + 0x269ec3) & 0xFFFFFFFF" xmath keys_1 "(0x343fd * keys_1 + 0x269ec3) & 0xFFFFFFFF" xmath keys_2 "(0x343fd * keys_2 + 0x269ec3) & 0xFFFFFFFF" next j get NAME basename string NAME + ".dat" log NAME 0 SIZE MEMORY_FILE
the resulting file is gzip compressed.
its code from this php script.
https://gist.github.com/esterTion/ff57a ... 004fc25536
aluigi
Site Admin
Posts: 12984 Joined: Wed Jul 30, 2014 9:32 pm
Post
by aluigi » Mon Oct 14, 2019 6:17 am
The only solution for improving performances is using C code embedded in a MEMORY_FILE and called with calldll.
chrrox
Posts: 388 Joined: Thu Aug 07, 2014 10:28 pm
Post
by chrrox » Mon Oct 14, 2019 1:07 pm
ah that worked great much faster now
Code: Select all
set MEMORY_FILE10 string " typedef unsigned char uchar; typedef unsigned int uint; int ll_decrypt(unsigned char *data, int size, int keys_0, int keys_1, int keys_2) { int i; for(i = 0; i < size; i++) { uchar c = data[i]; data[i] = data[i] ^ (((keys_1 ^ keys_0 ^ keys_2) >> 24) & 0xff); keys_0 = (0x343fd * keys_0 + 0x269ec3) & 0xFFFFFFFF; keys_1 = (0x343fd * keys_1 + 0x269ec3) & 0xFFFFFFFF; keys_2 = (0x343fd * keys_2 + 0x269ec3) & 0xFFFFFFFF; } } "