Skip to content

Instantly share code, notes, and snippets.

@sourenaraya
Created September 7, 2014 03:49
Show Gist options
  • Save sourenaraya/89f34d8be2cb598e4f4c to your computer and use it in GitHub Desktop.
Save sourenaraya/89f34d8be2cb598e4f4c to your computer and use it in GitHub Desktop.
script for extract and replace JPEG images in samsung SBL.img (bootloader.img). Tested on maguro (i9250).
#!/usr/bin/env python3
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# Version 2, December 2004
#
# Copyright (C) 2014 Souren Araya
#
# Everyone is permitted to copy and distribute verbatim or modified
# copies of this license document, and changing it is allowed as long
# as the name is changed.
#
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
#
# 0. You just DO WHAT THE FUCK YOU WANT TO.
# THIS PROGRAM CAN COMPLETELY BREAK YOUR PHONE! YOU HAVE BEEN WARNED.
from os.path import isfile
from io import BytesIO
soi = b'\xff\xd8\xff\xe0'
eoi = b'\xff\xd9'
def scan(source, verbose=False):
f = open(source, 'rb')
found = []
last_offset = 0
while True:
f.seek(last_offset)
start_offset = f.read().find(soi)
if start_offset != -1:
f.seek(start_offset+last_offset)
length = f.read().find(eoi)+2 # FFD9 bytes
if verbose:
print('JPEG found at offset %i, length %i' % (last_offset+start_offset, length))
found.append({'offset': last_offset+start_offset, 'length': length})
last_offset = last_offset+start_offset+length
else:
break
return found
def extract(source, offset, length, extension='jpg'):
f = open(source, 'rb')
output_name = '%i:%i.%s' % (offset, length, extension)
outfile = open(output_name, 'wb')
f.seek(offset)
content = f.read(length)
if content:
outfile.write(content)
outfile.flush()
outfile.close()
print('File %s written.' % output_name)
return True
else:
print('Invalid offset %s. Source file length is' % (offset, len(f.read)))
return False
def extract_everything(infile):
if not isfile(infile):
print('Source file does not exist\nExiting.')
return False
images = scan(infile)
print('Found %i images.' % len(images))
if len(images) > 0:
print('Extracting...')
for i in images:
extract(infile, i['offset'], i['length'])
return True
else:
print('Exiting')
def replace(output, source, offset, length, verbose=True):
if not (isfile(output) and isfile(source)):
print('Source file or output file does not exist\nExiting.')
return False
outfile = open(output, 'r+b')
sourcefile = open(source, 'rb')
sourceobj = sourcefile.read()
if not len(sourceobj) <= length:
print('Source file does not fit. Correct size is %i bytes or less.\nExiting.' % length)
return False
outfile.seek(offset)
tmpfile = BytesIO(b'\x00' * length)
outfile.seek(offset)
outfile.write(tmpfile.read())
outfile.seek(offset)
outfile.write(sourceobj)
outfile.flush()
outfile.close()
if verbose:
print('Replaced succesfully')
return True
if __name__ == "__main__":
import argparse
from os.path import basename
ap = argparse.ArgumentParser()
ap.add_argument('-e', nargs=4,
help='extract fragment of SOURCE by OFFSET with LENGTH and EXTENSION of output file\n %s -e sbl.img 1118428 3305 jpg' % basename(__file__),
metavar=('SOURCE', 'OFFSET', 'LENGTH', 'EXTENSION'))
ap.add_argument('-s', nargs=1,
help='find JPEGs in SOURCE, print offsets to console\n %s -s sbl.img' % basename(__file__),
metavar=('SOURCE'))
ap.add_argument('-a', nargs=1, help='extract all JPEGs from SOURCE\n %s -a sbl.img' % basename(__file__),
metavar=('SOURCE'))
ap.add_argument('-r', nargs=4,
help='replace fragment of OUTPUT with SOURCE by OFFSET with LENGTH\n %s -r sbl.img 1118428:3305.jpg 1118428 3305' % basename(__file__),
metavar=('OUTPUT', 'SOURCE', 'OFFSET', 'LENGTH'))
opts = ap.parse_args()
if not any([opts.e, opts.s, opts.a, opts.r]):
ap.print_usage()
quit()
if opts.e:
extract(opts.e[0], int(opts.e[1]), int(opts.e[2]), opts.e[3])
if opts.s:
scan(opts.s[0], True)
if opts.a:
extract_everything(opts.a[0])
if opts.r:
replace(opts.r[0], opts.r[1], int(opts.r[2]), int(opts.r[3]), True)
@sourenaraya
Copy link
Author

dump your SBL partition:
dd if=/dev/disk/by-partlabel/sbl of=/home/nemo/sbl.raw
modify, than writ it back:
dd if=/home/nemo/sbl.raw of=/dev/disk/by-partlabel/sbl

easy way to get suitable image:
convert -define jpeg:extent=LENGTH input.png output.jpg

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment