From 4940661658c604464609b0e9cf4bf353a265c2db Mon Sep 17 00:00:00 2001 From: Cody Harrington Date: Sun, 28 Aug 2016 03:01:18 +1200 Subject: [PATCH] ndrdump: Add the option --hex-input for hexdump parsing This allows the user to input a hexdump that has been generated by the dump option. Signed-off-by: Cody Harrington Reviewed-by: Garming Sam Reviewed-by: Andrew Bartlett --- lib/util/samba_util.h | 13 +++++++++---- lib/util/util.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- librpc/tools/ndrdump.c | 22 +++++++++++++++------- 3 files changed, 66 insertions(+), 13 deletions(-) diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h index 3f663690247..8aa8ebae3b9 100644 --- a/lib/util/samba_util.h +++ b/lib/util/samba_util.h @@ -122,7 +122,7 @@ _PUBLIC_ char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len); * Characters used are: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#., */ _PUBLIC_ char** generate_unique_strs(TALLOC_CTX *mem_ctx, size_t len, - uint32_t num); + uint32_t num); /* The following definitions come from lib/util/dprintf.c */ @@ -176,6 +176,11 @@ _PUBLIC_ size_t strhex_to_str(char *p, size_t p_len, const char *strhex, size_t _PUBLIC_ _PURE_ DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex) ; /** + * Parse a hex dump and return a data blob + */ +_PUBLIC_ _PURE_ DATA_BLOB hexdump_to_data_blob(TALLOC_CTX *mem_ctx, const char *hexdump, size_t len); + +/** * Print a buf in hex. Assumes dst is at least (srclen*2)+1 large. */ _PUBLIC_ void hex_encode_buf(char *dst, const uint8_t *src, size_t srclen); @@ -587,7 +592,7 @@ _PUBLIC_ void daemon_status(const char *name, const char *msg); * @param[in] prompt The prompt to show to ask for the password. * * @param[out] buf The buffer the password should be stored. It NEEDS to be - * empty or filled out. + * empty or filled out. * * @param[in] len The length of the buffer. * @@ -604,8 +609,8 @@ _PUBLIC_ int samba_getpass(const char *prompt, char *buf, size_t len, * Load a ini-style file. */ bool pm_process( const char *fileName, - bool (*sfunc)(const char *, void *), - bool (*pfunc)(const char *, const char *, void *), + bool (*sfunc)(const char *, void *), + bool (*pfunc)(const char *, const char *, void *), void *userdata); bool pm_process_with_flags(const char *filename, bool allow_empty_values, diff --git a/lib/util/util.c b/lib/util/util.c index 56056a3403c..a8f2e00a82d 100644 --- a/lib/util/util.c +++ b/lib/util/util.c @@ -903,8 +903,8 @@ _PUBLIC_ size_t strhex_to_str(char *p, size_t p_len, const char *strhex, size_t return num_chars; } -/** - * Parse a hex string and return a data blob. +/** + * Parse a hex string and return a data blob. */ _PUBLIC_ _PURE_ DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex) { @@ -918,6 +918,46 @@ _PUBLIC_ _PURE_ DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *s } /** + * Parse a hex dump and return a data blob. Hex dump is structured as + * is generated from dump_data_cb() elsewhere in this file + * + */ +_PUBLIC_ _PURE_ DATA_BLOB hexdump_to_data_blob(TALLOC_CTX *mem_ctx, const char *hexdump, size_t hexdump_len) +{ + DATA_BLOB ret_blob = {'\0'}; + size_t i = 0; + size_t char_count = 0; + /* hexdump line length is 77 chars long. We then use the ASCII representation of the bytes + * at the end of the final line to calculate how many are in that line, minus the extra space + * and newline. */ + size_t hexdump_byte_count = (16 * (hexdump_len / 77)); + if (hexdump_len % 77) { + hexdump_byte_count += ((hexdump_len % 77) - 59 - 2); + } + + ret_blob = data_blob_talloc(mem_ctx, NULL, hexdump_byte_count+1); + for (; i+1 < hexdump_len && hexdump[i] != 0 && hexdump[i+1] != 0; i++) { + if ((i%77) == 0) + i += 7; /* Skip the offset at the start of the line */ + if ((i%77) < 56) { /* position 56 is after both hex chunks */ + if (hexdump[i] != ' ') { + char_count += strhex_to_str((char *)&ret_blob.data[char_count], + hexdump_byte_count - char_count, + &hexdump[i], 2); + i += 2; + } else { + i++; + } + } else { + i++; + } + } + ret_blob.length = char_count; + + return ret_blob; +} + +/** * Print a buf in hex. Assumes dst is at least (srclen*2)+1 large. */ _PUBLIC_ void hex_encode_buf(char *dst, const uint8_t *src, size_t srclen) diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c index d534e3c1dba..b1e96b8a842 100644 --- a/librpc/tools/ndrdump.c +++ b/librpc/tools/ndrdump.c @@ -213,8 +213,9 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) bool dumpdata = false; bool assume_ndr64 = false; bool quiet = false; + bool hex_input = false; int opt; - enum {OPT_CONTEXT_FILE=1000, OPT_VALIDATE, OPT_DUMP_DATA, OPT_LOAD_DSO, OPT_NDR64, OPT_QUIET}; + enum {OPT_CONTEXT_FILE=1000, OPT_VALIDATE, OPT_DUMP_DATA, OPT_LOAD_DSO, OPT_NDR64, OPT_QUIET, OPT_HEX_INPUT}; struct poptOption long_options[] = { POPT_AUTOHELP {"context-file", 'c', POPT_ARG_STRING, NULL, OPT_CONTEXT_FILE, "In-filename to parse first", "CTX-FILE" }, @@ -223,6 +224,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) {"load-dso", 'l', POPT_ARG_STRING, NULL, OPT_LOAD_DSO, "load from shared object file", NULL }, {"ndr64", 0, POPT_ARG_NONE, NULL, OPT_NDR64, "Assume NDR64 data", NULL }, {"quiet", 0, POPT_ARG_NONE, NULL, OPT_QUIET, "Don't actually dump anything", NULL }, + {"hex-input", 0, POPT_ARG_NONE, NULL, OPT_HEX_INPUT, "Read the input file in as a hex dump", NULL }, POPT_COMMON_SAMBA POPT_COMMON_VERSION { NULL } @@ -231,7 +233,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) const struct ndr_interface_call_pipes *out_pipes = NULL; uint32_t highest_ofs; struct dcerpc_sec_verification_trailer *sec_vt = NULL; - + ndr_table_init(); /* Initialise samba stuff */ @@ -266,6 +268,9 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) case OPT_QUIET: quiet = true; break; + case OPT_HEX_INPUT: + hex_input = true; + break; } } @@ -381,7 +386,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) exit(1); } memcpy(v_st, st, f->struct_size); - } + } if (filename) data = (uint8_t *)file_load(filename, &size, 0, mem_ctx); @@ -395,9 +400,13 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) perror("stdin"); exit(1); } - - blob.data = data; - blob.length = size; + + if (hex_input) { + blob = hexdump_to_data_blob(mem_ctx, (char *)data, size); + } else { + blob.data = data; + blob.length = size; + } ndr_pull = ndr_pull_init_blob(&blob, mem_ctx); if (ndr_pull == NULL) { @@ -584,7 +593,6 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) } printf("dump OK\n"); - talloc_free(mem_ctx); poptFreeContext(pc); -- 2.11.4.GIT