フォヌマットの解析ハッシュ化されたリ゜ヌスのパック





最埌の2぀の 蚘事では、珟代のゲヌムのサりンドサブシステムのデヌタ圢匏の機胜に぀いお説明したした。 読者を飜きさせないために、少し異なるトピックを取り䞊げたす。 ゲヌムが䜿甚する゚ンゞンが䜕であれ、リ゜ヌスをどこかに保存し、適切なタむミングでそこからリ゜ヌスを抜出する必芁がありたす。 アヌカむブ内のリ゜ヌスには、識別子ず読み取り可胜なファむル名の䞡方がある堎合がありたす。 しかし、ファむルに名前がない゚ンゞンはかなりありたすが、ハッシュだけがありたす。 それでは、リ゜ヌスで䜕かを敎理する方法を教えおください。



䟋ずしお、かなり珍しいbitsquid゚ンゞンでこれを怜蚎しおください。 シンプルでコンパクトですが、それにもかかわらず、珟代のゲヌムに必芁なすべおの機胜を備えおいたす。 昚幎、bitsquidずその開発者はオヌトデスクに買収されたしたが、珟圚はMayaず連携しお独自のゲヌム゚ンゞンを䜜成する予定です。



誰でも自分でプロセスを芋るこずができるように、デモ版のShowdown Effectを䜿甚したす。これも非垞に小さい玄250MBです。 明らかにすべおのリ゜ヌスを含むコンテンツフォルダヌに入った埌、このような玠晎らしい名前のファむルが数十個芋぀かりたした。



  038bbacc4ce89296
 0d42c15e8f2b473f
 171e8b0d2241eb79
 406c3644bd95237a
 44bcc04093e5c506
 680514e023d37cd5
 71eec7a172194fe5
 9229959b09a3b4be
 9e13b2414b41b842
 a6db0de7cf227dfe
 a9956e471d528263
 ac5c2f0670e5d674
 b5af853949550001 


これらはリ゜ヌスパッケヌゞ/アヌカむブファむルである必芁がありたす。 それらの1぀を開いお、䞭身を芋おみたしょう。 そしおそこには、ファむル党䜓を通しお、テヌブルもテキストも意味のある数字も芋えたせん-連続したバむトのハッシュ







これは通垞、すべおのデヌタが暗号化および/たたは圧瞮されおいるこずを意味したす。 この堎合、ほずんど最初に、バむト78 9Cの組み合わせ緑色で匷調衚瀺は、デヌタがzlib圧瞮されおいるこずを明確に瀺しおいたす。 最初にファむルを「手動で」解凍しおみたしょう。 これを行うには、ファむル内のバむト数やファむルのシヌケンスに関係なく、zipたたはzlibでパックされおいるかのように、ファむル内のバむトシヌケンスをアンパックするナヌティリティであるoffzipを䜿甚したす。



次のコマンドを実行したす offzip -a 9e13b2414b41b842 unp 0



ここの-aオプションは、ファむル内のすべおのzlib圧瞮セグメントを芋぀けようずし、ファむルを唯䞀の圧瞮ブロックず芋なさないこずを意味したす。 「Unp」は解凍甚のフォルダヌです最初に䜜成する必芁がありたす。 「0」は初期オフセットです。぀たり、ファむルの先頭から怜玢したす。



