Hello again. I have two problems - is it possible to solve them?
I want to replace a few bytes after specific hex-string.
i.e.: I want to replace two bytes after AA AB AC:
AA AB AC 00 00 AA AA AA
so the expected result should be:
AA AB AC FF FF AA AA AA
I want to replace three bytes before specific hex-string.
i.e.: replace two bytes before 00 00 with FF FF:
AA AB AC 00 00 AA AA AA
result:
AA FF FF 00 00 AA AA AA
Everything above is pseudo hexcode. Also I attached real binary files to this post. Since this question was posted at "newbies" section, I'm expecting all possible solutions. Thank you
And, to add another question,
is the data in the file formatted like your example, or are you doing something to represent the data in this manner (like an od command)?
An example for the first part longhand using OSX 10.7.5, default bash terminal...
Altered the binary file to show it works...
#!/bin/bash
# bin_change.sh
# This will be SSLLOOWW with large files...
ifs_str="$IFS"
IFS=" "
> /tmp/bin
> /tmp/newbin
printf "\xBB\xCC\xAA\xAA\xAA\xAB\xAC\x00\x00\xAA\xAA\xAA" >> /tmp/bin
printf "\xBB\xCC\xAA\xAA\xAA\xAB\xAC\x00\x00\xAA\xAA\xAA" >> /tmp/bin
printf "\xBB\xCC\xAA\xAA\xAA\xAB\xAC\x00\x00\xAA\xAA\xAA" >> /tmp/bin
printf "\xBB\xCC\xAA\xAA\xAA\xAB\xAC\x00\x00\xAA\xAA\xAA" >> /tmp/bin
# Check existence of 48 bytes of example binary...
hexdump -C /tmp/bin
n=0
bin_array=(`hexdump -v -e '1/1 "%02X "' /tmp/bin`)
echo ""
# 48 is the /tmp/bin filelength.
while [ $n -lt 48 ]
do
if [ "${bin_array[$n]}${bin_array[$((n+1))]}${bin_array[$((n+2))]}" == "AAABAC" ] && [ "${bin_array[$((n+3))]}${bin_array[$((n+4))]}" == "0000" ]
then
printf "\x${bin_array[$n]}\x${bin_array[$((n+1))]}\x${bin_array[$((n+2))]}\xFF\xFF" >> /tmp/newbin
n=$((n+5))
fi
printf "\x${bin_array[$n]}" >> /tmp/newbin
n=$((n+1))
done
# Now check new 48 bytes of binary...
hexdump -C /tmp/newbin
echo ""
IFS="$ifs_str"
exit 0
Results:-
Last login: Tue May 27 22:27:08 on ttys000
AMIGA:barrywalker~> ./bin_change.sh
00000000 bb cc aa aa aa ab ac 00 00 aa aa aa bb cc aa aa |................|
00000010 aa ab ac 00 00 aa aa aa bb cc aa aa aa ab ac 00 |................|
00000020 00 aa aa aa bb cc aa aa aa ab ac 00 00 aa aa aa |................|
00000030
00000000 bb cc aa aa aa ab ac ff ff aa aa aa bb cc aa aa |................|
00000010 aa ab ac ff ff aa aa aa bb cc aa aa aa ab ac ff |................|
00000020 ff aa aa aa bb cc aa aa aa ab ac ff ff aa aa aa |................|
00000030
AMIGA:barrywalker~> _
I'm confused. The title of this thread is Binary search and replace. A binary search is used to search a sorted list. I see no order in the values that you are searching?
Please explain how you are doing anything other than a linear search for five contiguous values and then replacing two of those five matched values.
I'd guess that the OP meant Byte or Binary File Search and Replace. We would not expect that everyone knows that there is an efficient procedure for searching ordered collections that goes by that name http://en.wikipedia.org/wiki/Binary\_search_algorithm ... cheers, drl
Cough...
What? "hexdump" is excellent for creating an ASCII version array quickly of a pure binary file to work on before reconverting back to pure binary again.
However if hexdump is not good enough for you then go with Perl or Python. Python being probably the better of the two for this application...
EDIT:
hexdump creating /bin/bash into a 4+MB ASCII data file.
Last login: Wed May 28 18:01:35 on ttys000
AMIGA:barrywalker~> time bin_text=`hexdump -v -e '1/1 "%02X "' /bin/bash`
real 0m0.296s
user 0m0.314s
sys 0m0.021s
AMIGA:barrywalker~> ls -l /bin/bash
-r-xr-xr-x 1 root wheel 1371648 9 May 2012 /bin/bash
AMIGA:barrywalker~> echo "${#bin_text}"
4114944
AMIGA:barrywalker~> _
Not bad for speed eh!
It takes double that time to put it into an array format directly.