分享解ROM包技巧

From my:http://www.buildinger.tk/index.php/archives/66/

在刷入Root的Rom包,要小心包内可能夹带的其他推广app(也可能有病毒木马)

那么下面就学习如何解包,查看刷机时到底安装了什么玩意~


一般的刷机包用压缩软件打开后都长成这样,看到最大的文件“system.new.dat”,一般人都会猜到里面就存储着刷入的app了

但是,直接是打不开这个文件的

安卓5.0采用了新的封包模式system被存储在system.new.dat中

我们需要将它转换为“system.img”形式,之后用一般的Rom查看工具就可以解压出来、或直接看内部APP

使用转换脚本前,我们还需要提取其中的一个文件“system.transfer.list”

那么,总的来说,我们需要如下三个文件,放入同一路径

0x脚本如下:


#!/usr/bin/env python

# -*- coding: utf-8 -*-

#====================================================

#          FILE: sdat2img.py

#       AUTHORS: xpirt - luxi78 - howellzhu

#          DATE: 2016-11-23 16:20:11 CST

#====================================================


import sys, os, errno


__version__ = '1.0'


if sys.hexversion < 0x02070000:

    print >> sys.stderr, "Python 2.7 or newer is required."

    try:

       input = raw_input

    except NameError: pass

    input('Press ENTER to exit...')

    sys.exit(1)

else:

    print('sdat2img binary - version: %s\n' % __version__)


try:

    TRANSFER_LIST_FILE = str(sys.argv[1])

    NEW_DATA_FILE = str(sys.argv[2])

except IndexError:

    print('\nUsage: sdat2img.py <transfer_list> <system_new_file> [system_img]\n')

    print('    <transfer_list>: transfer list file')

    print('    <system_new_file>: system new dat file')

    print('    [system_img]: output system image\n\n')

    print('Visit xda thread for more information.\n')

    try:

       input = raw_input

    except NameError: pass

    input('Press ENTER to exit...')

    sys.exit()


try:

    OUTPUT_IMAGE_FILE = str(sys.argv[3])

except IndexError:

    OUTPUT_IMAGE_FILE = 'system.img'


BLOCK_SIZE = 4096


def rangeset(src):

    src_set = src.split(',')

    num_set =  [int(item) for item in src_set]

    if len(num_set) != num_set[0]+1:

        print('Error on parsing following data to rangeset:\n%s' % src)

        sys.exit(1)


    return tuple ([ (num_set[i], num_set[i+1]) for i in range(1, len(num_set), 2) ])


def parse_transfer_list_file(path):

    trans_list = open(TRANSFER_LIST_FILE, 'r')


    # First line in transfer list is the version number

    version = int(trans_list.readline())


    # Second line in transfer list is the total number of blocks we expect to write

    new_blocks = int(trans_list.readline())


    if version >= 2:

        # Third line is how many stash entries are needed simultaneously

        trans_list.readline()

        # Fourth line is the maximum number of blocks that will be stashed simultaneously

        trans_list.readline()


    # Subsequent lines are all individual transfer commands

    commands = []

    for line in trans_list:

        line = line.split(' ')

        cmd = line[0]

        if cmd in ['erase', 'new', 'zero']:

            commands.append([cmd, rangeset(line[1])])

        else:

            # Skip lines starting with numbers, they are not commands anyway

            if not cmd[0].isdigit():

                print('Command "%s" is not valid.' % cmd)

                trans_list.close()

                sys.exit(1)


    trans_list.close()

    return version, new_blocks, commands


def main(argv):

    version, new_blocks, commands = parse_transfer_list_file(TRANSFER_LIST_FILE)


    if version == 1:

        print('Android Lollipop 5.0 detected!\n')

    elif version == 2:

        print('Android Lollipop 5.1 detected!\n')

    elif version == 3:

        print('Android Marshmallow 6.0 detected!\n')

    elif version == 4:

        print('Android Nougat 7.0 detected!\n')

    else:

        print('Unknown Android version!\n')


    # Don't clobber existing files to avoid accidental data loss

    try:

        output_img = open(OUTPUT_IMAGE_FILE, 'wb')

    except IOError as e:

        if e.errno == errno.EEXIST:

            print('Error: the output file "{}" already exists'.format(e.filename))

            print('Remove it, rename it, or choose a different file name.')

            sys.exit(e.errno)

        else:

            raise


    new_data_file = open(NEW_DATA_FILE, 'rb')

    all_block_sets = [i for command in commands for i in command[1]]

    max_file_size = max(pair[1] for pair in all_block_sets)*BLOCK_SIZE


    for command in commands:

        if command[0] == 'new':

            for block in command[1]:

                begin = block[0]

                end = block[1]

                block_count = end - begin

                print('Copying {} blocks into position {}...'.format(block_count, begin))


                # Position output file

                output_img.seek(begin*BLOCK_SIZE)

                

                # Copy one block at a time

                while(block_count > 0):

                    output_img.write(new_data_file.read(BLOCK_SIZE))

                    block_count -= 1

        else:

            print('Skipping command %s...' % command[0])


    # Make file larger if necessary

    if(output_img.tell() < max_file_size):

        output_img.truncate(max_file_size)


    output_img.close()

    new_data_file.close()

    print('Done! Output image: %s' % os.path.realpath(output_img.name))


if __name__ == '__main__':

    main(sys.argv)


0x使用方法:

D:\文件路径>sdat2img.py system.transfer.list system.new.dat system.img

0x使用过程:

0x结果:

0x最后:

用Ext2explore 查看提取system.img中文件


参考:https://github.com/xpirt/sdat2img

评论
热度(3)
  1. redboybuilding 转载了此文字
© building / Powered by LOFTER