3

I have an unsigned char array unsigned char* name = malloc(nameLength); - how can I print it with printf? %sdoes not seem to work correctly, neither does %u (seeing random icons).

Here's how I create the data I want to print:

__int32 nameLength;
ReadProcessMemory(hProcess, (LPCVOID)(classNamePtr + 0x0004), &nameLength, sizeof(__int32), 0); //Reads nameLength to be 13 in this case
unsigned char* name = malloc(nameLength+5); //Add 5 for good measure, it is null terminated
ReadProcessMemory(hProcess, (LPCVOID)(nameStrPtr), name, nameLength, 0);
name[nameLength] = 0; //null terminate

printf("%s", name); //Outputs single character strange characters, like an up icon
10
  • If name contained a null-terminated string of printable characters, then the printf format %s would work. That's what it's for. What's in the array, just arbitrary numbers? Can you share a little more? Commented Jan 3, 2014 at 20:34
  • You haven't given us enough information. Read sscce.org Commented Jan 3, 2014 at 20:35
  • I've added some more information @KeithThompson Commented Jan 3, 2014 at 20:36
  • If it null-terminated, %s should work. As you have spare space at the end, try manually writing a \0 there, and try again. Commented Jan 3, 2014 at 20:40
  • @gnometorule In the code I do that - name[nameLength] = 0 Commented Jan 3, 2014 at 20:41

1 Answer 1

1

When one detects a non-printable char, output an escape sequence or hexadecimal value

#include <ctype.h>
#include <string.h>
#include <stdio.h>

int printf_ByteArray(const unsigned char *data, size_t len) {
  size_t i;
  int result = 0;
  for (i = 0; i < len; i++) {
    int y;
    int ch = data[i];
    static const char escapec[] = "\a\b\t\n\v\f\n\'\"\?\\";
    char *p = strchr(escapec, ch);
    if (p && ch) {
      static const char escapev[] = "abtnvfn\'\"\?\\";
      y = printf("\\%c", escapev[p - escapec]);
    } else if (isprint(ch)) {
      y = printf("%c", ch);
    } else {
      // If at end of array, assume _next_ potential character is a '0'.
      int nch = i >= (len - 1) ? '0' : data[i + 1];
      if (ch < 8 && (nch < '0' || nch > '7')) {
        y = printf("\\%o", ch);
      } else if (!isxdigit(nch)) {
        y = printf("\\x%X", ch);
      } else {
        y = printf("\\o%03o", ch);
      }
    }
    if (y == EOF)
      return EOF;
    result += y;
  }
  return result;
}

If data contained one of each byte, sample follows:

\0...\6\a\b\t\n\v\f\xD\xE\xF\x10...\x1F !\"#$%&\'()*+,-./0123456789:;<=>\?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7F...\xFE\o377

The selection of escape sequences will vary with code goals. The set above attempts to conform to something a C parser would accept.
Note: With the last else, always outputting a 3-digit octal sequence has scanning advantages, but folks are more accustomed to hexadecimal than octal.
Adjusted to conditionally print in hex depending on the following character.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.