-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbingrep
executable file
·85 lines (66 loc) · 2 KB
/
bingrep
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#!ruby
pattern = ARGV[0]
files = ARGV[1..]
if ARGV.length < 2
puts "Usage: bingrep [pattern/-i(interactive)] [path]"
puts "ex:"
puts " bingrep \"string with spaces and w.ldcard\" ./"
puts " bingrep \"0x004433 22.33\" ./somefile.bin # spaces are ignored"
puts " bingrep \"0x0044_33\" ./ # displayed offset will be relative to the _ position"
exit
end
def string_to_pattern(string)
if string.start_with?('0x')
string = string[2..].gsub(' ', '').gsub(/[0-9a-f]{2}/i) { |match| Regexp.escape(match.to_i(16).chr) }
if offset = string.index('_')
if offset > 0
# use 2 catching groups to figure out where the _ exists in the located strings
@offset_regex = string.split('_').tap { |one, _| break /^(#{one})/m }
end
string.slice!(offset)
end
end
string
end
def bin_to_hex(data)
data.each_byte.map { |b| b.to_s(16).rjust(2, '0') }.join.upcase
end
def search(file, pattern)
content = IO.binread(file)
index = 0
while found = content.index(pattern, index) do
bin_match = content.match(pattern, index)[0];
offset = @offset_regex ? bin_match.match(@offset_regex)[1].length : 0
match = bin_to_hex(bin_match)
match = offset > 0 ? match.insert(offset * 2, '_') : match
puts "#{file}: #{(found + offset).to_s(16).rjust(8, '0').upcase}: #{match}"
index = found + 1
end
end
def search_path(file, pattern)
if Dir.exist?(file)
(Dir.entries(file) - %w(. ..)).each { |path| search_path(File.join(file, path), pattern) }
else
search(file, pattern)
end
end
def do_search(pattern, files)
puts "Searching for \"#{pattern}\" in #{files.join(', ')}:"
pattern = string_to_pattern(pattern)
files.each do |file|
search_path(file, /#{pattern}/m)
end
end
if pattern == '-i'
puts "Interactive mode, type \"exit\" to quit."
require 'tty-prompt'
prompt = TTY::Prompt.new
loop do
input = prompt.ask("?")
break if input&.chomp == 'exit'
do_search(input, files) if input
end
exit
else
do_search(pattern, files)
end