アマチュアおよびバックエンジニアリング。 パート1:パスとファイル

プレイしたゲームに基づいてプロジェクトを進めたプログラムは何人ですか? 私はたくさん思います。 ゲームはあまりにも意味があり、意味のないプロジェクトに時間を費やす必要がないと言われるかもしれません。とにかく誰にも役に立たないでしょうが、それはあなたにとっては重要ではありません。



かつて、私はモリの「テイルズオブパイレーツ」(以降TOP)、より正確にはロシアのニバルのローカライズ版「パイレーツ」で多くのことをしました。 私にとってはスマートなゲームです。 はい、WOWではありませんが、彼についても何も知りませんでした。 何年も経って、「海賊」は閉じられ、私は成長しましたが、記憶の海で忘れられた海の征服者はまだレベル54のボートに浮かんでいます。



画像



彼らがロシアのサーバーを閉じたことを知った後、その瞬間、私は数年プレイしていませんでしたが、興奮は再び目覚めました。 数か月後、私はファンサーバーの世界を少し理解し、LAN上で独自の構成を試み、ファイル構造を理解し始めました。 そして、それが始まりました。 最初は、モデルの操作方法を学ぶことにしました。 数時間、Pastebinで、ファイルの後に、問題はあるもののモデルを開くことができるコードを見つけました。 しかし、ゲーム内のモデルに加えて、テクスチャは暗号化されていました。



幸いなことに、ゲームのテクスチャを通常の一般的な画像に変換できるGemini Decompilerというプログラムが1つありました。 さらに幸運なことに、このプログラムは.Netで作成されています。 逆コンパイラの後、通常のテクスチャは3つのブロックに分割されました-最初の44バイト、最後の44バイト、残り-最後の44バイトは最初に暗号化されたテクスチャに入り、次にメイン部分、次に最初の44バイト、そして理由もなく別の4バイトになりました。



Pastebinとテクスチャコンバーターを使用したコードに基づいて、モデルビューアーであることが判明しました。 もちろん恐ろしいが、それでも。 彼は、アニメーションのない剣\杖\短剣、キャラクター、装飾要素などの最も単純なモデルのみを読み取りました。



画像



そして動きが欲しかった。 そして、TOPエンジンライブラリを断片に解析する逆アセンブラを探し始めました。 海賊版IDA Proを見つけました。 そして、彼は壊れ始めました...特にコンパイラで処理した後、名前を適切に逆参照する方法を知っており、逆アセンブラの結果をCに非常に似た擬似コードに変換するという点で、一般的な便利なプログラムです。これはCaesar 3の記事で言及されました。



約2か月間、さまざまな成功を収めました。 まあ、彼がどのように働き、遊んだか。 数学的操作を伴うコードを見つけ、モデルビューアーからIDAデータベースに構造を貼り付け始めました。その後、.pdbをインポートできることがわかりました(そして、エラーがある場合は、フィードバック用と思われます)、コードと構造が発行されました。 しかし、すべてが正しくないと感じられました。 私は.pdbを持っていますが、私が知る限り、プロジェクトに関する情報があります。 たくさんの異なるプログラムを見つけましたが、それらはすべて一般的な情報のみを提供しました。 その後、Visual StudioのExpressバージョンにも付属している場合、Debug Interface Access(以降DIAと呼びます)の検討を開始しました。 要するに、今はProfessionalエディションについて書いています。 dia2dumpの例をコンパイルした後、私は夢中になりました。 手元にたくさんのサービス情報がありました。 30メガバイト強のテキスト。 たとえば、リンカーに供給されるすべての.objファイルのリストがあり、さらに各.objファイルにはそこに入力するソースのリストがあります。 一般に、ある日、TOPエンジンプロジェクトからファイルを作成するコードの準備が整いました。 そして、構造の作成と.pdbを介した包含の接続があります...



そのようなこと。



手始めに-dia2dumpの追加コード。 プロジェクト内の.objの数をカウントし、各.objのファイルを出力し、.pdbを使用してプロジェクトフォルダーとファイルを作成するためのコード。

エンコーダー出力を開く
int total=0; bool AQLCreateDirectory(WCHAR * sPathTo) { while(CreateDirectory(sPathTo, NULL) == FALSE) { WCHAR sTemp[MAX_PATH]; int k = wcslen(sPathTo); wcscpy(sTemp, sPathTo); while(CreateDirectory(sTemp, NULL) != TRUE) { while(sTemp[--k] != L'\\') { if(k<=1) return FALSE; sTemp[k] = NULL; } } } return TRUE; }; void Process(IDiaSession *pSession, IDiaSymbol *pGlobal) { int total=0; IDiaEnumSymbols *pEnumSymbols; if (FAILED(pGlobal->findChildren(SymTagCompiland, NULL, nsNone, &pEnumSymbols))) return; IDiaSymbol *pCompiland; ULONG celt = 0; while (SUCCEEDED(pEnumSymbols->Next(1, &pCompiland, &celt)) && (celt == 1)) { pCompiland->Release(); total++; } fwprintf(pFileout,L"%i\n", total); pEnumSymbols->Release(); if (FAILED(pGlobal->findChildren(SymTagCompiland, NULL, nsNone, &pEnumSymbols))) return; celt = 0; while (SUCCEEDED(pEnumSymbols->Next(1, &pCompiland, &celt)) && (celt == 1)) { BSTR bstrName; if (pCompiland->get_name(&bstrName) == S_OK) { fwprintf(pFileout,L"%s\n", bstrName); SysFreeString(bstrName); } int num=0; IDiaEnumSourceFiles *pEnumSourceFiles; if (SUCCEEDED(pSession->findFile(pCompiland, NULL, nsNone, &pEnumSourceFiles))) { IDiaSourceFile *pSourceFile; while (SUCCEEDED(pEnumSourceFiles->Next(1, &pSourceFile, &celt)) && (celt == 1)) { num++; pSourceFile->Release(); } pEnumSourceFiles->Release(); fwprintf(pFileout,L"%i\n", num); } if (SUCCEEDED(pSession->findFile(pCompiland, NULL, nsNone, &pEnumSourceFiles))) { IDiaSourceFile *pSourceFile; while (SUCCEEDED(pEnumSourceFiles->Next(1, &pSourceFile, &celt)) && (celt == 1)) { BSTR bstrSourceName; if (pSourceFile->get_fileName(&bstrSourceName) == S_OK) { fwprintf(pFileout,L"%s\n", bstrSourceName); WCHAR *path = new WCHAR[wcslen(bstrSourceName)+8]; wcscpy(path,L"c:\\test\\"); wcscat(path,bstrSourceName+2); WCHAR *filename = new WCHAR[wcslen(path)+1]; wcscpy(filename,path); for(int k=wcslen(path)-1;k>=0&&path[k]!=L'\\';k--)path[k]=0; bool ok = AQLCreateDirectory(path); FILE *file = _wfopen(filename,L"w"); fclose(file); delete(filename); delete(path); SysFreeString(bstrSourceName); } pSourceFile->Release(); } pEnumSourceFiles->Release(); } pCompiland->Release(); } pEnumSymbols->Release(); }
      
      








All Articles