私はここでバイナリ難読化を使用しているので、opコードで満たされたバッファーを取得し、Linuxを使用しているので、すべての関数呼び出しは同じ呼び出し元/呼び出し先の規則を使用し、ここでは問題ありません。
私の質問はE8オペコードについてです。このオペコードは相対アドレスを使用してニアコールを取ります。
私の質問は次のとおりです。私は電話がかかってきた住所を知っています。私は電話をかけなければならない住所を知っています。それで、E8電話に入れなければならないシフトアドレスをどのように見つけることができますか?これは:
signed long src = (signed long)buffer + shift; //get the position where E8 instruction is
signed long dst = (signed long)srand; //get the destination position where i want to call (yes, srand(long) function in this case.)
だから私のバッファには:
buffer[] = "[....]\xE8\xFF\xFA\xFE\x54[.....]"; //example
srandへの有効なポインタに置き換える必要がありますが、持っているものから相対アドレスを取得するにはどうすればよいですか?
FF命令で直接電話できると思っていたのですが、どうしたらいいのかわかりませんでした。代わりに5を超えるオペコードを入れることができないため(たとえば)$ eaxにアドレスをコピーできません(上記のすべてのjmp呼び出しがバナナになります)。 5バイトで直接呼び出します。
したがって、誰かがE8相対シフトアドレスを置き換えるための正しい値を取得する方法を知っている場合、またはE8呼び出しと同じ機能プロパティを維持し、5バイトだけを使用して何らかの直接呼び出しを行う方法がある場合...
(質問する前に、FF XX XX XX XXを実際のアドレスであるXXとして配置しようとしましたが、機能しませんでした。x86は呼び出しのようには見えず、INC(???)およびランダムとして解釈されます。私はこの方法で交換を試みました:
inline void endian_swap(long& x) {
x = (x>>24) |
((x<<8) & 0x00FF0000) |
((x>>8) & 0x0000FF00) |
(x<<24);
}
endian_swap(dst);
endian_swap(src);
unsigned int p = dst - src;
endian_swap(p);
そして、私が見つけたアドレスをE8コールに入れます。とにかくうまくいきませんでした。