ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/pbcdedit/pbcdedit
(Generate patch)

Comparing pbcdedit/pbcdedit (file contents):
Revision 1.5 by root, Wed Aug 14 22:11:21 2019 UTC vs.
Revision 1.9 by root, Wed Aug 14 22:54:28 2019 UTC

1#!/opt/bin/perl 1#!/usr/bin/perl
2 2
3# 3#
4# PBCDEDIT - Copyright 2019 Marc A. Lehmann <pbcbedit@schmorp.de> 4# PBCDEDIT - Copyright 2019 Marc A. Lehmann <pbcbedit@schmorp.de>
5# 5#
6# SPDX-License-Identifier: GPL-3.0-or-later 6# SPDX-License-Identifier: GPL-3.0-or-later
17# 17#
18# You should have received a copy of the GNU General Public License 18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <https://www.gnu.org/licenses/>. 19# along with this program. If not, see <https://www.gnu.org/licenses/>.
20# 20#
21 21
22use 5.014; # numerous features 22use 5.014; # numerous features needed
23 23
24our $VERSION = '1.0'; 24our $VERSION = '1.0';
25our $JSON_VERSION = 1; # the versiobn of the json objects generated by this program 25our $JSON_VERSION = 1; # the versiobn of the json objects generated by this program
26 26
27=head1 NAME 27=head1 NAME
41=head1 DESCRIPTION 41=head1 DESCRIPTION
42 42
43This program allows you to create, read and modify Boot Configuration Data 43This program allows you to create, read and modify Boot Configuration Data
44(BCD) stores used by Windows Vista and newer versions of Windows. 44(BCD) stores used by Windows Vista and newer versions of Windows.
45 45
46At this point, it is in relatively early stages of development and has
47received little to no real-world testing.
48
46Compared to other BCD editing programs it offers the following unique 49Compared to other BCD editing programs it offers the following unique
47features: 50features:
48 51
49=over 52=over
50 53
106The reverse of C<export>: Reads a JSON representation of a BCD data store 109The reverse of C<export>: Reads a JSON representation of a BCD data store
107from standard input, and creates or replaces the given BCD data store. 110from standard input, and creates or replaces the given BCD data store.
108 111
109=item edit F<path> instructions... 112=item edit F<path> instructions...
110 113
111#TODO 114Load a BCD data store, apply some instructions to it, and save it again.
115
116See the section L<EDITING BCD DATA STORES>, below, for more info.
117
118=item parse F<path> instructions...
119
120Same as C<edit>, above, except it doesn't save the data store again. Can
121be useful to extract some data from it.
112 122
113=item lsblk 123=item lsblk
114 124
115On a GNU/Linux system, you can get a list of partition device descriptors 125On a GNU/Linux system, you can get a list of partition device descriptors
116using this command - the external C<lsblk> command is required, as well as 126using this command - the external C<lsblk> command is required, as well as
697seems to be always there on this kind of entry. 707seems to be always there on this kind of entry.
698 708
699If you have some good examples to add here, feel free to mail me. 709If you have some good examples to add here, feel free to mail me.
700 710
701 711
712=head1 EDITING BCD DATA STORES
713
714The C<edit> and C<parse> subcommands allow you to read a BCD data store
715and modify it or extract data from it. This is done by exyecuting a series
716of "editing instructions" which are explained here.
717
718=over
719
720=item get I<object> I<element>
721
722Reads the BCD element I<element> from the BCD object I<object> and writes
723it to standard output, followed by a newline. The I<object> can be a GUID
724or a human-readable alias, or the special string C<{default}>, which will
725refer to the default BCD object.
726
727Example: find description of the default BCD object.
728
729 pbcdedit parse BCD get "{default}" description
730
731=item set I<object> I<element> I<value>
732
733Similar to C<get>, but sets the element to the given I<value> instead.
734
735Example: change bootmgr default too
736C<{b097d2ad-bc00-11e9-8a9a-525400123456}>:
737
738 pbcdedit edit BCD set "{bootmgr}" resumeobject "{b097d2ad-bc00-11e9-8a9a-525400123456}"
739
740=item eval I<perlcode>
741
742This takes the next argument, interprets it as Perl code and
743evaluates it. This allows you to do more complicated modifications or
744extractions.
745
746The following variables are predefined for your use:
747
748=over
749
750=item C<$PATH>
751
752The path to the BCD data store, as given to C<edit> or C<parse>.
753
754=item C<$BCD>
755
756The decoded BCD data store.
757
758=item C<$DEFAULT>
759
760The default BCD object name.
761
762=back
763
764The example given for C<get>, above, could be expressed like this with
765C<eval>:
766
767 pbcdedit edit BCD eval 'say $BCD->{$DEFAULT}{description}'
768
769The example given for C<set> could be expresed like this:
770
771 pbcdedit edit BCD eval '$BCD->{$DEFAULT}{resumeobject} = "{b097d2ad-bc00-11e9-8a9a-525400123456}"'
772
773=item do I<path>
774
775Similar to C<eval>, above, but instead of using the argument as perl code,
776it loads the perl code from the given file and executes it. This makes it
777easier to write more complicated or larger programs.
778
779=back
780
702=head1 SEE ALSO 781=head1 SEE ALSO
703 782
704For ideas on what you can do, and some introductory material, try 783For ideas on what you can do, and some introductory material, try
705L<http://www.mistyprojects.co.uk/documents/BCDEdit/index.html>. 784L<http://www.mistyprojects.co.uk/documents/BCDEdit/index.html>.
706 785
760 839
761# hack used for debugging 840# hack used for debugging
762sub xxd($$) { 841sub xxd($$) {
763 open my $xxd, "| xxd | sed -e 's/^/\Q$_[0]\E: /'"; 842 open my $xxd, "| xxd | sed -e 's/^/\Q$_[0]\E: /'";
764 syswrite $xxd, $_[1]; 843 syswrite $xxd, $_[1];
844}
845
846sub file_load($) {
847 my ($path) = @_;
848
849 open my $fh, "<:raw", $path
850 or die "$path: $!\n";
851 my $size = -s $fh;
852 $size = read $fh, my $buf, $size
853 or die "$path: short read\n";
854
855 $buf
765} 856}
766 857
767# sources and resources used for this: 858# sources and resources used for this:
768# registry: 859# registry:
769# https://github.com/msuhanov/regf/blob/master/Windows%20registry%20file%20format%20specification.md 860# https://github.com/msuhanov/regf/blob/master/Windows%20registry%20file%20format%20specification.md
1120} 1211}
1121 1212
1122# load and parse registry from file 1213# load and parse registry from file
1123sub regf_load($) { 1214sub regf_load($) {
1124 my ($path) = @_; 1215 my ($path) = @_;
1125 open my $regf, "<:raw", $path
1126 or die "$path: $!\n";
1127 my $size = -s $regf;
1128 $size = read $regf, my $buf, $size
1129 or die "$path: short read\n";
1130 1216
1131 regf_decode $buf 1217 regf_decode file_load $path
1132} 1218}
1133 1219
1134# encode and save registry to file 1220# encode and save registry to file
1135sub regf_save { 1221sub regf_save {
1136 my ($path, $hive) = @_; 1222 my ($path, $hive) = @_;
2157 }]] 2243 }]]
2158} 2244}
2159 2245
2160############################################################################# 2246#############################################################################
2161 2247
2248sub bcd_edit_eval {
2249 package pbcdedit;
2250
2251 our ($PATH, $BCD, $DEFAULT);
2252
2253 eval shift;
2254 die "$@" if $@;
2255}
2256
2257sub bcd_edit {
2258 my ($path, $bcd, @insns) = @_;
2259
2260 my $default = $bcd->{"{bootmgr}"}{resumeobject};
2261
2262 # prepare "officially visible" variables
2263 local $pbcdedit::PATH = $path;
2264 local $pbcdedit::BCD = $bcd;
2265 local $pbcdedit::DEFAULT = $default;
2266
2267 while (@insns) {
2268 my $insn = shift @insns;
2269
2270 if ($insn eq "get") {
2271 my $object = shift @insns;
2272 my $elem = shift @insns;
2273
2274 $object = $default if $object eq "{default}";
2275
2276 print $bcd->{$object}{$elem}, "\n";
2277
2278 } elsif ($insn eq "set") {
2279 my $object = shift @insns;
2280 my $elem = shift @insns;
2281 my $value = shift @insns;
2282
2283 $object = $default if $object eq "{default}";
2284
2285 $bcd->{$object}{$elem} = $value;
2286
2287 } elsif ($insn eq "eval") {
2288 bcd_edit_eval shift @insns;
2289
2290 } elsif ($insn eq "do") {
2291 my $path = shift @insns;
2292 my $file = file_load $path;
2293 bcd_edit_eval "#line 1 '$path'\n$file";
2294
2295 } else {
2296 die "$insn: not a recognized instruction for edit/parse\n";
2297 }
2298 }
2299
2300}
2301
2302#############################################################################
2303
2162# json to stdout 2304# json to stdout
2163sub prjson($) { 2305sub prjson($) {
2164 print $json_coder->encode ($_[0]); 2306 print $json_coder->encode ($_[0]);
2165} 2307}
2166 2308
2263 prjson bcd_decode regf_load shift; 2405 prjson bcd_decode regf_load shift;
2264 }, 2406 },
2265 2407
2266 import => sub { 2408 import => sub {
2267 regf_save shift, bcd_encode rdjson; 2409 regf_save shift, bcd_encode rdjson;
2410 },
2411
2412 edit => sub {
2413 my $path = shift;
2414 my $bcd = bcd_decode regf_load $path;
2415 bcd_edit $path, $bcd, @_;
2416 regf_save $path, bcd_encode $bcd;
2417 },
2418
2419 parse => sub {
2420 my $path = shift;
2421 my $bcd = bcd_decode regf_load $path;
2422 bcd_edit $path, $bcd, @_;
2268 }, 2423 },
2269 2424
2270 "export-regf" => sub { 2425 "export-regf" => sub {
2271 prjson regf_load shift; 2426 prjson regf_load shift;
2272 2427

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines