воскресенье, 24 июня 2012 г.

python pickle search (WoTReplay files)

провел небольшой анализ распакованных файлов реплеев.
В этих файлах содержаться сохраненные pickle данные их примерно(!) можно найти по сигнатуре 80 02
я решил  читать файл со смещением один байт и пробовать загрузить pickle данные, чтобы найти все сохраненные таким образом объекты.

import pickle
def unpickle(file):
    f = open(file,'rb')
    g = 0
    seg = f.tell()
    bb = f.read()
    while bb != b'' :
        seg += 1
        f.seek(seg+1)
        try:
            o = pickle.loads(bb)
            g += 1
            print g, hex(int(seg)-2)
            print o print "\n---------------------\n"
        except:
            pass
        bb = f.read()
unpickle("unpack.wotreplay")
Этот python скрипт будет искать все pickle данные в файле. про сигнатуру выше написано не совсем верно.

четверг, 14 июня 2012 г.

WoT Replay unpacker

Небольшая программка для распаковки replay файлов.
simple console application for unpack Worlds of Tank Replay Files.
download wotreplay_unpacker
Распакованный replay файл проигрывается клиентом игры!!!


понедельник, 11 июня 2012 г.

WoT Replay format

есть такая замечательная игра World of Tanks (0.7.3) Клиент игры умеет записывать реплеи боев. Во время боя создается файл (temp.wotreplay ???) так вот пока бой не закончен файл можно скопировать (потом пригодится :)) как только бой окончен начинаются чудеса: файл сжимается и переименовывается :(
Про просмотре hex редактором полученного файла в нем явно видно две части:
- 1ая текстовые данные о бое в JSON формате (данных о бое много: все ники игрков, команды, кланы, дамаг кадого, прибыль за бой и т. д.)
- 2ая явно выраженный архив.

посмотрев в отладчик можно заметить что 2ая часть это не просто архив, а зашифрованный (BLOWFISH) архив.

Собственно ключ (BF_KEY):
DE 72 BE A0 DE 04 BE B1 DE FE BE EF DE AD BE EF

процесс восстановления выглядит так blowfish - XOR (!!!) - zlib
расшиврованные данные надо ещё поксорить а потом расжать zlib'ом
В итоге получим файл идентичный тому временному файлу который записывался во время боя.

Что не может не радовать - так это то что расшиврованный / распакованный файл проигрывается клиентом успешно без лишних манипуляций :)

Посмотрев hex редактором на этот файл можно заметить заголовловок и дамп python объектов (pickle) которые представляют собой объекты игры и их сценарии поведения.

--------------------------------------------------------------------------------------------------
void BF_set_key(BF_KEY *key, int len, const unsigned char *data);
--------------------------------------------------------------------------------------------------
00CA77EE $-FF25 B853E600 JMP DWORD PTR DS:[<&LIBEAY32.#46>] ; LIBEAY32.BF_set_key
STACK:
0012EE20 008A961F RETURN to WORLDOFT.008A961F from <JMP.&LIBEAY32.#46>
0012EE24 0C3BA778 -> BF_KEY *key
0012EE28 00000010 -> int len
0012EE2C 08B51170 -> const unsigned char *data

[PASSWD]
08B51170 DE 72 BE A0 DE 04 BE B1 DE FE BE EF DE AD BE EF ▐r╛á▐ ╛▒▐■╛∩▐¡╛∩


--------------------------------------------------------------------------------------------------
void BF_decrypt(BF_LONG *data,const BF_KEY *key);
--------------------------------------------------------------------------------------------------
0222A9E9 E8 6D040000 CALL LIBEAY32.BF_decrypt

STACK:
0012EE1C 0012EE24 -> BF_LONG *data
0012EE20 0C3BA778 -> *data,const BF_KEY *key
0012EE24 B45E3A69 ---- 1st 64 bit(8 byte) to decrypt