Firmware of Silead Touchscreen Controller for Jumper EZpad 6 Pro.
Revision | 0c2696397edde93f497ed201d03dc45fe358ad8a (tree) |
---|---|
Time | 2018-05-15 03:57:12 |
Author | Gregor Riepl <onitake@gmai...> |
Commiter | Gregor Riepl |
Added Windows driver extraction tool
@@ -1,2 +1,3 @@ | ||
1 | 1 | fw_extractor is (c) 2013-2014 by Joe Burmeister <joe.a.burmeister@gmail.com> |
2 | -fwtool, unscramble, untscfg and autoconvert are (c) 2015-2016 by Gregor Riepl <onitake@gmail.com> | |
\ No newline at end of file | ||
2 | +fwtool, unscramble, untscfg and autoconvert are (c) 2015-2016 by Gregor Riepl <onitake@gmail.com> | |
3 | +scanwindrv is (c) 2018 by Gregor Riepl <onitake@gmail.com>, based on an example script by Bernhard Übelacker <bernhardu@mailbox.org> | |
\ No newline at end of file |
@@ -0,0 +1,129 @@ | ||
1 | +#!/usr/bin/perl | |
2 | + | |
3 | +use strict; | |
4 | +use warnings; | |
5 | +require 5.018; | |
6 | +use IO::File; | |
7 | + | |
8 | +sub usage() { | |
9 | + print(STDERR "Usage: scanwindrv SileadTouch.sys\n"); | |
10 | + print(STDERR "Scans a Windows driver for sections that look like a firmware image and\n"); | |
11 | + print(STDERR "writes each into sequentially numbered files: firmware_01.fw firmware_02.fw ...\n"); | |
12 | + -1; | |
13 | +} | |
14 | + | |
15 | +my $drvfile = $ARGV[0] or exit usage; | |
16 | + | |
17 | +my $driver = ''; | |
18 | +do { | |
19 | + my $in = IO::File->new($drvfile, 'r') or die "Can't open $drvfile: $!"; | |
20 | + $in->binmode(); | |
21 | + local $/; | |
22 | + $driver = <$in>; | |
23 | + defined $driver or die "Can't read firmware: $!"; | |
24 | + $in->close(); | |
25 | +}; | |
26 | + | |
27 | +my $candidate = 0; | |
28 | + | |
29 | +# find candidates | |
30 | +for (my $offset = 0; $offset + 8 <= length($driver); $offset++) { | |
31 | + | |
32 | + my ($cmd, $page) = unpack('(LL)<', substr($driver, $offset, 8)); | |
33 | + if ($cmd == 0x000000f0 && ($page & 0xffffff00) == 0x00000000) { | |
34 | + printf(STDERR "Found possible candidate at offset 0x%08x\n", $offset); | |
35 | + # possible candidate, start copying pages | |
36 | + | |
37 | + my $firmware = ''; | |
38 | + my $size; | |
39 | + FIRMWARE: for ($size = 0; $offset + $size + 129 * 8 <= length($driver);) { | |
40 | + | |
41 | + #printf(STDERR "offset=0x%08x size=%u[0x%08x]\n", $offset, $size, $size); | |
42 | + my ($cmd, $page) = unpack('(LL)<', substr($driver, $offset + $size, 8)); | |
43 | + #printf(STDERR "Page header at 0x%08x: [0x%02x, 0x%08x]\n", $offset + $size, $cmd, $page); | |
44 | + | |
45 | + # if this doesn't look like a page register - page pair, we're done | |
46 | + if ($cmd != 0x000000f0 || ($page & 0xffffff00) != 0x00000000) { | |
47 | + last FIRMWARE; | |
48 | + } | |
49 | + | |
50 | + for (my $index = 0; $index + 4 <= 128; $index += 4) { | |
51 | + my ($idx, $dat) = unpack('(LL)<', substr($driver, $offset + $size + 8 + $index * 2, 8)); | |
52 | + #printf(STDERR "Data at 0x%08x: [0x%02x, 0x%02x]\n", $offset + $size + 8 + $index * 2, $idx, $dat); | |
53 | + | |
54 | + # if the index is not sequential, this is probably not part of the fw and we're done | |
55 | + if ($idx != $index) { | |
56 | + #printf(STDERR "Expected index 0x%02x, got 0x%02x\n", $index, $idx); | |
57 | + last FIRMWARE; | |
58 | + } | |
59 | + } | |
60 | + | |
61 | + # one page complete, copy | |
62 | + substr($firmware, $size, 33 * 8) = substr($driver, $offset + $size, 33 * 8); | |
63 | + $size += 33 * 8; | |
64 | + } | |
65 | + | |
66 | + # check if we have enough data | |
67 | + if (length($firmware) > 8) { | |
68 | + my $fwname = sprintf("firmware_%02u.fw", $candidate); | |
69 | + printf(STDERR "Writing firmware to %s, size = %u bytes\n", $fwname, length($firmware)); | |
70 | + my $out = IO::File->new($fwname, 'w', 0666) or die "Can't open $fwname: $!"; | |
71 | + $out->binmode(); | |
72 | + print($out $firmware); | |
73 | + $out->close(); | |
74 | + $candidate++; | |
75 | + } else { | |
76 | + printf(STDERR "Not a firmware, ignoring\n"); | |
77 | + } | |
78 | + | |
79 | + # skip ahead | |
80 | + $offset += $size; | |
81 | + } | |
82 | +} | |
83 | + | |
84 | +=cut | |
85 | +export F=SileadTouch.sys | |
86 | +cat $F \ | |
87 | + | hexdump -e '1/1 "0x%8.8_ax "' -e '1/1 "%8._ad "' -e '8/1 "%02X ""\n"""' \ | |
88 | + | grep -i -E "F0 00 00 00 02 00 00 00|7C 00 00 00 .. .. .. .." \ | |
89 | + | grep "F0 00 00 00 02 00 00 00" -B1 \ | |
90 | + ; \ | |
91 | +echo -- \ | |
92 | + ; \ | |
93 | +cat $F \ | |
94 | + | hexdump -e '1/1 "0x%8.8_ax "' -e '1/1 "%8._ad "' -e '8/1 "%02X ""\n"""' \ | |
95 | + | grep -i -E "F0 00 00 00 02 00 00 00|7C 00 00 00 .. .. .. .." \ | |
96 | + | tail -n2 | |
97 | + | |
98 | +cat <<EOF | |
99 | +Search for the hex sequence F0 00 00 00, followed by a 32 bit | |
100 | +number of the form xx 00 00 00 (i.e. an 8 bit value in a little | |
101 | +endian 32 bit word) and lots of yy 00 00 00 zz zz zz zz word pairs | |
102 | +(where yy is counting from 00 to 7C and zz is any hex code). | |
103 | +There are normally several blocks of data with the same pattern that | |
104 | +follow. Copy all of them into a new file and call it firmware.fw. | |
105 | +This should be the firmware image for your device. | |
106 | +EOF | |
107 | + | |
108 | +cat <<EOF | |
109 | +0x00009540 38208 7C 00 00 00 00 00 00 01 | |
110 | +0x00009548 38216 F0 00 00 00 02 00 00 00 (start fw_1) | |
111 | +-- | |
112 | +0x0000b010 45072 7C 00 00 00 00 00 00 00 (end fw_1) | |
113 | +0x0000b818 47128 F0 00 00 00 02 00 00 00 (start fw_2) | |
114 | +-- | |
115 | +0x000152c0 86720 7C 00 00 00 30 32 3A 32 (end fw_2) | |
116 | +0x00015ac8 88776 F0 00 00 00 02 00 00 00 (start fw_3) | |
117 | +-- | |
118 | +0x0001f570 128368 7C 00 00 00 30 32 3A 32 (end fw_3) | |
119 | +0x0001fd78 130424 F0 00 00 00 02 00 00 00 (start fw_4) | |
120 | +-- | |
121 | +0x00029b38 170808 7C 00 00 00 30 32 3A 32 (end fw_4) | |
122 | +0x0002b468 177256 7C 00 00 00 01 30 07 30 | |
123 | +EOF | |
124 | + | |
125 | +dd bs=1 if=$F of=firmware.fw_1 skip=38216 count=$(( 45072 - 38216 + 8)) | |
126 | +dd bs=1 if=$F of=firmware.fw_2 skip=47128 count=$(( 86720 - 47128 + 8)) | |
127 | +dd bs=1 if=$F of=firmware.fw_3 skip=88776 count=$((128368 - 88776 + 8)) | |
128 | +dd bs=1 if=$F of=firmware.fw_4 skip=130424 count=$((170808 - 130424 + 8)) | |
129 | + |