您的位置:首页 > 编程语言 > C语言/C++

How to create a hex dump from binary data in C++

2013-04-15 18:36 671 查看
http://stahlworks.com/dev/index.php?tool=csc01

How to create a hex dump from binary data in C++ with a few lines of code:
free source code examples for instant use in any project, for windows and linux.

starting point: let's say we have a simple program like this:

#include <stdio.h>

int main(int argc, char *argv[])
{
char abStack[100];

printf("hello world, abStack == %p\n", abStack);
}

and we want to see the binary contents of abStack in a well-formatted hex dump.

solution 1: triple-column hex dump with ASCII representation

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

void hexdump(void *pAddressIn, long  lSize)
{
char szBuf[100];
long lIndent = 1;
long lOutLen, lIndex, lIndex2, lOutLen2;
long lRelPos;
struct { char *pData; unsigned long lSize; } buf;
unsigned char *pTmp,ucTmp;
unsigned char *pAddress = (unsigned char *)pAddressIn;

buf.pData   = (char *)pAddress;
buf.lSize   = lSize;

while (buf.lSize > 0)
{
pTmp     = (unsigned char *)buf.pData;
lOutLen  = (int)buf.lSize;
if (lOutLen > 16)
lOutLen = 16;

// create a 64-character formatted output line:
sprintf(szBuf, " >                            "
"                      "
"    %08lX", pTmp-pAddress);
lOutLen2 = lOutLen;

for(lIndex = 1+lIndent, lIndex2 = 53-15+lIndent, lRelPos = 0;
lOutLen2;
lOutLen2--, lIndex += 2, lIndex2++
)
{
ucTmp = *pTmp++;

sprintf(szBuf + lIndex, "%02X ", (unsigned short)ucTmp);
if(!isprint(ucTmp))  ucTmp = '.'; // nonprintable char
szBuf[lIndex2] = ucTmp;

if (!(++lRelPos & 3))     // extra blank after 4 bytes
{  lIndex++; szBuf[lIndex+2] = ' '; }
}

if (!(lRelPos & 3)) lIndex--;

szBuf[lIndex  ]   = '<';
szBuf[lIndex+1]   = ' ';

printf("%s\n", szBuf);

buf.pData   += lOutLen;
buf.lSize   -= lOutLen;
}
}

int main(int argc, char *argv[])
{
char abStack[100];

printf("hello world, dump of abStack follows:\n");
hexdump(abStack, 100);
}

example output:

hello world, dump of abStack follows:
>08080000 00000000 00003200 88000000< ..........2..... 00000000
>08080000 781B3200 00003200 8CFC1200< ....x.2...2..... 00000010
>90FC1200 B0FF1200 F088F977 94BEF477< ...........w...w 00000020
>9161E577 D0FE1200 B8FE1200 999E3600< .a.w..........6. 00000030
>00000000 E0FE1200 1B504000 D0FE1200< .........P@..... 00000040
>04904000 27B243B6 03000000 A6D26C36< ..@.'.C.......l6 00000050
>CA00C701<                            ....             00000060


the above hexdump() function provides

the raw binary data as hex values, in groups of 4 bytes, with 16 bytes per line

an ascii representation of the data, where printable

the hex offset of each record (line)

if you don't want the output on terminal but, for example, into a file-based tracing system like mtk, simply change the printf statement within hexdump().

the above example dumps only 16 data bytes per record. if you need
something more compact, try this:

solution 2: hex dump with 32 data bytes, 85 chars per output line

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

void hexdump(void *pAddressIn, long  lSize)
{
char szBuf[100];
long lIndent = 1;
long lOutLen, lIndex, lIndex2, lOutLen2;
long lRelPos;
struct { char *pData; unsigned long lSize; } buf;
unsigned char *pTmp,ucTmp;
unsigned char *pAddress = (unsigned char *)pAddressIn;

buf.pData   = (char *)pAddress;
buf.lSize   = lSize;

while (buf.lSize > 0)
{
pTmp     = (unsigned char *)buf.pData;
lOutLen  = (int)buf.lSize;
if (lOutLen > 32)
lOutLen = 32;

// create a 85-character formatted output line:
sprintf(szBuf, "                              "
"                              "
"              [%08lX]", pTmp-pAddress);
lOutLen2 = lOutLen;

for(lIndex = lIndent, lRelPos = 0;
lOutLen2;
lOutLen2--, lIndex += 2
)
{
ucTmp = *pTmp++;

sprintf(szBuf + lIndex, "%02X ", (unsigned short)ucTmp);

if (!(++lRelPos & 3))     // extra blank after 4 bytes
lIndex++;
}

if (!(lRelPos & 3)) lIndex--;

szBuf[lIndex+1] = ' ';

printf("%s\n", szBuf);

buf.pData   += lOutLen;
buf.lSize   -= lOutLen;
}
}

int main(int argc, char *argv[])
{
char abStack[100];

printf("hello world, dump of abStack follows:\n");
hexdump(abStack, 100);
}

example output follows (some bytes in the middle have been replaced by "(...)"):

hello world, dump of abStack follows:
08080000 00000000 00003200 (...) 781B3200 00003200 8CFC1200  [00000000]
90FC1200 B0FF1200 F088F977 (...) D0FE1200 B8FE1200 999E3600  [00000020]
00000000 E0FE1200 5B4D4000 (...) 852A9A06 05000000 8C3F15E2  [00000040]
CD00C701                   (...)                             [00000060]

the most compact solution uses only 76 characters per output line:

solution 3: hex dump with 32 data bytes, 76 chars per output line

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

void hexdump(void *pAddressIn, long  lSize)
{
char szBuf[100];
long lIndent = 0;
long lOutLen, lIndex, lIndex2, lOutLen2;
long lRelPos;
struct { char *pData; unsigned long lSize; } buf;
unsigned char *pTmp,ucTmp;
unsigned char *pAddress = (unsigned char *)pAddressIn;

buf.pData   = (char *)pAddress;
buf.lSize   = lSize;

while (buf.lSize > 0)
{
pTmp     = (unsigned char *)buf.pData;
lOutLen  = (int)buf.lSize;
if (lOutLen > 32)
lOutLen = 32;

// create a 76-character formatted output line:
sprintf(szBuf, "                              "
"                              "
"      [%08lX]", pTmp-pAddress);
lOutLen2 = lOutLen;

for(lIndex = lIndent, lRelPos = 0;
lOutLen2;
lOutLen2--, lIndex += 2
)
{
ucTmp = *pTmp++;
sprintf(szBuf + lIndex, "%02X ", (unsigned short)ucTmp);
}

szBuf[lIndex+1] = ' ';

printf("%s\n", szBuf);

buf.pData   += lOutLen;
buf.lSize   -= lOutLen;
}
}

int main(int argc, char *argv[])
{
char abStack[100];

printf("hello world, dump of abStack follows:\n");
hexdump(abStack, 100);
}

example output follows (some bytes in the middle have been replaced by "(...)"):

080800000000000000003200 (...) 781B3200000032008CFC1200  [00000000]
90FC1200B0FF1200F088F977 (...) D0FE1200B8FE1200999E3600  [00000020]
00000000E0FE12002B4D4000 (...) AE6E71210500000054B6122D  [00000040]
CE00C701                 (...)                           [00000060]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