nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | #define _XOPEN_SOURCE 700 |
2 | |||
3 | #include <stdio.h> |
||
4 | #include <stdlib.h> |
||
5 | #include <argp.h> |
||
6 | #include <string.h> |
||
7 | |||
8 | #include <arpa/inet.h> |
||
9 | #include <netinet/in.h> |
||
10 | #include <sys/types.h> |
||
11 | #include <sys/socket.h> |
||
12 | #include <unistd.h> |
||
13 | |||
14 | #define AS_STR2(TEXT) #TEXT |
||
15 | #define AS_STR(TEXT) AS_STR2(TEXT) |
||
16 | |||
17 | char *ram_array = NULL; |
||
18 | long ram_len = 0; |
||
19 | |||
20 | char *ram_file_name = AS_STR(RAM_FILE_NAME); |
||
21 | int ucode_start = 0; |
||
22 | int ucode_length = 0; |
||
23 | char *ucode_file_name = ""; |
||
24 | |||
25 | const char *argp_program_version = "fpext"; |
||
26 | const char *argp_program_bug_address = "<mschulz@seemoo.tu-darmstadt.de>"; |
||
27 | |||
28 | static char doc[] = "fpext -- a program to extract flash patches form a firmware rom."; |
||
29 | |||
30 | static struct argp_option options[] = { |
||
31 | {"ramfile", 'r', "FILE", 0, "Read ram from FILE"}, |
||
32 | {"ucodestart", 'b', "ADDR", 0, "Start address of ucode"}, |
||
33 | {"ucodelength", 'l', "LEN", 0, "Size of ucode in firmware"}, |
||
34 | {"ucodefile", 'o', "FILE", 0, "Write extracted firmware to FILE"}, |
||
35 | { 0 } |
||
36 | }; |
||
37 | |||
38 | static error_t |
||
39 | parse_opt(int key, char *arg, struct argp_state *state) |
||
40 | { |
||
41 | switch (key) { |
||
42 | |||
43 | case 'r': |
||
44 | ram_file_name = arg; |
||
45 | break; |
||
46 | |||
47 | case 'b': |
||
48 | ucode_start = strtol(arg, NULL, 0); |
||
49 | break; |
||
50 | |||
51 | case 'l': |
||
52 | ucode_length = strtol(arg, NULL, 0); |
||
53 | break; |
||
54 | |||
55 | case 'o': |
||
56 | ucode_file_name = arg; |
||
57 | break; |
||
58 | |||
59 | default: |
||
60 | return ARGP_ERR_UNKNOWN; |
||
61 | } |
||
62 | |||
63 | return 0; |
||
64 | } |
||
65 | |||
66 | static struct argp argp = { options, parse_opt, 0, doc }; |
||
67 | |||
68 | int |
||
69 | read_file_to_array(char *filename, char **buffer, long *filelen) |
||
70 | { |
||
71 | FILE *fileptr; |
||
72 | |||
73 | if((fileptr = fopen(filename, "rb"))) { |
||
74 | fseek(fileptr, 0, SEEK_END); |
||
75 | *filelen = ftell(fileptr); |
||
76 | rewind(fileptr); |
||
77 | |||
78 | *buffer = (char *) malloc(*filelen + 1); |
||
79 | fread(*buffer, *filelen, 1, fileptr); |
||
80 | fclose(fileptr); |
||
81 | |||
82 | return *filelen; |
||
83 | } |
||
84 | |||
85 | return 0; |
||
86 | } |
||
87 | |||
88 | void |
||
89 | analyse_ram(FILE *fp) |
||
90 | { |
||
91 | unsigned char *ucode = (unsigned char *) &ram_array[ucode_start]; |
||
92 | int i = 0; |
||
93 | unsigned int a = 0; |
||
94 | unsigned int b = 0; |
||
95 | |||
96 | for (i = 0; i < ucode_length; i+=7) { |
||
97 | ucode += 7; |
||
98 | a = (*(ucode - 3) << 16) | (*(ucode - 4) << 24) | *(ucode - 1) | (*(ucode - 2) << 8); |
||
99 | b = (*(ucode - 6) << 8) | (*(ucode - 7) << 16) | *(ucode - 5); |
||
100 | fwrite(&a, sizeof(int), 1, fp); |
||
101 | fwrite(&b, sizeof(int), 1, fp); |
||
102 | } |
||
103 | } |
||
104 | |||
105 | int |
||
106 | main(int argc, char **argv) |
||
107 | { |
||
108 | argp_parse(&argp, argc, argv, 0, 0, 0); |
||
109 | |||
110 | if(!read_file_to_array(ram_file_name, &ram_array, &ram_len)) { |
||
111 | fprintf(stderr, "ERR: ram file empty or unavailable.\n"); |
||
112 | exit(EXIT_FAILURE); |
||
113 | } |
||
114 | |||
115 | FILE *fp; |
||
116 | |||
117 | if((fp = fopen(ucode_file_name, "wb"))) { |
||
118 | analyse_ram(fp); |
||
119 | fclose(fp); |
||
120 | } |
||
121 | |||
122 | exit(EXIT_SUCCESS); |
||
123 | } |