5 use RFID::Libnfc::Reader;
6 use RFID::Libnfc::Constants;
8 use Digest::MD5 qw(md5_hex);
10 use Data::Dump qw(dump);
12 my $debug = $ENV{DEBUG} || 0;
13 my $keyfile = shift @ARGV;
15 my $r = RFID::Libnfc::Reader->new(debug => $debug);
17 printf ("Reader: %s\n", $r->name);
18 my $tag = $r->connect(IM_ISO14443A_106);
27 my $uid = sprintf "%02x%02x%02x%02x", unpack('C4', $tag->{_nai}->abtUid);
28 # @{ $tag->uid }; # FIXME this doesn't work with tags which have 00 in UID!
32 $keyfile ||= "cards/$uid.key";
35 warn "# loading keys from $keyfile";
36 $tag->load_keys($keyfile);
37 warn "## _keys = ", dump($tag->{_keys});
40 $tag->select if ($tag->can("select"));
44 print STDERR "reading";
45 for (my $i = 0; $i < $tag->blocks; $i++) {
46 if (my $data = $tag->read_block($i)) {
47 # if we are dumping an ultralight token,
48 # we receive 16 bytes (while a block is 4bytes long)
49 # so we can skip next 3 blocks
50 $i += 3 if ($tag->type eq "ULTRA");
53 } elsif ( $tag->error =~ m/auth/ ) {
54 warn $tag->error,"\n";
56 # disconnect from reader so we can run mfoc
57 RFID::Libnfc::nfc_disconnect($r->{_pdi});
59 my $file = "cards/$uid.key";
61 warn "# finding keys for card $uid with: mfoc -O $file\n";
62 exec "mfoc -O $file" || die $!;
67 print STDERR "done\n";
69 # re-insert keys into dump
70 my $keys = $tag->{_keys} || die "can't find _keys";
71 foreach my $i ( 0 .. $#$keys ) {
72 my $o = $i * 0x40 + 0x30;
73 last if $o > length($card);
75 = substr($card, 0, $o) . $keys->[$i]->[0]
76 . substr($card, $o+6, 4) . $keys->[$i]->[1]
77 . substr($card, $o+16)
79 warn "sector $i keys re-inserted at $o\n";
82 if ( my $padding = 4096 - length($card) ) {
83 warn "add $padding bytes up to 4k dump (needed for keys loading)\n";
84 $card .= "\x00" x $padding;
87 my $md5 = md5_hex($card);
88 if ( glob "cards/$uid.$md5.*" ) {
89 warn "SKIPPING, same dump allready exits\n";
91 my $out_file = "cards/$uid.$md5";
92 write_file $out_file, $card;
93 print "$out_file ", -s $out_file, " bytes\n";
94 if ( ! -e "cards/$uid.key" ) {
95 symlink $out_file, "cards/$uid.key" || die "cards/$uid.key: $!";
96 warn "using keys as default for card $uid\n";
98 $ENV{MAD} && system "./mifare-mad.pl $out_file | vi -R -";