pop↑ push↓

☆ (ゝω・)v

プログラムを改造する(D)

EU4のパッチ情報です。

前回

popush.hatenablog.com

パッチバグについて

翻訳が進むに連れて、強制終了の報告が多く上がるようになりました。 f:id:saito-matanki:20171202013228p:plain

これは44文字目もしくは45文字目にエスケープ文字が存在するマップテキストのバイト列が、次章で示す理由により45文字目で途切れた時に、不正なコードポイントが発生することで、フォントデータへのアクセス違反を誘発するために起こるバグです。修正に確信が持てないため、すぐに修正するにはmapテキストに関する翻訳ファイル(prov_namesなど)を適用しないでください。

なぜ45文字で途切れるか

 簡単に言えば、内部のコードがそうなっているからです。下記の画像の左のルートのpush 2Dhがそれです。 f:id:saito-matanki:20171202014854p:plain

テキストバイト列はここで、0x38の大きさを持つ構造体(下記は適当です)のテキスト用の変数(大きさ0x2E、最後にnull文字が入るため)にコピー(sub_1A1B180)されます。

typedef struct hoge{
  uint32_t* address;
  uint32_t index;
  char maptext[2E];
  char length; 
  char padding;  
} hoge_t;

修正できるのか?

 上記の2DをFFなどに変えれば修正可能に思われますが、構造体そのもの大きさが決められているため、うまく行きません(でした)。しかし、左のルートではなくて、右のルートを見てください。こちらはテキスト元(esi)のアドレスをそのまま転送(mov [ecx+eax*4], esi)しているように見えます。実際この右ルートに入ってくるマップテキストも存在しており、例えばPROV1がそれです。PROV1とPROV2に同じ文字列を設定していますが、PROV2に対してPROV1の表示がすべて表示されていることがわかります。 f:id:saito-matanki:20171202021426p:plain f:id:saito-matanki:20171202021324p:plain

一方で、テキストが不自然に大きかったり、まっすぐ過ぎたり、なぜ右ルートに入るマップテキストと左ルートに入るマップテキストがあるのかわかっていません。

右ルートと左ルートの分岐条件(追記)

 テキストが不自然になるのに、思いあたりがあります。map/positions.txtです(詳細はここを参照)。確認してみると、PROV1とPROV2は次のような感じでした。 f:id:saito-matanki:20171202023447p:plain

PROV1はText Rotationが0.087で、PROV2は0.000です。一方で条件分岐にブレークポイントを置いたときの決定打となるxmm0レジスタの値は下記です。 f:id:saito-matanki:20171202023412p:plain

浮動小数点の誤差が出ていますが、positions.txtのrotationの値で間違いなさそうです。

次回プログラムを改造する(E)に続く