[Android Software/Hacking General [Developers Only]] Catrane:
Sony obfuscation hash

Here are the first 96 bytes of the Sony obfuscation hash. It's applied as an xor. I haven't put much work into finding a pattern yet. Here's what I do know:

* It isn't just a static repeating pattern, or if it is then it's longer than 96 bytes before repeat.

* The mask for any given byte position is the same across all files, so a static mask that works for one file will work for all files.

00000000 38 cf 4f aa 7a 8a 2e 3e 2b 41 82 9a ad 31 e9 dc |8.O.z..>+A...1..|
00000010 ef 47 2f 0b 26 76 12 fe 5f 5b 58 e1 10 18 7d e6 |.G/.&v.._[X...}.|
00000020 ad 92 1b 91 8e 90 69 f7 8a 9b 68 d8 98 58 fa 95 |......i...h..X..|
00000030 63 81 d6 5f 04 7d 29 8b 09 cf b9 21 b8 d9 df dd |c.._.})....!....|
00000040 c4 7e 71 d9 3f 35 ea 7b 0d ec 7f d1 a3 76 64 88 |.~q.?5.{.....vd.|
00000050 a5 8e 27 49 60 c0 a0 bc 77 54 31 e3 d6 6a bf e5 |..'I`...wT1..j..|

It could be a large random pad, as someone previously suggested. Or if we're really lucky it could just be a random number sequence accessed via knowing it's seed and which rand algorithm it's using. Or it could be an output feedback cipher, which could be a bugger if they used a non-zero key in the encryption.

The approach I used was to find all the obfuscated text files I could, then write a small program to iterate over the hash options for each byte, weed out the ones that yield an invalid result in any of those files, and produce a character-by-character list of the possibilities. This was facilitated by knowing that a shell script is only printable characters and whitespace and the .hex file is only hex characters, colons, and CRLFs. If anybody has strong knowledge of limitations in gzip file content beyond the first 96 bytes, that could be used to further filter the options.

Here are the decoded sections of the obfuscated text files I could find. These are the same in all three versions of the Sony update that I have.

history/board_conf.sh

#!/bin/sh

chkerr()
{
ret=$?
if [ $ret -ne 0 ]; then
echo "Error!!!"
exit 1
fi
}

history/NBL/batch_sync-vfat.sh > batch_sync-vfat.sh

#!/bin/sh

unset -f MOUNT

MOUNT()
{
mount | grep "$2" > /dev/null && return 0

if [ "$1"

history/other/check_spectra1_20100929.sh

#!/bin/sh

#----------------------------------
# unmount /tmp/mntx
UMOUNT()
{
mount | grep $1

history/other/factory_reset_conditional_keepremote_20101012.sh

#!/bin/sh
# last modified 2010/10/12
#
# conditional factory-reset for asura / eagle on updating.

history/other/format_sda_20100514.sh

#!/bin/sh
FDISK_HASH_8G="80dd0463e8cf28c0d2c0836408499e03 -"
FDISK_HASH_2G="fdd1d1adb5517785c3e

history/other/RfHid_v0156_2010091601_NL.hex

:020000040000FA
:0600000091EF1FF0120059
:0600080004EF04F01200F9
:060018000CEF04F01200E1
:0608

Here's a small script I wrote to apply the mask to any file. First parameter is the mask file, second is the obfuscated file. Result gets printed. Since it's an xor, you can give it the mask file and plaintext file and it will obfuscate it for you if you'd like to go that way.

#!/usr/bin/perl

use strict;
use warnings;

use IO::File;

my $file1 = shift;
die "Missing filename parameter.\n" unless defined $file1;
die "File '$file1' does not exist.\n" unless ( -f $file1 );my $fh1 = IO::File->new("< $file1") or die "Unable to open file '$file1'.\n";
my $file2 = shift;
die "Missing filename parameter.\n" unless defined $file2;
die "File '$file2' does not exist.\n" unless ( -f $file2 );my $fh2 = IO::File->new("< $file2") or die "Unable to open file '$file2'.\n";

while ( defined ( my $c1 = getc($fh1) ) )
{
my $c2 = getc($fh2);
$c2 = "\x00" unless defined $c2;
my $o = $c1 ^ $c2;
print $o;
}

- Catrane