Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

365
Visualizações
Printing variable number of bytes using format strings with printf

Goal: Print variable number of bytes using a single format specifier.

Environment: x86-64 Ubuntu 20.04.3 LTS running in VM on an x86-64 host machine.

Example:

Let %kmagic be the format specifier I am looking for which prints k bytes by popping them from the stack and additing them to the output. Then, for %rsp pointing to a region in memory holding bytes 0xde 0xad 0xbe 0xef, I want printf("Next 4 bytes on the stack: %4magic") to print Next 4 bytes on the stack: deadbeef.

What I tried so far:

  1. %khhx, which unfortunately just results in k-1 blank spaces followed by two hex-characters (one byte of data).
  2. %kx, which I expected to print k/2 bytes interpreted as one number. This only prints 8 hex-characters (4 bytes) prepended by k - 8 blank spaces.

The number of non-blank characters printed matches the length of the format specifiers, i.e. the expected length of %hhx is 2, which is also the number of non-blank characters printed. The same holds for %x, which one expects to print 8 characters.

Question: Is it possible to get the desired behavior? If so, how?

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Is it possible to get the desired behavior? If so, how?

There does not exist printf format specifier to do what you want.

Is it possible

Write your own printf implementation that supports what you want. Use implementation-specific tools to create your own printf format specifier. You can take inspiration from linux kernel printk %*phN format speciifer.

over 4 years ago · Santiago Trujillo Relatório

0

It is not possible to using standard printf. You need to write your own function and customize the printf function.

http://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html

Example (simple dump):

int printdump (FILE *stream, const struct printf_info *info, const void *const *args)
{
    const unsigned char *ptr = *(const unsigned char **)args[0];
    size_t size = *(size_t*)args[1];
    for(size_t i = 1; i <= size; i++)
    {
        fprintf(stream, "%02X%c", ptr[i-1], i % 8 ? ' ' : '\n');
    }
  return 1;
}

int printdumpargs (const struct printf_info *info, size_t n, int *argtypes)
{
  if (n == 2)
    argtypes[0] = PA_POINTER;
    argtypes[1] = PA_INT;
  return 2;
}

int main(void)
{
    double x[4] = {456543645.6786e45, 456543654, 1e345, -345.56e67};
    register_printf_function ('Y', printdump, printdumpargs);

    printf("%Y\n", &x, sizeof(x));
}

As I see it is depreciated now (probably no one was using it)

https://godbolt.org/z/qKs6e1d9q

Output:

30 18 CB 5A EF 10 13 4B
00 00 00 A6 4D 36 BB 41
00 00 00 00 00 00 F0 7F
C4 5D ED 48 9C 05 60 CE
over 4 years ago · Santiago Trujillo Relatório

0

There is no standard conversion specifier for your purpose, but you can achieve your goal in C99 using an ancillary function and dynamic array:

#include <stdio.h>

char *dump_bytes(char *buf, const void *p, size_t count) {
    const unsigned char *src = p;
    char *dest = buf;
    while (count --> 0) {
        dest += sprintf(dest, "%.2X", *src++);
        if (count)
            *dest++ = ' ';
    }
    *dest = '\0';  // return an empty sting for an empty memory chunk
    return buf;
}

int main() {
    long n = 0x12345;
    printf("n is at address %p with contents: %s\n",
           (void *)&n,
           dump_bytes((char[3 * sizeof(n)]){""}, &n, sizeof(n)));
    return 0;
}

Output: n is at address 0x7fff523f57d8 with contents: 45 23 01 00 00 00 00 00

You can use a macro for simpler invocation:

#define DUMPBYTES(p, n)  dump_bytes((char[3 * (n)]){""}, p, n)

int main() {
    char *p = malloc(5);
    printf("allocated 5 bytes at address %p with contents: %s\n",
           p, DUMPBYTES(p, 5));
    free(p);
    return 0;
}
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda