1 // SPDX-License-Identifier: GPL-2.0-only 2 #include <stdlib.h> 3 #include <stdio.h> 4 #include <string.h> 5 6 7 #define IMG_SIZE 0x3e0000 8 9 #define KERNEL_START 0x020000 10 #define KERNEL_SIZE 0x0b0000 11 12 #define ROOTFS_START 0x0d0000 13 #define ROOTFS_SIZE 0x30ffb2 14 15 char* app_name; 16 17 18 19 20 void print_usage(void) 21 { 22 fprintf(stderr, "usage: dgfirmware [<opts>] <img>\n"); 23 fprintf(stderr, " <img> firmware image filename\n"); 24 fprintf(stderr, " <opts> -h print this message\n"); 25 fprintf(stderr, " -f fix the checksum\n"); 26 fprintf(stderr, " -x <file> extract the rootfs file to <file>\n"); 27 fprintf(stderr, " -xk <file> extract the kernel to <file>\n"); 28 fprintf(stderr, " -m <file> merge in rootfs fil\e from <file>\n"); 29 fprintf(stderr, " -k <file> merge in kernel from <file>\n"); 30 fprintf(stderr, " -w <file> write back the modified firmware\n"); 31 } 32 33 34 unsigned char* read_img(const char *fname) 35 { 36 FILE *fp; 37 int size; 38 unsigned char *img; 39 40 fp = fopen(fname, "rb"); 41 if (fp == NULL) { 42 perror(app_name); 43 exit(-1); 44 } 45 46 fseek(fp, 0, SEEK_END); 47 size = ftell(fp); 48 49 if (size != IMG_SIZE) { 50 fprintf(stderr, "%s: image file has wrong size\n", app_name); 51 fclose(fp); 52 exit(-1); 53 } 54 55 rewind(fp); 56 57 img = malloc(IMG_SIZE); 58 if (img == NULL) { 59 perror(app_name); 60 fclose(fp); 61 exit(-1); 62 } 63 64 if (fread(img, 1, IMG_SIZE, fp) != IMG_SIZE) { 65 fprintf(stderr, "%s: can't read image file\n", app_name); 66 fclose(fp); 67 exit(-1); 68 } 69 70 fclose(fp); 71 return img; 72 } 73 74 75 void write_img(unsigned char* img, const char *fname) 76 { 77 FILE *fp; 78 79 fp = fopen(fname, "wb"); 80 if (fp == NULL) { 81 perror(app_name); 82 exit(-1); 83 } 84 85 if (fwrite(img, 1, IMG_SIZE, fp) != IMG_SIZE) { 86 fprintf(stderr, "%s: can't write image file\n", app_name); 87 fclose(fp); 88 exit(-1); 89 } 90 91 fclose(fp); 92 } 93 94 95 void write_rootfs(unsigned char* img, const char *fname) 96 { 97 FILE *fp; 98 99 fp = fopen(fname, "wb"); 100 if (fp == NULL) { 101 perror(app_name); 102 exit(-1); 103 } 104 105 if (fwrite(img+ROOTFS_START, 1, ROOTFS_SIZE, fp) != ROOTFS_SIZE) { 106 fprintf(stderr, "%s: can't write image file\n", app_name); 107 fclose(fp); 108 exit(-1); 109 } 110 111 fclose(fp); 112 } 113 114 115 void write_kernel(unsigned char* img, const char *fname) 116 { 117 FILE *fp; 118 119 fp = fopen(fname, "wb"); 120 if (fp == NULL) { 121 perror(app_name); 122 exit(-1); 123 } 124 125 if (fwrite(img+KERNEL_START, 1, KERNEL_SIZE, fp) != KERNEL_SIZE) { 126 fprintf(stderr, "%s: can't write kernel file\n", app_name); 127 fclose(fp); 128 exit(-1); 129 } 130 131 fclose(fp); 132 } 133 134 135 unsigned char* read_rootfs(unsigned char* img, const char *fname) 136 { 137 FILE *fp; 138 int size; 139 int i; 140 141 for (i=ROOTFS_START; i<ROOTFS_START+ROOTFS_SIZE; i++) 142 img[i] = 0xff; 143 144 fp = fopen(fname, "rb"); 145 if (fp == NULL) { 146 perror(app_name); 147 exit(-1); 148 } 149 150 fseek(fp, 0, SEEK_END); 151 size = ftell(fp); 152 153 if (size > ROOTFS_SIZE) { 154 fprintf(stderr, "%s: rootfs image file is too big\n", app_name); 155 fclose(fp); 156 exit(-1); 157 } 158 159 rewind(fp); 160 161 if (fread(img+ROOTFS_START, 1, size, fp) != size) { 162 fprintf(stderr, "%s: can't read rootfs image file\n", app_name); 163 fclose(fp); 164 exit(-1); 165 } 166 167 fclose(fp); 168 return img; 169 } 170 171 172 unsigned char* read_kernel(unsigned char* img, const char *fname) 173 { 174 FILE *fp; 175 int size; 176 int i; 177 178 for (i=KERNEL_START; i<KERNEL_START+KERNEL_SIZE; i++) 179 img[i] = 0xff; 180 181 fp = fopen(fname, "rb"); 182 if (fp == NULL) { 183 perror(app_name); 184 exit(-1); 185 } 186 187 fseek(fp, 0, SEEK_END); 188 size = ftell(fp); 189 190 if (size > KERNEL_SIZE) { 191 fprintf(stderr, "%s: kernel binary file is too big\n", app_name); 192 fclose(fp); 193 exit(-1); 194 } 195 196 rewind(fp); 197 198 if (fread(img+KERNEL_START, 1, size, fp) != size) { 199 fprintf(stderr, "%s: can't read kernel file\n", app_name); 200 fclose(fp); 201 exit(-1); 202 } 203 204 fclose(fp); 205 return img; 206 } 207 208 209 int get_checksum(unsigned char* img) 210 { 211 short unsigned s; 212 213 s = img[0x3dfffc] + (img[0x3dfffd]<<8); 214 215 return s; 216 } 217 218 219 void set_checksum(unsigned char*img, unsigned short sum) 220 { 221 img[0x3dfffc] = sum & 0xff; 222 img[0x3dfffd] = (sum>>8) & 0xff; 223 } 224 225 226 int compute_checksum(unsigned char* img) 227 { 228 int i; 229 short s=0; 230 231 for (i=0; i<0x3dfffc; i++) 232 s += img[i]; 233 234 return s; 235 } 236 237 238 int main(int argc, char* argv[]) 239 { 240 char *img_fname = NULL; 241 char *rootfs_fname = NULL; 242 char *kernel_fname = NULL; 243 char *new_img_fname = NULL; 244 245 int do_fix_checksum = 0; 246 int do_write = 0; 247 int do_write_rootfs = 0; 248 int do_read_rootfs = 0; 249 int do_write_kernel = 0; 250 int do_read_kernel = 0; 251 252 int i; 253 unsigned char *img; 254 unsigned short img_checksum; 255 unsigned short real_checksum; 256 257 app_name = argv[0]; 258 259 for (i=1; i<argc; i++) { 260 if (!strcmp(argv[i], "-h")) { 261 print_usage(); 262 return 0; 263 } 264 else if (!strcmp(argv[i], "-f")) { 265 do_fix_checksum = 1; 266 } 267 else if (!strcmp(argv[i], "-x")) { 268 if (i+1 >= argc) { 269 fprintf(stderr, "%s: missing argument\n", app_name); 270 return -1; 271 } 272 do_write_rootfs = 1; 273 rootfs_fname = argv[i+1]; 274 i++; 275 } 276 else if (!strcmp(argv[i], "-xk")) { 277 if (i+1 >= argc) { 278 fprintf(stderr, "%s: missing argument\n", app_name); 279 return -1; 280 } 281 do_write_kernel = 1; 282 kernel_fname = argv[i+1]; 283 i++; 284 } 285 else if (!strcmp(argv[i], "-m")) { 286 if (i+1 >= argc) { 287 fprintf(stderr, "%s: missing argument\n", app_name); 288 return -1; 289 } 290 do_read_rootfs = 1; 291 rootfs_fname = argv[i+1]; 292 i++; 293 } 294 else if (!strcmp(argv[i], "-k")) { 295 if (i+1 >= argc) { 296 fprintf(stderr, "%s: missing argument\n", app_name); 297 return -1; 298 } 299 do_read_kernel = 1; 300 kernel_fname = argv[i+1]; 301 i++; 302 } 303 else if (!strcmp(argv[i], "-w")) { 304 if (i+1 >= argc) { 305 fprintf(stderr, "%s: missing argument\n", app_name); 306 return -1; 307 } 308 do_write = 1; 309 new_img_fname = argv[i+1]; 310 i++; 311 } 312 else if (img_fname != 0) { 313 fprintf(stderr, "%s: too many arguments\n", app_name); 314 return -1; 315 } 316 else { 317 img_fname = argv[i]; 318 } 319 } 320 321 if (img_fname == NULL) { 322 fprintf(stderr, "%s: missing argument\n", app_name); 323 return -1; 324 } 325 326 if ((do_read_rootfs && do_write_rootfs) || 327 (do_read_kernel && do_write_kernel)) { 328 fprintf(stderr, "%s: conflictuous options\n", app_name); 329 return -1; 330 } 331 332 printf ("** Read firmware file\n"); 333 img = read_img(img_fname); 334 335 printf ("Firmware product: %s\n", img+0x3dffbd); 336 printf ("Firmware version: 1.%02d.%02d\n", (img[0x3dffeb] & 0x7f), img[0x3dffec]); 337 338 if (do_write_rootfs) { 339 printf ("** Write rootfs file\n"); 340 write_rootfs(img, rootfs_fname); 341 } 342 343 if (do_write_kernel) { 344 printf ("** Write kernel file\n"); 345 write_kernel(img, kernel_fname); 346 } 347 348 if (do_read_rootfs) { 349 printf ("** Read rootfs file\n"); 350 read_rootfs(img, rootfs_fname); 351 do_fix_checksum = 1; 352 } 353 354 if (do_read_kernel) { 355 printf ("** Read kernel file\n"); 356 read_kernel(img, kernel_fname); 357 do_fix_checksum = 1; 358 } 359 360 img_checksum = get_checksum(img); 361 real_checksum = compute_checksum(img); 362 363 printf ("image checksum = %04x\n", img_checksum); 364 printf ("real checksum = %04x\n", real_checksum); 365 366 if (do_fix_checksum) { 367 if (img_checksum != real_checksum) { 368 printf ("** Bad Checksum, fix it\n"); 369 set_checksum(img, real_checksum); 370 } 371 else { 372 printf ("** Checksum is correct, good\n"); 373 } 374 } 375 376 if (do_write) { 377 printf ("** Write image file\n"); 378 write_img(img, new_img_fname); 379 } 380 381 free(img); 382 return 0; 383 } 384 385
This page was automatically generated by LXR 0.3.1. • OpenWrt