Passing variable arguments to another function that accepts a variable argument list

Viewed 130378

So I have 2 functions that both have similar arguments

void example(int a, int b, ...);
void exampleB(int b, ...);

Now example calls exampleB, but how can I pass along the variables in the variable argument list without modifying exampleB (as this is already used elsewhere too).

10 Answers

A possible way is to use #define:

#define exampleB(int b, ...)  example(0, b, __VA_ARGS__)

It might not be exactly the same situation as described here, but if you were to define a wrapper for a string format function (e.g. logger):

void logger(const char *name, const char *format, ...);
void wrapper(const char *format, ...);

when you implement a wrapper that calls logger, we can just create a string first with vasprintf and then pass it to logger.

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

static void wrapper(const char *format, ...)
{
    char *string;
    va_list args;
    va_start(args, format);

    // variadic printf with allocated string. must free()
    vasprintf(&string, format, args);
    logger("wrapper", "%s", string);

    free(string);
    va_end(args);
}

Not the cleanest, but works. Try this when you must avoid using macro functions.

This is the only way to do it.. and the best way to do it too..

static BOOL(__cdecl *OriginalVarArgsFunction)(BYTE variable1, char* format, ...)(0x12345678); //TODO: change address lolz

BOOL __cdecl HookedVarArgsFunction(BYTE variable1, char* format, ...)
{
    BOOL res;

    va_list vl;
    va_start(vl, format);

    // Get variable arguments count from disasm. -2 because of existing 'format', 'variable1'
    uint32_t argCount = *((uint8_t*)_ReturnAddress() + 2) / sizeof(void*) - 2;
    printf("arg count = %d\n", argCount);

    // ((int( __cdecl* )(const char*, ...))&oldCode)(fmt, ...);
    __asm
    {
        mov eax, argCount
        test eax, eax
        je noLoop
        mov edx, vl
        loop1 :
        push dword ptr[edx + eax * 4 - 4]
        sub eax, 1
        jnz loop1
        noLoop :
        push format
        push variable1
        //lea eax, [oldCode] // oldCode - original function pointer
        mov eax, OriginalVarArgsFunction
        call eax
        mov res, eax
        mov eax, argCount
        lea eax, [eax * 4 + 8] //+8 because 2 parameters (format and variable1)
        add esp, eax
    }
    return res;
}
Related