简体   繁体   English

如何对 memory 中的地址执行十六进制 memory 转储?

[英]How can I perform a hex memory dump on an address in memory?

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:我正在尝试为我的计算机组织 class 编写一个 C++ 程序,其中我在存储在 memory 中的某个地址上以十六进制形式执行 memory 转储。我真的不明白什么是 memory 转储,并且我对编写 887148649 很陌生我的问题是:

  1. How can I create a method that takes two arguments in which they specify address in memory?如何创建一个采用两个 arguments 的方法,其中它们在 memory 中指定地址?
  2. How can I further modify those arguments to specify a word address that is exactly 4 bytes long?我如何进一步修改那些 arguments 以指定一个恰好 4 个字节长的字地址?
  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;
}

How to write a Hex dump tool while learning C++:如何在学习C++的同时编写一个Hex dump工具:

  1. Start with something simple:从简单的事情开始:
#include <iostream>

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

Output: Output:

M

Live demo on coliru 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: Output:

M
4d

Live demo on coliru coliru 现场演示

Note:笔记:

The stream output operator for char is intended to print a character (of course). char的 stream output 运算符旨在打印一个字符(当然)。 There is another stream output operator for unsigned which fits better.还有另一个 stream output 运算符用于unsigned更适合。 To achieve that it's used, the char has to be converted to unsigned .为了实现它的使用, char必须转换为unsigned

But be prepared: The C++ standard doesn't mandate whether char is signed or unsigned—this decision is left to the compiler vendor.但要做好准备:C++ 标准不强制要求char是有符号的还是无符号的——这个决定留给编译器供应商。 To be on the safe side, the 'char' is first converted to 'unsigned char' then converted to unsigned .为了安全起见,首先将 'char' 转换为 'unsigned char' 然后再转换为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: Output:

My sample data
0x7ffd3baf9b70

Live demo on coliru coliru 现场演示

Note:笔记:

There is one stream output operator for const char* which is intended to print a (zero-terminated) string. const char*有一个 stream output 运算符,用于打印(零终止)字符串。 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.因此,转换为const void*的(丑陋的)技巧是必要的,它会触发另一个更适合的 stream output 运算符。


  1. What if the data is not a 2 digit hex?如果数据不是 2 位十六进制怎么办?
#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: Output:

6
06

Live demo on coliru coliru 现场演示

Note:笔记:

There are I/O manipulators which can be used to modify the formatting of (some) stream output operators.有一些I/O 操纵器可用于修改(某些)stream output 运算符的格式。


  1. Now, put it all together (in loops) et voilà: a hex-dump.现在,将它们放在一起(循环)et voilà:一个十六进制转储。
#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: 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 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: 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 coliru 现场演示


  1. Make it a function:将其设为 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: 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 coliru 现场演示

Note:笔记:

(const char*)&n may look a bit adventurous. (const char*)&n可能看起来有点冒险。 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一个更好的 hexdump 可以在
SO: How would I create a hex dump utility in C++?所以:我将如何在 C++ 中创建一个十六进制转储实用程序?
(which I recommended OP beforehand). (我事先推荐了 OP)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM