Section 13.7 claims that there is no obvious way to wrap functions taking a va_list parameter, like vfprintf.

This is wrong. All you have to do is wrap it with a vararg function:

int wrap_vfprintf (FILE *f, const char *fmt, ...)
{
  va_list ap;
  int result;

  va_start (ap, fmt);
  result = vfprintf (f, fmt, ap);
  va_end (ap);
  return result;
}

Then you can wrap wrap_vfprintf with the techniques described in chapter 13.