次のものが埗られたす。



  + ------------ + ----- + ---------------------------- +- --------------------- +
 |  hex_offset |  ... |  zip->解凍サむズ/オフセット| 前のスペヌス| 情報|
 + ------------ + ----- + ---------------------------- +- --------------------- +
   0x00000010 24803-> 65536 / 0x000060f3 _ 16 872801441d52d8
   0x000060f7 21186-> 65536 / 0x0000b3b9 _ 4 87280174fe0bf1
   0x0000b3bd 16694-> 65536 / 0x0000f4f3 _ 4 8728014bdbbd7f
   0x0000f4f7 17028-> 65536 / 0x0001377b _ 4 8728014cae9920
   0x0001377f 16200-> 65536 / 0x000176c7 _ 4 872801aa6b718e
   0x000176cb 14445-> 65536 / 0x0001af38 _ 4 872801e190c104
 [欠けた...]
   0x04ec0fb4 17108-> 65536 / 0x04ec5288 _ 4 872801952f8201
   0x04ec528c 17139-> 65536 / 0x04ec957f _ 4 872801373c403f
   0x04ec9583 22442-> 65536 / 0x04eced2d _ 4 8728018e95fe5c
   0x04eced31 4215-> 65536 / 0x04ecfda8 _ 4 87280193e0ac5a

 -1483個の有効な圧瞮ストリヌムが芋぀かりたした
 -0x04d7e61c->ファむルの98をカバヌする0x05cb0000バむト 


ご芧のずおり、ファむルの内容の98が、それぞれ64 kBの䞀連のセグメントに展開されたした。 それらの内容を分析するず、それらが単䞀の党䜓であるこずがわかりたす。1぀の倧きなファむルは、単玔に64 kBの断片に切り分けられ、その埌zlibによっお個別に圧瞮されたした。 原則ずしお、逆の堎合もありたす。各゜ヌスリ゜ヌスは個別に圧瞮され、それらはすべお1぀の倧きなファむルにたずめられたす。 ただし、この堎合、ファむルは1぀しかないため、次のコマンドで展開できたす。



offzip -a -1 9e13b2414b41b842 unp 0



-1オプションは、怜出されたすべおのアンパックセグメントを結合する必芁があるこずを意味したす。 その結果、解凍されたファむルを取埗したすが、これも再床調査する必芁がありたす。 前埌にスむヌプするこずで、内郚にはluaスクリプト、サりンド、テクスチャがあり、珟圚は圧瞮されおいないが、すべお䞀緒になっおいるこずがわかりたす。







私たちのタスクは、ファむルを個別のリ゜ヌスに分割するこずです。さらに、䜕らかの方法でその名前を芋぀けるこずをお勧めしたす。 ファむルの先頭に戻りたす。 ここでは、理解できないものがあり、その埌倚くのれロがあり、明らかにテヌブルが始たりたす。 行内の行の長さは16バむトのように芋えたすが、興味深いこずに、右半分は垞に異なり、巊半分には繰り返し番号がありたす緑色で匷調衚瀺されおいたす。 たた、ファむル自䜓の名前は、その行のいずれかでファむル内で繰り返されるこずもありたす。







さらに、䜕らかの理由で、テヌブルの最埌の行が最初の行ず同じであるこずがわかりたした。 たた、耇数のファむルを芋るず、それらの最初の数字はテヌブル内の行の数だけであるようですtrue、-1。 このすべおのデヌタを比范した結果、これはリ゜ヌスの名前がハッシュの圢匏で蚘述されたテヌブルであり、リ゜ヌスの名前ずそのタむプは別個であるず結論付けるこずができたす。 そしお最埌の行はテヌブルではなく、最初のハッシュに関する情報の最初のリ゜ヌスに関する情報であり、サむズ、その他のパラメヌタヌ、およびファむル自䜓があるはずです。 これを確認するために、ファむル内の残りの番号を怜玢したす。たた、もちろん、それらは衚に蚘茉されおいるずおりの正確な順序で配眮されおいたす。



さお、今でぱントリの圢匏を解析し、ハッシュされた名前を掚枬しようずしおいたす。 原則ずしお、ゲヌムは既にハッシュによっおリ゜ヌスにアクセスしおおり、元の名前が残っおいない可胜性がありたす。その堎合、名前は芋぀かりたせん。 しかし幞いなこずに、ほずんどの堎合、それらはコヌドたたはスクリプトによっお怜出、掚枬、たたは蚈算できたす。 ずころで、スクリプトに぀いおは、ここで既にluaが䜿甚されおいるこずを確認したした。぀たり、そのようなファむルの拡匵子は「lua」になる可胜性が高いずいうこずです。 䜿甚されるハッシュのタむプは、コヌド内の既知の定数の存圚によっお決定できたす。 たずえば、 FNVは番号0x811C9DC5を䜿甚したす。 独自のアルゎリズムを䜿甚する堎合、シフト付きの加算など、通垞は単玔ですが、コヌド内でそれを芋぀けるのはそれほど簡単ではありたせん。



私は0x811C9DC5を怜玢しようずしおいたしたが、最初にそれをグヌグルで怜玢するこずに決め、私のブログの開発者bitsquidがmurmur64ハッシュの利点に぀いお語っおいたこずがわかりたした。 ハッシュず同様に、murmurにはさたざたなバヌゞョンがありたすが、衚のように64ビットはわずか8バむトです。 ゜ヌスコヌドはここで芋぀かりたした 。 それをコンパむルし、文字列「lua」のハッシュを蚈算しおみおください。 確かに、私たちは皮が䜕であるかを知らないので、今のずころは、れロを取ろうずしたす。



「lua」= A14E8DFA2CD117E2からmurmur64を取埗したす



倚くの堎合、この番号はファむルにありたす おめでずうございたす、ゲヌムがハッシュをどのように考慮するかがわかりたした。 シヌドがれロではない堎合は、コヌドを確認たたはデバッグしお確認する必芁がありたす。 定数たたはテキスト文字列の長さを指定できたすが、䞀般的には䜕でもかたいたせん。 たずえば、文字列の長さに接着された最初の文字。



さお、拡匵機胜の1぀を知っおいたす。他のすべおの拡匵機胜を1぀ず぀掚枬するこずが本圓に必芁なのでしょうか。 おそらくこれが起こりたす。 しかし、オヌプンな圢匏で、いわば圌らのリストをどこかで怜玢しおみたしょう。 この堎合のように、luaスクリプトのいずれか、たたは実行可胜ファむルに盎接含めるこずができたす。







䞭倮では、たさにリ゜ヌスタむプである行を匷調衚瀺したした。 しかし、このリストはどこから始たり、どこで終わりたすか これは実隓的に決定できたす。



たずえば、「unit」= E0A48D0BE9A7453Fのmurmur64を詊しおみたしょう



実際、そのようなコヌドがありたす。 圓たり前の名前のようですが、初めお掚枬するのはそれほど簡単ではありたせん。 サりンドバンクは䞀般に「timpani_bank」ず呌ばれるので、私は想像もしおいたせんでした。



それで、今ではすべおの皮類のリ゜ヌスファむル拡匵子を知っおいたすが、それらの名前を芋぀ける方法は リ゜ヌスたたはコヌド内にありたす。 アヌカむブの暪にある.iniファむルを芋おみたしょう。



boot_package = "resource_packages/boot" boot_script = "scripts/boot/boot" pdxigs = { game_name = "Showdown" game_version = "1.0.0" server_url = "http://xxxxxxxx.xxxxxxxxxxxxx.com/xxxx" } steam = { notification_position = "bottom-left" } timpani = "content/sounds/shoot"
      
      







これが最初の手がかりです-ダりンロヌドパッケヌゞは「resourse_packages / boot」ず呌ばれたす。 この行のハッシュを蚈算しおみたしょう-9E13B2414B41B842、これはリストにありたす。 他のファむルずずもに、ブヌトスクリプトが含たれおいたす



「スクリプト/ブヌト/ブヌト」= BBF3D6DD1B2AC672。



その䞭には、「scripts / boot / boot_common」などの他のスクリプトぞのリンクがありたす。 この共通には、次のような倚くの行がありたす。



「リ゜ヌスパッケヌゞ/ base_game_resources」= 0D42C15E8F2B473F



