Advertisement
SaintAnd

python2.GPTAnalyzer.py

Dec 2nd, 2022
806
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 24.01 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3.  
  4. # Author : n0fate
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2 of the License, or (at
  9. # your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful, but
  12. # WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. # General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program; if not, write to the Free Software
  18. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. #
  20. # Using structures defined in Wikipedia('http://en.wikipedia.org/wiki/GUID_Partition_Table')
  21.  
  22.  
  23. import sys,os,getopt
  24. import random,math
  25. import struct
  26. import hashlib
  27. import codecs
  28. import uuid
  29.  
  30. import zlib
  31.  
  32. if sys.version_info < (2,5):
  33.     sys.stdout.write("\n\nERROR: This script needs Python version 2.5 or greater, detected as ")
  34.     print sys.version_info
  35.     sys.exit()  # error
  36.  
  37. LBA_SIZE = 512
  38.  
  39. PRIMARY_GPT_LBA = 1
  40.  
  41. OFFSET_CRC32_OF_HEADER = 16
  42. GPT_HEADER_FORMAT = '<8sIIIIQQQQ16sQIII420x'
  43. GUID_PARTITION_ENTRY_FORMAT = '<16s16sQQQ72s'
  44.  
  45.  
  46. def ReverseByteOrder(data):
  47.     """
  48.    Method to reverse the byte order of a given unsigned data value
  49.    Input:
  50.        data:   data value whose byte order needs to be swap
  51.                data can only be as big as 4 bytes
  52.    Output:
  53.        revD: data value with its byte order reversed
  54.    """
  55.     s = "Error: Only 'unsigned' data of type 'int' or 'long' is allowed"
  56.     if not ((type(data) == int)or(type(data) == long)):
  57.         s1 = "Error: Invalid data type: %s" % type(data)
  58.         print(''.join([s,'\n',s1]))
  59.         return data
  60.     if(data < 0):
  61.         s2 = "Error: Data is signed. Value is less than 0"
  62.         print(''.join([s,'\n',s2]))
  63.         return data
  64.  
  65.     seq = ["0x"]
  66.  
  67.     while(data > 0):
  68.         d = data & 0xFF     # extract the least significant(LS) byte
  69.         seq.append('%02x'%d)# convert to appropriate string, append to sequence
  70.         data >>= 8          # push next higher byte to LS position
  71.  
  72.     revD = int(''.join(seq),16)
  73.  
  74.     return revD
  75.  
  76. ## gpt parser code start
  77.  
  78. def get_lba(fhandle, entry_number, count):
  79.     fhandle.seek(LBA_SIZE*entry_number)
  80.     fbuf = fhandle.read(LBA_SIZE*count)
  81.    
  82.     return fbuf
  83.  
  84. def swap64(x):
  85.     if ( x ==0 ):
  86.     return 0
  87.     little_endian = ReverseByteOrder(x)
  88.     return little_endian
  89.  
  90. def unsigned32(n):
  91.   return n & 0xFFFFFFFFL
  92.  
  93. def get_gpt_header(fhandle, fbuf, lba):
  94.     fbuf = get_lba(fhandle, lba, 1)
  95.    
  96.     gpt_header = struct.unpack(GPT_HEADER_FORMAT, fbuf)
  97.    
  98.     crc32_header_value = calc_header_crc32(fbuf, gpt_header[2])
  99.    
  100.     return gpt_header, crc32_header_value, fbuf
  101.  
  102. def make_nop(byte):
  103.     nop_code = 0x00
  104.     pk_nop_code = struct.pack('=B', nop_code)
  105.     nop = pk_nop_code*byte
  106.     return nop
  107.  
  108. def calc_header_crc32(fbuf, header_size):
  109.    
  110.     nop = make_nop(4)
  111.    
  112.     clean_header = fbuf[:OFFSET_CRC32_OF_HEADER] + nop + fbuf[OFFSET_CRC32_OF_HEADER+4:header_size]
  113.    
  114.     crc32_header_value = unsigned32(zlib.crc32(clean_header))
  115.     return crc32_header_value
  116.  
  117. def an_gpt_header(gpt_header, crc32_header_value, gpt_buf):
  118.     md5 = hashlib.md5()
  119.     md5.update(gpt_buf)
  120.     md5 = md5.hexdigest()
  121.  
  122.     signature = gpt_header[0]
  123.     revision = gpt_header[1]
  124.     headersize = gpt_header[2]
  125.     crc32_header = gpt_header[3]
  126.     reserved = gpt_header[4]
  127.     currentlba = gpt_header[5]
  128.     backuplba = gpt_header[6]
  129.     first_use_lba_for_partitions = gpt_header[7]
  130.     last_use_lba_for_partitions = gpt_header[8]
  131.     disk_guid = uuid.UUID(bytes_le=gpt_header[9])
  132.     part_entry_start_lba = gpt_header[10]
  133.     num_of_part_entry = gpt_header[11]
  134.     size_of_part_entry = gpt_header[12]
  135.     crc32_of_partition_array = gpt_header[13]
  136.  
  137.     print '<?xml version="1.0"?>'
  138.     print '\t<configuration>'
  139.     print '\t\t<!-- Primary GPT header: -->'
  140.     print '\t\t<!-- MD5: %s -->' %md5
  141.     print '\t\t<!-- Signature: %s -->' %signature
  142.     print '\t\t<!-- Revision: %d -->' %revision
  143.     print '\t\t<!-- Header Size: %d -->' %headersize
  144.     if crc32_header_value == crc32_header:
  145.         print '\t\t<!-- CRC32 of header: %X (VALID) => Real: %X -->'%(crc32_header, crc32_header_value)
  146.     else:
  147.         print '\t\t<!-- WARNING!! CRC32 of header: %X (INVALID) => Real: %X -->'%(crc32_header, crc32_header_value)
  148.     print '\t\t<!-- Current LBA: 0x%.8X -->'%currentlba
  149.     print '\t\t<!-- Backup LBA: 0x%.8X -->'%backuplba
  150.     print '\t\t<!-- First usable LBA for partitions: 0x%.8X -->'%first_use_lba_for_partitions
  151.     print '\t\t<!-- Last usable LBA for partitions: 0x%.8X -->'%last_use_lba_for_partitions
  152.     print '\t\t<!-- Disk GUID: %s -->'%str(disk_guid).upper()
  153.     print '\t\t<!-- Partition entries starting LBA: 0x%.8X -->'%part_entry_start_lba
  154.     print '\t\t<!-- Number of partition entries: %d -->'%num_of_part_entry
  155.     print '\t\t<!-- Size of partition entry: 0x%.8X -->'%size_of_part_entry
  156.     print '\t\t<!-- CRC32 of partition array: 0x%.8X -->'%crc32_of_partition_array
  157.  
  158.     print '\t\t<parser_instructions>'
  159.     print '\t\t\t<!-- NOTE: entries here are used by the parser when generating output -->'
  160.     print '\t\t\t<!-- NOTE: each filename must be on it\'s own line as in variable=value-->'
  161.     print '\t\t\tWRITE_PROTECT_BOUNDARY_IN_KB = 32768'
  162.     print '\t\t\tGROW_LAST_PARTITION_TO_FILL_DISK = false'
  163.     print '\t\t</parser_instructions>\n'
  164.  
  165.     print '\t\t<!-- NOTE: "physical_partition" are listed in order and apply to devices such as eMMC cards that have (for example) 3 physical partitions -->'
  166.     print '\t\t<!-- This is physical partition 0 -->'
  167.     print '\t\t<physical_partition>'
  168.     print '\t\t\t<!-- NOTE: Define information for each partition, which will be created in order listed here -->'
  169.     print '\t\t\t<!-- NOTE: Place all "readonly=true" partitions side by side for optimum space usage -->'
  170.     print '\t\t\t<!-- NOTE: If OPTIMIZE_READONLY_PARTITIONS=true, then partitions won\'t be in the order listed here -->'
  171.     print '\t\t\t<!--       they will instead be placed side by side at the beginning of the disk -->'
  172.  
  173.  
  174. # get partition entry
  175. def get_part_entry(fbuf, offset, size):
  176.     return struct.unpack(GUID_PARTITION_ENTRY_FORMAT, fbuf[offset:offset+size])
  177.  
  178. def get_part_table_area(f, gpt_header):
  179.     part_entry_start_lba = gpt_header[10]
  180.     first_use_lba_for_partitions = gpt_header[7]
  181.     fbuf = get_lba(f, part_entry_start_lba, first_use_lba_for_partitions - part_entry_start_lba)
  182.    
  183.     return fbuf
  184.  
  185. def part_attribute(value):
  186.     if value == 0:
  187.         return 'System Partition'
  188.     elif value == 2:
  189.         return 'Legacy BIOS Bootable'
  190.     elif value == 60:
  191.         return 'Read-Only'
  192.     elif value == 62:
  193.         return 'Hidden'
  194.     elif value == 63:
  195.         return 'Do not automount'
  196.     else:
  197.         return 'UNKNOWN'
  198.  
  199. def check_partition_guid_type(guid):
  200.     if guid == '024DEE41-33E7-11D3-9D69-0008C781F39F':
  201.         return 'MBR partition scheme', 'None'
  202.    
  203.     elif guid == 'C12A7328-F81F-11D2-BA4B-00A0C93EC93B':
  204.         return 'EFI System partition', 'None'
  205.    
  206.     elif guid == '21686148-6449-6E6F-744E-656564454649':
  207.         return 'BIOS Boot partition', 'None'
  208.    
  209.     # Windows
  210.     elif guid == 'E3C9E316-0B5C-4DB8-817D-F92DF00215AE':
  211.         return 'Microsoft Reserved Partition', 'Windows'
  212.    
  213.     elif guid == 'EBD0A0A2-B9E5-4433-87C0-68B6B72699C7':
  214.         return 'Basic data partition / Linux filesystem data', 'Windows / Linux'
  215.    
  216.     elif guid == '5808C8AA-7E8F-42E0-85D2-E1E90434CFB3':
  217.         return 'Logical Disk Manager metadata partition', 'Windows'
  218.    
  219.     elif guid == 'AF9B60A0-1431-4F62-BC68-3311714A69AD':
  220.         return 'Logical Disk Manager data partition', 'Windows'
  221.    
  222.     elif guid == 'DE94BBA4-06D1-4D40-A16A-BFD50179D6AC':
  223.         return 'Windows Recovery Environment', 'Windows'
  224.    
  225.     elif guid == '37AFFC90-EF7D-4E96-91C3-2D7AE055B174':
  226.         return 'IBM General Parallel File System (GPFS) partition', 'Windows'
  227.    
  228.     elif guid == 'DB97DBA9-0840-4BAE-97F0-FFB9A327C7E1':
  229.         return 'Cluster metadata partition', 'Windows'
  230.    
  231.     # HP-UX
  232.     elif guid == '75894C1E-3AEB-11D3-B7C1-7B03A0000000':
  233.         return 'Data partition', 'HP-UX'
  234.    
  235.     elif guid == 'E2A1E728-32E3-11D6-A682-7B03A0000000':
  236.         return 'Service partition', 'HP-UX'
  237.    
  238.     # Linux
  239.     elif guid == '0FC63DAF-8483-4772-8E79-3D69D8477DE4':
  240.         return 'Linux filesystem data', 'Linux'
  241.    
  242.     elif guid == 'A19D880F-05FC-4D3B-A006-743F0F84911E':
  243.         return 'RAID partition', 'Linux'
  244.    
  245.     elif guid == '0657FD6D-A4AB-43C4-84E5-0933C84B4F4F':
  246.         return 'Swao partition', 'Linux'
  247.    
  248.     elif guid == 'E6D6D379-F507-44C2-A23C-238F2A3DF928':
  249.         return 'Logical Volume Manager (LVM) partition', 'Linux'
  250.    
  251.     elif guid == '8DA63339-0007-60C0-C436-083AC8230908':
  252.         return 'Reserved', 'Linux'
  253.    
  254.     # FreeBSD
  255.     elif guid == '83BD6B9D-7F41-11DC-BE0B-001560B84F0F':
  256.         return 'Boot partition', 'FreeBSD'
  257.    
  258.     elif guid == '516E7CB4-6ECF-11D6-8FF8-00022D09712B':
  259.         return 'Data partition', 'FreeBSD'
  260.    
  261.     elif guid == '516E7CB5-6ECF-11D6-8FF8-00022D09712B':
  262.         return 'Swap partition', 'FreeBSD'
  263.    
  264.     elif guid == '516E7CB6-6ECF-11D6-8FF8-00022D09712B':
  265.         return 'Unix File System(UFS) partition', 'FreeBSD'
  266.    
  267.     elif guid == '516E7CB8-6ECF-11D6-8FF8-00022D09712B':
  268.         return 'Vinum volume manager partition', 'FreeBSD'
  269.    
  270.     elif guid == '516E7CB8-6ECF-11D6-8FF8-00022D09712B':
  271.         return 'ZFS partition', 'FreeBSD'
  272.    
  273.     # Mac OS X
  274.     elif guid == '48465300-0000-11AA-AA11-00306543ECAC':
  275.         return 'Hierarchical File System Plus (HFS+) partition', 'Mac OS X'
  276.    
  277.     elif guid == '55465300-0000-11AA-AA11-00306543ECAC':
  278.         return 'Apple UFS', 'Mac OS X'
  279.    
  280.     elif guid == '6A898CC3-1DD2-11B2-99A6-080020736631':
  281.         return 'ZFS / /usr partition', 'Mac OS X / Solaris'
  282.    
  283.     elif guid == '52414944-0000-11AA-AA11-00306543ECAC':
  284.         return 'Apple RAID partition', 'Mac OS X'
  285.    
  286.     elif guid == '52414944-5F4F-11AA-AA11-00306543ECAC':
  287.         return 'Apple RAID partition, offline', 'Mac OS X'
  288.    
  289.     elif guid == '426F6F74-0000-11AA-AA11-00306543ECAC':
  290.         return 'Apple Boot partition', 'Mac OS X'
  291.    
  292.     elif guid == '4C616265-6C00-11AA-AA11-00306543ECAC':
  293.         return 'Apple Label', 'Mac OS X'
  294.    
  295.     elif guid == '5265636F-7665-11AA-AA11-00306543ECAC':
  296.         return 'Apple TV Recovery partition', 'Mac OS X'
  297.    
  298.     elif guid == '53746F72-6167-11AA-AA11-00306543ECAC':
  299.         return 'Apple Core Storage (i.e. Lion FileVault) partition', 'Mac OS X'
  300.    
  301.     # Solaris
  302.     elif guid == '6A82CB45-1DD2-11B2-99A6-080020736631':
  303.         return 'Boot partition', 'Solaris'
  304.    
  305.     elif guid == '6A85CF4D-1DD2-11B2-99A6-080020736631':
  306.         return 'Root partition', 'Solaris'
  307.    
  308.     elif guid == '6A87C46F-1DD2-11B2-99A6-080020736631':
  309.         return 'Swap partition', 'Solaris'
  310.    
  311.     elif guid == '6A8B642B-1DD2-11B2-99A6-080020736631':
  312.         return 'Backup partition', 'Solaris'
  313.    
  314.     #elif guid == '6A898CC3-1DD2-11B2-99A6-080020736631':
  315.     #    return '/usr partition', 'Solaris'
  316.    
  317.     elif guid == '6A8EF2E9-1DD2-11B2-99A6-080020736631':
  318.         return '/var partition', 'Solaris'
  319.    
  320.     elif guid == '6A90BA39-1DD2-11B2-99A6-080020736631':
  321.         return '/home partition', 'Solaris'
  322.    
  323.     elif guid == '6A9283A5-1DD2-11B2-99A6-080020736631':
  324.         return 'Alternate sector', 'Solaris'
  325.    
  326.     elif guid == '6A945A3B-1DD2-11B2-99A6-080020736631' or \
  327.     guid == '6A9630D1-1DD2-11B2-99A6-080020736631' or \
  328.     guid == '6A980767-1DD2-11B2-99A6-080020736631' or \
  329.     guid == '6A96237F-1DD2-11B2-99A6-080020736631' or \
  330.     guid == '6A8D2AC7-1DD2-11B2-99A6-080020736631':
  331.         return 'Reserved partition', 'Solaris'
  332.    
  333.     # NetBSD
  334.     elif guid == '49F48D32-B10E-11DC-B99B-0019D1879648':
  335.         return 'Swap partition', 'NetBSD'
  336.    
  337.     elif guid == '49F48D5A-B10E-11DC-B99B-0019D1879648':
  338.         return 'FFS partition', 'NetBSD'
  339.    
  340.     elif guid == '49F48D82-B10E-11DC-B99B-0019D1879648':
  341.         return 'LFS partition', 'NetBSD'
  342.    
  343.     elif guid == '49F48DAA-B10E-11DC-B99B-0019D1879648':
  344.         return 'RAID partition', 'NetBSD'
  345.    
  346.     elif guid == '2DB519C4-B10F-11DC-B99B-0019D1879648':
  347.         return 'Concatenated partition', 'NetBSD'
  348.    
  349.     elif guid == '2DB519EC-B10F-11DC-B99B-0019D1879648':
  350.         return 'Encrypted partition', 'NetBSD'
  351.    
  352.     # Chrome OS
  353.     elif guid == 'FE3A2A5D-4F32-41A7-B725-ACCC3285A309':
  354.         return 'ChromeOS kernel', 'Chrome OS'
  355.    
  356.     elif guid == '3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC':
  357.         return 'ChromeOS rootfs', 'Chrome OS'
  358.    
  359.     elif guid == '2E0A753D-9E48-43B0-8337-B15192CB1B5E':
  360.         return 'ChromeOS future use', 'Chrome OS'
  361.    
  362.     # VMware ESX
  363.     elif guid == 'AA31E02A-400F-11DB-9590-000C2911D1B8':
  364.         return 'VMFS partition', 'VMware ESX'
  365.    
  366.     elif guid == '9D275380-40AD-11DB-BF97-000C2911D1B8':
  367.         return 'vmkcore crash partition', 'VMware ESX'
  368.    
  369.     # Midnight BSD
  370.     elif guid == '85D5E45E-237C-11E1-B4B3-E89A8F7FC3A7':
  371.         return 'Boot partition', 'MidnightBSD'
  372.    
  373.     elif guid == '85D5E45A-237C-11E1-B4B3-E89A8F7FC3A7':
  374.         return 'Data partition', 'MidnightBSD'
  375.    
  376.     elif guid == '85D5E45B-237C-11E1-B4B3-E89A8F7FC3A7':
  377.         return 'Swap partition', 'MidnightBSD'
  378.    
  379.     elif guid == '0394Ef8B-237E-11E1-B4B3-E89A8F7FC3A7':
  380.         return 'Unix File System (UFS) partition', 'MidnightBSD'
  381.    
  382.     elif guid == '85D5E45C-237C-11E1-B4B3-E89A8F7FC3A7':
  383.         return 'Vinum volume manager partition', 'MidnightBSD'
  384.    
  385.     elif guid == '85D5E45D-237C-11E1-B4B3-E89A8F7FC3A7':
  386.         return 'ZFS partition', 'MidnightBSD'
  387.    
  388.     # Qualcomm Boot GPT Partition IDs
  389.     elif guid == 'DEA0BA2C-CBDD-4805-B4F9-F428251C3E98':
  390.         return 'SBL1 partition', 'Qualcomm'
  391.  
  392.     elif guid == '8C6B52AD-8A9E-4398-AD09-AE916E53AE2D':
  393.         return 'SBL2 partition', 'Qualcomm'
  394.  
  395.     elif guid == '05E044DF-92F1-4325-B69E-374A82E97D6E':
  396.         return 'SBL3 partition', 'Qualcomm'
  397.  
  398.     elif guid == '400FFDCD-22E0-47E7-9A23-F16ED9382388':
  399.         return 'APPSBL partition', 'Qualcomm'
  400.  
  401.     elif guid == 'A053AA7F-40B8-4B1C-BA08-2F68AC71A4F4':
  402.         return 'QSEE partition', 'Qualcomm'
  403.  
  404.     elif guid == 'E1A6A689-0C8D-4CC6-B4E8-55A4320FBD8A':
  405.         return 'QHEE partition', 'Qualcomm'
  406.  
  407.     elif guid == '098DF793-D712-413D-9D4E-89D711772228':
  408.         return 'RPM partition', 'Qualcomm'
  409.  
  410.     elif guid == 'D4E0D938-B7FA-48C1-9D21-BC5ED5C4B203':
  411.         return 'WDOG debug partition', 'Qualcomm'
  412.  
  413.     elif guid == '20A0C19C-286A-42FA-9CE7-F64C3226A794':
  414.         return 'DDR partition', 'Qualcomm'
  415.  
  416.     elif guid == 'A19F205F-CCD8-4B6D-8F1E-2D9BC24CFFB1':
  417.         return 'CDT partition', 'Qualcomm'
  418.  
  419.     elif guid == '66C9B323-F7FC-48B6-BF96-6F32E335A428':
  420.         return 'RAM dump partition', 'Qualcomm'
  421.  
  422.     elif guid == '303E6AC3-AF15-4C54-9E9B-D9A8FBECF401':
  423.         return 'SEC partition', 'Qualcomm'
  424.  
  425.     elif guid == 'C00EEF24-7709-43D6-9799-DD2B411E7A3C':
  426.         return 'PMIC config data partition', 'Qualcomm'
  427.  
  428.     elif guid == '82ACC91F-357C-4A68-9C8F-689E1B1A23A1':
  429.         return 'MISC? partition', 'Qualcomm'
  430.  
  431.     elif guid == '10A0C19C-516A-5444-5CE3-664C3226A794':
  432.         return 'LIMITS? partition', 'Qualcomm'
  433.  
  434.     elif guid == '65ADDCF4-0C5C-4D9A-AC2D-D90B5CBFCD03':
  435.         return 'DEVINFO? partition', 'Qualcomm'
  436.  
  437.     elif guid == 'E6E98DA2-E22A-4D12-AB33-169E7DEAA507':
  438.         return 'APDP? partition', 'Qualcomm'
  439.  
  440.     elif guid == 'ED9E8101-05FA-46B7-82AA-8D58770D200B':
  441.         return 'MSADP? partition', 'Qualcomm'
  442.  
  443.     elif guid == '11406F35-1173-4869-807B-27DF71802812':
  444.         return 'DPO? partition', 'Qualcomm'
  445.  
  446.     elif guid == 'DF24E5ED-8C96-4B86-B00B-79667DC6DE11':
  447.         return 'SPARE1? partition', 'Qualcomm'
  448.  
  449.     elif guid == '6C95E238-E343-4BA8-B489-8681ED22AD0B':
  450.         return 'PERSIST? partition', 'Qualcomm'
  451.  
  452.     elif guid == 'EBBEADAF-22C9-E33B-8F5D-0E81686A68CB':
  453.         return 'MODEMST1 partition', 'Qualcomm'
  454.  
  455.     elif guid == '0A288B1F-22C9-E33B-8F5D-0E81686A68CB':
  456.         return 'MODEMST2 partition', 'Qualcomm'
  457.  
  458.     elif guid == 'EBBEADAF-22C9-E33B-8F5D-0E81686A68CB':
  459.         return 'MODEMST1 partition', 'Qualcomm'
  460.  
  461.     elif guid == '638FF8E2-22C9-E33B-8F5D-0E81686A68CB':
  462.         return 'FSG? partition', 'Qualcomm'
  463.  
  464.     elif guid == '57B90A16-22C9-E33B-8F5D-0E81686A68CB':
  465.         return 'FSC? partition', 'Qualcomm'
  466.  
  467.     elif guid == '2C86E742-745E-4FDD-BFD8-B6A7AC638772':
  468.         return 'SSD? partition', 'Qualcomm'
  469.  
  470.     elif guid == 'DE7D4029-0F5B-41C8-AE7E-F6C023A02B33':
  471.         return 'KEYSTORE? partition', 'Qualcomm'
  472.  
  473.     elif guid == '323EF595-AF7A-4AFA-8060-97BE72841BB9':
  474.         return 'ENCRYPT? partition', 'Qualcomm'
  475.  
  476.     elif guid == '45864011-CF89-46E6-A445-85262E065604':
  477.         return 'EKSST? partition', 'Qualcomm'
  478.  
  479.     elif guid == '8ED8AE95-597F-4C8A-A5BD-A7FF8E4DFAA9':
  480.         return 'RCT partition', 'Qualcomm'
  481.  
  482.     elif guid == '7C29D3AD-78B9-452E-9DEB-D098D542F092':
  483.         return 'SPARE2? partition', 'Qualcomm'
  484.  
  485.     elif guid == '9D72D4E4-9958-42DA-AC26-BEA7A90B0434':
  486.         return 'RECOVERY? partition', 'Qualcomm'
  487.  
  488.     elif guid == '4627AE27-CFEF-48A1-88FE-99C3509ADE26':
  489.         return 'raw_resources? partition', 'Qualcomm'
  490.  
  491.     elif guid == '20117F86-E985-4357-B9EE-374BC1D8487D':
  492.         return 'BOOT partition', 'Qualcomm'
  493.  
  494.     elif guid == '379D107E-229E-499D-AD4F-61F5BCF87BD4':
  495.         return 'SPARE3? partition', 'Qualcomm'
  496.  
  497.     elif guid == '86A7CB80-84E1-408C-99AB-694F1A410FC7':
  498.         return 'FOTA? partition', 'Qualcomm'
  499.  
  500.     elif guid == '0DEA65E5-A676-4CDF-823C-77568B577ED5':
  501.         return 'SPARE4? partition', 'Qualcomm'
  502.  
  503.     elif guid == '97D7B011-54DA-4835-B3C4-917AD6E73D74':
  504.         return 'SYSTEM? partition', 'Qualcomm'
  505.  
  506.     elif guid == '5594C694-C871-4B5F-90B1-690A6F68E0F7':
  507.         return 'CACHE? partition', 'Qualcomm'
  508.  
  509.     elif guid == '1B81E7E6-F50D-419B-A739-2AEEF8DA3335':
  510.         return 'USERDATA? partition', 'Qualcomm'
  511.  
  512.     # LG Advanced Flasher Partition
  513.     elif guid == '98523EC6-90FE-4C67-B50A-0FC59ED6F56D':
  514.         return 'LG Advanced Flasher partition', 'LG'
  515.  
  516.     # else
  517.     else:
  518.         return 'unknown partition', 'UNKNOWN'
  519.    
  520.  
  521. # analysis partition table
  522. def an_part_table(partition_table, gpt_header, fbuf):
  523.     md5 = hashlib.md5()
  524.     md5.update(fbuf)
  525.     md5 = md5.hexdigest()
  526.    
  527.     num_of_part_entry = gpt_header[11]
  528.     size_of_part_entry = gpt_header[12]
  529.     crc32_of_partition_array = gpt_header[13]
  530.    
  531.     part_list = []
  532.    
  533.     crc32_part_value = unsigned32(zlib.crc32(partition_table))
  534.  
  535.     print '\n\t\t\t<!-- Partition table: -->'
  536.     print '\t\t\t\t<!-- MD5: %s -->'%md5
  537.     if crc32_part_value == crc32_of_partition_array:
  538.         print '\t\t\t\t<!-- CRC32 Check : %.8X (VALID) -->\n'%crc32_part_value
  539.     else:
  540.         print '\t\t\t\t<!-- WARNING!! CRC32 Check : %.8X (INVALID) -->\n'%crc32_part_value
  541.    
  542.     for part_entry_num in range(0, num_of_part_entry):
  543.         part_entry = get_part_entry(partition_table, size_of_part_entry*part_entry_num, size_of_part_entry)
  544.        
  545.         # first LBA, last LBA
  546.         if part_entry[2] == 0 or part_entry[3] == 0:
  547.             continue
  548.        
  549.         part_list.append(part_entry)
  550.    
  551.     count = 1
  552.     for part_entry in part_list:
  553.         part_type = check_partition_guid_type(str(uuid.UUID(bytes_le=part_entry[0])).upper())
  554.         part_guid = str(uuid.UUID(bytes_le=part_entry[1])).upper()
  555.         part_label = unicode(part_entry[5].replace('\0',''))
  556.         part_type = str(uuid.UUID(bytes_le=part_entry[0])).upper()
  557.         part_type_label = check_partition_guid_type(part_type)
  558.         part_bootable = 'false'
  559.         part_lba_first = part_entry[2]
  560.         part_lba_first_offset = (part_entry[2] * LBA_SIZE)
  561.         part_lba_last = part_entry[3]
  562.         part_lba_last_offset = (part_entry[3] * LBA_SIZE)
  563.         part_size = (((part_lba_last - part_lba_first) + 1) / 2)
  564.  
  565.         print '\t\t\t<!-- #%02d -->' %count
  566.         print '\t\t\t<!-- First LBA: %s /' %part_lba_first,
  567.         print 'Disk Offset: %s -->' %part_lba_first_offset
  568.         print '\t\t\t<!-- Last LBA : %s /' %part_lba_last,
  569.         print 'Disk Offset: %s -->' %part_lba_last_offset
  570.         print '\t\t\t<!-- %s |' %part_type_label[0],
  571.         print '%s -->' %part_type_label[1]
  572.         print '\t\t\t<!-- GUID: %s -->' %part_guid
  573.  
  574.         print '\t\t\t<partition',
  575.         print 'label="%s"' %part_label,
  576.         print 'size_in_kb="%d"' %part_size,
  577.         print 'type="%s"'%part_type,
  578.         print 'bootable="%s"' %part_bootable,
  579.         print 'firstlba="%s"' %part_lba_first,
  580.         print 'uniqueguid="%s"' %part_guid,
  581.  
  582.         #print 'attributes="0x%0.2X"' %part_entry[4],
  583.         part_attr_tag = swap64( part_entry[4] )
  584.         if(part_attr_tag & 0):
  585.             print 'system="true"',
  586.         elif(part_attr_tag & 60):
  587.             print 'readonly="true"',
  588.         elif(part_attr_tag & 62):
  589.             print 'hidden="true"',
  590.         elif(part_attr_tag & 63):
  591.             print 'automount="true"',
  592.  
  593.         part_filename = ''
  594.         part_match = part_label
  595.  
  596.         part_list_bak = ['rpm','sdi','hyp','sbl1','tz','pmic','aboot','raw_resources']
  597.         part_list_img = ['persist','laf','drm','sns','mpt','eri','system','cache','userdata']
  598.  
  599.         for party in part_list_bak:
  600.             if party in part_match:
  601.                 part_filename = '%s.mbn' %part_match.replace('bak','')
  602.  
  603.         for party in part_list_img:
  604.             if party in part_match:
  605.                 part_filename = '%s.img' %party
  606.  
  607.         if part_match == str('modem'):
  608.             part_filename = 'NON-HLOS.bin'
  609.         elif part_match == str('DDR'):
  610.             part_filename = 'DDR.bin'
  611.         elif part_match == str('sec'):
  612.             part_filename = 'sec.dat'
  613.         elif part_match == 'aboot':
  614.             part_filename = 'emmc_appsboot.mbn'
  615.  
  616.         print 'filename="%s"/>\n' %part_filename
  617.  
  618.         count += 1
  619.  
  620. def usage(argv):
  621.     print '%s <DISK IMAGE>'%argv[0]
  622.     sys.exit()
  623.    
  624.  
  625. def main():
  626.    
  627.     try:
  628.         option, args = getopt.getopt(sys.argv[1:], '')
  629.  
  630.     except getopt.GetoptError, err:
  631.         usage(sys.argv)
  632.         sys.exit()
  633.    
  634.     try:
  635.         if len(sys.argv) != 2:
  636.             usage(sys.argv)
  637.             sys.exit()
  638.    
  639.     except IndexError:
  640.         usage()
  641.         sys.exit()
  642.    
  643.     try:
  644.         f = open(sys.argv[1], 'rb')
  645.     except IOError:
  646.         print '[+] WARNING!! Can not open disk image.'
  647.         #usage(sys.argv)
  648.         sys.exit()
  649.    
  650.     fbuf = ''
  651.    
  652.     # Protected MBR
  653.     # You can use mbr_parser.py at http://gleeda.blogspot.com/2012/04/mbr-parser.html
  654.    
  655.     # Primary GPT header
  656.     gpt_header, crc32_header_value, gpt_buf = get_gpt_header(f, fbuf, PRIMARY_GPT_LBA)
  657.     an_gpt_header(gpt_header, crc32_header_value, gpt_buf)
  658.    
  659.    
  660.     # Partition entries
  661.     fbuf = get_part_table_area(f, gpt_header)
  662.     an_part_table(fbuf, gpt_header, fbuf)
  663.    
  664.     ## backup GPT header
  665.     # print ''
  666.     # try:
  667.     #     gpt_header, crc32_header_value, gpt_buf = get_gpt_header(f, fbuf, gpt_header[6])
  668.     #     an_gpt_header(gpt_header, crc32_header_value, gpt_buf)
  669.        
  670.     #     h = hashlib.md5()
  671.     #     h.update(gpt_buf)
  672.     #     print '\t\t\t<!-- [+] Backup GPT header md5: %s -->'%h.hexdigest()
  673.     # except struct.error:
  674.     #     print '\t\t\t<!-- [+] WARNING!! Backup GPT header can not found. Check your disk image. -->'
  675.     #     print '\t\t\t<!-- [+] WARNING!! Backup GPT header offset: 0x%.8X -->'%(gpt_header[6] * LBA_SIZE)
  676.  
  677.     print '\t\t</physical_partition>'
  678.     print '\t</configuration>'
  679.    
  680.     f.close()
  681.    
  682. if __name__ == "__main__":
  683.     main()
  684.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement