-
Notifications
You must be signed in to change notification settings - Fork 1
/
代码分析.txt
476 lines (437 loc) · 17.6 KB
/
代码分析.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
0:0000~0:00FF 向量表 256 B
0:0100~0:7E7D 数据 31.37 KiB
0:7E7E~0:FBFF 代码 31.38 KiB
1:0000~1:FFFD 代码 64.00 KiB
2:0000~2:BEED 代码 47.73 KiB
3:FFC0~3:FFE7 数据 39 B
3:FFEE~3:FFF5 型号 8 B
43 59 2D 32 33 39 43 20
C Y - 2 3 9 C [space]
3:FFF6~3:FFF7 正确的checksum: A8 04 (04A8)
=======================================================================================
CPU 对 POP PC 有特殊处理,POP PC 其实相当于POP两次 POP PC, POP CSR, 4个字节 PUSH/POP LR 也是类似的
PUSH 和 POP 永远是2字节为一单位
=======================================================================================
数据类型记号
ptr 指针 (本身是个word
byte 1字节
word 2字节
dword 4字节
=======================================================================================
_strcpy_nn 0:D070
00D070 6E F8 PUSH XR8
00D072 5E FC PUSH ER12
00D074 05 F8 MOV ER8, ER0 //保留er0
//之后 [er0]...<-[er2]...
00D076 25 FA MOV ER10, ER2
00D078 05 FC MOV ER12, ER0
//loop until R0==0, [ER12]<-[ER10]
00D07A A0 90 L R0, [ER10] //R0<-[ER10]
00D07C C1 90 ST R0, [ER12] //[ER12]<-R0
00D07E 81 EA ADD ER10, #1
00D080 81 EC ADD ER12, #1
00D082 00 80 MOV R0, R0
00D084 FA C8 BC NE, 0D07Ah
00D086 85 F0 MOV ER0, ER8 //恢复er0
00D088 1E FC POP ER12
00D08A 2E F8 POP XR8
00D08C 1F FE RT
输入: er0,er2 er2表示src, er0表示dst,没有返回值
void _strcpy_nn(ptr src:er2, ptr dst:er0)
=====================================================================================
smart_strcpy_nn 2:03C2
0203C2 CE F8 PUSH LR
0203C4 05 F0 MOV ER0, ER0
0203C6 04 C9 BC EQ, 203D0h (if er0==0, return)
0203C8 25 F2 MOV ER2, ER2 gadget:smart_strcpy_nn_
0203CA 03 C9 BC EQ, 203D2h (if er2==0, jmp br2)
0203CC 01 F0 70 D0 BL 00h:0D070h (er0!=0,er2!=0)
0203D0 8E F2 POP PC
br2:
0203D2 01 92 ST R2, [ER0] //er2==0,r2==0
0203D4 8E F2 POP PC
输入: er0,er2 er2表示src, er0表示dst,没有返回值
void smart_strcpy_nn(ptr src:er2, ptr dst:er0)
可以输入空指针
当 dst 为 NULL, 什么都不做
当 src 为 NULL, 把 dst 处字符串设为 ""
都不是 NULL, 把 src 处字符串复制到 dst 处
=====================================================================================
hex_byte 2:2492
022492 00 81 MOV R1, R0
022494 0F 21 AND R1, #15
022496 0A 71 CMP R1, #10
022498 02 C0 BC GE, 2249Eh
02249A 30 11 ADD R1, #48
02249C 01 CE BC AL, 224A0h
02249E 37 11 ADD R1, #55
0224A0 4C 90 SRL R0, #4
0224A2 0A 70 CMP R0, #10
0224A4 02 C0 BC GE, 224AAh
0224A6 30 10 ADD R0, #48
0224A8 01 CE BC AL, 224ACh
0224AA 37 10 ADD R0, #55
0224AC 1F FE RT
输入:R0 输出:ER0
R1=R0 & 0x0F
if(R1>=#10) R1+=0x37 //A->0x41,B->0x42...
else R1+=0x30 //0->0x30,1->0x31...
R0>>=4
if(R0>=#10) R0+=0x37
else R0+=0x30
把R0转换成字符串存在ER0中
输入R0为0xAB时,输出ER0为"AB"
word hex_byte(byte in:r0):er0
=====================================================================================
diag_calc_checksum 2:2392
022392 CE F8 PUSH LR
022394 7E F8 PUSH QR8 //R8,R9,ER10,ER12,ER14
022396 00 E8 MOV ER8, #0 //R8,R9<-0,0
022398 01 00 MOV R0, #1
02239A 11 90 04 F0 ST R0, 0F004h //#1->[F004]
// 现在 R8,R9 都是 0
////seg0 0000~FBFF
02239E 00 0E MOV R14, #0
0223A0 FC 0F MOV R15, #252 //0xFC00=#64512->er14
0223A2 00 EA MOV ER10, #0
0223A4 AA F0 LEA [ER10] //0->EA //gadget:calc_checksum_0
//loop
0223A6 05 E3 DSR<- 005h
0223A8 52 9A L ER10, [EA+] //EA move 2bytes
0223AA 8F FE NOP
0223AC A8 88 SUB R8, R10
0223AE B9 89 SUBC R9, R11
0223B0 FE EE ADD ER14, #-2
0223B2 F9 C8 BC NE, 223A6h
////seg1 0000~FFFF
0223B4 00 EE MOV ER14, #0 //0x10000
0223B6 00 EA MOV ER10, #0
0223B8 AA F0 LEA [ER10]
//loop
0223BA 01 E3 DSR<- 001h
0223BC 52 9A L ER10, [EA+]
0223BE 8F FE NOP
0223C0 A8 88 SUB R8, R10
0223C2 B9 89 SUBC R9, R11
0223C4 FE EE ADD ER14, #-2
0223C6 F9 C8 BC NE, 223BAh
////seg2 0000~FFFF
0223C8 00 EE MOV ER14, #0
0223CA 00 EA MOV ER10, #0
0223CC AA F0 LEA [ER10] //gadget:calc_checksum_2
//loop
0223CE 02 E3 DSR<- 002h
0223D0 52 9A L ER10, [EA+]
0223D2 8F FE NOP
0223D4 A8 88 SUB R8, R10
0223D6 B9 89 SUBC R9, R11
0223D8 FE EE ADD ER14, #-2
0223DA F9 C8 BC NE, 223CEh
////seg3 0000~FFF5
0223DC F6 0E MOV R14, #246
0223DE FF 0F MOV R15, #255 //ER14<-0xFFF6
0223E0 00 EA MOV ER10, #0
0223E2 AA F0 LEA [ER10]
//loop
0223E4 03 E3 DSR<- 003h
0223E6 52 9A L ER10, [EA+]
0223E8 8F FE NOP
0223EA A8 88 SUB R8, R10
0223EC B9 89 SUBC R9, R11
0223EE FE EE ADD ER14, #-2
0223F0 F9 C8 BC NE, 223E4h
0223F2 90 80 MOV R0, R9
0223F4 01 F2 92 24 BL 02h:02492h
0223F8 05 F4 MOV ER4, ER0
0223FA 80 80 MOV R0, R8
0223FC 01 F2 92 24 BL 02h:02492h
022400 05 F6 MOV ER6, ER0
022402 85 F0 MOV ER0, ER8
022404 3E F8 POP QR8
022406 8E F2 POP PC
输入:无
输出:ER0,XR4 ER0为checksum数值 XR4为ER0的字符串
副作用:把F004设成1
(word,dword) diag_calc_checksum():(er0,xr4)
=====================================================================================
<unknown> 2:0E5A
020E5A 10 90 11 D1 L R0, 0D111h
020E5E 88 70 CMP R0, #136
020E60 07 C9 BC EQ, 20E70h
020E62 71 A0 TB R0.7
020E64 03 C9 BC EQ, 20E6Ch
020E66 22 00 MOV R0, #34
020E68 D5 01 MOV R1, #213
020E6A 1F FE RT
020E6C 61 A0 TB R0.6
020E6E 03 C9 BC EQ, 20E76h
020E70 84 00 MOV R0, #132
020E72 D7 01 MOV R1, #215
020E74 1F FE RT
020E76 00 E0 MOV ER0, #0
020E78 1F FE RT
输入:无
输出:ER0
R0=[cur_mode]
if (R0==0x88) { //table模式
ER0=0xD784 //table模式的撤销区
}
else if (R0.7==0) {
if (R0.6==0) {
ER0=0
}
else { //R0.6==1
ER0=0xD784
}
}
else {
ER0=0xD522
}
获得当前模式撤销区的位置
如果模式代码是 0b00...,那就没有撤销区
如果模式代码是 0b01...,那撤销区在 0xD784
如果模式代码是 0b1x...,那撤销区在 0xD522 (表格模式是特例,它的撤销区在0xD784
ptr <unknown>():er0
=====================================================================================
diag_checksum 2:22D4
0222D4 CE F8 PUSH LR
0222D6 7E F0 PUSH QR0
0222D8 7E F8 PUSH QR8
0222DA 1A AE MOV ER14, SP
0222DC F0 E1 ADD SP, #-10h
0222DE 01 F0 00 7F BL 00h:07F00h //buffer_clear
0222E2 01 F2 78 22 BL 02h:02278h //diag_print_ver
0222E6 01 F0 04 87 BL 00h:08704h //render_ddd4
0222EA 01 F2 92 23 BL 02h:02392h //diag_calc_checksum, 此时er0为checksum数值, xr4为对应字符串
0222EE 0C F0 F6 FF LEA 0FFF6h
0222F2 03 E3 DSR<- 003h
0222F4 52 92 L ER2, [EA+] //er2<-正确的checksum(04A8)
0222F6 27 F0 CMP ER0, ER2
0222F8 04 C8 BC NE, 22302h
0222FA 20 08 MOV R8, 0x20
0222FC 4F 09 MOV R9, 0x4F
0222FE 4B 0A MOV R10, 0x4B
022300 03 CE BC AL, 22308h
022302 20 08 MOV R8, 0x20
022304 4E 09 MOV R9, 0x4E
022306 47 0A MOV R10, 0x47 //gadget:pr_checksum
022308 00 0B MOV R11, #0
// 上述代码:checksum正确则 xr8=" OK\0", 不正确则 xr8=" NG\0"
02230A 53 00 MOV R0, 0x53
02230C 55 01 MOV R1, 0x55
02230E 4D 02 MOV R2, 0x4D
022310 20 03 MOV R3, 0x20
// xr0="SUM "
022312 01 F2 82 23 BL 02h:02382h //store_reg_to_stack stack: xr0,xr4,xr8,xr12(unused),<ret>...
022316 11 01 MOV R1, 0x11 // ^^ (xr8末尾是\0
022318 1A A2 MOV ER2, SP // SP
02231A 01 F0 1C 82 BL 00h:0821Ch //line_print.col_0 (r1:row=#1,er2:addr
02231E 01 F2 AE 22 BL 02h:022AEh //diag_print_pd
022322 01 F0 04 87 BL 00h:08704h //render_ddd4
022326 01 F2 08 24 BL 02h:02408h //跟pd有关
02232A A5 70 CMP R0, 0xA5
02232C 04 C8 BC NE, 22336h
02232E 20 04 MOV R4, 0x20
022330 4F 05 MOV R5, 0x4F
022332 4B 06 MOV R6, 0x4B
022334 03 CE BC AL, 2233Ch
022336 20 04 MOV R4, 0x20
022338 4E 05 MOV R5, 0x4E
02233A 47 06 MOV R6, 0x47
02233C 00 07 MOV R7, #0
// 上述代码 r0==0xa5则 xr4=" OK\0",不正确则 xr4=" NG\0"
02233E 52 00 MOV R0, #82 //gadget:pr_checksum_2
022340 65 01 MOV R1, #101
022342 61 02 MOV R2, #97
022344 64 03 MOV R3, #100
// xr0="Read"
022346 01 F2 82 23 BL 02h:02382h //store_reg_to_stack
02234A 2C 00 MOV R0, #44
02234C 21 01 MOV R1, 0x21
02234E 1A A2 MOV ER2, SP
022350 01 F0 1E 82 BL 00h:0821Eh //line_print (r0:col=44px,r1:row=#2,er2:addr
022354 31 00 MOV R0, 0x31
022356 CE 02 MOV R2, 0xCE
022358 4D 03 MOV R3, 0x4D
02235A 01 F2 AC 21 BL 02h:021ACh //line_print_font14_col0 (r0:row=#3,er2:addr=0x4DCE "Press AC"
02235E 0C F0 49 F0 LEA 0F049h
022362 01 E0 MOV ER0, #1
022364 51 90 ST R0, [EA+]
022366 51 90 ST R0, [EA+]
022368 51 90 ST R0, [EA+]
02236A 31 91 ST R1, [EA]
// wait until AC is pressed
02236C 01 F0 04 87 BL 00h:08704h //render_ddd4
022370 01 F0 BA 93 BL 00h:093BAh //AC按了, flag_Z=0; else, flag_Z=1
022374 FB C9 BC EQ, 2236Ch //jmp if flag_Z==1
022376 01 F0 A0 92 BL 00h:092A0h // 00707 -> F048,F049,F050,F051,F052
02237A EA A1 MOV SP, ER14
02237C 3E F8 POP QR8
02237E 3E F0 POP QR0
022380 8E F2 POP PC
=====================================================================================
store_reg_to_stack 2:2382
022382 5E FC PUSH ER12
022384 E5 FC MOV ER12, ER14
022386 F0 EC ADD ER12, #-16
022388 CA F0 LEA [ER12]
02238A 1E FC POP ER12
02238C 57 90 ST QR0, [EA+]
02238E 57 98 ST QR8, [EA+]
022390 1F FE RT
副作用: r0..r15 -> [FP-#16]
void store_reg_to_stack()
=====================================================================================
line_print_col0 r1:row,er2:char* 0:821C
00821C 00 00 MOV R0, #0
line_print r0:col,r1:row,er2:char* 0:821E
00821E CE F8 PUSH LR
008220 7E F8 PUSH QR8
008222 05 F8 MOV ER8, ER0
008224 25 FA MOV ER10, ER2
008226 0B 0D MOV R13, #11
008228 10 90 37 D1 L R0, 0D137h //r0<-font_size
00822C 0E 70 CMP R0, #14
00822E 01 C9 BC EQ, 08232h
008230 06 0D MOV R13, #6
/// r8:col, r9:row, er10:char*
/// font_size==14: r13<-#11; else: r13<-#6
008232 C0 0F MOV R15, #192 //屏幕一行192个像素
008234 D8 8F SUB R15, R13
/// r15<-#192-r13
008236 00 0C MOV R12, #0
008238 00 03 MOV R3, #0
///loop
00823A F7 88 CMP R8, R15
00823C 28 C2 BC GT, 0828Eh //if R8>R15, loop ends
00823E A0 92 L R2, [ER10] //读取一个字符
008240 26 C9 BC EQ, 0828Eh //'\0'字符, loop ends
008242 04 72 CMP R2, #4
008244 07 C9 BC EQ, 08254h //r2==4, jmp br1
008246 F0 72 CMP R2, 0xF0
008248 1F C0 BC GE, 08288h //双字节字符头, jmp br4
00824A 01 72 CMP R2, #1
00824C 0E C8 BC NE, 0826Ah //r2!=1, jmp br2
00824E 01 F0 96 82 BL 00h:08296h //else (r2==1), call 0:8296
008252 17 CE BC AL, 08282h //jmp br3
br1:
008254 10 90 37 D1 L R0, 0D137h
008258 0E 70 CMP R0, #14
00825A 17 C8 BC NE, 0828Ah //font_size!=14则er10++,continue
00825C 81 EA ADD ER10, #1 //else (font_size==14)
00825E A0 92 L R2, [ER10] //再读取一个字符
008260 85 F0 MOV ER0, ER8
008262 01 F0 F6 82 BL 00h:082F6h //char_print r0:col,r1:row,er2:char
008266 09 18 ADD R8, #9
008268 0C CE BC AL, 08282h //jmp br3
br2:
00826A 85 F0 MOV ER0, ER8
00826C 5E F2 PUSH ER2
00826E 01 F0 F6 82 BL 00h:082F6h //char_print r0:col,r1:row,er2:char
008272 1E F2 POP ER2
008274 F1 73 CMP R3, 0xF1
008276 04 C9 BC EQ, 08280h
008278 F2 73 CMP R3, 0xF2
00827A 02 C9 BC EQ, 08280h
00827C D1 88 ADD R8, R13
00827E 01 CE BC AL, 08282h //jmp br3
008280 0C 18 ADD R8, #12
br3:
008282 00 03 MOV R3, #0
008284 01 1C ADD R12, #1
008286 01 CE BC AL, 0828Ah //er10++,continue
br4:
008288 20 83 MOV R3, R2
00828A 81 EA ADD ER10, #1
00828C D6 CE BC AL, 0823Ah
///loop
00828E C0 80 MOV R0, R12 //r12:字符数
008290 A5 F2 MOV ER2, ER10
008292 3E F8 POP QR8
008294 8E F2 POP PC
er2: ptr
r1: row
r0: col
line_print(&ptr,row,&col_px)
cnt<-0
header<-0
d_px<-(font_size==14?11:6)
while col_px<=192-d_px && *ptr!=0:
if *ptr>=0xF0
header<-*ptr
ptr++
continue
if *ptr==0x04
ptr++
if font_size!=14: continue
char_print((header,*ptr),row,col_px)
col_px+=9
elif *ptr==0x01
call 0:8296
else
char_print((header,*ptr),row,col_px)
col_px+=(header==0xF1||header==0xF2 ? 12 : d_px)
header<-0
ptr++
cnt++
col_px<-cnt
=====================================================================================
gadget: 0:EBCE
0:EBCE BL _memcpy_nn
0:ECD2 ADD SP, #2
0:EBD4 B LEAVE
LEAVE: mov sp,er14; pop xr4,qr8,pc
_memcpy_nn:
push er14 ; 22DC4 | FE5E
mov er14, sp ; 22DC6 | AE1A
push er12 ; 22DC8 | FC5E
push er8 ; 22DCA | F85E
push er4 ; 22DCC | F45E
mov er8, er0 ; 22DCE | F805
mov er4, er0 ; 22DD0 | F405
mov er12, er2 ; 22DD2 | FC25
bc al, .l_024 ; 22DD4 | CE09
.l_012:
mov er0, er4 ; 22DD6 | F045
l r2, [er12] ; 22DD8 | 92C0
st r2, [er4] ; 22DDA | 9241
add er0, 1 ; 22DDC | E081
mov er4, er0 ; 22DDE | F405
add er12, 1 ; 22DE0 | EC81
l er0, 2[er14] ; 22DE2 | B042
add er0, -1 ; 22DE4 | E0FF
st er0, 2[er14] ; 22DE6 | B0C2
.l_024:
mov er0, 0 ; 22DE8 | E000
l er2, 2[er14] ; 22DEA | B242
cmp er0, er2 ; 22DEC | F027
bc lt, .l_012 ; 22DEE | C1F3
mov er0, er8 ; 22DF0 | F085
pop er4 ; 22DF2 | F41E
pop er8 ; 22DF4 | F81E
pop er12 ; 22DF6 | FC1E
mov sp, er14 ; 22DF8 | A1EA
pop er14 ; 22DFA | FE1E
rt ; 22DFC | FE1F
输入
er0: dst
er2: src
栈顶两字节: len
副作用
破坏er2
push er14
mov er14,sp
push er12
push er8
push er4
p1=er0
p2=er2
while *(er14+2)>0:
*p1++=*p2++
*(er14+2)--
er2=0
pop er4
pop er8
pop er12
pop er14
rt