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