メモリ内の値をX86_64の%rip
から読み取ろうとしています。私の最初の例では、私はちょうど私がCに次のコードを記述する場合、私はそれを呼び出すと、正しい結果(\x....C3C9
)を取得することができます動的に生成されたX86_64を取得してRIP/RBPを基準にした値を返す方法
を読みたい:
void * test() {
__asm("mov 0(%rip), %rax");
}
次のように生成されたコードが見えます:
0000000000400624 <test>:
400624: 55 push %rbp
400625: 48 89 e5 mov %rsp,%rbp
400628: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 40062f <test+0xb>
40062f: c9 leaveq
400630: c3 retq
私は今、しかし、メモリに直接このコードを入れて、私は読むことを期待しながら、私はセグメンテーションフォルトを取得し、それを実行した場合\x0000C3C9
:
int main()
{
int codesize = 9;
unsigned char * code = (unsigned char*)malloc(1024);
memcpy(code, "\x48\x8B\x5\x0\x0\x0\x0\xC9\xC3\x00\x00", codesize + 2);
mprotect(code, codesize, PROT_EXEC | PROT_READ);
goto *code;
}
私は間違っていますか?
編集 答えは私がページ整列メモリ領域を割り当てるためにmalloc
が、mmap
を使用しているべきではないということです。
(unsigned char*)mmap(NULL, 1024, PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
そしてもちろん、私は、コールの戻り値をチェックしているはずですmprotect
に失敗したことを示す-1というフラグを返しました。
私は再び彼のコメントを削除した誰かによってコメントが、しかし彼は正しい方向に私をリードしました。彼は正しく、mprotectが失敗している(愚かな私、私はチェックすべきだった)。私は 'malloc'(明らかに)がページ境界に合わせてメモリを返さないと思います。 '(unsigned char *)mmap(NULL、1024、PROT_WRITE | PROT_READ、MAP_ANONYMOUS | MAP_SHARED、-1、0);を使用することによって動作します。 – tverwaes
'PROT_EXEC'を' mmap'呼び出しに追加すると、 'mprotect'は必要ありません。 –
私は、いくつかのカーネルが 'PROT_WRITE'と' PROT_EXEC'を同時に使用できない場所を読んだので、私はそれをしませんでした。私はそれを誤解しましたか? – tverwaes