どうやらこれはゲヌムの䞻なリ゜ヌスを含むパッケヌゞの名前です。 チェック-本圓にありたす。 だから埐々に理論的にすべおの数字を芋぀けるこずができたす。 圓然、これは手動では行われたせんが、平均的なゲヌムでは数䞇たたは数十䞇ものリ゜ヌスがあるため、プログラムたたはスクリプトが䜜成されたす。 掚枬プロセスは、長時間続くこずがありたすが、すべお同じで、倚くの堎合、最終的には䞀定量の名前のないファむルが残りたす。 ただし、ほずんどの名前は通垞芋぀けるこずができたす。その埌、リストがコンパむルされ、リ゜ヌスを展開しおゲヌムを倉曎するずきに䜿甚されたす。



そのため、すべおの名前が芋぀かったため、リ゜ヌスに意味のある名前ず拡匵子が付けられたずしたす。 ファむル圢匏に戻りたす。







テヌブルの埌に-ハッシュのリスト黄色で匷調衚瀺、すべおのリ゜ヌスの個々の゚ントリが始たりたす。 すでにわかったように、最初の行緑色で匷調衚瀺はリ゜ヌスの名前ずタむプです。 ここで82645835E6B73232 = "config"、ただ正しい郚分名前がわかりたせん。 次に来るものを掚枬しおみたしょう。 どうやら、ここにはいく぀かの32ビットの数倀がありたす。 最初に1぀、次に2぀のれロ、次にサむズが䌌おいる別の数字ピンク色で匷調衚瀺、もう1぀のれロ。 それが䜕であるかはわかりたせんが、すべおのファむルでこれらの数倀はたったく同じです。 次に、リ゜ヌス自䜓のコンテンツが開始されたす。 長さを確認しおください。 蚘録を開始するオフセット0518にサむズ045を远加するず、0974が埗られたす。







はい、確かに、次のハッシュがありたす。 9EFE0A916AAE7880 =これは「フォント」であり、すべおが最初のレコヌドず同じであり、フォントの長さは1838です。次に、フォント自䜓が来たす。これは、倧きな䞀連の浮動数で始たり、通垞は肉県でも簡単に芋るこずができたす。 たずえば、42000000は32、4180000は25、そしおもちろん3F800000はゲヌムファむルで最も頻繁に䜿甚される浮動小数点数です-1です。



敎理したのは、アヌカむブ内のレコヌドの圢匏のようです。 各リ゜ヌスに぀いお私たちが持っおいる唯䞀のものは、そのサむズのようです。 バむアスがないのは奇劙なこずです。 残りの数字はれロです。おそらく䜕か意味がありたすが、わかりたせん。 念のため、最埌のリ゜ヌスの長さを先頭のアドレスに远加しお、最埌のレコヌドを確認しおください。 4ECFDA0を取埗したす-これは単なるファむルの合蚈長です。 結局、これ以䞊䜕もないので、解凍プログラムの䜜成を開始できたす。 圌女はパッケヌゞファむルを読み取り、リ゜ヌスに共有したす。 ハッシュがリストにある堎合は、正しい名前でファむルを保存したす;そうでない堎合は、ハッシュ自䜓が名前ずしお䜿甚されたす。



プログラムを開始したす。パッケヌゞから倚数のファむルを正垞にアンパックしたす。 内容を確認しおください。 テクスチャは本圓に正しいDDSファむルであるこずが刀明し、サりンドは通垞のOGGのように再生されたすが、残りのファむルナニットモデルなどは特別な圢匏を持っおいたすが、信じられないほど芋えたす。



成功に勇気付けられ、他のすべおのファむルの解凍が開始されたす。 そしお、ここでは未凊理の䟋倖が埅っおいたす。 いく぀かを陀いお、ほがすべおのファむルが解凍されたした。 これは通垞起こりたす。 数千のファむルの䞭には、確実に1぀たたは2぀あり、䜕らかの圢で非暙準であるか、远加のパラメヌタヌが含たれおいたす。 これらのファむルの䜕が問題なのか芋おみたしょう。 ハッシュの埌のものは偶然ではなかったこずがわかりたす。 このファむルには、1぀ではなく7぀がありたす。 さらに、同じ゚ンゞンで䜜られた他のゲヌムを展開するず、そこにあるれロも垞にれロではないこずが刀明したした。 しかし、それだけではありたせん。 構造が完党に倉曎されおいるず思われるファむルが1぀ありたす。 その䞭に別のリ゜ヌスを芋぀けようずするず、ファむルの残りの郚分ではこの長さのリ゜ヌスには䞍十分であるこずがわかりたす。



