0

私のプログラムは、関数の最初の数バイト(i386のみ)にjmp命令を書き込むことにより、関数を別の関数にリダイレクトします。期待どおりに機能しますが、常に新しい関数にジャンプするため、元の関数を呼び出すことができなくなります。

私が考えることができる2つの可能な回避策があります:

  1. ターゲット関数のjmp命令を上書きして呼び出す、新しい関数を作成します。その後、関数はjmp命令を書き戻します。しかし、引数はいくつでも存在する可能性があるため、引数を渡す方法がわかりません。そして、ターゲット関数がどこか別の場所でjmpして、jmp命令の書き戻しをスキップできるかどうか疑問に思います(throw catchのように?)。

  2. jmp命令で上書きしたコードを実行する新しい関数を作成します。しかし、上書きされたデータが完全な命令であるかどうかはわかりません。完全な手順を実行するには、コピーする必要のあるバイト数を知る必要があります。

それで、最後に、私の質問:

  1. 私が考えていなかった別の方法はありますか?

  2. 命令のサイズを見つけるにはどうすればよいですか?私はすでにbinutilsを調べてこれを見つけましが、それを解釈する方法がわかりません。

サンプルは次のとおりです。

mov, 2, 0xa0, None, 1, Cpu64, D|W|CheckRegSize|No_sSuf|No_ldSuf, { Disp64|Unspecified|Byte|Word|Dword|Qword, Acc|Byte|Word|Dword|Qword }

2番目の列にはオペランドの数(2)が表示され、最後の列にはオペランドに関する情報がコンマで区切られて表示されます。

この質問もほとんど同じですが、7バイトに命令全体が含まれていることを確認できません。 トランポリン関数の記述

どんな助けでも大歓迎です!ありがとう。

4

2 に答える 2

1

セバスチャン、hotpatchでexe_load_symbols()関数を使用して、既存のexe内のシンボルとその場所のリストを取得し、それをメモリ内で上書きできるかどうかを確認できます。まだ試していません。hotpatchの代わりにLD_PRELOAD環境変数を使用してそれを行うことができる場合があります。

--Vikas

于 2014-09-04T20:35:33.727 に答える
0

このようなものはどうですか:

これが元の関数であるとしましょう。

Instruction1
Instruction2
Instruction3
...
RET

これに変換します:

JMP new_stuff
old:
Instruction2
Instruction3
...
RET
...
new_stuff:
CMP call_my_function,0
JNZ my_function
Instruction1
JMP old
my_function:
...

もちろん、最初の命令が完全に収まるように、元の命令のサイズを考慮に入れる必要があります(objdumpたとえば、で分解するとわかります)(元の命令よりも短い場合は、sで埋めます)。 )。JMPNOPJMP

于 2013-02-26T11:04:14.387 に答える