Changeset 11478 for trunk/reader-dre-st20.c
- Timestamp:
- 01/18/19 23:36:20 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/reader-dre-st20.c
r11246 r11478 8 8 #define CREG 4 9 9 10 #define FLASHS 11 #define FLASHE 12 #define RAMS 13 #define RAME 14 #define IRAMS 15 #define IRAME 10 #define FLASHS 0x7FE00000 11 #define FLASHE 0x7FFFFFFF 12 #define RAMS 0x40000000 13 #define RAME 0x401FFFFF 14 #define IRAMS 0x80000000 15 #define IRAME 0x800017FF 16 16 17 17 #define ERR_ILL_OP -1 … … 23 23 #define STACKMASK (STACKMAX-1) 24 24 25 typedef struct 26 { 27 28 29 30 31 32 33 25 typedef struct 26 { 27 uint32_t Iptr, Wptr; 28 uint8_t *flash, *ram; 29 uint32_t flashSize, ramSize; 30 int sptr, stack[STACKMAX]; 31 uint8_t iram[0x1800]; 32 int invalid; 33 int verbose; 34 34 } st20_context_t; 35 36 35 37 36 static void st20_set_flash(st20_context_t *ctx, uint8_t *m, int len); … … 41 40 42 41 static void st20_set_call_frame(st20_context_t *ctx, uint32_t raddr, int p1, int p2, int p3); 43 44 42 45 43 static uint32_t st20_get_reg(st20_context_t *ctx, int reg); … … 50 48 static void st20_wword(st20_context_t *ctx, uint32_t off, uint32_t val); 51 49 52 #define INVALID_VALUE 0xCCCCCCCC 53 #define ERRORVAL 0xDEADBEEF 54 55 #define MININT 0x7FFFFFFF 56 #define MOSTPOS 0x7FFFFFFF 57 #define MOSTNEG 0x80000000 58 50 #define INVALID_VALUE 0xCCCCCCCC 51 #define ERRORVAL 0xDEADBEEF 52 53 #define MININT 0x7FFFFFFF 54 #define MOSTPOS 0x7FFFFFFF 55 #define MOSTNEG 0x80000000 59 56 60 57 #define POP() ctx->stack[(ctx->sptr++)&STACKMASK] … … 66 63 #define CCC ctx->stack[(ctx->sptr+2)&STACKMASK] 67 64 68 #define GET_OP() 69 #define CLEAR_OP() 70 #define JUMP(x) 71 #define POP64() 65 #define GET_OP() operand|=op1&0x0F 66 #define CLEAR_OP() operand=0 67 #define JUMP(x) ctx->Iptr+=(x) 68 #define POP64() ({ uint32_t __b=POP(); ((uint64_t)POP()<<32)|__b; }) 72 69 #define PUSHPOP(op,val) do { int32_t __a=val; AAA op##= (__a); } while(0) 73 70 … … 78 75 static uint32_t st20_get_reg(st20_context_t *ctx, int32_t reg) 79 76 { 80 switch(reg) 77 switch(reg) 81 78 { 82 79 case IPTR: return ctx->Iptr; … … 112 109 } 113 110 else if(off >= IRAMS && off <= IRAME) 111 { 114 112 return &ctx->iram[off - IRAMS]; 113 } 115 114 116 115 ctx->invalid = ERRORVAL; … … 122 121 uint8_t *temp; 123 122 temp = st20_addr(ctx, off); 124 125 return ((temp[3] <<24) | (temp[2]<<16) | (temp[1]<<8) | temp[0]);123 124 return ((temp[3] << 24) | (temp[2] << 16) | (temp[1] << 8) | temp[0]); 126 125 } 127 126 … … 130 129 uint8_t *temp; 131 130 temp = st20_addr(ctx, off); 132 133 return ((temp[0] <<8) | temp[1]);131 132 return ((temp[0] << 8) | temp[1]); 134 133 } 135 134 … … 160 159 int32_t operand = 0; 161 160 CLEAR_OP(); 161 162 162 while(ctx->Iptr != 0) 163 163 { 164 164 int32_t a, op1 = RB(ctx->Iptr++); 165 165 GET_OP(); 166 166 167 switch(op1 >> 4) 167 168 { … … 170 171 CLEAR_OP(); 171 172 break; 173 172 174 case 0x1: // ldlp 173 175 PUSH(ctx->Wptr + (operand * 4)); 174 176 CLEAR_OP(); 175 177 break; 178 176 179 case 0x2: // positive prefix 177 180 operand <<= 4; 178 181 break; 182 179 183 case 0x3: // ldnl 180 184 AAA=RW(AAA + (operand * 4)); 181 185 CLEAR_OP(); 182 186 break; 187 183 188 case 0x4: // ldc 184 189 PUSH(operand); 185 190 CLEAR_OP(); 186 191 break; 192 187 193 case 0x5: // ldnlp 188 194 PUSHPOP(+, operand * 4); 189 195 CLEAR_OP(); 190 196 break; 197 191 198 case 0x6: // negative prefix 192 199 operand = (~operand) << 4; 193 200 break; 201 194 202 case 0x7: // ldl 195 203 PUSH(RW(ctx->Wptr + (operand * 4))); 196 204 CLEAR_OP(); 197 205 break; 206 198 207 case 0x8: // adc 199 208 PUSHPOP(+, operand); 200 209 CLEAR_OP(); 201 210 break; 211 202 212 case 0x9: // call 203 213 ctx->Wptr -= 16; … … 207 217 CLEAR_OP(); 208 218 break; 219 209 220 case 0xA: // cj / conditional jump 210 221 if(AAA) { DROP(1); } else { JUMP(operand); } 211 222 CLEAR_OP(); 212 223 break; 224 213 225 case 0xB: // ajw / adjust workspace 214 226 ctx->Wptr += operand * 4; 215 227 CLEAR_OP(); 216 228 break; 229 217 230 case 0xC: // eqc / equals constant 218 231 AAA = (operand == AAA ? 1 : 0); 219 232 CLEAR_OP(); 220 233 break; 234 221 235 case 0xD: // stl 222 236 WW(ctx->Wptr + (operand * 4), POP()); 223 237 CLEAR_OP(); 224 238 break; 239 225 240 case 0xE: // stnl 226 241 a = POP(); WW(a + (operand * 4), POP()); 227 242 CLEAR_OP(); 228 243 break; 244 229 245 case 0xF: // opr (secondary ins) 230 246 switch(operand) 231 247 { 232 case 233 case 234 case 235 case 236 case 237 case 238 case 239 case 240 case 241 case 242 case 243 case 244 case 245 case 246 case 247 case 248 case 249 case 250 case 251 case 252 case 253 case 254 case 255 case 256 case 257 case 258 case 259 case 260 case 261 case 262 case 263 case 264 case 265 case 266 case 267 default: 268 cs_log("[icg] unknown opcode %X", operand);269 return ERR_ILL_OP;248 case 0x00: a = AAA; AAA = BBB; BBB = a; break; 249 case 0x01: AAA = RB(AAA); break; 250 case 0x02: PUSHPOP(+, POP()); break; 251 case 0x04: PUSHPOP(-, POP()); break; 252 case 0x05: PUSHPOP(+, POP()); break; 253 case 0x06: a = AAA; AAA = ctx->Iptr; ctx->Iptr = a; break; 254 case 0x08: PUSHPOP(*, POP()); break; 255 case 0x09: a=POP(); AAA = (AAA > a); break; 256 case 0x0A: a=POP(); AAA = a + (AAA * 4); break; 257 case 0x0C: PUSHPOP(-, POP()); break; 258 case 0x1A: { a = POP(); uint64_t ll = POP64(); PUSH(ll % (uint32_t)a); PUSH(ll / (uint32_t)a); } break; 259 case 0x1B: PUSHPOP(+, ctx->Iptr); break; 260 case 0x1D: CCC = BBB; BBB = (AAA >= 0 ? 0 : -1); break; 261 case 0x1F: PUSHPOP(%, POP()); break; 262 case 0x20: ctx->Iptr = RW(ctx->Wptr); ctx->Wptr = ctx->Wptr + 16; break; 263 case 0x2C: PUSHPOP(/, POP()); break; 264 case 0x30: break; 265 case 0x32: AAA =~ AAA; break; 266 case 0x33: PUSHPOP(^, POP()); break; 267 case 0x34: PUSHPOP(*, 4); break; 268 case 0x35: { a = POP(); uint64_t ll = POP64() >> a; PUSH((ll >> 32) & 0xFFFFFFFF); PUSH(ll & 0xFFFFFFFF); } break; 269 case 0x36: { a = POP(); uint64_t ll = POP64() << a; PUSH((ll >> 32) & 0xFFFFFFFF); PUSH(ll & 0xFFFFFFFF); } break; 270 case 0x3B: a = POP(); st20_wbyte(ctx, a, POP()); break; 271 case 0x3F: a = POP(); PUSH(a & 3); PUSH((uint32_t)a >> 2); break; 272 case 0x40: a = POP(); AAA = (uint32_t)AAA >> a; break; 273 case 0x41: a = POP(); AAA = (uint32_t)AAA << a; break; 274 case 0x42: PUSH(MOSTNEG); break; 275 case 0x46: PUSHPOP(&, POP()); break; 276 case 0x4A: { a = POP(); int32_t b = POP(); int32_t c = POP(); while(a--) st20_wbyte(ctx, b++, st20_rbyte(ctx, c++)); } break; 277 case 0x4B: PUSHPOP(|, POP()); break; 278 case 0x53: PUSHPOP(*, POP()); break; 279 case 0x5A: PUSH(AAA); break; 280 case 0x5F: a = POP(); AAA = ((uint32_t)AAA > (uint32_t)a); break; 281 case 0x78: { a = POP(); int32_t b = POP(); int32_t bb = 0; while(a--){bb <<= 1; bb |= b & 1; b >>= 1;} PUSH(bb);} break; 282 case 0xCA: AAA = st20_rshort(ctx, AAA); break; 283 default: 284 cs_log("[icg] unknown opcode %X", operand); 285 return ERR_ILL_OP; 270 286 } 271 287 CLEAR_OP(); 272 288 break; 273 } 274 if(--count <= 0 && operand == 0) return ERR_CNT; 289 } 290 291 if(--count <= 0 && operand == 0) 292 { 293 return ERR_CNT; 294 } 275 295 } 276 296 return 0; … … 279 299 static void st20_set_flash(st20_context_t *ctx, uint8_t *m, int32_t len) 280 300 { 281 if(ctx->flash) free(ctx->flash); 301 if(ctx->flash) 302 { 303 free(ctx->flash); 304 } 282 305 ctx->flash = malloc(len); 283 if(ctx->flash && m) memcpy(ctx->flash, m, len); 284 else memset(ctx->flash, 0, len); 306 307 if(ctx->flash && m) 308 { 309 memcpy(ctx->flash, m, len); 310 } 311 else 312 { 313 memset(ctx->flash, 0, len); 314 } 285 315 ctx->flashSize = len; 286 316 } … … 288 318 static void st20_set_ram(st20_context_t *ctx, uint8_t *m, int32_t len) 289 319 { 290 if(ctx->ram) free(ctx->ram); 320 if(ctx->ram) 321 { 322 free(ctx->ram); 323 } 291 324 ctx->ram = malloc(len); 292 if(ctx->ram && m) memcpy(ctx->ram, m, len); 293 else memset(ctx->ram, 0, len); 325 326 if(ctx->ram && m) 327 { 328 memcpy(ctx->ram, m, len); 329 } 330 else 331 { 332 memset(ctx->ram, 0, len); 333 } 294 334 ctx->ramSize = len; 295 335 } … … 297 337 static void st20_init(st20_context_t *ctx, uint32_t IPtr, uint32_t WPtr, int32_t verbose) 298 338 { 299 ctx->Wptr = WPtr; ctx->Iptr = IPtr; 300 memset(ctx->stack, INVALID_VALUE, sizeof(ctx->stack)); ctx->sptr = STACKMAX - 3; 339 ctx->Wptr = WPtr; 340 ctx->Iptr = IPtr; 341 memset(ctx->stack, INVALID_VALUE, sizeof(ctx->stack)); 342 ctx->sptr = STACKMAX - 3; 301 343 memset(ctx->iram, 0, sizeof(ctx->iram)); 302 344 ctx->verbose = verbose; … … 305 347 static void st20_free(st20_context_t *ctx) 306 348 { 307 if(ctx->flash) free(ctx->flash); 308 if(ctx->ram) free(ctx->ram); 349 if(ctx->flash) 350 { 351 free(ctx->flash); 352 } 309 353 ctx->flash = NULL; 354 355 if(ctx->ram) 356 { 357 free(ctx->ram); 358 } 310 359 ctx->ram = NULL; 311 360 } … … 315 364 ctx->Wptr -= 16; 316 365 st20_wword(ctx, ctx->Wptr, raddr); // RET 317 st20_wword(ctx, ctx->Wptr + 4, p1); //Areg318 st20_wword(ctx, ctx->Wptr + 8, p1); //Breg319 st20_wword(ctx, ctx->Wptr + 12, p1); // Creg366 st20_wword(ctx, ctx->Wptr + 4, p1); // Areg 367 st20_wword(ctx, ctx->Wptr + 8, p1); // Breg 368 st20_wword(ctx, ctx->Wptr + 12, p1); // Creg 320 369 st20_wword(ctx, ctx->Wptr + 16, p2); 321 370 st20_wword(ctx, ctx->Wptr + 20, p3); 322 st20_set_reg(ctx, AREG, raddr); 371 st20_set_reg(ctx, AREG, raddr); // RET 323 372 } 324 373 … … 330 379 cs_log("[icg] decrypt address = 0x%X, id = %04X", addr, overcryptId); 331 380 332 cs_log("[icg] CW: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X " 333 ,data[0], data[1], data[2] , data[3] , data[4] , data[5] , data[6] , data[7] 334 ,data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]); 335 for(n=0;n<2;n++) 381 cs_log("[icg] CW: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X ", 382 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], 383 data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]); 384 385 for(n = 0; n < 2; n++) 336 386 { 337 387 memset(&ctx, 0, sizeof(st20_context_t)); … … 340 390 st20_init(&ctx, FLASHS + addr, RAMS + 0x100, 1); 341 391 st20_set_call_frame(&ctx, 0, RAMS, RAMS, RAMS); 342 for(i = 0; i < 8; i++) st20_wbyte(&ctx, RAMS + i, data[i+n*8]); 343 if ((error = st20_decode(&ctx, 800000)) < 0) break; 344 cs_log("[icg] cw%d ret = %d, AREG = %X", n+1, error, st20_get_reg(&ctx, AREG)); 345 for(i = 0; i < 8; i++) data[i+n*8] = st20_rbyte(&ctx, RAMS + i); 392 393 for(i = 0; i < 8; i++) 394 { 395 st20_wbyte(&ctx, RAMS + i, data[i + n * 8]); 396 } 397 398 if((error = st20_decode(&ctx, 800000)) < 0) 399 { 400 break; 401 } 402 403 cs_log("[icg] cw%d ret = %d, AREG = %X", n + 1, error, st20_get_reg(&ctx, AREG)); 404 405 for(i = 0; i < 8; i++) 406 { 407 data[i + n * 8] = st20_rbyte(&ctx, RAMS + i); 408 } 346 409 st20_free(&ctx); 347 410 } 348 411 349 412 if(error < 0) 350 413 { … … 352 415 return 0; 353 416 } 354 355 cs_log("[icg] DW: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X " 356 ,data[0], data[1], data[2] , data[3] , data[4] , data[5] , data[6] , data[7]357 ,data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]);417 418 cs_log("[icg] DW: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X ", 419 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], 420 data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]); 358 421 return 1; 359 422 } 360
Note:
See TracChangeset
for help on using the changeset viewer.