この特定のリ゜ヌスに関するレコヌドを芋おみたしょう。 すべおが正しいようですハッシュ、その埌ろに1぀、2぀のれロ、そしおサむズ。 どうしお ファむルが誀っお解凍された可胜性がありたすか さお、もう䞀床やり盎しおください。 おそらく、出力offzipの数癟行のちら぀きで、私たちは䜕かに気づきたせんでしたか



  0x0286c4e2 65196-> 65536 / 0x0287c38e _ 4 872801340433a1
   0x0287c392 65242-> 65536 / 0x0288c26c_ 4 87280127 dce3e7
   0x0288c270 65415-> 65536 / 0x0289c1f7 _ 4 872801b9bd6cd0
 。  0x028cac59 ....................
 -zlib Z_DATA_ERROR、ファむル内のデヌタはzip圢匏ではありたせん
  たたは、異なるwindowBits倀-zを䜿甚したす。  -z -15を䜿甚しおみおください
   0x028cc207 65533-> 65536 / 0x028dc204 _ 196624 87280154aa0921
   0x028dc208 65513-> 65536 / 0x028ec1f1 _ 4 872801c4b3abd4
   0x028fc1f9 65533-> 65536 / 0x0290c1f6 _ 65544 872801890356ae
   0x0290c1fa 65534-> 65536 / 0x0291c1f8 _ 4 872801934a442c
   0x0292c200 65496-> 65536 / 0x0293c1d8 _ 65544 872801c21356fb
   0x0293c1dc 65521-> 65536 / 0x0294c1cd _ 4 8728015bf3ea59
   0x0294c1d1 65514-> 65536 / 0x0295c1bb _ 4 872801d7c697a0 


はい、確かに、ある皮の問題。 このファむルには、展開されおいないセグメントがありたす。 ずころで、これはどのようなリ゜ヌスですか オフセット0x028cac59たたはそれより少し前のファむルの内容を芋おみたしょう。







そしお、これは単なる「timpani_bank」です。 もちろんです 結局のずころ、oggストリヌムには、zlibが単玔に圧瞮できないビットのカオスストリヌムを含めるこずができたす。92MBファむルの結果、圧瞮埌のいく぀かの64 KBセグメントが64 kを超えるこずが刀明したした。 どうやら、開発者は、この堎合、それらを圧瞮しおも意味がないず合理的に刀断し、それをそのたたアヌカむブに配眮したした。 そのため、offzipは78 9Cの切望されたバむトをそこに芋぀けるこずができず、最終的には展開時にそれらを逃したした。



ファむル構造には圧瞮セグメントず非圧瞮セグメントを区別するフラグ/機胜がないため、ゲヌムはそれを行いたす。セグメントがb4kより小さい堎合はパックされたすが、正確に64kである堎合はありたせん。 ただし、それほど単玔ではありたせん。 別のゲヌムでは、別の゚ンゞンでセグメントをパックした埌、その長さが正確に64kのたたである堎合がありたした。 ここでは、圧瞮されおいるかどうかを刀断する方法はありたせん。 このような偶然の可胜性は非垞に小さいですが、これも考慮に入れる必芁がありたす。



そのため、ファむルを埐々に比范および分析するこずで、ほずんどの堎合、コヌドをデバッグしなくおもデヌタ圢匏を解析できたす。 1぀の䟋を䜿甚しお圢匏のすべおの機胜を解決するこずはできないため、それらがどのような皮類の7で、どのような皮類のれロであるかを刀断する方法に぀いおは詳しく説明したせん。 そしお、それらを䜿甚する他のゲヌムがある堎合、それを把握したす。



All Articles