AviUtl1.10のfastcall
https://ja.wikipedia.org/wiki/呼出規約
AviUtl1.10および拡張編集0.93rc1の呼出規約が__fastcallの関数の仕様は一般的なケースとは異なることが判明しました。
ウィキペディアより
関数の引数の個数が可変でない場合は、スタックからの引数データの除去は(Pascal 呼出規約のように)サブルーチン側で行うのが通例である。
それに対して、AviUtl1.10および拡張編集0.93rc1のfastcallでは(cdecl 呼出規約のように)呼び出し側で行うようになっています。
つまり、patch.aulなど改造プラグインで引数が3個以上のfastcall関数を自前の関数に置き換えたり呼び出したりする場合には、それに適合するようにしなければなりません。
対策方法
関数の置き換え・呼び出し共に対応できる方法
コンパイラの設定にて__fastcallの引数除去を呼び出し側で行うように設定する
Visual Studio 2022ではよく分かりませんでした!
引数の個数を可変にすることで呼び出し側で行うようになる
Visual Studio 2022では可変にすると勝手に__cdeclになるようなので上手くいきませんでした!
初めからインラインアセンブラやバイナリで書くことで対応
関数を置き換えする場合の方法
(現在patch.aulで採用)置き換えるcall funcの後ろにあるadd espをnopにすれば、通常の__fastcall関数に置き換えられる
関数を呼び出しする場合の方法
呼び出し関数のすぐ後にインラインアセンブラadd espを書いておく(例:__asm add esp,0x4)
コンパイラの最適化などの関係で、間に別の処理が挟まって問題を起こす可能性あり
(現在patch.aulで採用)専用の関数を経由させる fastcall_caller