Home > Net >  How can I perform a hex memory dump on an address in memory?
How can I perform a hex memory dump on an address in memory?

Time:03-04

I am trying to write a C program for my Computer Machine Organization class in which I perform a memory dump in hex on some address stored in memory. I don't really understand what a memory dump is, and am pretty new to writing C . My questions are:

  1. How can I create a method that takes two arguments in which they specify address in memory?
  2. How can I further modify those arguments to specify a word address that is exactly 4 bytes long?
  3. How can I then convert those addresses into hex values?

I know that this is a lot, but thank you for any suggestions.

For anyone who needs it, here is my code so far:

#include <stdio.h>

// Create something to do the methods on
char array[3] = {'a', 'b', 'c'};

void mdump(char start, char end){

    // Create pointers to get the address of the starting and ending characters
    char* pointer1 = (char *)& start;
    char* pointer2 = (char *)& end;

    // Check to see if starting pointer is in lower memory than ending pointer
    if(pointer1 < pointer2){
        printf("Passed");
    }
    else{
        printf("Failed");
    }

    // Modify both the arguments so that each of them are exactly 4 bytes
    // Create a header for the dump
    // Iterate through the addresses, from start pointer to end pointer, and produce lines of hex values
    // Declare a struct to format the values
    // Add code that creates printable ASCII characters for each memory location (print "cntrl-xx" for values 0-31, or map them into a blank)
    // Print the values in decimal and in ASCII form
}

int main(){
    mdump(array[0], array[2]);
    return 0;
}

CodePudding user response:

How to write a Hex dump tool while learning C :

  1. Start with something simple:
#include <iostream>

int main()
{
  char test[32] = "My sample data";
  // output character
  std::cout << test[0] << '\n';
}

Output:

M

Live demo on coliru


  1. Print the hex-value instead of the character:
#include <iostream>

int main()
{
  char test[32] = "My sample data";
  // output a character as hex-code
  std::cout << std::hex << test[0] << '\n'; // Uh oh -> still a character
  std::cout << std::hex << (unsigned)(unsigned char)test[0] << '\n';
}

Output:

M
4d

Live demo on coliru

Note:

The stream output operator for char is intended to print a character (of course). There is another stream output operator for unsigned which fits better. To achieve that it's used, the char has to be converted to unsigned.

But be prepared: The C standard doesn't mandate whether char is signed or unsigned—this decision is left to the compiler vendor. To be on the safe side, the 'char' is first converted to 'unsigned char' then converted to unsigned.


  1. Print the address of the variable with the character:
#include <iostream>

int main()
{
  char test[32] = "My sample data";
  // output an address
  std::cout << &test[0] << '\n'; // Uh oh -> wrong output stream operator
  std::cout << (const void*)&test[0] << '\n';
}

Output:

My sample data
0x7ffd3baf9b70

Live demo on coliru

Note:

There is one stream output operator for const char* which is intended to print a (zero-terminated) string. This is not what is intended. Hence, the (ugly) trick with the cast to const void* is necessary which triggers another stream output operator which fits better.


  1. What if the data is not a 2 digit hex?
#include <iomanip>
#include <iostream>

int main()
{
  // output character as 2 digit hex-code
  std::cout << (unsigned)(unsigned char)'\x6' << '\n'; // Uh oh -> output not with two digits
  std::cout << std::hex << std::setw(2) << std::setfill('0')
    << (unsigned)(unsigned char)'\x6' << '\n';
}

Output:

6
06

Live demo on coliru

Note:

There are I/O manipulators which can be used to modify the formatting of (some) stream output operators.


  1. Now, put it all together (in loops) et voilà: a hex-dump.
#include <iomanip>
#include <iostream>

int main()
{
  char test[32] = "My sample data";
  // output an address
  std::cout << (const void*)&test[0] << ':';
  // output the contents
  for (char c : test) {
    std::cout << ' '
      << std::hex << std::setw(2) << std::setfill('0')
      << (unsigned)(unsigned char)c;
  }
  std::cout << '\n';
}

Output:

0x7ffd345d9820: 4d 79 20 73 61 6d 70 6c 65 20 64 61 74 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Live demo on coliru


  1. Make it nice:
#include <algorithm>
#include <iomanip>
#include <iostream>

int main()
{
  char test[32] = "My sample data";
  // hex dump
  const size_t len = sizeof test;
  for (size_t i = 0; i < len; i  = 16) {
    // output an address
    std::cout << (const void*)&test[i] << ':';
    // output the contents
    for (size_t j = 0, n = std::min<size_t>(len - i, 16); j < n;   j) {
      std::cout << ' '
        << std::hex << std::setw(2) << std::setfill('0')
        << (unsigned)(unsigned char)test[i   j];
    }
    std::cout << '\n';
  }
}

Output:

0x7fffd341f2b0: 4d 79 20 73 61 6d 70 6c 65 20 64 61 74 61 00 00
0x7fffd341f2c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Live demo on coliru


  1. Make it a function:
#include <algorithm>
#include <iomanip>
#include <iostream>

void hexdump(const char* data, size_t len)
{
  // hex dump
  for (size_t i = 0; i < len; i  = 16) {
    // output an address
    std::cout << (const void*)&data[i] << ':';
    // output the contents
    for (size_t j = 0, n = std::min<size_t>(len - i, 16); j < n;   j) {
      std::cout << ' '
        << std::hex << std::setw(2) << std::setfill('0')
        << (unsigned)(unsigned char)data[i   j];
    }
    std::cout << '\n';
  }
}

int main()
{
  char test[32] = "My sample data";
  std::cout << "dump test:\n";
  hexdump(test, sizeof test);
  std::cout << "dump 4 bytes of test:\n";
  hexdump(test, 4);
  std::cout << "dump an int:\n";
  int n = 123;
  hexdump((const char*)&n, sizeof n);
}

Output:

dump test:
0x7ffe900f4ea0: 4d 79 20 73 61 6d 70 6c 65 20 64 61 74 61 00 00
0x7ffe900f4eb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
dump 4 bytes of test:
0x7ffe900f4ea0: 4d 79 20 73
dump an int:
0x7ffe900f4e9c: 7b 00 00 00

Live demo on coliru

Note:

(const char*)&n may look a bit adventurous. In fact, conversion of pointers is always something which should be at best not necessary. However, for the dump tool this is the easiest way to access the bytes of arbitrary data. (This is one of the rare cases which is explicitly allowed by the standard.)


An even nicer hexdump can be found in
SO: How would I create a hex dump utility in C ?
(which I recommended OP beforehand).

  • Related