2016-10-04 3 views
1

저는 현재 LD_PRELOAD 트릭을 사용 중이며 링커 버전 스크립트 as detailed in an article on another website을 사용하고 있습니다. 내 MCVE 코드는 아래에 포함되어 있습니다.링커 스크립트를 통해 라이브러리 함수 끼우기 : 다른 함수는 segfault를 발생시킵니다.

#define _GNU_SOURCE 
#include <dlfcn.h> 
#include <stdio.h> 
#include <stdarg.h> 
#include <string.h> 
#include <unistd.h> 
#define BUFFER_SIZE  (1024) 


int __printf__(const char *fmt, ...) 
{ 
    char buf[BUFFER_SIZE] = { 0 }; 
    int ret; 
    int len; 
    va_list args; 
    va_start(args, fmt); 

    vsnprintf(buf, BUFFER_SIZE - 1, fmt, args); 

#if 1 
    //typeof(vsnprintf) *real_func = dlsym(RTLD_NEXT, "vsnprintf"); 
    //(*real_func)(buf, BUFFER_SIZE - 1, fmt, args); 
#endif 

    len = strlen(buf); 
    ret = write(STDOUT_FILENO, buf, len); 
    va_end(args); 

    return ret; 
} 
asm(".symver __printf__, [email protected]_2.3.4"); 

사용자 정의 printf 함수를 수정하여 정적 문자열을 쓰면 문제가 없습니다. 그러나, 나는 printf (접두사, 접미사를 추가하고 대문자에 특정 문자를 설정하는 등)을 통해 콘솔에 전송되는 데이터를 수정하려고합니다. 다른 모든 printf -family 함수를 사용하여 사용자가 제공 한 문자열의 사본을 생성하려고 시도 할 때마다 아래와 같이 segfault가 표시되는 것으로 보입니다.

Program received signal SIGSEGV, Segmentation fault. 
strchrnul() at ../sysdeps/x86_64/strchr.S:32 
32 ../sysdeps/x86_64/strchr.S: No such file or directory. 
(gdb) bt 
#0 strchrnul() at ../sysdeps/x86_64/strchr.S:32 
#1 0x00007ffff78591c8 in __find_specmb (format=0x1 <error: Cannot access memory at address 0x1>) at printf-parse.h:108 
#2 _IO_vfprintf_internal ([email protected]=0x7fffffffc380, [email protected]=0x1 <error: Cannot access memory at address 0x1>, [email protected]=0x7fffffffc4f8) at vfprintf.c:1312 
#3 0x00007ffff7882989 in _IO_vsnprintf (string=0x7fffffffc510 "", maxlen=<optimized out>, format=0x1 <error: Cannot access memory at address 0x1>, args=0x7fffffffc4f8) 
    at vsnprintf.c:114 
#4 0x00007ffff7bd58a1 in __printf__ (fmt=0x1 <error: Cannot access memory at address 0x1>) at libfakeprintf.c:19 
#5 0x00000000004004aa in printf (__fmt=0x400644 "%s received %d args\n") at /usr/include/x86_64-linux-gnu/bits/stdio2.h:104 
#6 main (argc=<optimized out>, argv=<optimized out>) at print_args.c:5 
(gdb) quit 

이 충돌의 원인은 무엇입니까?

감사합니다.

답변

2

glibc 내부 함수 __printf_chk을 재정의했지만이 함수에는 printf와 일치하는 프로토 타입이 없습니다. 그것은의 프로토 타입은 다음과 같습니다

int __printf_chk(int flag, const char * format, ...); 

그래서 자신의 __printf__ 기능은 그 프로토 타입을 너무 가지고 있는지 확인하십시오. 간단한 설명이 __printf_chk here

입니다.
관련 문제