Maurus Cuelenaere | 3b45b8c | 2008-10-27 18:45:01 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 2 | * __________ __ ___. |
| 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
| 7 | * \/ \/ \/ \/ \/ |
| 8 | * $Id$ |
| 9 | * |
| 10 | * Copyright (C) 2008 by Jin Le |
| 11 | * |
| 12 | * This program is free software; you can redistribute it and/or |
| 13 | * modify it under the terms of the GNU General Public License |
| 14 | * as published by the Free Software Foundation; either version 2 |
| 15 | * of the License, or (at your option) any later version. |
| 16 | * |
| 17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| 18 | * KIND, either express or implied. |
| 19 | * |
| 20 | ****************************************************************************/ |
| 21 | |
| 22 | |
| 23 | /* |
| 24 | * dl_analyser.c ONDA VX767 DL file analyser |
| 25 | * |
| 26 | * Copyright (C) 2008 - JinLe |
| 27 | * |
| 28 | * This is free software; you can redistribute it and/or modify |
| 29 | * it under the terms of the GNU General Public License as published by |
| 30 | * the Free Software Foundation; either version 2 of the License, or |
| 31 | * (at your option) any later version. |
| 32 | * |
| 33 | * This is distributed in the hope that it will be useful, |
| 34 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 35 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 36 | * GNU General Public License for more details. |
| 37 | * |
| 38 | * You should have received a copy of the GNU General Public License |
| 39 | * along with ; if not, write to the Free Software |
| 40 | * Foundation, Inc., 51 Franklin St, Fifth Floor, |
| 41 | * Boston, MA 02110-1301 USA |
| 42 | |
| 43 | The DL file can not find any entry point, |
| 44 | so I think it just a dynamic library |
| 45 | not executable. |
| 46 | |
| 47 | IN THE FILE |
| 48 | +-------------------------- |
| 49 | + block_header_t |
| 50 | +-------------------------- |
| 51 | + block_impt_header_t |
| 52 | +-------------------------- |
| 53 | + block_expt_header_t |
| 54 | +-------------------------- |
| 55 | + block_raw_header_t |
| 56 | +-------------------------- |
| 57 | + import symbol |
| 58 | +-------------------------- |
| 59 | + export symbol |
| 60 | +-------------------------- |
| 61 | + padding |
| 62 | +-------------------------- <-----(raw->offset) |
| 63 | + |
| 64 | + raw code seg |
| 65 | + |
| 66 | +-------------------------- |
| 67 | + |
| 68 | + inited mem seg |
| 69 | + |
| 70 | +-------------------------- <-----(raw->offset + raw->size)(bss start) |
| 71 | |
| 72 | IN THE MEMORY |
| 73 | +-------------------------- <-----(raw->mem2) |
| 74 | + |
| 75 | + code seg |
| 76 | + |
| 77 | +-------------------------- |
| 78 | + |
| 79 | + inited mem seg |
| 80 | + |
| 81 | +-------------------------- <-----(raw->mem2 + raw->size)(bss start) |
| 82 | + |
| 83 | + BSS(Not in file) |
| 84 | + |
| 85 | +-------------------------- <-----(raw->mem2 + raw->memsize)(bss end) |
| 86 | |
| 87 | HOW TO disassemble (Ex: VX767_V1.0.dl) |
| 88 | |
| 89 | STEP 1: |
| 90 | ./dl_analyser VX767_V1.0.dl |
| 91 | |
| 92 | =======================HEADER===================== |
| 93 | File magic: CCDL |
| 94 | File Type : 0x00010000 |
| 95 | Offset : 0x00020001 |
| 96 | Size : 0x00000004 |
| 97 | BuildDate : 2008/03/26 09:59:19 |
| 98 | PaddindSum: 0x0 |
| 99 | =====================IMPT HEADER================== |
| 100 | Header magic : IMPT |
| 101 | Header Type : 0x00000008 |
| 102 | Offset : 0x000000a0 |
| 103 | Size : 0x0000007c |
| 104 | PaddindSum : 0x0 |
| 105 | =====================EXPT HEADER================== |
| 106 | Header magic : EXPT |
| 107 | Header Type : 0x00000009 |
| 108 | Offset : 0x00000120 |
| 109 | Size : 0x00000108 |
| 110 | PaddindSum : 0x0 |
| 111 | =====================RAWD HEADER================== |
| 112 | Header magic : RAWD |
| 113 | Header Type : 0x00000001 |
| 114 | Offset : 0x00000230 |
| 115 | Size : 0x000058a0 |
| 116 | Paddind1 : 0x0 |
| 117 | BSS Clear Code : 0x80f82714 start at file 0x2944 |
| 118 | mem_place_start : 0x80f80000 start at file 0x230 |
| 119 | memsize : 0x5a58 |
| 120 | mem_end(BSS end): 0x80f85a58 |
| 121 | Paddind2Sum : 0x0 |
| 122 | =====================IMPORT SYMBOL================== |
| 123 | number symbols : 0x4 |
| 124 | PaddindSum : 0x0 |
| 125 | Sym[00] offset 0x0000 padding 0x0 flag 0x20000 address 0x80f82750 name: printf |
| 126 | Sym[01] offset 0x0008 padding 0x0 flag 0x20000 address 0x80f82758 name: udelay |
| 127 | Sym[02] offset 0x0010 padding 0x0 flag 0x20000 address 0x80f82760 name: delay_ms |
| 128 | Sym[03] offset 0x001c padding 0x0 flag 0x20000 address 0x80f82768 name: get_rgb_lcd_buf |
| 129 | =====================EXPORT SYMBOL================== |
| 130 | number symbols : 0x7 |
| 131 | PaddindSum : 0x0 |
| 132 | Sym[00] offset 0x0000 padding 0x0 flag 0x20000 address 0x80f826dc name: init_lcd_register |
| 133 | Sym[01] offset 0x0014 padding 0x0 flag 0x20000 address 0x80f80160 name: get_ccpmp_config |
| 134 | Sym[02] offset 0x0028 padding 0x0 flag 0x20000 address 0x80f82690 name: get_bklight_config |
| 135 | Sym[03] offset 0x003c padding 0x0 flag 0x20000 address 0x80f81120 name: init_lcd_gpio |
| 136 | Sym[04] offset 0x004c padding 0x0 flag 0x20000 address 0x80f804d0 name: rgb_user_init |
| 137 | Sym[05] offset 0x005c padding 0x0 flag 0x20000 address 0x80f806a4 name: get_rgb_frame_buf |
| 138 | Sym[06] offset 0x0070 padding 0x0 flag 0x20000 address 0x80f8269c name: lcd_set_direction_mode |
| 139 | |
| 140 | STEP 2: |
| 141 | mips-linux-objdump -bbinary -mmips -D VX767_V1.0.dl > 767.as |
| 142 | |
| 143 | STEP 3: |
| 144 | for function lcd_set_direction_mode(address 0x80f8269c) |
| 145 | we translate that address into 'file address' |
| 146 | file address = 0x80f8269c - 0x80f80000 + 0x230 = 0x28CC |
| 147 | |
| 148 | STEP 4: |
| 149 | Find code in 767.as use this 'file address' |
| 150 | |
| 151 | 2008.10.20 6:23PM |
| 152 | */ |
| 153 | |
| 154 | #include <stdlib.h> |
| 155 | #include <stdio.h> |
| 156 | #include <string.h> |
| 157 | #include <unistd.h> |
| 158 | #include <sys/types.h> |
| 159 | #include <sys/stat.h> |
| 160 | #include <fcntl.h> |
| 161 | |
| 162 | /*******************************HEADER*****************************/ |
| 163 | typedef struct |
| 164 | { |
| 165 | char magic[4]; |
| 166 | int type; |
| 167 | int offset; |
| 168 | int size; |
| 169 | unsigned char date[7]; |
| 170 | unsigned char padding[9]; |
| 171 | }block_header_t; |
| 172 | |
| 173 | typedef struct |
| 174 | { |
| 175 | char magic[4]; |
| 176 | int type; |
| 177 | int offset; |
| 178 | int size; |
| 179 | int padding[4]; |
| 180 | }block_impt_header_t; |
| 181 | |
| 182 | typedef struct |
| 183 | { |
| 184 | char magic[4]; |
| 185 | int type; |
| 186 | int offset; |
| 187 | int size; |
| 188 | int padding[4]; |
| 189 | }block_expt_header_t; |
| 190 | |
| 191 | typedef struct |
| 192 | { |
| 193 | char magic[4]; |
| 194 | int type; |
| 195 | int offset; |
| 196 | int size; |
| 197 | int padding1; |
| 198 | int mem1; |
| 199 | int mem2; |
| 200 | int memsize; |
| 201 | int padding2[8]; |
| 202 | }block_raw_header_t; |
| 203 | |
| 204 | /*******************************SYMBOL*****************************/ |
| 205 | typedef struct |
| 206 | { |
| 207 | int offset; |
| 208 | int padding; |
| 209 | int flag; |
| 210 | int address; |
| 211 | char *name; |
| 212 | }symbol_t; |
| 213 | |
| 214 | typedef struct |
| 215 | { |
| 216 | int numsymbol; |
| 217 | int padding[3]; |
| 218 | int isimport; |
| 219 | symbol_t *symbol; |
| 220 | }import_export_symbol_t; |
| 221 | |
| 222 | void usage(char *name) |
| 223 | { |
| 224 | fprintf(stderr, "Usage: %s [dl file]\n", name); |
| 225 | } |
| 226 | |
| 227 | void dump_header(block_header_t *header) |
| 228 | { |
| 229 | int tmp; |
| 230 | fprintf(stderr, "=======================HEADER=====================\n"); |
| 231 | fprintf(stderr, "File magic: %c%c%c%c\n", header->magic[0], header->magic[1], header->magic[2], header->magic[3]); |
| 232 | fprintf(stderr, "File Type : 0x%08x\n", header->type); |
| 233 | fprintf(stderr, "Offset : 0x%08x\n", header->offset); |
| 234 | fprintf(stderr, "Size : 0x%08x\n", header->size); |
| 235 | fprintf(stderr, "BuildDate : %02x%02x/%02x/%02x %02x:%02x:%02x\n", |
| 236 | header->date[0], header->date[1], |
| 237 | header->date[2], header->date[3], |
| 238 | header->date[4], header->date[5], |
| 239 | header->date[6]); |
| 240 | tmp = header->padding[0] + header->padding[1] + header->padding[2] + header->padding[3] + header->padding[4] + |
| 241 | header->padding[5] + header->padding[6] + header->padding[7] + header->padding[8]; |
| 242 | fprintf(stderr, "PaddindSum: 0x%x\n", tmp); |
| 243 | } |
| 244 | |
| 245 | void dump_import_symbol_header(block_impt_header_t *impt) |
| 246 | { |
| 247 | int tmp; |
| 248 | fprintf(stderr, "=====================IMPT HEADER==================\n"); |
| 249 | fprintf(stderr, "Header magic : %c%c%c%c\n", impt->magic[0], impt->magic[1], impt->magic[2], impt->magic[3]); |
| 250 | fprintf(stderr, "Header Type : 0x%08x\n", impt->type); |
| 251 | fprintf(stderr, "Offset : 0x%08x\n", impt->offset); |
| 252 | fprintf(stderr, "Size : 0x%08x\n", impt->size); |
| 253 | tmp = impt->padding[0] + impt->padding[1] + impt->padding[2] + impt->padding[3]; |
| 254 | fprintf(stderr, "PaddindSum : 0x%x\n", tmp); |
| 255 | } |
| 256 | |
| 257 | void dump_export_symbol_header(block_expt_header_t *expt) |
| 258 | { |
| 259 | int tmp; |
| 260 | fprintf(stderr, "=====================EXPT HEADER==================\n"); |
| 261 | fprintf(stderr, "Header magic : %c%c%c%c\n", expt->magic[0], expt->magic[1], expt->magic[2], expt->magic[3]); |
| 262 | fprintf(stderr, "Header Type : 0x%08x\n", expt->type); |
| 263 | fprintf(stderr, "Offset : 0x%08x\n", expt->offset); |
| 264 | fprintf(stderr, "Size : 0x%08x\n", expt->size); |
| 265 | tmp = expt->padding[0] + expt->padding[1] + expt->padding[2] + expt->padding[3]; |
| 266 | fprintf(stderr, "PaddindSum : 0x%x\n", tmp); |
| 267 | } |
| 268 | |
| 269 | void dump_raw_data_header(block_raw_header_t *raw) |
| 270 | { |
| 271 | int tmp; |
| 272 | fprintf(stderr, "=====================RAWD HEADER==================\n"); |
| 273 | fprintf(stderr, "Header magic : %c%c%c%c\n", raw->magic[0], raw->magic[1], raw->magic[2], raw->magic[3]); |
| 274 | fprintf(stderr, "Header Type : 0x%08x\n", raw->type); |
| 275 | fprintf(stderr, "Offset : 0x%08x\n", raw->offset); |
| 276 | fprintf(stderr, "Size : 0x%08x\n", raw->size); |
| 277 | fprintf(stderr, "Paddind1 : 0x%x\n", raw->padding1); |
| 278 | fprintf(stderr, "BSS Clear Code : 0x%x start at file 0x%x\n", raw->mem1, raw->mem1-raw->mem2+raw->offset); |
| 279 | fprintf(stderr, "mem_start : 0x%x start at file 0x%x\n", raw->mem2, raw->offset); |
| 280 | fprintf(stderr, "memsize : 0x%x\n", raw->memsize); |
| 281 | fprintf(stderr, "mem_end(BSS end): 0x%x\n", raw->memsize + raw->mem2); |
| 282 | tmp = raw->padding2[0] + raw->padding2[1] + raw->padding2[2] + raw->padding2[3] + |
| 283 | raw->padding2[4] + raw->padding2[5] + raw->padding2[6] + raw->padding2[7]; |
| 284 | fprintf(stderr, "Paddind2Sum : 0x%x\n", tmp); |
| 285 | } |
| 286 | |
| 287 | void dump_symbol_table(import_export_symbol_t *sym, char *prefix) |
| 288 | { |
| 289 | int tmp; |
| 290 | int i; |
| 291 | |
| 292 | fprintf(stderr, "=====================%s==================\n", prefix); |
| 293 | fprintf(stderr, "number symbols : 0x%x\n", sym->numsymbol); |
| 294 | tmp = sym->padding[0] + sym->padding[1] + sym->padding[2]; |
| 295 | fprintf(stderr, "PaddindSum : 0x%x\n", tmp); |
| 296 | for(i=0; i<sym->numsymbol; i++) |
| 297 | { |
| 298 | fprintf(stderr, "Sym[%02d] offset 0x%04x padding 0x%x flag 0x%x address 0x%x name: %s\n", |
| 299 | i, sym->symbol[i].offset, sym->symbol[i].padding, |
| 300 | sym->symbol[i].flag, sym->symbol[i].address, sym->symbol[i].name); |
| 301 | } |
| 302 | } |
| 303 | |
| 304 | static int read_symbols(int fd, import_export_symbol_t *sym) |
| 305 | { |
| 306 | int numbers = sym->numsymbol; |
| 307 | int i, ret; |
| 308 | int len = 0, flag = 0; |
| 309 | char buffer; |
| 310 | int nametab_offset; |
| 311 | |
| 312 | if(numbers == 0 || fd < 0) |
| 313 | return 0; |
| 314 | /*Read table*/ |
| 315 | sym->symbol = (symbol_t *)malloc(sizeof(symbol_t) * numbers); |
| 316 | for(i=0; i<numbers; i++) |
| 317 | { |
| 318 | /*Offset*/ |
| 319 | if((ret = read(fd, &sym->symbol[i].offset, sizeof(int))) < 0) |
| 320 | return -1; |
| 321 | /*Padding*/ |
| 322 | if((ret = read(fd, &sym->symbol[i].padding, sizeof(int))) < 0) |
| 323 | return -1; |
| 324 | /*Flag*/ |
| 325 | if((ret = read(fd, &sym->symbol[i].flag, sizeof(int))) < 0) |
| 326 | return -1; |
| 327 | /*Address*/ |
| 328 | if((ret = read(fd, &sym->symbol[i].address, sizeof(int))) < 0) |
| 329 | return -1; |
| 330 | } |
| 331 | /*Read name*/ |
| 332 | nametab_offset = lseek(fd, 0, SEEK_CUR); |
| 333 | for(i=0; i<numbers; i++) |
| 334 | { |
| 335 | /*Set seek start*/ |
| 336 | lseek(fd, nametab_offset + sym->symbol[i].offset, SEEK_SET); |
| 337 | /*get length of name*/ |
| 338 | while(flag != 2) |
| 339 | { |
| 340 | if((ret = read(fd, &buffer, sizeof(char))) < 0) |
| 341 | return -1; |
| 342 | if(buffer != 0) |
| 343 | len++; |
| 344 | else |
| 345 | flag++; |
| 346 | } |
| 347 | if(len == 0) |
| 348 | break; |
| 349 | /*Reset seek start*/ |
| 350 | lseek(fd, nametab_offset + sym->symbol[i].offset, SEEK_SET); |
| 351 | /*Read name*/ |
| 352 | sym->symbol[i].name = (char *)malloc(sizeof(char) * (len+1)); |
| 353 | memset(sym->symbol[i].name, 0, len+1); |
| 354 | if((ret = read(fd, sym->symbol[i].name, sizeof(char)*len)) < 0) |
| 355 | return -1; |
| 356 | flag = len = 0; |
| 357 | } |
| 358 | return i; |
| 359 | } |
| 360 | |
| 361 | int analyze_dl(int fd) |
| 362 | { |
| 363 | int ret = -1; |
| 364 | block_header_t header; |
| 365 | block_impt_header_t impt; |
| 366 | block_expt_header_t expt; |
| 367 | block_raw_header_t raw; |
| 368 | import_export_symbol_t isym; |
| 369 | import_export_symbol_t esym; |
| 370 | |
| 371 | /*Read Header*/ |
| 372 | if((ret = read(fd, &header, sizeof(block_header_t))) < 0) |
| 373 | return -1; |
| 374 | dump_header(&header); |
| 375 | /*Read Import header*/ |
| 376 | if((ret = read(fd, &impt, sizeof(block_impt_header_t))) < 0) |
| 377 | return -1; |
| 378 | dump_import_symbol_header(&impt); |
| 379 | /*Read Export header*/ |
| 380 | if((ret = read(fd, &expt, sizeof(block_expt_header_t))) < 0) |
| 381 | return -1; |
| 382 | dump_export_symbol_header(&expt); |
| 383 | /*Read Raw data header*/ |
| 384 | if((ret = read(fd, &raw, sizeof(block_raw_header_t))) < 0) |
| 385 | return -1; |
| 386 | dump_raw_data_header(&raw); |
| 387 | |
| 388 | /*read import symbol*/ |
| 389 | lseek(fd, impt.offset, SEEK_SET); |
| 390 | /*number*/ |
| 391 | if((ret = read(fd, &isym.numsymbol, sizeof(int))) < 0) |
| 392 | return -1; |
| 393 | /*padding*/ |
| 394 | if((ret = read(fd, &isym.padding, sizeof(int)*3)) < 0) |
| 395 | return -1; |
| 396 | if((ret = read_symbols(fd, &isym)) < 0) |
| 397 | { |
| 398 | return -1; |
| 399 | } |
| 400 | dump_symbol_table(&isym, "IMPORT SYMBOL"); |
| 401 | |
| 402 | /*read export symbol*/ |
| 403 | lseek(fd, expt.offset, SEEK_SET); |
| 404 | /*number*/ |
| 405 | if((ret = read(fd, &esym.numsymbol, sizeof(int))) < 0) |
| 406 | return -1; |
| 407 | /*padding*/ |
| 408 | if((ret = read(fd, &esym.padding, sizeof(int)*3)) < 0) |
| 409 | return -1; |
| 410 | if((ret = read_symbols(fd, &esym)) < 0) |
| 411 | { |
| 412 | return -1; |
| 413 | } |
| 414 | dump_symbol_table(&esym, "EXPORT SYMBOL"); |
| 415 | return 0; |
| 416 | } |
| 417 | |
| 418 | int main(int argc, char *argv[]) |
| 419 | { |
| 420 | int fd = -1; |
| 421 | int ret = -1; |
| 422 | |
| 423 | if(argc != 2) |
| 424 | { |
| 425 | usage(argv[0]); |
| 426 | return -1; |
| 427 | } |
| 428 | fd = open(argv[1], O_RDONLY); |
| 429 | if(fd < 0) |
| 430 | { |
| 431 | perror("Open"); |
| 432 | return -1; |
| 433 | } |
| 434 | ret = analyze_dl(fd); |
| 435 | return ret; |
| 436 | } |