Hi.
Anybody know how to extract these .PAK files?
Samples: http://66.7.218.134/~usaportu/pub/Paks.rar
Important information: this site is currently scheduled to go offline indefinitely by end of the year.
Cities XL .PAK files
- aluigi
- VVIP member
- Posts: 1916
- Joined: Thu Dec 08, 2005 12:26 pm
- Location: www.ZENHAX.com
- Has thanked: 4 times
- Been thanked: 664 times
- Contact:
Re: Cities XL .PAK files
the only problem there is the file table which is obfuscated so it's not possible to retrieve the names of the file, while there is no problem for the content which is simply zipped (job for offzip).
maybe there is a bit of luck if you post also the executable of the game (although I highly doubt because it's a debugging job).
maybe there is a bit of luck if you post also the executable of the game (although I highly doubt because it's a debugging job).
-
- Site Admin
- Posts: 4073
- Joined: Wed Jan 15, 2003 6:45 pm
- Location: Dungeons of Doom
- Has thanked: 450 times
- Been thanked: 682 times
- Contact:
Re: Cities XL .PAK files
Yes, the file table is at the end of the files, pointed to by a variable at the beginning. It's encrypted by some process. The resources can simply by unzlibbed, but it's a bit annoying to do, as you don't know the size of the compressed resources.
-
- Site Admin
- Posts: 4073
- Joined: Wed Jan 15, 2003 6:45 pm
- Location: Dungeons of Doom
- Has thanked: 450 times
- Been thanked: 682 times
- Contact:
Re: Cities XL .PAK files
Well, it looks like the first encrypted part in the header might be decrypted from this piece of asm in core_vr.dll
Code: Select all
.text:10065990 ; class stlp_std::basic_string<char, class stlp_std::char_traits<char>, class stlp_std::allocator<char>> __cdecl mcPack_namespace::SHA1toStr(unsigned char * const)
.text:10065990 ?SHA1toStr@mcPack_namespace@@YA?AV?$basic_string@DV?$char_traits@D@stlp_std@@V?$allocator@D@2@@stlp_std@@QAE@Z_0 proc near
.text:10065990 ; CODE XREF: mcPack_namespace::SHA1toStr(uchar * const)j
.text:10065990
.text:10065990 var_55 = byte ptr -55h
.text:10065990 var_54 = dword ptr -54h
.text:10065990 var_44 = dword ptr -44h
.text:10065990 var_3C = byte ptr -3Ch
.text:10065990 var_14 = dword ptr -14h
.text:10065990 var_10 = dword ptr -10h
.text:10065990 var_C = dword ptr -0Ch
.text:10065990 var_4 = dword ptr -4
.text:10065990 arg_0 = dword ptr 4
.text:10065990 arg_4 = dword ptr 8
.text:10065990
.text:10065990 push 0FFFFFFFFh
.text:10065992 push offset loc_100DD5C9
.text:10065997 mov eax, large fs:0
.text:1006599D push eax
.text:1006599E sub esp, 4Ch
.text:100659A1 mov eax, dword_101271F8
.text:100659A6 xor eax, esp
.text:100659A8 mov [esp+58h+var_10], eax
.text:100659AC push ebx
.text:100659AD push ebp
.text:100659AE push esi
.text:100659AF push edi
.text:100659B0 mov eax, dword_101271F8
.text:100659B5 xor eax, esp
.text:100659B7 push eax
.text:100659B8 lea eax, [esp+6Ch+var_C]
.text:100659BC mov large fs:0, eax
.text:100659C2 mov eax, [esp+6Ch+arg_4]
.text:100659C6 movzx edx, byte ptr [eax+2]
.text:100659CA xor ecx, ecx
.text:100659CC mov ch, [eax]
.text:100659CE movzx edi, byte ptr [eax+6]
.text:100659D2 movzx ebx, byte ptr [eax+0Ah]
.text:100659D6 mov cl, [eax+1]
.text:100659D9 mov esi, [esp+6Ch+arg_0]
.text:100659DD mov [esp+6Ch+var_54], 0
.text:100659E5 shl ecx, 8
.text:100659E8 or ecx, edx
.text:100659EA movzx edx, byte ptr [eax+3]
.text:100659EE shl ecx, 8
.text:100659F1 or ecx, edx
.text:100659F3 xor edx, edx
.text:100659F5 mov dh, [eax+4]
.text:100659F8 mov dl, [eax+5]
.text:100659FB shl edx, 8
.text:100659FE or edx, edi
.text:10065A00 movzx edi, byte ptr [eax+7]
.text:10065A04 shl edx, 8
.text:10065A07 or edi, edx
.text:10065A09 xor edx, edx
.text:10065A0B mov dh, [eax+8]
.text:10065A0E mov dl, [eax+9]
.text:10065A11 shl edx, 8
.text:10065A14 or edx, ebx
.text:10065A16 movzx ebx, byte ptr [eax+0Bh]
.text:10065A1A shl edx, 8
.text:10065A1D or edx, ebx
.text:10065A1F movzx ebx, byte ptr [eax+0Eh]
.text:10065A23 mov ebp, edx
.text:10065A25 xor edx, edx
.text:10065A27 mov dh, [eax+0Ch]
.text:10065A2A mov dl, [eax+0Dh]
.text:10065A2D shl edx, 8
.text:10065A30 or edx, ebx
.text:10065A32 movzx ebx, byte ptr [eax+0Fh]
.text:10065A36 shl edx, 8
.text:10065A39 or edx, ebx
.text:10065A3B movzx ebx, byte ptr [eax+12h]
.text:10065A3F mov [esp+6Ch+var_44], edx
.text:10065A43 xor edx, edx
.text:10065A45 mov dh, [eax+10h]
.text:10065A48 mov dl, [eax+11h]
.text:10065A4B movzx eax, byte ptr [eax+13h]
.text:10065A4F shl edx, 8
.text:10065A52 or edx, ebx
.text:10065A54 shl edx, 8
.text:10065A57 or eax, edx
.text:10065A59 mov edx, [esp+6Ch+var_44]
.text:10065A5D push eax
.text:10065A5E push edx
.text:10065A5F push ebp
.text:10065A60 push edi
.text:10065A61 push ecx
.text:10065A62 lea eax, [esp+80h+var_3C]
.text:10065A66 push offset a08x08x08x08x08 ; "%08X%08X%08X%08X%08X"
.text:10065A6B push eax ; char *
.text:10065A6C call ds:sprintf
.text:10065A72 xor ebx, ebx
.text:10065A74 add esp, 1Ch
.text:10065A77 lea ecx, [esp+6Ch+var_55]
.text:10065A7B mov byte ptr [esp+6Ch+var_14], bl
.text:10065A7F call ds:??0?$allocator@D@stlp_std@@QAE@XZ ; stlp_std::allocator<char>::allocator<char>(void)
.text:10065A85 push eax
.text:10065A86 lea ecx, [esp+70h+var_3C]
.text:10065A8A push ecx
.text:10065A8B mov ecx, esi
.text:10065A8D mov [esp+74h+var_4], ebx
.text:10065A91 call ds:??0?$basic_string@DV?$char_traits@D@stlp_std@@V?$allocator@D@2@@stlp_std@@QAE@PBDABV?$allocator@D@1@@Z ; stlp_std::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>(char const *,basic_string<char,stlp_std::char_traits<char>,stlp_std::allocator<char>>::allocator<char> const &)
.text:10065A97 lea ecx, [esp+6Ch+var_55]
.text:10065A9B call ds:??1?$allocator@D@stlp_std@@QAE@XZ ; stlp_std::allocator<char>::~allocator<char>(void)
.text:10065AA1 mov eax, esi
.text:10065AA3 mov ecx, [esp+6Ch+var_C]
.text:10065AA7 mov large fs:0, ecx
.text:10065AAE pop ecx
.text:10065AAF pop edi
.text:10065AB0 pop esi
.text:10065AB1 pop ebp
.text:10065AB2 pop ebx
.text:10065AB3 mov ecx, [esp+58h+var_10]
.text:10065AB7 xor ecx, esp
.text:10065AB9 call sub_100D36BC
.text:10065ABE add esp, 58h
.text:10065AC1 retn
.text:10065AC1 ?SHA1toStr@mcPack_namespace@@YA?AV?$basic_string@DV?$char_traits@D@stlp_std@@V?$allocator@D@2@@stlp_std@@QAE@Z_0 endp
.text:10065AC1
.text:10065AC1 ; ---------------------------------------------------------------------------
- aluigi
- VVIP member
- Posts: 1916
- Joined: Thu Dec 08, 2005 12:26 pm
- Location: www.ZENHAX.com
- Has thanked: 4 times
- Been thanked: 664 times
- Contact:
Re: Cities XL .PAK files
I don't know if I rock or I'm simply lucky but I saw that in core.dll was used the CryptDecrypt function of Windows and looking a bit there I found the string "allocator" so I decided to see if I was so lucky to have catched the right decryption and... yes :)
the following is the part of C code for the decryption:*edit* updated the code so it's just a stand-alone function
the following is the part of C code for the decryption:
Code: Select all
int citiesxl_decrypt(unsigned char *data, int datalen) {
unsigned char key[] = "allocator";
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
DWORD len;
len = datalen;
if(!CryptAcquireContext(
&hProv,
NULL,
MS_ENHANCED_PROV,
PROV_RSA_FULL,
0)) return(-1);
if(!CryptCreateHash(
hProv,
CALG_MD5,
0,
0,
&hHash)) return(-1);
if(!CryptHashData(
hHash,
key,
strlen(key),
0)) return(-1);
if(!CryptDeriveKey(
hProv,
CALG_RC4,
hHash,
0x00800000,
&hKey)) return(-1);
if(!CryptDecrypt(
hKey,
0,
TRUE,
0,
data,
&len)) return(-1);
CryptDestroyKey(hKey);
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return(0);
}
-
- Site Admin
- Posts: 4073
- Joined: Wed Jan 15, 2003 6:45 pm
- Location: Dungeons of Doom
- Has thanked: 450 times
- Been thanked: 682 times
- Contact:
Re: Cities XL .PAK files
Nice work! I'd seen that one as well, but did not get round to it to take a good look at it. Seems the game uses a lot - A LOT - of standard Windows functions + a great deal of open source code. The whole game.exe is a collection of declarations to the huge number of dlls the game uses. haha.
Anyway, do you have a complete working piece of code to decrypt a buffer that way?
Anyway, do you have a complete working piece of code to decrypt a buffer that way?
- aluigi
- VVIP member
- Posts: 1916
- Joined: Thu Dec 08, 2005 12:26 pm
- Location: www.ZENHAX.com
- Has thanked: 4 times
- Been thanked: 664 times
- Contact:
Re: Cities XL .PAK files
I have the full BMS script for doing it :)
*edit, was updated to version 0.1.1*
http://aluigi.org/papers/bms/citiesxl.bms
*edit, was updated to version 0.1.1*
http://aluigi.org/papers/bms/citiesxl.bms
Last edited by aluigi on Sun Mar 14, 2010 11:36 am, edited 1 time in total.
-
- Site Admin
- Posts: 4073
- Joined: Wed Jan 15, 2003 6:45 pm
- Location: Dungeons of Doom
- Has thanked: 450 times
- Been thanked: 682 times
- Contact:
Re: Cities XL .PAK files
Awesome. It's great to see that no job is too difficult here at our forum .
I've attached all unpacked files from the .PAK examples in the first post in this thread.
That will help studying the game engine.
The jpgs:
test1.mission (XML)
cityresourcesconsumption.xml:
I've attached all unpacked files from the .PAK examples in the first post in this thread.
That will help studying the game engine.
The jpgs:
test1.mission (XML)
Code: Select all
<?xml version="1.0" encoding="Windows-1252" ?>
- <mission>
<statetypes>PLAY,</statetypes>
<filter>""</filter>
<synchronisation>TIME_BASED</synchronisation>
<period>1</period>
<scene>GAME</scene>
<version>7</version>
- <bloc>
<type>OBJECTIVE</type>
<realisation>AND_R</realisation>
<fncheck>localCounter = ( localCounter or 0 ) + 1 LOG_INFO( "localCounter = " .. localCounter ) return ( localCounter == 10 )</fncheck>
<fnrealize>LOG_INFO( "[test01] objective has been realized, localCounter = " .. localCounter )</fnrealize>
<flags>""</flags>
</bloc>
</mission>
Code: Select all
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>
- <resources>
- <consumption>
- <citizenrange min="0" max="0">
- <resources>
<RELE_0>600</RELE_0>
<RFUE_0>1000</RFUE_0>
<RWAT_0>400</RWAT_0>
<RWAS_0>800</RWAS_0>
<RFRE_0>1000</RFRE_0>
<RHOL_1>100</RHOL_1>
<RPAS_0>1000</RPAS_0>
<ROFF_0>1000</ROFF_0>
<RHOT_0>100</RHOT_0>
<RIN1_0>1000</RIN1_0>
<RIN2_0>1000</RIN2_0>
<RIN3_0>1000</RIN3_0>
<RAGR_0>1000</RAGR_0>
<RRET_1>0</RRET_1>
<RLEI_1>300</RLEI_1>
</resources>
</citizenrange>
- <citizenrange min="1" max="135">
- <resources>
<RELE_0>668</RELE_0>
<RFUE_0>1068</RFUE_0>
<RWAT_0>468</RWAT_0>
<RWAS_0>868</RWAS_0>
<RFRE_0>1068</RFRE_0>
<RHOL_1>168</RHOL_1>
<RPAS_0>1068</RPAS_0>
<ROFF_0>1945</ROFF_0>
<RHOT_0>127</RHOT_0>
<RIN1_0>2945</RIN1_0>
<RIN2_0>1000</RIN2_0>
<RIN3_0>1000</RIN3_0>
<RAGR_0>1068</RAGR_0>
<RRET_1>270</RRET_1>
<RLEI_1>300</RLEI_1>
</resources>
</citizenrange>
- <citizenrange min="136" max="243">
- <resources>
<RELE_0>722</RELE_0>
<RFUE_0>1122</RFUE_0>
<RWAT_0>522</RWAT_0>
<RWAS_0>922</RWAS_0>
<RFRE_0>1122</RFRE_0>
<RHOL_1>222</RHOL_1>
<RPAS_0>1122</RPAS_0>
<ROFF_0>2701</ROFF_0>
<RHOT_0>149</RHOT_0>
<RIN1_0>3701</RIN1_0>
<RIN2_0>2701</RIN2_0>
<RIN3_0>1000</RIN3_0>
<RAGR_0>1122</RAGR_0>
<RRET_1>486</RRET_1>
<RLEI_1>570</RLEI_1>
</resources>
</citizenrange>
- <citizenrange min="244" max="381">
- <resources>
<RELE_0>791</RELE_0>
<RFUE_0>1191</RFUE_0>
<RWAT_0>591</RWAT_0>
<RWAS_0>991</RWAS_0>
<RFRE_0>1191</RFRE_0>
<RHOL_1>291</RHOL_1>
<RPAS_0>1191</RPAS_0>
<ROFF_0>3667</ROFF_0>
<RHOT_0>176</RHOT_0>
<RIN1_0>3667</RIN1_0>
<RIN2_0>3667</RIN2_0>
<RIN3_0>3667</RIN3_0>
<RAGR_0>1191</RAGR_0>
<RRET_1>762</RRET_1>
<RLEI_1>786</RLEI_1>
</resources>
</citizenrange>
- <citizenrange min="382" max="595">
- <resources>
<RELE_0>898</RELE_0>
<RFUE_0>1298</RFUE_0>
<RWAT_0>698</RWAT_0>
<RWAS_0>1098</RWAS_0>
<RFRE_0>1298</RFRE_0>
<RHOL_1>398</RHOL_1>
<RPAS_0>1298</RPAS_0>
<ROFF_0>5165</ROFF_0>
<RHOT_0>219</RHOT_0>
<RIN1_0>5165</RIN1_0>
<RIN2_0>5165</RIN2_0>
<RIN3_0>5165</RIN3_0>
<RAGR_0>1298</RAGR_0>
<RRET_1>1190</RRET_1>
<RLEI_1>1062</RLEI_1>
</resources>
</citizenrange>
- <citizenrange min="596" max="1075">
- <resources>
<RELE_0>1138</RELE_0>
<RFUE_0>1538</RFUE_0>
<RWAT_0>938</RWAT_0>
<RWAS_0>1338</RWAS_0>
<RFRE_0>1538</RFRE_0>
<RHOL_1>638</RHOL_1>
<RPAS_0>1538</RPAS_0>
<ROFF_0>8525</ROFF_0>
<RHOT_0>315</RHOT_0>
<RIN1_0>8525</RIN1_0>
<RIN2_0>8525</RIN2_0>
<RIN3_0>8525</RIN3_0>
<RAGR_0>1538</RAGR_0>
<RRET_1>2150</RRET_1>
<RLEI_1>1490</RLEI_1>
</resources>
</citizenrange>
- <citizenrange min="1076" max="1397">
- <resources>
<RELE_0>1299</RELE_0>
<RFUE_0>1699</RFUE_0>
<RWAT_0>1099</RWAT_0>
<RWAS_0>1499</RWAS_0>
<RFRE_0>1699</RFRE_0>
<RHOL_1>799</RHOL_1>
<RPAS_0>1699</RPAS_0>
<ROFF_0>10779</ROFF_0>
<RHOT_0>379</RHOT_0>
<RIN1_0>10779</RIN1_0>
<RIN2_0>10779</RIN2_0>
<RIN3_0>10779</RIN3_0>
<RAGR_0>1699</RAGR_0>
<RRET_1>2794</RRET_1>
<RLEI_1>2450</RLEI_1>
</resources>
</citizenrange>
- <citizenrange min="1398" max="1682">
- <resources>
<RELE_0>1441</RELE_0>
<RFUE_0>1841</RFUE_0>
<RWAT_0>1241</RWAT_0>
<RWAS_0>1641</RWAS_0>
<RFRE_0>1841</RFRE_0>
<RHOL_1>941</RHOL_1>
<RPAS_0>1841</RPAS_0>
<ROFF_0>12774</ROFF_0>
<RHOT_0>436</RHOT_0>
<RIN1_0>12774</RIN1_0>
<RIN2_0>12774</RIN2_0>
<RIN3_0>12774</RIN3_0>
<RAGR_0>1841</RAGR_0>
<RRET_1>3364</RRET_1>
<RLEI_1>3094</RLEI_1>
</resources>
</citizenrange>
- <citizenrange min="1683" max="2185">
- <resources>
<RELE_0>1693</RELE_0>
<RFUE_0>2093</RFUE_0>
<RWAT_0>1493</RWAT_0>
<RWAS_0>1893</RWAS_0>
<RFRE_0>2093</RFRE_0>
<RHOL_1>1193</RHOL_1>
<RPAS_0>2093</RPAS_0>
<ROFF_0>16295</ROFF_0>
<RHOT_0>537</RHOT_0>
<RIN1_0>16295</RIN1_0>
<RIN2_0>16295</RIN2_0>
<RIN3_0>16295</RIN3_0>
<RAGR_0>2093</RAGR_0>
<RRET_1>4370</RRET_1>
<RLEI_1>3664</RLEI_1>
</resources>
</citizenrange>
- <citizenrange min="2186" max="4751">
- <resources>
<RELE_0>2976</RELE_0>
<RFUE_0>3376</RFUE_0>
<RWAT_0>2776</RWAT_0>
<RWAS_0>3176</RWAS_0>
<RFRE_0>3376</RFRE_0>
<RHOL_1>2476</RHOL_1>
<RPAS_0>3376</RPAS_0>
<ROFF_0>34257</ROFF_0>
<RHOT_0>1050</RHOT_0>
<RIN1_0>34257</RIN1_0>
<RIN2_0>34257</RIN2_0>
<RIN3_0>34257</RIN3_0>
<RAGR_0>3376</RAGR_0>
<RRET_1>9502</RRET_1>
<RLEI_1>4670</RLEI_1>
</resources>
</citizenrange>
- <citizenrange min="4752" max="6171">
- <resources>
<RELE_0>3686</RELE_0>
<RFUE_0>4086</RFUE_0>
<RWAT_0>3486</RWAT_0>
<RWAS_0>3886</RWAS_0>
<RFRE_0>4086</RFRE_0>
<RHOL_1>3186</RHOL_1>
<RPAS_0>4086</RPAS_0>
<ROFF_0>44197</ROFF_0>
<RHOT_0>1334</RHOT_0>
<RIN1_0>44197</RIN1_0>
<RIN2_0>44197</RIN2_0>
<RIN3_0>44197</RIN3_0>
<RAGR_0>4086</RAGR_0>
<RRET_1>12342</RRET_1>
<RLEI_1>9802</RLEI_1>
</resources>
</citizenrange>
- <citizenrange min="6172" max="7430">
- <resources>
<RELE_0>4315</RELE_0>
<RFUE_0>4715</RFUE_0>
<RWAT_0>4115</RWAT_0>
<RWAS_0>4515</RWAS_0>
<RFRE_0>4715</RFRE_0>
<RHOL_1>3815</RHOL_1>
<RPAS_0>4715</RPAS_0>
<ROFF_0>53010</ROFF_0>
<RHOT_0>1586</RHOT_0>
<RIN1_0>53010</RIN1_0>
<RIN2_0>53010</RIN2_0>
<RIN3_0>53010</RIN3_0>
<RAGR_0>4715</RAGR_0>
<RRET_1>14860</RRET_1>
<RLEI_1>12642</RLEI_1>
</resources>
</citizenrange>
- <citizenrange min="7431" max="11619">
- <resources>
<RELE_0>6410</RELE_0>
<RFUE_0>6810</RFUE_0>
<RWAT_0>6210</RWAT_0>
<RWAS_0>6610</RWAS_0>
<RFRE_0>6810</RFRE_0>
<RHOL_1>5910</RHOL_1>
<RPAS_0>6810</RPAS_0>
<ROFF_0>82333</ROFF_0>
<RHOT_0>2424</RHOT_0>
<RIN1_0>82333</RIN1_0>
<RIN2_0>82333</RIN2_0>
<RIN3_0>82333</RIN3_0>
<RAGR_0>6810</RAGR_0>
<RRET_1>23238</RRET_1>
<RLEI_1>15160</RLEI_1>
</resources>
</citizenrange>
</consumption>
- <pricelevels>
- <verylow>
<percent>3</percent>
</verylow>
- <low>
<percent>2</percent>
</low>
- <medium>
<percent>1</percent>
</medium>
- <high>
<percent>0.5</percent>
</high>
- <veryhigh>
<percent>0.33</percent>
</veryhigh>
</pricelevels>
</resources>
You do not have the required permissions to view the files attached to this post.
-
- Site Admin
- Posts: 4073
- Joined: Wed Jan 15, 2003 6:45 pm
- Location: Dungeons of Doom
- Has thanked: 450 times
- Been thanked: 682 times
- Contact:
Re: Cities XL .PAK files
http://www.xentax.com
I've also added you to the team list, btw : http://www.xentax.com/?page_id=106
I've also added you to the team list, btw : http://www.xentax.com/?page_id=106
Re: Cities XL .PAK files
Bugtest your a bloody legend mate thanks a million for that script...
All textures and sounds successfully extracted
Still waiting on my damn key for this game though... really want to try it out
-jenx
All textures and sounds successfully extracted
Still waiting on my damn key for this game though... really want to try it out
-jenx
Re: Cities XL .PAK files
Thanks, nice work....
However, it doesn't seem to work on the big 'all_sgbin.pak' file.
However, it doesn't seem to work on the big 'all_sgbin.pak' file.
Any fixes?offset filesize filename
------------------------------
24c13670 841357 data/gfx/building/b_ressource_t1.sgbin
Error: the compressed zlib/deflate input is wrong or incomplete
- aluigi
- VVIP member
- Posts: 1916
- Joined: Thu Dec 08, 2005 12:26 pm
- Location: www.ZENHAX.com
- Has thanked: 4 times
- Been thanked: 664 times
- Contact:
Re: Cities XL .PAK files
do the following:
- open citiesxl.bms with notepad
- add the following string "before" the clog command at the end like in the following example:- now launch the tool as usual (although would be faster to do it with the -l for listing the files) and then paste here the content of the quickbms output for the last files so I can verify it.
- open citiesxl.bms with notepad
- add the following string "before" the clog command at the end like in the following example:
Code: Select all
print "%DUMMY% %ZSIZE% %SIZE%"
clog NAME OFFSET ZSIZE SIZE