?? bat.c
字號:
/* * (c) petter wahlman, badeip@binary-art.net * * binary analysis tool: combined cat, dd, hexdump * * To get colorized output with a pager, use e.g 'less' * with -R * * */#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <unistd.h>#include <ctype.h>#include <getopt.h>#include <signal.h>#include <string.h>#include <arpa/inet.h>#include <sys/types.h>#include <sys/stat.h>#include <bat.h>static u32 opt_hex_print = 0;static u32 opt_verbose = 0;static u32 opt_count = 0;u32 print_usage(void){ fprintf(stderr, "by petter wahlman. badeip@binary-art.net\n"); fprintf(stderr, "usage: bat source [option(s)]\n" " -s, --soff <offset>\n" " -d, --doff <offset>\n" " -c, --count <bytes> dump #bytes data\n" " -h, --hex dump output in hex/dwords/ascii\n" " -W, --nodwords don't display 32-bit hex values\n" " -C, --nocolors don't use colorized output\n" " -e, --eswap swap endianness of 32-bit values in hex output\n" " -v, --verbose display verbose output [only if printing to terminal]\n" "\n" ); exit(1);}#define HEX_SWAP_ENDIAN 1#define HEX_PRINT_DWORDS 2#define HEX_PRINT_COLORS 4off_t g_src_offset;u32 g_quit = 0;void sigint_handler(s32 sig) { g_quit = 1; }static void hex_print(s32 fd, u8 *data, u32 bytes, u32 flags){ s8 line[512]; s32 i; if (!bytes) return; i = 0; while (i < bytes) { u32 idx, len, chunk, values; u32 colorize; len = 0; //---[ offset: ]--- len += sprintf(line, "0x%08lx |", g_src_offset); //---[ 4 chunks of 4 characters ]--- idx = 0; colorize = 0; for (chunk = 0; chunk < 4; chunk++) { colorize ^= 1; if (colorize && (flags & HEX_PRINT_COLORS)) len += sprintf(&line[len], LIGHT); //---[ 1 * 4 chars ]--- values = 0; while (values++ < 4) len += sprintf(&line[len], "%.2x ", data[i + idx++]); if (flags & HEX_PRINT_COLORS) len += sprintf(&line[len], NORMAL); } len += sprintf(&line[len], "|"); //---[ 4 * 1 dword ]---- idx = 0; if (flags & HEX_PRINT_DWORDS) { values = 0; while (values++ < 4) { colorize ^= 1; if (colorize && (flags & HEX_PRINT_COLORS)) len += sprintf(&line[len], LIGHT); len += sprintf(&line[len], "%.8x ", flags & HEX_SWAP_ENDIAN ? htonl(*(u32 *)&data[i + idx]) : *(u32 *)&data[i + idx]) ; idx += sizeof(u32); if (flags & HEX_PRINT_COLORS) len += sprintf(&line[len], NORMAL); } len += sprintf(&line[len], "|"); } //---[ 16 * 1 chars ]---- idx = 0; values = 0; while (values++ < 16) { if (isprint(data[i + idx])) len += sprintf(&line[len], "%c", data[i + idx++]); else { if (flags & HEX_PRINT_COLORS) { sprintf(&line[len], RED); len += strlen(RED); } len += sprintf(&line[len], "."), idx++; if (flags & HEX_PRINT_COLORS) { sprintf(&line[len], NORMAL); len += strlen(NORMAL); } } } len += sprintf(&line[len], "|"); i += 16; g_src_offset += 16; puts(line); if (g_quit) { printf("bye\n"); break; } } return;}int main(int argc, char **argv){ struct sigaction act; struct stat st; off_t soff, doff; u8 buf[8192]; s8 *source; s8 *dest; u32 hex_flags; u32 blocksize; u32 count; u32 fd, fdd; u32 nr; u32 rc = 1; soff = 0; doff = 0; count = 0; fd = fileno(stdin); fdd = fileno(stdout); blocksize = sizeof(buf); hex_flags = HEX_PRINT_DWORDS | HEX_PRINT_COLORS; // handle SIGINT: act.sa_handler = sigint_handler; act.sa_flags = 0; sigemptyset (&act.sa_mask); sigaction(SIGINT, &act, NULL); sigaction(SIGQUIT, &act, NULL); while (1) { u32 c; s32 option_index = 0; static struct option long_options[] = { { "soff", 1, 0, 's' }, { "doff", 1, 0, 'd' }, { "count", 1, 0, 'c' }, { "hex", 0, 0, 'x' }, { "nodwords",0, 0, 'W' }, { "nocolors",0, 0, 'C' }, { "eswap", 0, 0, 'e' }, { "verbose", 0, 0, 'v' }, { NULL, 0, 0, 0 } }; c = getopt_long(argc, argv, "s:d:c:hWCexv", long_options, &option_index); if (-1 == c) break; switch (c) { case 's': soff = strtoul(optarg, NULL, 0x0); break; case 'd': doff = strtoul(optarg, NULL, 0x0); break; case 'c': count = strtoul(optarg, NULL, 0x0); opt_count = 1; break; case 'x': opt_hex_print = 1; break; case 'W': hex_flags &= ~HEX_PRINT_DWORDS; break; case 'C': hex_flags &= ~HEX_PRINT_COLORS; break; case 'e': hex_flags |= HEX_SWAP_ENDIAN; break; case 'v': if (isatty(1)) opt_verbose = 1; break; default: print_usage(); } } if (argc > optind) { source = argv[optind++]; fd = open(source, O_RDONLY); if (-1 == fd) { perror(source); return rc; } fstat(fd, &st); if (soff > st.st_size) { fprintf(stderr, "source offset: 0x%08lx > file size: 0x%08lx\n", soff, st.st_size); return rc; } g_src_offset = lseek(fd, soff, SEEK_SET); if (((off_t)-1 == g_src_offset) || (soff != g_src_offset)) { fprintf(stderr, "unable to seek to offset: 0x%08lx\n", soff); close(fd); return rc; } } else // can't seek on stdin soff = 0; if (argc > optind) { dest = argv[optind++]; fdd = open(dest, O_WRONLY | O_CREAT, 0644); if (-1 == fdd) { perror(dest); close(fd); return rc; } fstat(fd, &st); if (soff > st.st_size) { fprintf(stderr, "offset: 0x%08lx > file size: 0x%08lx\n", soff, st.st_size); return rc; }#if 1 // this is legal, but rarely wanted: if (doff != lseek(fdd, doff, SEEK_SET)) { fprintf(stderr, "unable to seek to offset: 0x%08lx\n", soff); close(fd); return rc; } #endif } else // can't seek on stdout doff = 0; if (opt_verbose) { printf("src: offset: 0x%08lx (%.10ld): %s\n", soff, soff, source ? source : "stdin"); printf("dst: offset: 0x%08lx (%.10ld): %s\n\n", doff, doff, dest ? dest : "stdout"); } if (opt_count) { if (blocksize > count) blocksize = count; } nr = 0; do { if (opt_count) { count -= nr; if (!count) break; if (blocksize > count) blocksize = count; } nr = read(fd, buf, blocksize); if (-1 == nr) break; opt_hex_print ? hex_print(fdd, buf, nr, hex_flags) : write(fdd, buf, nr); if (g_quit) break; } while(nr); close(fd); if (dest) close(fdd); return 0;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -