Skip to content

Instantly share code, notes, and snippets.

@cosysn
Created April 11, 2017 08:57
Show Gist options
  • Save cosysn/64596fe3f6eb1ec167c0047832295d9e to your computer and use it in GitHub Desktop.
Save cosysn/64596fe3f6eb1ec167c0047832295d9e to your computer and use it in GitHub Desktop.
移植 Linux Kernel 的 print_hex_dump 函数到 Windows 驱动中,帮助 dump 二进制数据。
CHAR hex_asc[] = "0123456789abcdef";
#define hex_asc_lo(x) hex_asc[((x) & 0x0f)]
#define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4]
#define TracePrintEx(Fmt, ...) \
do\
{\
DbgPrintEx(DPFLTR_FASTFAT_ID, DPFLTR_ERROR_LEVEL, Fmt, __VA_ARGS__); \
}while (0)
INT32 hex_dump_to_buffer(PVOID buf, INT32 len, INT32 rowsize, INT32 groupsize,
PCHAR linebuf, INT32 linebuflen, BOOLEAN ascii)
{
const PUINT8 ptr = (PUINT8)buf;
INT32 ngroups = 0;;
UINT8 ch;
INT32 j, lx = 0;
INT32 ascii_column = 0;
INT32 ret = 0;
if (rowsize != 16 && rowsize != 32)
rowsize = 16;
if (len > rowsize) /* limit to one line at a time */
len = rowsize;
if ((len % groupsize) != 0) /* no mixed size output */
groupsize = 1;
ngroups = len / groupsize;
ascii_column = rowsize * 2 + rowsize / groupsize + 1;
if (!linebuflen)
goto overflow1;
if (!len)
goto nil;
if (groupsize == 8) {
PUINT64 ptr8 = (PUINT64)buf;
for (j = 0; j < ngroups; j++) {
ret = RtlStringCbPrintfA(linebuf + lx, linebuflen - lx,
"%s%16.16llx", j ? " " : "",
(PUINT64)(ptr8 + j));
if (ret >= linebuflen - lx)
goto overflow1;
lx += ret;
}
}
else if (groupsize == 4) {
PUINT32 ptr4 = (PUINT32)buf;
for (j = 0; j < ngroups; j++) {
ret = RtlStringCbPrintfA(linebuf + lx, linebuflen - lx,
"%s%8.8x", j ? " " : "",
(PUINT32)(ptr4 + j));
if (ret >= linebuflen - lx)
goto overflow1;
lx += ret;
}
}
else if (groupsize == 2) {
PUINT16 ptr2 = (PUINT16)buf;
for (j = 0; j < ngroups; j++) {
ret = RtlStringCbPrintfA(linebuf + lx, linebuflen - lx,
"%s%4.4x", j ? " " : "",
(PUINT16)(ptr2 + j));
if (ret >= linebuflen - lx)
goto overflow1;
lx += ret;
}
}
else {
for (j = 0; j < len; j++) {
if (linebuflen < lx + 2)
goto overflow2;
ch = ptr[j];
linebuf[lx++] = hex_asc_hi(ch);
if (linebuflen < lx + 2)
goto overflow2;
linebuf[lx++] = hex_asc_lo(ch);
if (linebuflen < lx + 2)
goto overflow2;
linebuf[lx++] = ' ';
}
if (j)
lx--;
}
if (!ascii)
goto nil;
while (lx < ascii_column) {
if (linebuflen < lx + 2)
goto overflow2;
linebuf[lx++] = ' ';
}
for (j = 0; j < len; j++) {
if (linebuflen < lx + 2)
goto overflow2;
ch = ptr[j];
linebuf[lx++] = ch;
}
nil:
linebuf[lx] = '\0';
return lx;
overflow2:
linebuf[lx++] = '\0';
overflow1:
return ascii ? ascii_column + len : (groupsize * 2 + 1) * ngroups - 1;
}
void TracePrintHexDump(PVOID pBuffer, INT32 BufferLen)
{
PUINT8 ptr = (PUINT8)pBuffer;
INT32 i, linelen, remaining = BufferLen;
CHAR linebuf[32 * 3 + 2 + 32 + 1];
INT32 rowsize = 32;
INT32 groupsize = 1;
BOOLEAN ascii = TRUE;
if (rowsize != 16 && rowsize != 32)
rowsize = 16;
for (i = 0; i < BufferLen; i += rowsize) {
linelen = min(remaining, rowsize);
remaining -= rowsize;
hex_dump_to_buffer((PVOID)(ptr + i), linelen, rowsize, groupsize,
linebuf, (INT32)sizeof(linebuf), ascii);
TracePrintEx("%08x: %s\n", i, linebuf);
}
}
@cosysn
Copy link
Author

cosysn commented Apr 11, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment