0

最初に malloc 関数を呼び出すために malloc 関数をハックしようとしています。その中で malloc 関数が実行されたら、標準の malloc を呼び出したいと思います。しかし、定義したmallocをロードしているだけなので、再帰が発生しています。以下のコードを修正するにはどうすればよいですか?

#include <dlfcn.h>
#include "stdio.h"
//#include "stdlib.h"


void *handle;

void *handle_malloc;

int (*loadprg)(void);

void * (*malloc_sysm)(size_t);


void init()
{
    handle = dlopen ("/export/home/joshis1/Foxtel/temp/libloadmap.so", RTLD_LAZY);
    if( handle == NULL)
     {
       puts(dlerror());
     }


   handle_malloc = dlopen ("/lib/libc.so.6", RTLD_LAZY);
    if( handle_malloc == NULL)
     {
       puts("handle malloc error\r\n");
       puts(dlerror());
     }


}


#include "stdio.h"


void *malloc(int size)
{
   printf("called..my malloc\r\n");

   malloc_sysm = dlsym(handle_malloc,"malloc");

   if ( dlerror() != NULL)
    {
       puts("malloc symbol not found..");
       exit(1);
    }


    printf("This should call actual malloc now..\r\n");
    return  malloc_sysm(size);




}


int main()
{
  int *t;
  init();
  printf("call load program now\r\n");

  loadprg = dlsym(handle, "loadprg");

  if( dlerror()!= NULL)
   {
      puts("Symbol load errror");
   }

  (*loadprg)();  

  printf("Close the handle now..\r\n");

  dlclose(handle);


  t = (int *) malloc (100);

  dlclose(handle_malloc);



  return 0;

}

出力は、定義した malloc() への再帰です。これを修正するには?

4

3 に答える 3

3

共有関数をオーバーライドするには、独自の共有ライブラリをコンパイルし、LD_PRELOAD 環境変数を介してプリロードする必要があります。

#define _GNU_SOURCE

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

void *malloc(size_t size) {
    printf("called..my malloc\r\n");

    void *(*original_malloc)(size_t size);
    // Find original malloc function
    original_malloc = dlsym(RTLD_NEXT, "malloc");

    if ( dlerror() != NULL)
    {
        puts("malloc symbol not found..");
        exit(1);
    }

    printf("This should call actual malloc now..\r\n");
    return (*original_malloc)(size);
}

$ gcc -Wall -fPIC -shared -o mymalloc.so mymalloc.c -ldl
$ LD_PRELOAD=./mymalloc.so ./prog

これで、プログラムはプリロードされたライブラリから malloc を使用します。

于 2013-09-16T12:28:16.803 に答える
1

私が常に使用している標準的な方法は、MALLOC(MYMALLOCまたは何でも) と呼ばれるマクロを作成することです。もちろん、Iの出現はすべてmallocマクロを使用して置き換える必要があります。これが必要でない場合は理解できます。

また、機能を含めたいソースをコンパイルするときにのみ呼び出されるマクロmalloc(つまり、元の のように綴る)を定義することによって、目的を達成することもできます。このマクロは、たとえば、ファイルで宣言する必要がある関数を呼び出します。これはマクロを定義せずにコンパイルされ、次に元の関数を呼び出すことができます。この makefile をいじるのが面倒な場合は、次のように呼び出して元の関数を呼び出すこともできます(これにより、マクロが再度実行されるのを回避できます)。mallocmallocwrappingMallocmallocmalloc(malloc)

    #include <stdlib.h>
    #include <stdio.h>

    #define malloc(size) myMalloc(size)

    void *myMalloc(size_t size) {
      void *result;
      printf("mallocing %ld bytes", size);
      result = (malloc)(size);
      printf(" at %p\n", result);
      return result;
    }

    int main(int argc, char *argv[]) {
      char *buffer;
      buffer = malloc(10);
      return 0;
    }

newC++ では、クラスの演算子をオーバーロードすることでうまくいく場合があります。

于 2013-09-16T12:29:40.427 に答える
0

あなたのコードに問題は見当たりません。しかし、なぜmalloc_sysm = dlsym(handle_malloc,"malloc");あなたのinit()機能に移動しないのですか?

于 2013-09-16T12:18:43.780 に答える