SimpleROHook jRO 2015.02.03のパッチについて

SimpleROHook jRO 2015.02.03のパッチについて少し書いておきます。技術的な事なので読みたい方だけどうぞ

jROでの確認をしていませんがbROのほうにも同様の変化があったのを確認しました。

対処方法ですが避難所に少々書き込みがあるようですが概ね正解です。正解として出すとするなら USE_GAMEOBJ_COUNTER というプリプロセッサを定義して以下のようにするべきかと思います。

class CGameObject {
public:
#ifdef USE_GAMEOBJ_COUNTER
    long long m_unknown_qword_counter;
#endif
    CGameObject(class CGameObject&) {};
    CGameObject::CGameObject() {};
      .
      .

動作としては CGameObject のコンストラクタが呼び出されると QWORD の一意のカウンターがインクリメントされていき各オブジェクトへ埋め込まれていきます。

バイト長が8ですがコンパイル時にアラインメント(境界整列)されて以下のようになります。12バイトのデータが追加されたように見えるのはこのためです。

CRenderObject : public CGameObject {
00000000|DWORD    vfptr;  // class base pointer
00000004|BYTE     pad[4]; // padding
00000008|QWORD    m_unknown_qword_counter;
00000010|vector3d m_pos;
0000001C|string   m_bodyPaletteName;
        .
        .
        .

管理人的にはデバッグカウンターの消し忘れかなと邪推しております。

例外的な物は恐らく上記の物だけですので、残りの不整合は各自の努力に委ねます。pull request してくれればマージします。

今後のために記事としてまとめておくべき事が一つ出来てしまいましたが、年始から体調不良が続いて、季節も病にやさしくない時期に突入してしまったため落ち着いてからという事で何卒。

さらにもっと詳しく解説

bROの例でアレですが、見るべきところとしては CGameObject のクラス関数のテーブルです。

.MPRESS1:00901574 CGameObject___vftable dd offset CGameObject___vector
.MPRESS1:00901574                                         ; DATA XREF: CGameObject__CGameObject+2o
.MPRESS1:00901574                                         ; sub_72D210o ...
.MPRESS1:00901578                 dd offset CGameObject__OnProcess
.MPRESS1:0090157C                 dd offset CGameObject__SendMsg
.MPRESS1:00901580                 dd offset CGameObject__Render ; void __thiscall CGameObject__Render(CGameObject *this, matrix *ptm)
.MPRESS1:00901584                 dd offset CGameObject__Get8Dir

各関数の実装と前後関係、テーブル長から判断が付くかと思います。

テーブルのアドレスが発見できれば、それを元に検索してコンストラクタが発見できます。

.MPRESS1:0072D1D0 ; void __thiscall CGameObject__CGameObject(CGameObject *this)
.MPRESS1:0072D1D0
.MPRESS1:0072D1D0 CGameObject__CGameObject proc near      ; CODE XREF: CGrannyCorpse3d__CGrannyCorpse3d+29p
.MPRESS1:0072D1D0                 mov     eax, ecx
.MPRESS1:0072D1D2                 mov     dword ptr [eax], offset CGameObject___vftable
.MPRESS1:0072D1D8                 mov     ecx, dword ptr qword_994F50
.MPRESS1:0072D1DE                 mov     edx, dword ptr qword_994F50+4
.MPRESS1:0072D1E4                 add     ecx, 1
.MPRESS1:0072D1E7                 adc     edx, 0          ; g_qword_counter++
.MPRESS1:0072D1EA                 mov     dword ptr qword_994F50, ecx
.MPRESS1:0072D1F0                 mov     dword ptr qword_994F50+4, edx
.MPRESS1:0072D1F6                 mov     [eax+8], ecx
.MPRESS1:0072D1F9                 mov     [eax+0Ch], edx  ; m_qword_counter = g_qword_counter
.MPRESS1:0072D1FC                 retn
.MPRESS1:0072D1FC CGameObject__CGameObject endp