Legend Of Silkroad (LOS) .steamer file

Network protocols, internals and low-level information about games
blar0
Posts: 2
Joined: Fri Aug 08, 2014 12:13 pm

Legend Of Silkroad (LOS) .steamer file

Post by blar0 »

Hi,

I don't know if this should be post in this section or not.

Legend of Silkroad was released August 27, 2014. I downloaded the client downloader and was wondering what they were using.

Code: Select all

LOS_FullClient_Downloader.exe
md5  : F03B629D8DB6AAF12F57D1B6893B7F36
sha1 :EE17AFF29C24A52EA3C6FC69BCFBB9D6D9FC255A
Original Filename : SteamerWinClient.exe


The first thing this client do his downloading configuration for the desired game. In our case:

Code: Select all

http://p2p.jcplanet.com:8080/Admin/Interface/GetConfigureationInfo.aspx?serviceId=LOS_FullClient


Inside this file configuration we can see a MetaInfoFileURL:

Code: Select all

Steamer/MetaInfoFileURL         = http://p2p.jcplanet.com:8080/admin/MetaFile/LOS_FullClient_LOS_SetupEN_V1.1.81.exe.steamer


This type of file looks like a .torrent file.
Here are the spec (data stored in little endian):

Code: Select all

STEAMER:
+ 0x00 : Nb_files       [DWORD]
+ 0x04 : File_Entry     [FILE_ENTRY] * Nb_files
   
FILE_ENTRY:
+ 0x00       : STR_W_LENGTH [WORD]
+ 0x02       : STR_W        [BYTE] * STR_W_LENGTH
+ 0xXX       : FILE_SIZE    [DWORD64]
+ 0xXX + 8   : NB_BLOCK     [DWORD]
+ 0xXX + 0xC : SIZE_BLOCK   [DWORD]
+ 0xXX + 0x10: SHA_1_BLOCKS [BYTE] * 0x14 * NB_BLOCK   // Array of sha1 for each block
+ 0xXX       : SHA_1        [BYTE] * 0x14            // sha1 of SHA_1_BLOCKS


Here a python script to convert .steamer file to .torrent file using python construct module (https://pypi.python.org/pypi/construct/2.5.2):

Code: Select all

import construct

FILE_NAME = "LOS_FullClient_LOS_SetupEN_v1.0.354.exe.steamer"
TRACKER_URL = "http://p2p.jcplanet.com:8080/tracker/announce.aspx"
HTTP_SEED_URL = "http://p2pseedclient-1.cloudapp.net:8080/los/fullclient/LOS_SetupEN_V1.0.354.exe"

Fentry = construct.Struct("Fentry",
    construct.ULInt16("length"),
    construct.Bytes("data", lambda ctx: ctx.length + 2),
    construct.ULInt64("size"),
    construct.ULInt32("nb_block"),
    construct.ULInt32("size_block"),
    construct.Array(lambda ctx: ctx.nb_block, construct.Bytes("sha1", 20)))

Steamer = construct.Struct("Steamer",
    construct.ULInt32("nb_files"),
    construct.Array(lambda ctx: ctx.nb_files, Fentry))

fd_in = open(FILE_NAME, "rb")
data = fd_in.read()
fd_in.close()

f = Steamer.parse(data)
file_name = f['Fentry'][0]['data'].replace('\x00', '')
size_file = f['Fentry'][0]['size']
nb_block = f['Fentry'][0]['nb_block']
size_block = f['Fentry'][0]['size_block']

print "[+] filename   = %s" % file_name
print "[+] size_file  = 0x%X" % (size_file)
print "[+] nb_block   = 0x%X" % nb_block
print "[+] size_block = 0x%X" % size_block

# http://en.wikipedia.org/wiki/Bencode
fd_out = open(file_name + ".torrent", "wb")
fd_out.write("d8:announce%d:%s" % (len(TRACKER_URL), TRACKER_URL))
fd_out.write("8:encoding5:UTF-84:infod6:lengthi%de" % size_file)
fd_out.write("4:name%d:%s" % (len(file_name), file_name))
fd_out.write("12:piece lengthi%de" % size_block)
fd_out.write("6:pieces%d:" % (nb_block * 20))
for i in f['Fentry'][0]['sha1']:
    fd_out.write(i)
fd_out.write("e8:url-listl%d:%see" % (len(HTTP_SEED_URL), HTTP_SEED_URL))
fd_out.close()
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Legend Of Silkroad (LOS) .steamer file

Post by aluigi »

Yes, correct section.
And good job :)