linux、渗透测试、网络安全、CTF、windows

分享解ROM包技巧

☯KK | 补丁君:

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 转载了此文字

© redboy | Powered by LOFTER