3 amsinfo - a tool for examining AMS firmware files
5 Copyright (C) Dave Chapman 2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
26 #include <sys/types.h>
32 /* Win32 compatibility */
38 #define PAD_TO_BOUNDARY(x) ((x) + 0x1ff) & ~0x1ff;
41 static off_t
filesize(int fd
) {
44 if (fstat(fd
,&buf
) < 0) {
45 perror("[ERR] Checking filesize of input file");
52 static uint32_t get_uint32le(unsigned char* p
)
54 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
57 static uint16_t get_uint16le(unsigned char* p
)
59 return p
[0] | (p
[1] << 8);
62 static int calc_checksum(unsigned char* buf
, int n
)
68 sum
+= get_uint32le(buf
+ 0x400 + i
);
74 static void dump_header(unsigned char* buf
, int i
)
76 printf("0x%08x:\n",i
);
77 printf(" HEADER: 0x%08x\n",i
);
78 printf(" FirmwareHeaderIndex: 0x%08x\n",get_uint32le(&buf
[i
]));
79 printf(" FirmwareChecksum: 0x%08x\n",get_uint32le(&buf
[i
+0x04]));
80 printf(" CodeBlockSizeMultiplier: 0x%08x\n",get_uint32le(&buf
[i
+0x08]));
81 printf(" FirmwareSize: 0x%08x\n",get_uint32le(&buf
[i
+0x0c]));
82 printf(" Unknown1: 0x%08x\n",get_uint32le(&buf
[i
+0x10]));
83 printf(" ModelID: 0x%04x\n",get_uint16le(&buf
[i
+0x14]));
84 printf(" Unknown2: 0x%04x\n",get_uint16le(&buf
[i
+0x16]));
87 static int dump_lib(unsigned char* buf
, int i
)
92 int baseaddr
, endaddr
;
94 baseaddr
= get_uint32le(&buf
[i
+0x04]);
95 endaddr
= get_uint32le(&buf
[i
+0x08]);
96 size
= get_uint32le(&buf
[i
+0x0c]);
97 unknown1
= get_uint32le(&buf
[i
+0x10]);
98 export_count
= get_uint32le(&buf
[i
+0x14]);
100 printf("0x%08x: \"%s\" 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",i
, buf
+ i
+ get_uint32le(&buf
[i
]),baseaddr
,endaddr
,size
,unknown1
,export_count
);
103 if (export_count
> 1) {
104 for (j
=0;j
<export_count
;j
++) {
105 printf(" Exports[%02d]: 0x%08x\n",j
,get_uint32le(&buf
[i
+0x18+4*j
]));
109 return PAD_TO_BOUNDARY(size
);
112 int main(int argc
, char* argv
[])
122 fprintf(stderr
,"USAGE: amsinfo firmware.bin\n");
126 fd
= open(argv
[1],O_RDONLY
|O_BINARY
);
128 if ((len
= filesize(fd
)) < 0)
131 if ((buf
= malloc(len
)) == NULL
) {
132 fprintf(stderr
,"[ERR] Could not allocate buffer for input file (%d bytes)\n",(int)len
);
136 n
= read(fd
, buf
, len
);
139 fprintf(stderr
,"[ERR] Could not read file\n");
145 /* Now we dump the firmware structure */
147 dump_header(buf
,0); /* First copy of header block */
148 // dump_header(buf,0x200); /* Second copy of header block */
150 firmware_size
= get_uint32le(&buf
[0x0c]);
152 printf("Calculated firmware checksum: 0x%08x\n",calc_checksum(buf
,firmware_size
));
154 /* Round size up to next multiple of 0x200 */
156 firmware_size
= PAD_TO_BOUNDARY(firmware_size
);
158 i
= firmware_size
+ 0x400;
160 printf("LIBRARY BLOCKS:\n");
161 printf("Offset Name BaseAddr EndAddr BlockSize Unknown1 EntryCount\n");
163 while (get_uint32le(&buf
[i
]) != 0xffffffff)
165 i
+= dump_lib(buf
,i
);
167 while (get_uint32le(&buf
[i
]) == 0xefbeadde)
171 printf("0x%08x: PADDING BLOCK\n",i
);