2 # -samy kamkar, rfid@samy.pl
6 die "usage: $0 <file with data> <binary to search for>\n" unless @ARGV == 2;
8 my ($file, $search) = @ARGV;
11 # sure, these aren't perfect, but simplifies usability if you know what you're doing
12 # if in doubt, use binary
15 if ($search =~ /^[01]+$/) { }
17 elsif ($search =~ /^\d+$/)
19 $search = unpack("B*", pack("N", $search));
23 elsif ($search =~ /^[\da-fA-F]+$/)
25 $search = unpack("B*", pack("H*", $search));
31 $search = unpack("B*", $search);
37 open(F
, "<$file") || die "Can't read $file: $!";
38 my $data = join("", <F
>);
44 if ($data =~ /^[01]+$/) { }
45 elsif ($data =~ /^[\da-fA-F]+$/)
47 $data = unpack("B*", pack("H*", $data));
52 die "Seriously. What sort of data is this file? Binary or hex only please.\n";
56 # search every method we know how
57 print "Testing normally...\n";
58 test_all
($data, $search);
60 print "Testing with flipped bits...\n";
61 test_all
($data, $search, 1);
63 # now try manchester demodulating
64 my @bits = split(//, $data);
67 for (my $i = 1; $i < @bits; $i++)
69 # if we changed, flip our bit
77 print "Testing with manchester demodulation...\n";
78 test_all
($man, $search);
80 print "Testing with flipped manchester demodulation...\n";
81 test_all
($man, $search, 1);
86 my ($data, $search, $flip) = @_;
90 $data =~ s/(.)/$1 ^ 1/eg;
93 # first just see if our data is in the stream
94 if ($data =~ /$search/)
96 print "Found $search in our stream ($data)\n";
99 # try removing parity every 4 and 8 bits
100 foreach my $parity (4, 8)
102 # try removing a parity bit every $parity bits
103 # test by cutting off a bit at a time in case we're in the wrong bit position
105 foreach (1 .. $parity)
108 $test =~ s/(.{$parity})./$1/g;
110 if ($test =~ /$search/)
112 print "Found $search with parity every " . ($parity + 1) . "th bit, round $_ out of $parity ($test)\n";
115 # chop of a bit to change our bit position next round