2

プロジェクトの 1 つで glibc の printf() をハッキングしていて、問題が発生しました。手がかりを教えてください。私の懸念の 1 つは、malloc/free の同じソリューションが完璧に機能する理由です。

添付の「PrintfHank.c」には、標準ライブラリの前にプリロードされる独自の printf() ソリューションが含まれています。「main.c」はprintf()を使って文章を出力するだけです。2 つのファイルを編集した後、次のコマンドを発行しました。

  1. main.c をコンパイル gcc –Wall –o main main.c
  2. 独自のライブラリを作成 gcc –Wall –fPIC –shared –o PrintfHank.so PrintfHank.c –ldl
  3. 新しいライブラリをテストします LD_PRELOAD=”$mypath/PrintfHank.so” $mypath/main

しかし、コンソールで「自分のprintf内」ではなく「hello world」を受け取りました。malloc/free 関数をハッキングする場合は問題ありません。

システムに「root」としてログインし、2.6.23.1-42.fc8-i686 を使用しています。どんなコメントでも大歓迎です!!

main.c

#include <stdio.h>

int main(void)
{
    printf("hello world\n");

    return 0;
}

PrintfHank.c

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

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

static int (*orig_printf)(const char *format, ...) = NULL;

int printf(const char *format, ...)
{
 if (orig_printf == NULL)
 {
  orig_printf = (int (*)(const char *format, ...))dlsym(RTLD_NEXT, "printf");
 }

 // TODO: print desired message from caller. 
 return orig_printf("within my own printf\n");
}
4

3 に答える 3

3

この質問は古くからありますが、次のとおりです。

ではmain.c、最後に改行があり、の書式設定機能を使用していませんprintf

LD_DEBUG=all LD_PRELOAD=./printhack.so hello 2>&1(ファイルの名前を多少変更しました)の出力を見ると、下部近くに表示されます

 17246:     transferring control: ./hello
 17246:     
 17246:     symbol=puts;  lookup in file=./hello [0]
 17246:     symbol=puts;  lookup in file=./printhack.so [0]
 17246:     symbol=puts;  lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0]
 17246:     binding file ./hello [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `puts' [GLIBC_2.2.5]

の実際の言及はありませんprintfputs基本的に printf は書式設定がなく、最後に自動改行があるため、これは明らかに gcc を . に置き換えることで「役立つ」結果printfですputs

あなたの例を機能させるために、\nからを削除しましたprintf。これにより、次のような出力が得られます。

 17114:     transferring control: ./hello
 17114:     
 17114:     symbol=printf;  lookup in file=./hello [0]
 17114:     symbol=printf;  lookup in file=./printhack.so [0]
 17114:     binding file ./hello [0] to ./printhack.so [0]: normal symbol `printf' [GLIBC_2.2.5]

printhack.soこれで、それが実際にそのカスタムに引きずり込まれていることがわかりますprintf

または、カスタムputs関数を定義することもできます:

static int (*orig_puts)(const char *str) = NULL;
int puts(const char *str)
{
    if (orig_puts == NULL)
    {
        orig_puts = (int (*)(const char *str))dlsym(RTLD_NEXT, "puts");
    }

    // TODO: print desired message from caller.
    return orig_puts("within my own puts");
}
于 2016-03-10T09:56:54.847 に答える
1

1) プリプロセッサの出力を確認します。printf は smth else に変更できます

gcc -E main.c

2) printf シンボルとプリロードに関する ld_debug 情報

LD_DEBUG=help LD_PRELOAD=”$mypath/PrintfHank.so” $mypath/main
LD_DEBUG=all LD_PRELOAD=”$mypath/PrintfHank.so” $mypath/main
于 2010-03-31T22:33:09.103 に答える
0

変化する

return orig_printf("within my own printf\n");

return (*orig_printf)("within my own printf\n");
于 2012-12-07T20:31:08.653 に答える