Add infrastructure for applying patches
parent
cf8a512596
commit
e4f59704da
@ -0,0 +1,196 @@
|
||||
#!/usr/bin/env perl
|
||||
use warnings;
|
||||
use strict;
|
||||
#
|
||||
# Apply a diff of two hexdumps as a binary patch
|
||||
|
||||
use IO::File;
|
||||
|
||||
use Data::Dumper;
|
||||
$Data::Dumper::Indent = 1;
|
||||
$Data::Dumper::Sortkeys = 1;
|
||||
$Data::Dumper::Quotekeys = 0;
|
||||
|
||||
sub usage() {
|
||||
print("This utility will take a diff of two hexdumps and can apply\n");
|
||||
print("the binary changes to the original binary file, using the\n");
|
||||
print("context lines to provide data to match and confirm we are\n");
|
||||
print("patching the right file\n");
|
||||
print("\n");
|
||||
print("Usage:\n");
|
||||
print(" hexpatch.pl patchfile binaryfile\n");
|
||||
print("\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sub parse_hexline {
|
||||
my $line = shift;
|
||||
|
||||
my $addr;
|
||||
my $binary;
|
||||
|
||||
my @fields = split(/\s+/,$line);
|
||||
|
||||
if ($fields[0] !~ m/^([0-9a-fA-F])+$/) {
|
||||
return undef;
|
||||
}
|
||||
$addr = hex($fields[0]);
|
||||
shift @fields;
|
||||
|
||||
while (defined($fields[0]) && $fields[0] =~ m/^([0-9a-fA-F])+$/) {
|
||||
$binary .= chr(hex($fields[0]));
|
||||
shift @fields;
|
||||
}
|
||||
|
||||
return ($addr,$binary);
|
||||
}
|
||||
|
||||
sub read_patchfile {
|
||||
my $filename = shift;
|
||||
|
||||
my $fh = IO::File->new($filename, O_RDONLY);
|
||||
if (!defined($fh)) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $db = {};
|
||||
|
||||
my $seen_at_symbols = 0;
|
||||
|
||||
while(<$fh>) {
|
||||
# anything before we see a starting at symbol line can be ignored
|
||||
if (!$seen_at_symbols) {
|
||||
if (m/^\@\@ .* \@\@$/) {
|
||||
$seen_at_symbols = 1;
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
my $addr;
|
||||
my $binary;
|
||||
my $type;
|
||||
if (m/^([-+ ])(.*)/) {
|
||||
# a context, oldfile or newfile line
|
||||
$type = $1;
|
||||
($addr, $binary) = parse_hexline($2);
|
||||
} elsif (m/^\@\@ .* \@\@$/) {
|
||||
# hunk separator - we can ignore it since we use the hex addr
|
||||
next;
|
||||
} else {
|
||||
warn("Invalid prefix in patchfile");
|
||||
# TODO - linenumber
|
||||
return(undef);
|
||||
}
|
||||
|
||||
if (!defined($addr)) {
|
||||
warn("Invalid data in hexline");
|
||||
# TODO - linenumber
|
||||
return(undef);
|
||||
}
|
||||
|
||||
if (!defined($binary)) {
|
||||
# this line was empty of data
|
||||
next;
|
||||
}
|
||||
|
||||
if ($type eq ' ') {
|
||||
$type = 'context';
|
||||
} elsif ($type eq '-') {
|
||||
$type = 'old';
|
||||
} elsif ($type eq '+') {
|
||||
$type = 'new';
|
||||
}
|
||||
|
||||
if (defined($db->{addr}{$addr}{$type})) {
|
||||
warn("Duplicate address in hexdata");
|
||||
# TODO - linenumber
|
||||
return(undef);
|
||||
}
|
||||
|
||||
$db->{addr}{$addr}{$type} = $binary;
|
||||
}
|
||||
return $db;
|
||||
}
|
||||
|
||||
sub verify_context {
|
||||
my $db = shift;
|
||||
my $fh = shift;
|
||||
|
||||
for my $addr (sort keys(%{$db->{addr}})) {
|
||||
my $entry = $db->{addr}{$addr};
|
||||
my $expected;
|
||||
if ($entry->{context}) {
|
||||
$expected = $entry->{context};
|
||||
} elsif ($entry->{old}) {
|
||||
$expected = $entry->{old};
|
||||
} elsif ($entry->{new}) {
|
||||
warn("Address $addr has new data but no old data\n");
|
||||
return undef;
|
||||
} else {
|
||||
# No data of any kind here, just skip it
|
||||
next;
|
||||
}
|
||||
|
||||
my $found;
|
||||
$fh->seek($addr,SEEK_SET);
|
||||
$fh->read($found,length($expected));
|
||||
|
||||
if ($found ne $expected) {
|
||||
warn("Address $addr mismatched data\n");
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub apply_patch {
|
||||
my $db = shift;
|
||||
my $fh = shift;
|
||||
|
||||
for my $addr (sort keys(%{$db->{addr}})) {
|
||||
my $entry = $db->{addr}{$addr};
|
||||
|
||||
my $newdata;
|
||||
if ($entry->{new}) {
|
||||
$newdata = $entry->{new};
|
||||
} else {
|
||||
# No data to write at this address, just skip it
|
||||
next;
|
||||
}
|
||||
|
||||
$fh->seek($addr,SEEK_SET);
|
||||
$fh->print($newdata);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sub main() {
|
||||
my $patchfile = shift @ARGV;
|
||||
my $binaryfile = shift @ARGV;
|
||||
|
||||
if (!defined($patchfile) or !defined($binaryfile)) {
|
||||
usage();
|
||||
}
|
||||
|
||||
my $db = read_patchfile($patchfile);
|
||||
|
||||
if (!defined($db)) {
|
||||
warn("Cannot read $patchfile\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
my $fh = IO::File->new($binaryfile, O_RDWR);
|
||||
if (!defined($fh)) {
|
||||
warn("Could not open binaryfile\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!verify_context($db,$fh)) {
|
||||
warn("The binaryfile does not match the context bytes from the patch");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
apply_patch($db,$fh);
|
||||
}
|
||||
main();
|
||||
|
@ -0,0 +1,22 @@
|
||||
This updates the keyboard matrix scancode table.
|
||||
|
||||
Copied directly from the x220 firmware
|
||||
|
||||
@@ keysym @@
|
||||
00021930 00 00 00 00 00 00 00 00 77 0a 19 76 27 84 36 85 |........w..v'.6.|
|
||||
00021940 00 00 00 00 00 00 00 00 0c 0b 1a 1b 28 29 2a 37 |............()*7|
|
||||
00021950 00 00 00 00 00 00 00 00 78 79 0e 0f 1d 74 2b 3d |........xy...t+=|
|
||||
-00021960 00 00 00 00 00 00 00 00 00 7b 00 9b 00 00 00 59 |.........{.....Y|
|
||||
-00021970 00 00 00 00 00 00 00 00 50 7a 9a 99 98 97 a0 54 |........Pz.....T|
|
||||
-00021980 00 00 00 00 00 00 00 00 4c 4b 00 00 7c 00 55 56 |........LK..|.UV|
|
||||
-00021990 00 00 00 00 00 00 00 00 00 51 00 00 00 53 00 4f |.........Q...S.O|
|
||||
-000219a0 00 00 00 00 00 00 00 00 00 00 00 00 00 3c 00 3e |.............<.>|
|
||||
+00021960 00 00 00 00 00 00 00 00 4b 7b 00 9b 00 00 00 59 |........K{.....Y|
|
||||
+00021970 00 00 00 00 00 00 00 00 4c 7a 9a 99 98 97 a0 54 |........Lz.....T|
|
||||
+00021980 00 00 00 00 00 00 00 00 55 56 00 00 9c 00 89 8a |........UV......|
|
||||
+00021990 00 00 00 00 00 00 00 00 50 51 00 00 00 53 7e 4f |........PQ...S~O|
|
||||
+000219a0 00 00 00 00 00 00 00 00 00 7c 7d 00 00 3c 00 3e |.........|}..<.>|
|
||||
000219b0 00 00 00 00 00 00 00 00 00 00 00 2c 00 00 39 00 |...........,..9.|
|
||||
000219c0 00 00 00 00 00 00 00 00 3a 00 00 00 00 00 40 00 |........:.....@.|
|
||||
000219d0 00 00 00 00 00 00 00 96 00 9d 00 9e 9f 4a 3a 9c |.............J:.|
|
||||
000219e0 7d 7e 00 00 00 00 00 00 ff 00 7f 00 7f 00 ff 00 |}~..............|
|
@ -0,0 +1,16 @@
|
||||
This updates the bitmap of live/dead keys to enable the missing keys
|
||||
|
||||
Copied directly from the x220 firmware
|
||||
|
||||
@@ dead_keys @@
|
||||
000219b0 00 00 00 00 00 00 00 00 00 00 00 2c 00 00 39 00 |...........,..9.|
|
||||
000219c0 00 00 00 00 00 00 00 00 3a 00 00 00 00 00 40 00 |........:.....@.|
|
||||
000219d0 00 00 00 00 00 00 00 96 00 9d 00 9e 9f 4a 3a 9c |.............J:.|
|
||||
000219e0 7d 7e 00 00 00 00 00 00 ff 00 7f 00 7f 00 ff 00 |}~..............|
|
||||
-000219f0 ff 00 ff 00 ff 00 ff 00 ff 00 8a 00 ff 00 d3 00 |................|
|
||||
-00021a00 a2 00 a0 00 48 00 41 80 fa 03 00 00 a0 97 00 00 |....H.A.........|
|
||||
+000219f0 ff 00 ff 00 ff 00 ff 00 ff 00 8b 00 ff 00 d3 00 |................|
|
||||
+00021a00 e3 00 a6 00 48 00 41 80 fa 03 00 00 a0 97 00 00 |....H.A.........|
|
||||
00021a10 10 01 00 00 d8 18 02 00 e8 19 02 00 0c 1a 02 00 |................|
|
||||
00021a20 ff 43 41 3f 3d 3b 3c 58 64 44 42 40 3e 0f 29 59 |.CA?=;<XdDB@>.)Y|
|
||||
00021a30 65 38 2a 70 1d 10 02 5a 66 71 2c 1f 1e 11 03 5b |e8*p...Zfq,....[|
|
@ -0,0 +1,16 @@
|
||||
This updates the table of "simple replacements", fixing the multimedia keys
|
||||
and the seventh row Fn combos
|
||||
|
||||
Copied directly from the x220 firmware
|
||||
|
||||
@@ keysym_replacements @@
|
||||
00021860 5b 60 65 5f 00 00 00 00 00 00 00 00 00 00 00 5c |[`e_...........\|
|
||||
00021870 61 66 64 00 00 00 00 00 00 00 00 00 00 5d 62 67 |afd..........]bg|
|
||||
00021880 69 00 00 6c 00 00 00 00 00 00 00 00 63 00 68 6a |i..l........c.hj|
|
||||
-00021890 00 00 00 00 00 00 00 00 79 6d 00 7a 58 00 7b 6f |........ym.zX.{o|
|
||||
-000218a0 00 32 46 02 20 44 01 26 7d 00 1a 7e 00 00 00 00 |.2F. D.&}..~....|
|
||||
+00021890 00 00 00 00 00 00 00 00 7c 44 01 7d 5a 00 7e 46 |........|D.}Z.~F|
|
||||
+000218a0 02 4f 6d 00 53 6b 00 54 58 00 59 6f 00 00 00 00 |.Om.Sk.TX.Yo....|
|
||||
000218b0 9e 9e 00 9f 9f 00 4a 4a 00 00 00 00 b2 00 00 00 |......JJ........|
|
||||
000218c0 b4 16 02 00 40 00 00 00 58 18 02 00 18 18 02 00 |....@...X.......|
|
||||
000218d0 0b 00 00 00 98 18 02 00 01 02 11 10 1f 6e 2e 83 |.............n..|
|
@ -0,0 +1,24 @@
|
||||
This fixes the table of Fn key combos with "more complex" functions. This
|
||||
fixes most of the Fn+F key codes.
|
||||
|
||||
Specifically missing is F12, as I was uncertain about the "action" byte to
|
||||
be used for it.
|
||||
|
||||
Also, with this patch, the Fn+F3 generates a Screen Lock code.
|
||||
|
||||
Used the x220 table as a template as the "action" byte values have changed from
|
||||
the old firmware
|
||||
|
||||
@@ fn_keys @@
|
||||
00021640 5a 00 00 00 ff ff 00 00 00 00 00 00 9c 8e 01 00 |Z...............|
|
||||
00021650 a0 8e 01 00 a4 8e 01 00 a8 8e 01 00 ac 8e 01 00 |................|
|
||||
00021660 98 f4 01 00 b0 8e 01 00 b4 8e 01 00 c0 70 c0 71 |.............p.q|
|
||||
-00021670 c0 72 c7 73 e4 78 e5 77 c0 76 c0 00 c0 00 c0 97 |.r.s.x.w.v......|
|
||||
-00021680 c0 00 c8 00 c0 02 c0 03 00 00 c6 3d 00 00 00 00 |...........=....|
|
||||
-00021690 00 00 c0 00 c0 74 c0 75 00 00 00 00 00 00 00 00 |.....t.u........|
|
||||
+00021670 c0 72 c7 73 e4 50 e5 51 c0 76 c0 77 c0 78 c0 97 |.r.s.P.Q.v.w.x..|
|
||||
+00021680 c0 7a c8 00 c0 02 c0 03 00 00 c6 55 00 00 00 00 |.z.........U....|
|
||||
+00021690 00 00 c0 3d c0 74 c0 75 00 00 00 00 00 00 00 00 |...=.t.u........|
|
||||
000216a0 c0 a0 00 00 08 00 00 00 4c 16 02 00 1b 00 00 00 |........L.......|
|
||||
000216b0 6c 16 02 00 00 00 00 0e 00 16 00 1e 00 26 00 25 |l............&.%|
|
||||
000216c0 00 2e 00 36 00 3d 00 3e 00 46 00 45 00 4e 00 55 |...6.=.>.F.E.N.U|
|
Loading…
Reference in New Issue