2009-10-16 19 views
2

Je piratais printf() de la glibc dans l'un de mes projets et j'ai rencontré un problème. Pourriez-vous s'il vous plaît donner quelques indices? Et une de mes préoccupations est pourquoi la même solution pour malloc/free fonctionne parfaitement! Comme ci-joint, "PrintfHank.c" contient ma propre solution de printf() qui sera préchargé avant la bibliothèque standard; et "main.c" sort juste une phrase en utilisant printf(). Après avoir modifié deux fichiers, j'envoyaient des commandes suivantes:Problèmes lors de l'injection dans printf à l'aide de la méthode LD_PRELOAD

  1. main.c compilation gcc -Wall -o principale main.c
  2. Créer ma propre bibliothèque gcc -Wall -fPIC -shared -o PrintfHank.so PrintfHank.c de
  3. test de la nouvelle bibliothèque LD_PRELOAD = » monchemin de $/PrintfHank.so » monchemin de $/main

Mais j'ai reçu "bonjour monde" au lieu de "dans mon propre printf" dans la console. Lors du piratage de fonctions malloc/free, c'est bon.

Je me connecte à mon système en tant que "root" et j'utilise 2.6.23.1-42.fc8-i686. Tous les commentaires seront très appréciés !!

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"); 
} 

Répondre

1

Vérifier 1) de sortie de préprocesseur. printf peut être changé pour SMTH autre

gcc -E main.c 

2) info LD_DEBUG au sujet symbole printf et le préchargement

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

changement

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

à

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

Cette question est ancienne cependant:

Dans votre main.c, vous avez une nouvelle ligne à la fin et n'utilisez pas la capacité de formatage de printf.

Si je regarde la sortie de LD_DEBUG=all LD_PRELOAD=./printhack.so hello 2>&1 (je l'ai rebaptisés vos fichiers un peu), puis près du fond, je peux voir

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] 

et aucune mention réelle de printf. puts est fondamentalement printf sans le formatage et avec un saut de ligne automatique à la fin, donc évidemment le résultat de gcc étant "utile" en remplaçant le printf par un .

Pour rendre votre exemple, le travail, j'ai enlevé le \n du printf, ce qui me donne une sortie comme:

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] 

Maintenant, je peux voir que printhack.so est en effet d'être traînés dans sa coutume printf.

Vous pouvez également définir une fonction personnalisée puts ainsi:

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

Yat-il un moyen de désactiver gcc de changer printf() de fonction puts()? – bawejakunal