void wdump(uint8 *payload, int32 len) { int32 len_rem = len; int32 line_width = 16; int32 line_len; int32 offset = 0; uint8 *ch = payload; if ( len <= 0 ) { return; } if ( len <= line_width ) { print_hex_line(ch, len, offset); return; } for(;;) { line_len = line_width % len_rem; print_hex_line(ch, line_len, offset); len_rem = len_rem - line_len; ch = ch + line_len; offset = offset + line_width; if ( len_rem <= line_width ) { print_hex_line(ch, len_rem, offset); break; } } return; }
xed_uint_t disas_decode_binary(const xed_state_t* dstate, const xed_uint8_t* hex_decode_text, const unsigned int bytes, xed_decoded_inst_t* xedd, xed_uint64_t runtime_address) { xed_uint64_t t1,t2; xed_error_enum_t xed_error; xed_bool_t okay; if (CLIENT_VERBOSE) { print_hex_line(hex_decode_text, bytes); } t1 = xed_get_time(); xed_error = xed_decode(xedd, hex_decode_text, bytes); t2 = xed_get_time(); okay = (xed_error == XED_ERROR_NONE); if (CLIENT_VERBOSE3) { xed_uint64_t delta = t2-t1; printf("Decode time = " XED_FMT_LU "\n", delta); } if (okay) { if (CLIENT_VERBOSE1) { char tbuf[XED_TMP_BUF_LEN]; xed_decoded_inst_dump(xedd,tbuf,XED_TMP_BUF_LEN); printf("%s\n",tbuf); } if (CLIENT_VERBOSE) { char buf[XED_TMP_BUF_LEN]; if (xed_decoded_inst_valid(xedd)) { printf( "ICLASS: %s CATEGORY: %s EXTENSION: %s IFORM: %s" " ISA_SET: %s\n", xed_iclass_enum_t2str(xed_decoded_inst_get_iclass(xedd)), xed_category_enum_t2str(xed_decoded_inst_get_category(xedd)), xed_extension_enum_t2str(xed_decoded_inst_get_extension(xedd)), xed_iform_enum_t2str(xed_decoded_inst_get_iform_enum(xedd)), xed_isa_set_enum_t2str(xed_decoded_inst_get_isa_set(xedd))); } memset(buf,0,XED_TMP_BUF_LEN); disassemble(buf,XED_TMP_BUF_LEN, xedd, runtime_address,0); printf("SHORT: %s\n", buf); } return 1; } else { xed_decode_error(0, 0, hex_decode_text, xed_error); return 0; } (void) dstate; // pacify compiler }
int main(int argc, char **argv) { signal(SIGINT, intHandler); struct termios options; fd_set mask, smask; int fd; speed_t speed = BAUDRATE; char *speedname = BAUDRATE_S; char *device = MODEMDEVICE; char *timeformat = NULL; unsigned char buf[BUFSIZE], outbuf[HCOLS]; unsigned char mode = MODE_START_TEXT; int nfound, flags = 0; unsigned char lastc = '\0'; int index = 1; while(index < argc) { if(argv[index][0] == '-') { switch(argv[index][1]) { case 'b': /* set speed */ if(strcmp(&argv[index][2], "38400") == 0) { speed = B38400; speedname = "38400"; } else if(strcmp(&argv[index][2], "19200") == 0) { speed = B19200; speedname = "19200"; } else if(strcmp(&argv[index][2], "57600") == 0) { speed = B57600; speedname = "57600"; } else if(strcmp(&argv[index][2], "115200") == 0) { speed = B115200; speedname = "115200"; } else { fprintf(stderr, "unsupported speed: %s\n", &argv[index][2]); return usage(1); } break; case 'x': mode = MODE_HEX; break; case 'i': mode = MODE_INT; break; case 's': switch(argv[index][2]) { case 'n': mode = MODE_SLIP_HIDE; break; case 'o': mode = MODE_SLIP; break; default: mode = MODE_SLIP_AUTO; break; } break; case 'T': if(strlen(&argv[index][2]) == 0) { timeformat = "%Y-%m-%d %H:%M:%S"; } else { timeformat = &argv[index][2]; } mode = MODE_START_DATE; break; case 'h': return usage(0); default: fprintf(stderr, "unknown option '%c'\n", argv[index][1]); return usage(1); } index++; } else { device = argv[index++]; if(index < argc) { fprintf(stderr, "too many arguments\n"); return usage(1); } } } fprintf(stderr, "connecting to %s (%s)", device, speedname); fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC); if(fd < 0) { fprintf(stderr, "\n"); perror(device); exit(-1); } fprintf(stderr, " [OK]\n"); if(fcntl(fd, F_SETFL, 0) < 0) { perror("could not set fcntl"); exit(-1); } #ifdef __APPLE__ if(fcntl(fd, F_NOCACHE, 1) < 0) { perror("could not set fcntl"); exit(-1); } #endif if(tcgetattr(fd, &options) < 0) { perror("could not get options"); exit(-1); } /* fprintf(stderr, "serial options set\n"); */ cfsetispeed(&options, speed); cfsetospeed(&options, speed); /* Enable the receiver and set local mode */ options.c_cflag |= (CLOCAL | CREAD); /* Mask the character size bits and turn off (odd) parity */ options.c_cflag &= ~(CSIZE | PARENB | PARODD); /* Select 8 data bits */ options.c_cflag |= CS8; /* Raw input */ options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* Raw output */ options.c_oflag &= ~OPOST; if(tcsetattr(fd, TCSANOW, &options) < 0) { perror("could not set options"); exit(-1); } /* Make read() return immediately */ /* if (fcntl(fd, F_SETFL, FNDELAY) < 0) { */ /* perror("\ncould not set fcntl"); */ /* exit(-1); */ /* } */ FD_ZERO(&mask); FD_SET(fd, &mask); FD_SET(fileno(stdin), &mask); index = 0; for(;;) { smask = mask; nfound = select(FD_SETSIZE, &smask, (fd_set *)0, (fd_set *)0, (struct timeval *)0); if(nfound < 0) { if(errno == EINTR) { fprintf(stderr, "interrupted system call\n"); continue; } /* something is very wrong! */ perror("select"); exit(1); } if(FD_ISSET(fileno(stdin), &smask)) { /* data from standard in */ int n = read(fileno(stdin), buf, sizeof(buf)); if(n < 0) { perror("could not read"); exit(-1); } else if(n > 0) { /* because commands might need parameters, lines needs to be separated which means the terminating LF must be sent */ /* while(n > 0 && buf[n - 1] < 32) { */ /* n--; */ /* } */ if(n > 0) { int i; /* fprintf(stderr, "SEND %d bytes\n", n);*/ /* write slowly */ for(i = 0; i < n; i++) { if(write(fd, &buf[i], 1) <= 0) { perror("write"); exit(1); } else { fflush(NULL); usleep(6000); } } } } else { /* End of input, exit. */ exit(0); } } if(FD_ISSET(fd, &smask)) { int i, j, n = read(fd, buf, sizeof(buf)); if(n < 0) { perror("could not read"); exit(-1); } if(n == 0) { errno = EBADF; perror("serial device disconnected"); exit(-1); } for(i = 0; i < n; i++) { switch(mode) { case MODE_START_TEXT: case MODE_TEXT: printf("%c", buf[i]); break; case MODE_START_DATE: { time_t t; t = time(&t); strftime(outbuf, HCOLS, timeformat, localtime(&t)); printf("%s|", outbuf); mode = MODE_DATE; } /* continue into the MODE_DATE */ case MODE_DATE: printf("%c", buf[i]); if(buf[i] == '\n') { mode = MODE_START_DATE; } break; case MODE_INT: printf("%03d ", buf[i]); if(++index >= ICOLS) { index = 0; printf("\n"); } break; case MODE_HEX: rxbuf[index++] = buf[i]; if(index >= HCOLS) { print_hex_line("", rxbuf, index); index = 0; printf("\n"); } break; case MODE_SLIP_AUTO: case MODE_SLIP_HIDE: if(!flags && (buf[i] != SLIP_END)) { /* Not a SLIP packet? */ printf("%c", buf[i]); break; } /* continue to slip only mode */ case MODE_SLIP: switch(buf[i]) { case SLIP_ESC: lastc = SLIP_ESC; break; case SLIP_END: if(index > 0) { if(flags != 2 && mode != MODE_SLIP_HIDE) { /* not overflowed: show packet */ print_hex_line("SLIP: ", rxbuf, index > HCOLS ? HCOLS : index); printf("\n"); } lastc = '\0'; index = 0; flags = 0; } else { flags = !flags; } break; default: if(lastc == SLIP_ESC) { lastc = '\0'; /* Previous read byte was an escape byte, so this byte will be interpreted differently from others. */ switch(buf[i]) { case SLIP_ESC_END: buf[i] = SLIP_END; break; case SLIP_ESC_ESC: buf[i] = SLIP_ESC; break; } } rxbuf[index++] = buf[i]; if(index >= sizeof(rxbuf)) { fprintf(stderr, "**** slip overflow\n"); index = 0; flags = 2; } break; } break; } } /* after processing for some output modes */ if(index > 0) { switch(mode) { case MODE_HEX: print_hex_line("", rxbuf, index); break; } } fflush(stdout); } } }
static string disassemble(UINT64 start, UINT64 stop) { UINT64 pc = start; xed_state_t dstate; xed_syntax_enum_t syntax = XED_SYNTAX_INTEL; xed_error_enum_t xed_error; xed_decoded_inst_t xedd; ostringstream os; if (sizeof(ADDRINT) == 4) xed_state_init(&dstate, XED_MACHINE_MODE_LEGACY_32, XED_ADDRESS_WIDTH_32b, XED_ADDRESS_WIDTH_32b); else xed_state_init(&dstate, XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b, XED_ADDRESS_WIDTH_64b); /*while( pc < stop )*/ { xed_decoded_inst_zero_set_mode(&xedd, &dstate); UINT32 len = 15; if (stop - pc < 15) len = stop-pc; xed_error = xed_decode(&xedd, reinterpret_cast<const UINT8*>(pc), len); bool okay = (xed_error == XED_ERROR_NONE); iostream::fmtflags fmt = os.flags(); os << std::setfill('0') << "XDIS " << std::hex << std::setw(sizeof(ADDRINT)*2) << pc << std::dec << ": " << std::setfill(' ') << std::setw(4); if (okay) { char buffer[200]; unsigned int dec_len, sp; os << xed_extension_enum_t2str(xed_decoded_inst_get_extension(&xedd)); dec_len = xed_decoded_inst_get_length(&xedd); print_hex_line(buffer, reinterpret_cast<UINT8*>(pc), dec_len); os << " " << buffer; for ( sp=dec_len; sp < 12; sp++) // pad out the instruction bytes os << " "; os << " "; memset(buffer,0,200); int dis_okay = xed_format(syntax, &xedd, buffer, 200, pc); if (dis_okay) os << buffer << endl; else os << "Error disasassembling pc 0x" << std::hex << pc << std::dec << endl; pc += dec_len; } else { // print the byte and keep going. UINT8 memval = *reinterpret_cast<UINT8*>(pc); os << "???? " // no extension << std::hex << std::setw(2) << std::setfill('0') << static_cast<UINT32>(memval) << std::endl; pc += 1; } os.flags(fmt); } return os.str(); }