2013-10-28 9 views
14

それにより、動的メモリを割り当て、それにはいくつかのアセンブラ命令コードを書き込むことによって、動的機能を作成することである(等0x90をNOP RETために0xC2)、そのダイナミックメモリを指すと同じように実行する関数ポインタを作成しますCプログラム内の正規関数ですか?C関数ポインタ:ヒープメモリアセンブラコードにジャンプできますか?

対象は通常のx86 Linuxシステムである必要があります。

+0

類似していますが、同じことではありません - 'int main = 0xc290;'はコンパイルして正常に実行します。 – ugoren

+0

@ugoren特定の状況下でのみ。 – glglgl

+0

@glglgl、質問に記載された状況で。 – ugoren

答えて

3

このメモリはヒープメモリではありません(下記を参照)。また、ヒープメモリの実行権限を変更することはできないと思います。

#include <sys/mman.h> 
size_t size = 0x1000; // 1 page 
// this will be mapped somewhere between /lib/x86_64-linux-gnu/ld-2.15.so 
// and stack (see note and memory map below) 
void *code = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS, -1, 0); 
// use `code` to write your instructions 
// then store location at which you want to jump to in `fp` 
void *fp = ...; 
mprotect(code, size, PROT_READ | PROT_EXEC); 
// use some inline assembly to jump to fp 

:Linuxの

、あなたは次のように使用することができますLinuxでは、ユーザーがマップされたメモリは、x86のLinux上でスタックする別の地域(400000000000から、最大のようなものに位置しており、おそらく7f0000000000 on x64 one)。ヒープは、プログラムのELFセグメントの前後に配置され、mmapで利用可能です。ヒープ自体は、brkシステムコールを使用して直接割り当てることができます(今はmallocに置き換えられています)。あなたが見ることができるようにあなたが実行可能なメモリを取得するためにmallocを使用することはできませんので、heapが実行可能ではない(ので当然である)、

➜ ~ ps 
    PID TTY   TIME CMD 
9429 pts/3 00:00:07 zsh 
20069 pts/3 00:00:00 git-credential- 
22626 pts/3 00:00:00 ps 
➜ ~ cat /proc/9429/maps 
00400000-004a2000 r-xp 00000000 08:01 6291468       /bin/zsh5 
006a1000-006a2000 r--p 000a1000 08:01 6291468       /bin/zsh5 
006a2000-006a8000 rw-p 000a2000 08:01 6291468       /bin/zsh5 
006a8000-006bc000 rw-p 00000000 00:00 0 
01a51000-01fd8000 rw-p 00000000 00:00 0         [heap] 
... 
7f6529d61000-7f6529d91000 rw-p 00000000 00:00 0 
... 
7f652d0d3000-7f652d0d5000 rw-p 00023000 08:01 44833271     /lib/x86_64-linux-gnu/ld-2.15.so 
7fffd7c7f000-7fffd7cae000 rw-p 00000000 00:00 0       [stack] 
7fffd7dff000-7fffd7e00000 r-xp 00000000 00:00 0       [vdso] 
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0     [vsyscall] 

:この例を(私のUbuntu 12.10 x64の上で得た)を参照してください。

2

多くのシステムでは、実行可能コードが含まれているかどうかを示す仮想メモリページに長い時間フラグが設定されています。最も可能性が高いヒープに割り当てられたメモリは、にこの "実行可能"フラグが設定されていません。だからあなたはそれを直接行うことはできません。

OS固有の機能を使用する必要がある場合は、そのプログラムを「管理者」または「root」として実行する必要がありますが、必要ではないようです。

+2

私はあなたがルートになる必要はないと思います。実行可能メモリを割り当てることは、システムに危険を及ぼすものではなく、その使用方法を(ほとんどの現在のブラウザはJavaScriptエンジンで行います)。 –

+0

より多くのユビキタスな.Netフレームワークについては言うまでもない。 – Blindy

17

一般的にはそうですが、そうするにはシステム固有のものに進む必要があります。これはあまり驚くことではないと思います。なぜなら、バイナリアセンブリ命令を使用するという事実はかなり明確になっているからです。

現代のオペレーティングシステムのヒープメモリは実行可能であると想定できないので、いくつかのフープをジャンプする必要があります。 malloc()を呼び出して、返されたポインタがコードを実行できるメモリを指していると仮定することはできません。

Linuxでは、mmap()を使用してカーネルにメモリをマップするように指示し、呼び出しにPROT_EXECフラグを指定することでメモリを実行可能にすることができます。

+1

Windowsでは、[VirtualProtect](http://msdn.microsoft.com/en-us/library/aa366898%28v=vs.85%29)を使用できます。aspx) – Asaf

+1

私はあなたがヒープメモリが実行可能であると仮定することさえできないと思います。しかし、このメモリをヒープにする必要はありません。私の答えを見てください。 –

関連する問題