2009-10-16 5 views
2

내 프로젝트 중 하나에서 glibc의 printf()를 해킹하고 일부 문제가 발생했습니다. 몇 가지 단서를 주시겠습니까? 그리고 내 관심사 중 하나는 왜 malloc/free에 대한 동일한 솔루션이 완벽하게 작동하는지입니다!LD_PRELOAD 메서드를 사용하여 printf에 주입 할 때의 문제

"PrintfHank.c"에는 표준 라이브러리보다 먼저 미리로드되는 printf() 솔루션이 포함되어 있습니다. "main.c"는 printf()를 사용하여 문장을 출력합니다. 두 개의 파일을 편집 한 후, 나는 다음과 같은 명령을 발행 :

  1. 컴파일 main.c에 GCC 내 자신의 라이브러리
  2. 주요 main.c의를 -o 만들 -Wall을 의 gcc -Wall -fPIC -shared -o PrintfHank.so PrintfHank.c -ldl
  3. 테스트의 주요 새 라이브러리 LD_PRELOAD = "$의 MYPATH/PrintfHank.so"$의 MYPATH/

하지만 콘솔에서 "내 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"); 
} 

답변

1

체크 1) 전처리 출력. printf와는이 질문은 고대이다

gcc -E main.c 

2) LD_DEBUG printf의 기호에 대한 정보와

LD_DEBUG=help LD_PRELOAD=”$mypath/PrintfHank.so” $mypath/main 
LD_DEBUG=all LD_PRELOAD=”$mypath/PrintfHank.so” $mypath/main 
1

변경

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

return (*orig_printf)("within my own printf\n"); 
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] 

printf의 실제 언급을 볼 수 있습니다 (I 다소 파일을 이름을 변경했습니다). puts은 기본적으로 형식이없고 마지막에 자동 줄 바꿈이없는 printf이므로이 내용은 printfputs으로 대체하여 gcc가 "도움이되는"결과입니다.지금은 printhack.so가 실제로는 사용자 정의 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] 

:

내가 나에게 같은 출력을 제공하는의 printf에서 \n을 제거, 귀하의 예제를 작동하게합니다.

또는, 당신은뿐만 아니라 사용자 정의 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"); 
} 
+0

) (풋에 함수의 printf()를 변경하는 GCC를 해제하는 방법이 있나요? – bawejakunal

관련 문제