FreeCalypso > hg > freecalypso-sw
view rvinterf/lowlevel/tfc139.c @ 858:4c6e7ada647b
compressed trace decoder almost fully implemented
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Sat, 02 May 2015 08:08:26 +0000 |
parents | 15e69d31c96f |
children | 0d7cc054ef72 |
line wrap: on
line source
/* * This program is a contender for the title of the ugliest hack * in the FreeCalypso project. It will attempt to break into a * locked-down TracFone C139 by mimicking the actions of the * mot931c.exe TF "unlocker". */ #include <sys/types.h> #include <sys/errno.h> #include <stdio.h> #include <string.h> #include <strings.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include "../include/pktmux.h" #include "../include/limits.h" extern int target_fd; extern char *baudrate_name; extern u_char rxpkt[]; extern size_t rxpkt_len; char *logfname; FILE *logF; time_t logtime; int no_output; /* for output.c */ int wakeup_after_sec = 7; /* see ../../target-utils/tf-breakin/payload.S for the source */ static u_char iram_payload[112] = { 0xD3, 0xF0, 0x21, 0xE3, 0x58, 0x10, 0x9F, 0xE5, 0xF5, 0x00, 0xA0, 0xE3, 0xB2, 0x00, 0xC1, 0xE1, 0xA0, 0x00, 0xA0, 0xE3, 0xB2, 0x00, 0xC1, 0xE1, 0x48, 0x60, 0x9F, 0xE5, 0x05, 0x00, 0xD6, 0xE5, 0x20, 0x00, 0x10, 0xE3, 0xFC, 0xFF, 0xFF, 0x0A, 0x2C, 0x10, 0x8F, 0xE2, 0x06, 0x20, 0xA0, 0xE3, 0x01, 0x00, 0xD1, 0xE4, 0x00, 0x00, 0xC6, 0xE5, 0x01, 0x20, 0x52, 0xE2, 0xFB, 0xFF, 0xFF, 0x1A, 0x05, 0x00, 0xD6, 0xE5, 0x40, 0x00, 0x10, 0xE3, 0xFC, 0xFF, 0xFF, 0x0A, 0x18, 0x10, 0x9F, 0xE5, 0x01, 0x2C, 0xA0, 0xE3, 0xB0, 0x20, 0xC1, 0xE1, 0x00, 0xF0, 0xA0, 0xE3, 0x02, 0x02, 0x02, 0x4F, 0x4B, 0x02, 0x00, 0x00, 0x02, 0xF8, 0xFF, 0xFF, 0x00, 0x58, 0xFF, 0xFF, 0x10, 0xFB, 0xFF, 0xFF }; static unsigned iram_load_addr = 0x800000; static unsigned stack_smash_addr = 0x837C54; static u_char stack_smash_payload[4]; static char *target_tty_port; static void send_compal_memwrite(addr, payload, payload_len) unsigned addr; u_char *payload; { u_char pkt[MAX_PKT_TO_TARGET]; int i, csum, csum_offset; pkt[0] = RVT_TM_HEADER; pkt[1] = 0x40; /* Compal's non-standard addition */ pkt[2] = addr; pkt[3] = addr >> 8; pkt[4] = addr >> 16; pkt[5] = addr >> 24; bcopy(payload, pkt + 6, payload_len); csum_offset = payload_len + 6; csum = 0; for (i = 1; i < csum_offset; i++) csum ^= pkt[i]; pkt[i] = csum; send_pkt_to_target(pkt, i + 1); } main(argc, argv) char **argv; { extern char *optarg; extern int optind; int c; fd_set fds; baudrate_name = "57600"; /* what C139 firmware uses */ while ((c = getopt(argc, argv, "a:B:l:s:w:")) != EOF) switch (c) { case 'a': iram_load_addr = strtoul(optarg, 0, 16); continue; case 'B': baudrate_name = optarg; continue; case 'l': logfname = optarg; continue; case 's': stack_smash_addr = strtoul(optarg, 0, 16); continue; case 'w': wakeup_after_sec = strtoul(optarg, 0, 0); continue; case '?': default: usage: fprintf(stderr, "usage: %s [options] ttyport\n", argv[0]); exit(1); } if (argc - optind != 1) goto usage; open_target_serial(argv[optind]); target_tty_port = argv[optind]; set_serial_nonblock(0); setlinebuf(stdout); if (logfname) { logF = fopen(logfname, "w"); if (!logF) { perror(logfname); exit(1); } setlinebuf(logF); fprintf(logF, "*** Log of TFC139 break-in session ***\n"); } time(&logtime); output_line("Sending IRAM payload"); send_compal_memwrite(iram_load_addr, iram_payload, sizeof iram_payload); stack_smash_payload[0] = iram_load_addr; stack_smash_payload[1] = iram_load_addr >> 8; stack_smash_payload[2] = iram_load_addr >> 16; stack_smash_payload[3] = iram_load_addr >> 24; for (;;) { FD_ZERO(&fds); FD_SET(target_fd, &fds); c = select(target_fd+1, &fds, 0, 0, 0); time(&logtime); if (c < 0) { if (errno == EINTR) continue; perror("select"); exit(1); } if (FD_ISSET(target_fd, &fds)) process_serial_rx(); } } static void handle_etm_response() { char msgbuf[80]; if (rxpkt_len != 4 || rxpkt[1] != 0x40 || rxpkt[2] || rxpkt[3] != 0x40){ output_line("ETM response differs from expected"); return; } sprintf(msgbuf, "Sending stack smash write at 0x%x", stack_smash_addr); output_line(msgbuf); send_compal_memwrite(stack_smash_addr, stack_smash_payload, 4); stack_smash_addr += 4; } handle_rx_packet() { if (rxpkt_len == 2 && rxpkt[0] == 'O' && rxpkt[1] == 'K') { output_line( "Success: target should now be in boot ROM download wait"); printf("You can now run fc-loadtool -h compal -c none %s\n", target_tty_port); exit(0); } switch (rxpkt[0]) { case RVT_RV_HEADER: if (rxpkt_len < 6) goto unknown; print_rv_trace(); return; case RVT_L1_HEADER: print_l1_trace(); return; case RVT_L23_HEADER: print_g23_trace(); return; case RVT_TM_HEADER: print_etm_output_raw(); handle_etm_response(); return; default: unknown: print_unknown_packet(); } }