1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stdint.h>
4 #include <string.h>
5 #include <unistd.h>
6
7
8 typedef struct {
9 uint32_t inst;
10 uint32_t mask;
11 uint32_t ignore;
12 char cmd[8];
13 int is_adr;
14 } Instr;
15
16 /*
17 Cond 0 C I Opcode S Rn Rd Operand2
18 Cond 0 0 0 0 0 0 A S Rd Rn Rs 1 0 0 1 Rm
19 Cond 0 0 0 0 1 U A S RdHi RdLo Rs 1 0 0 1 Rm
20 Cond 0 0 0 1 0 B Rn Rd 0 0 0 0 1 0 0 1 Rm
21 Cond 0 1 I P U B W L Rn Rd Offset
22 Cond 1 0 0 P U S W L Rn Register List
23 Cond 0 0 0 P U 1 W L Rn Rd Offsetl 1 S H 1 Offset2
24 Cond 0 0 0 P U 0 W L Rn Rd 0 0 0 0 1 S H 1 Rm
25 Cond 1 0 1 L Offset
26 Cond 0 0 0 1 0 0 1 0 1111 1111 1111 0 0 0 1 Rn
27 Cond 1 1 0 P U N W L Rn CRd CPNum Offset
28 Cond 1 1 1 0 Opl CRn CRd CPNum Op2 0 CRm
29 Cond 1 1 1 0 Opl L CRn Rd CPNum Op2 1 CRm
30 Cond 1 1 1 1 SWI Number
31 */
32
33 /* ARM instructions */ /*
34 {0xe1a00000, 0xffffffff, "nop"},
35 {0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
36 {0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"},
37 {0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"},
38 {0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"},
39 {0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
40 {0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
41 {0x00000090, 0x0e100090, "str%c%6's%h\t%12-15r, %s"},
42 {0x00100090, 0x0e100090, "ldr%c%6's%h\t%12-15r, %s"},
43 {0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"},
44 {0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"},
45 {0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"},
46 {0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"},
47 {0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"},
48 {0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"},
49 {0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"},
50 {0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"},
51 {0x0120f000, 0x0db6f000, "msr%c\t%22?scpsr%C, %o"},
52 {0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?scpsr"},
53 {0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"},
54 {0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"},
55 {0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"},
56 {0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"},
57 {0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"},
58 {0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"},
59 {0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"},
60 {0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"},
61 {0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"},
62 {0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"},
63 {0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"},
64 {0x06000010, 0x0e000010, "undefined"},
65 {0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"},
66 {0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
67 {0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
68 {0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
69 {0x0f000000, 0x0f000000, "swi%c\t%0-23x"},
70 */
71
72 /*
73 Instr instrs[] = {
74 // {0x00000000 , 0x00000000, 0x00000000 }, // adc
75 {0x00800000 , 0x0df00000, 0x02000000 }, // add
76 {0x00000000 , 0x0de00000, 0x02000000 }, // and
77 {0x0a000000 , 0x0e000000, 0x00ffffff }, // b, bl
78 {0x01c00000 , 0x0de00000, 0x02000000 }, // bic
79 // {0x00000000 , 0x00000000, 0x00000000 }, // bkpt
80 // {0x00000000 , 0x00000000, 0x00000000 }, // blx
81 // {0x00000000 , 0x00000000, 0x00000000 }, // blx
82 // {0x00000000 , 0x00000000, 0x00000000 }, // bx
83 // {0x00000000 , 0x00000000, 0x00000000 }, // cdp
84 // {0x00000000 , 0x00000000, 0x00000000 }, // clz
85 {0x01700000 , 0x0df00000, 0x02000000 }, // cmn
86 {0x01500000 , 0x0df00000, 0x02000000 }, // cmp
87 // {0x00000000 , 0x00000000, 0x00000000 }, // eor
88 // {0x00000000 , 0x00000000, 0x00000000 }, // ldc
89 // {0x00000000 , 0x00000000, 0x00000000 }, // ldm
90 // {0x00000000 , 0x00000000, 0x00000000 }, // ldm
91 // {0x00000000 , 0x00000000, 0x00000000 }, // ldm
92 /// {0x00000000 , 0x00000000, 0x00000000 }, // ldr
93 /// {0x00000000 , 0x00000000, 0x00000000 }, // ldrb
94 /// {0x00000000 , 0x00000000, 0x00000000 }, // ldrbt
95 /// {0x00000000 , 0x00000000, 0x00000000 }, // ldrh
96 /// {0x00000000 , 0x00000000, 0x00000000 }, // ldrsb
97 /// {0x00000000 , 0x00000000, 0x00000000 }, // ldrsh
98 /// {0x00000000 , 0x00000000, 0x00000000 }, // ldrt
99 // {0x00000000 , 0x00000000, 0x00000000 }, // mcr
100 // {0x00000000 , 0x00000000, 0x00000000 }, // mla
101 {0x01a00000 , 0x0de00000, 0x02000000 }, // mov
102 // {0x00000000 , 0x00000000, 0x00000000 }, // mrc
103 // {0x00000000 , 0x00000000, 0x00000000 }, // mrs
104 // {0x00000000 , 0x00000000, 0x00000000 }, // msr
105 // {0x00000000 , 0x00000000, 0x00000000 }, // mul
106 // {0x00000000 , 0x00000000, 0x00000000 }, // mvn
107 // {0x00000000 , 0x00000000, 0x00000000 }, // orr
108 // {0x00000000 , 0x00000000, 0x00000000 }, // rsb
109 // {0x00000000 , 0x00000000, 0x00000000 }, // rsc
110 // {0x00000000 , 0x00000000, 0x00000000 }, // scb
111 // {0x00000000 , 0x00000000, 0x00000000 }, // smlal
112 // {0x00000000 , 0x00000000, 0x00000000 }, // smull
113 // {0x00000000 , 0x00000000, 0x00000000 }, // src
114 // {0x00000000 , 0x00000000, 0x00000000 }, // stm
115 // {0x00000000 , 0x00000000, 0x00000000 }, // stm
116 /// {0x00000000 , 0x00000000, 0x00000000 }, // str
117 /// {0x00000000 , 0x00000000, 0x00000000 }, // strb
118 /// {0x00000000 , 0x00000000, 0x00000000 }, // strbt
119 /// {0x00000000 , 0x00000000, 0x00000000 }, // strh
120 /// {0x00000000 , 0x00000000, 0x00000000 }, // strt
121 {0x00400000 , 0x0de00000, 0x02000000 }, // sub
122 // {0x00000000 , 0x00000000, 0x00000000 }, // swi
123 // {0x00000000 , 0x00000000, 0x00000000 }, // swp
124 // {0x00000000 , 0x00000000, 0x00000000 }, // swpb
125 // {0x00000000 , 0x00000000, 0x00000000 }, // teq
126 {0x01100000 , 0x0df00000, 0x02000000 }, // tst
127 // {0x00000000 , 0x00000000, 0x00000000 }, // umlal
128 // {0x00000000 , 0x00000000, 0x00000000 }, // umull
129
130 { 0, 0, 0 }
131 };
132 // */
133
134 /*
135 Instr instrs[] = {
136 {0x00a00000 , 0x0de00000, 0x02000fff, "adc" },
137 {0x00800000 , 0x0de00000, 0x02000fff, "add" },
138 {0x00000000 , 0x0de00000, 0x02000fff, "and" },
139 {0x0a000000 , 0x0e000000, 0x00ffffff, "b, bl" },
140 {0x01c00000 , 0x0de00000, 0x02000fff, "bic" },
141 {0xe1200070 , 0xfff000f0, 0x000fff0f, "bkpt" },
142 {0xfa000000 , 0xfe000000, 0x00ffffff, "blx" },
143 {0x01200030 , 0x0ff000f0, 0x000fff00, "blx" },
144 {0x01200010 , 0x0ff000f0, 0x000fff00, "bx" },
145 {0x0e000000 , 0x0f000010, 0x00000000, "cdp" },
146 {0x01600010 , 0x0ff000f0, 0x000f0f00, "clz" },
147 {0x01700000 , 0x0df00000, 0x0200ffff, "cmn" },
148 {0x01500000 , 0x0df00000, 0x0200ffff, "cmp" },
149 {0x00200000 , 0x0de00000, 0x02000fff, "eor" },
150 {0x0c100000 , 0x0e100000, 0x000000ff, "ldc" },
151 {0x08100000 , 0x0e500000, 0x00000000, "ldm" },
152 {0x08500000 , 0x0e708000, 0x00000000, "ldm" },
153 {0x08508000 , 0x0e508000, 0x00000000, "ldm" },
154 {0x04100000 , 0x0c500000, 0x02000fff, "ldr" },
155 {0x04500000 , 0x0c500000, 0x02000fff, "ldrb" },
156 {0x04700000 , 0x0f700000, 0x02000fff, "ldrbt" },
157 {0x001000b0 , 0x0e1000f0, 0x00400f0f, "ldrh" },
158 {0x001000d0 , 0x0e1000f0, 0x00400f0f, "ldrsb" },
159 {0x001000f0 , 0x0e1000f0, 0x00400f0f, "ldrsh" },
160 {0x04300000 , 0x0d700000, 0x02000fff, "ldrt" },
161 {0x0e000010 , 0x0f100010, 0x00000000, "mcr" },
162 {0x00200090 , 0x0fe000f0, 0x00000000, "mla" },
163 {0x01a00000 , 0x0de00000, 0x020f0fff, "mov" },
164 {0x0e100010 , 0x0f100010, 0x00000000, "mrc" },
165 {0x01000000 , 0x0fb00000, 0x000f0fff, "mrs" },
166 {0x03200000 , 0x0fb00000, 0x0000f000, "msr" },
167 {0x01200000 , 0x0fb000f0, 0x0000ff00, "msr" },
168 {0x00000090 , 0x0fe000f0, 0x0000f000, "mul" },
169 {0x01e00000 , 0x0de00000, 0x020f0fff, "mvn" },
170 {0x01800000 , 0x0de00000, 0x02000fff, "orr" },
171 {0x00600000 , 0x0de00000, 0x02000fff, "rsb" },
172 {0x00e00000 , 0x0de00000, 0x02000fff, "rsc" },
173 {0x00c00000 , 0x0de00000, 0x02000fff, "sbc" },
174 {0x00e00090 , 0x0fe000f0, 0x00000000, "smlal" },
175 {0x00c00090 , 0x0fe000f0, 0x00000000, "smull" },
176 {0x0c000000 , 0x0e100000, 0x000000ff, "stc" },
177 {0x08000000 , 0x0e500000, 0x00000000, "stm" },
178 {0x08400000 , 0x0e700000, 0x00000000, "stm" },
179 {0x04000000 , 0x0c500000, 0x02000fff, "str" },
180 {0x04400000 , 0x0c500000, 0x02000fff, "strb" },
181 {0x04600000 , 0x0d700000, 0x02000fff, "strbt" },
182 {0x000000b0 , 0x0e1000f0, 0x00400f0f, "strh" },
183 {0x04200000 , 0x0d700000, 0x02000fff, "strt" },
184 {0x00400000 , 0x0de00000, 0x02000fff, "sub" },
185 {0x0f000000 , 0x0f000000, 0x00000000, "swi" },
186 {0x01000090 , 0x0ff000f0, 0x00000f00, "swp" },
187 {0x01400090 , 0x0ff000f0, 0x00000f00, "swpb" },
188 {0x01300000 , 0x0df00000, 0x0200ffff, "teq" },
189 {0x01100000 , 0x0df00000, 0x0200ffff, "tst" },
190 {0x00a00090 , 0x0fe000f0, 0x00000000, "umlal" },
191 {0x00800090 , 0x0fe000f0, 0x00000000, "umull" },
192 { 0, 0, 0 , "" }
193 };
194 */
195
196 //*
197 Instr instrs[] = {
198 // {0x00a00000 , 0x0de00000, 0x02000000, "adc" },
199 {0x008f0000 , 0x0def0000, 0x0ff00fff, "add", 1 },
200 {0x00800000 , 0x0de00000, 0x020f0fff, "add", 0 },
201 {0x02000000 , 0x0fe00000, 0x00000fff, "and", 0 },
202 {0x0a000000 , 0x0e000000, 0xf0ffffff, "b, bl", 0 },
203 {0x01c00000 , 0x0de00000, 0x02000fff, "bic", 0 },
204 // {0xe1200070 , 0xfff000f0, 0x00000000, "bkpt" },
205 // {0xfa000000 , 0xfe000000, 0x00ffffff, "blx" },
206 // {0x01200030 , 0x0ff000f0, 0x00000000, "blx" },
207 // {0x01200010 , 0x0ff000f0, 0x00000000, "bx" },
208 // {0x0e000000 , 0x0f000010, 0x00000000, "cdp" },
209 // {0x01600010 , 0x0ff000f0, 0x00000000, "clz" },
210 {0x01700000 , 0x0df00000, 0x02000000, "cmn", 0 },
211 {0x01500000 , 0x0df00000, 0x02000fff, "cmp", 0 },
212 // {0x00200000 , 0x0de00000, 0x02000000, "eor" },
213 // {0x0c100000 , 0x0e100000, 0x00000000, "ldc" },
214 {0x08100000 , 0x0e500000, 0x0000ffff, "ldm", 0 },
215 // {0x08500000 , 0x0e708000, 0x00000000, "ldm" },
216 // {0x08508000 , 0x0e508000, 0x00000000, "ldm" },
217 {0x041f0000 , 0x0c5f0000, 0x0ff00fff, "ldr", 1 },
218 {0x04100000 , 0x0c500000, 0x02000fff, "ldr", 0 },
219 // {0x04500000 , 0x0c500000, 0x02000000, "ldrb" },
220 // {0x04700000 , 0x0f700000, 0x02000000, "ldrbt" },
221 // {0x001000b0 , 0x0e1000f0, 0x00400000, "ldrh" },
222 // {0x001000d0 , 0x0e1000f0, 0x00400000, "ldrsb" },
223 // {0x001000f0 , 0x0e1000f0, 0x00400000, "ldrsh" },
224 // {0x04300000 , 0x0d700000, 0x02000000, "ldrt" },
225 // {0x0e000010 , 0x0f100010, 0x00000000, "mcr" },
226 // {0x00200090 , 0x0fe000f0, 0x00000000, "mla" },
227 {0x01af0000 , 0x0def0000, 0x0ff00fff, "mov", 1 },
228 {0x01a00000 , 0x0de00000, 0x02000fff, "mov", 0 },
229 // {0x0e100010 , 0x0f100010, 0x00000000, "mrc" },
230 // {0x01000000 , 0x0fb00000, 0x00000000, "mrs" },
231 // {0x03200000 , 0x0fb00000, 0x00000000, "msr" },
232 // {0x01200000 , 0x0fb000f0, 0x00000000, "msr" },
233 {0x00000090 , 0x0fe000f0, 0x00000000, "mul", 0 },
234 {0x01ef0000 , 0x0def0000, 0x0ff00fff, "mvn", 1 },
235 {0x01e00000 , 0x0de00000, 0x02000fff, "mvn", 0 },
236 // {0x01800000 , 0x0de00000, 0x02000000, "orr" },
237 {0x00600000 , 0x0de00000, 0x02000000, "rsb", 0 },
238 {0x00e00000 , 0x0de00000, 0x02000000, "rsc", 0 },
239 // {0x00c00000 , 0x0de00000, 0x02000000, "sbc" },
240 // {0x00e00090 , 0x0fe000f0, 0x00000000, "smlal" },
241 // {0x00c00090 , 0x0fe000f0, 0x00000000, "smull" },
242 // {0x0c000000 , 0x0e100000, 0x00000000, "stc" },
243 {0x08000000 , 0x0e500000, 0x0000ffff, "stm", 0 },
244 // {0x08400000 , 0x0e700000, 0x00000000, "stm" },
245 {0x04000000 , 0x0c500000, 0x02000fff, "str", 0 },
246 {0x04400000 , 0x0c500000, 0x02000fff, "strb", 0 },
247 // {0x04600000 , 0x0d700000, 0x02000000, "strbt" },
248 // {0x000000b0 , 0x0e1000f0, 0x00400000, "strh" },
249 // {0x04200000 , 0x0d700000, 0x02000000, "strt" },
250 {0x004f0000 , 0x0def0000, 0x0ff00fff, "sub", 1 },
251 {0x00400000 , 0x0de00000, 0x02000fff, "sub", 0 },
252 // {0x0f000000 , 0x0f000000, 0x00000000, "swi" },
253 // {0x01000090 , 0x0ff000f0, 0x00000000, "swp" },
254 // {0x01400090 , 0x0ff000f0, 0x00000000, "swpb" },
255 // {0x01300000 , 0x0df00000, 0x02000000, "teq" },
256 {0x01100000 , 0x0df00000, 0x02000000, "tst", 0 },
257 // {0x00a00090 , 0x0fe000f0, 0x00000000, "umlal" },
258 // {0x00800090 , 0x0fe000f0, 0x00000000, "umull" },
259 { 0, 0, 0 , "" }
260 };
261 // */
262
263 void usage()
264 {
265 printf("gensig <primary> <base> <proc_name> <proc_vaddr> <proc_size>\n");
266 exit(1);
267 }
268
269 int bits (uint32_t v) {
270 int i, res=0;
271
272 for (i=0; i<32; ++i)
273 res+=(v>>i)&1;
274
275 return res;
276 }
277
278 uint32_t buf[1024];
279
280 void dump_sig(uint32_t pos, int size, FILE *f)
281 {
282 int i, j;
283 char tbuf[1024];
284 int finish = 0;
285 int wcount = 0;
286
287 int offset_mask = 0;
288 if (size < 0)
289 {
290 size = -size;
291 offset_mask = 0xfff;
292 }
293
294 fseek(f, pos, SEEK_SET);
295 i = fread(buf, 4, size, f);
296
297 for (i=0;i<size;++i){
298 tbuf[0]=0;
299 for (j=0;instrs[j].inst | instrs[j].mask;j++){
300 if ((buf[i] & instrs[j].mask) == instrs[j].inst){
301 uint32_t ignore = ~instrs[j].ignore | offset_mask;
302 //if (!instrs[j].is_adr)
303 {
304 if (!tbuf[0])
305 sprintf(tbuf, "\t{ %3d, 0x%08x, 0x%08x }, //", i, buf[i] & ignore, ignore);
306 sprintf(tbuf+strlen(tbuf), " %s:%d:0x%08X", instrs[j].cmd, bits(instrs[j].mask), buf[i]);
307 wcount++;
308 if ((buf[i] == 0xe1a0f00e) /* "mov pc,lr" aka "ret" */
309 && (size*100/wcount) > 75){
310 sprintf(tbuf+strlen(tbuf), "\t/* RET found, stopping... */");
311 finish = 1;
312 }
313 }
314 break;
315 }
316 }
317 if (tbuf[0])
318 printf("%s\n", tbuf);
319 if (finish)
320 break;
321 }
322 printf("\t/* %d/%d */\n",wcount, size);
323 }
324
325 int main(int argc, char **argv)
326 {
327 char *proc_name;
328 FILE *f;
329 uint32_t base;
330 uint32_t pos, lnk_pos;
331 uint32_t size, lnk_size;
332 // int i,j;
333 // int wcount;
334 // char tbuf[1024];
335 // int finish;
336
337 if (argc != 8)
338 usage();
339
340 f = fopen(argv[1], "r+b");
341
342 if (f == NULL)
343 usage();
344
345 base = strtoul(argv[2], NULL, 0);
346 proc_name = argv[3];
347 pos = strtoul(argv[4], NULL, 0) - base;
348 size = strtoul(argv[5], NULL, 0);
349 lnk_pos = strtoul(argv[6], NULL, 0);
350 if (lnk_pos != 0) lnk_pos -= base;
351 lnk_size = strtoul(argv[7], NULL, 0);
352 // wcount = 0;
353
354 printf("static FuncSig func_sig_%s[] = {\n",proc_name);
355
356 dump_sig(pos,size,f);
357
358 if (lnk_pos != 0)
359 {
360 printf("\t{ -1, %d, -2 },\n",size-1);
361 dump_sig(lnk_pos,lnk_size,f);
362 }
363 printf("\t{ -1, -1, -1 },\n");
364 printf("};\n\n");
365
366 fclose(f);
367
368 return 0;
369 }
370