0

特定のバイナリ(できれば、呼び出しを行う実際のsyscall / sysenterレベル(x86-64およびx86)で)にインストルメントsyscall brk化(および他の呼び出しですが、これは私にとって最も重要です)したいと思います。sys_brk

主な目標:

  • 投獄されたプロセスに一定量のメモリを与えるサンドボックスの一部
  • brkそのため、システム コール (および次の順序で最も可能性が高い他のコール)を取り除き、固定 limitの下でメモリ割り当てをシミュレートしたいと考えています。固定制限は、プログラムに使用できるメモリ空間です。(利用可能なメモリ量が固定された一種のサンドボックスを作るようなものと考えることができます)

いくつかの可能な解決策(またはあなたの解決策)の例(の1つ)を実装する方法:

  • 指示を変更するだけですNOP
  • 成功時に 0 を返すように、成功時に呼び出されるようにbrk、メモリ (レジスタ) の状態を設定する操作を設定して、成功をシミュレートします。brk
  • より複雑な...固定制限の下で成功メモリ割り当てをシミュレートするコード(または関数呼び出し)を備えたインストゥルメント。
  • このsyscallを関数呼び出しに変更し、提供された関数をバイナリに追加するのが最も柔軟です(私の場合はやり過ぎかもしれません)。

与えられたバイナリは、次の 2 つの形式のいずれか (最も望ましいのは両方:) で悪意のある可能性があるコードです。

  • 共有ライブラリ - ここでは、関数呼び出しの前に環境をセットアップできます (たとえば、制御された方法で brk 呼び出しを行います)
  • プログラム バイナリ - この場合、プログラムに一定量のメモリを与える必要があります (呼び出し元によって、またはプログラムの開始時に「1 つのシステム コール」で)、メモリを割り当てることができないためです。そのようなプログラムを呼び出す例は、回答に含める必要があります。

問題は他の多くの側面と密接に関連しているため、質問として区切るように最善を尽くしましたが、多かれ少なかれ何かを指定する必要がある場合は、アドバイスをお願いします。

実装に関する回答、リソース (本、チュートリアル) へのリンクは大歓迎です。

(私が最も興味を持っているのはLinuxであり、信頼できるソリューションです。これにより、アセンブラーでもバイナリを準備する人々がコードの実行について心配する必要がなくなります)

4

2 に答える 2

1

LD_PRELOADはbrk()へのC呼び出しをトラップしますが、実際のシステムコール(int / syscall命令)はトラップしません。それらをトラップするポータブルな方法はありませんが、Linuxではptraceがそれを行います。メモリはmmap()によってプログラムに割り当てることもできるので、その呼び出しもインターセプトする必要があります。

もちろん、あなたが本当に探しているように見えるのはrlimit()です。

于 2011-11-06T04:48:42.407 に答える
0

ええ、私はあなたがこれのためにvalgrindを望んでいないと思います。

LD_PRELOADまたはリンカートリックを使用してbrk(2)をキャプチャできます。他の説明を参照してください。

dlsymを使用しないLinuxでの関数の挿入

LD_PRELOADメカニズムを使用して「malloc」をオーバーライドする

コードは次のようになります。

#include <unistd.h>
#include <dlfcn.h>

/* prototype int brk(void *addr); */

static int (*real_brk)(void *addr) = NULL;

int brk(void * addr) {

    real_brk = dlsym(RTLD_NEXT, "brk");
    if (real_brk == NULL) {
            fprintf(stderr, "error mapping brk: %s\n", dlerror());
            return -1;
    }
    printf("calling brk(2) for %p\n", addr);
    return (real_brk (addr));
}`   

次に、LD_PRELOADを実行して、brk(2)をインターセプトします。

于 2011-11-03T13:05:51.483 に答える