(*(void(*)()) shellcode)()
ってなんぞ?
最近、アセンブリ言語の勉強を始めたわけだが、文字列を関数として呼び出すコードを書く際、決まってこの表現が出てくる。
char shellcode[] = "\x00\x00\x00\x00\x00";
(*(void(*)()) shellcode)()
なんとなく関数ポインタを指していることは予想がつくが、そもそも文字列を関数として処理させるには どうしたらいんだろう?そんな疑問に大正義StackOverflowが答えてくれた。
そもそも関数ポインタってなんだっけ
#include <stdio.h>
void func(void);
int main() {
void (*hoge)() = func;
hoge();
return 0;
}
void func() {
printf("hoge hoge");
}
変数hogeは関数ポインタ(アドレス)を指す。宣言方法は戻り値の型 (*変数名) (仮引数); つまり引数がある場合はこうする。
#include <stdio.h>
int func(int, int);
int main() {
int (*hoge)(int, int) = func;
hoge(1,2);
return 0;
}
int func(int a, int b) {
return a+b;
}
少し書き下してみる
つまり下記を少し書き下すと、
(*(void(*)()) shellcode)()
char shellcode[] = "\x00\x00\x00\x00\x00";
void (*funcPointer)() = (void(*)())shellcode;
funcPointer();
2行目で文字を関数ポインタへキャストし、3行目で実行する。 ここから変数名と仮引数を省略し、関数呼び出しを1行で行うと上記の表現になる。
(*(の*っている?
するとこれって
((void(*)()) shellcode)()
でもよいのでは?
この疑問にもStackOverflowは答えてくれていた!
(*(plainsig_t*)shellcode) ();
For function pointers, you don’t need to dereference them, so it is shorter to just code:
((plainsig_t*) shellcode) ();
やS神