system/corennnnn
Revision | 22d3b10954ba6415e28c5fd8a08fb048c8d5cbfd (tree) |
---|---|
Zeit | 2016-09-04 08:47:14 |
Autor | M1cha <sigmaepsilon92@gmai...> |
Commiter | Steve Kondik |
unpackbootimg: turn into a python script
Turn unpackbootimg into a python script instead of a C utility
Change-Id: If049319d12ee9841eefb9ca3fdae5c775403bbbf
@@ -10,7 +10,13 @@ LOCAL_MODULE := mkbootimg | ||
10 | 10 | |
11 | 11 | include $(BUILD_PREBUILT) |
12 | 12 | |
13 | + | |
13 | 14 | include $(CLEAR_VARS) |
14 | -LOCAL_SRC_FILES := unpackbootimg.c | |
15 | + | |
16 | +LOCAL_SRC_FILES := unpackbootimg | |
17 | +LOCAL_MODULE_CLASS := EXECUTABLES | |
18 | +LOCAL_IS_HOST_MODULE := true | |
19 | + | |
15 | 20 | LOCAL_MODULE := unpackbootimg |
16 | -include $(BUILD_HOST_EXECUTABLE) | |
21 | + | |
22 | +include $(BUILD_PREBUILT) |
@@ -0,0 +1,167 @@ | ||
1 | +#!/usr/bin/env python | |
2 | +# Copyright 2015, The Android Open Source Project | |
3 | +# | |
4 | +# Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | +# you may not use this file except in compliance with the License. | |
6 | +# You may obtain a copy of the License at | |
7 | +# | |
8 | +# http://www.apache.org/licenses/LICENSE-2.0 | |
9 | +# | |
10 | +# Unless required by applicable law or agreed to in writing, software | |
11 | +# distributed under the License is distributed on an "AS IS" BASIS, | |
12 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | +# See the License for the specific language governing permissions and | |
14 | +# limitations under the License. | |
15 | + | |
16 | +from __future__ import print_function | |
17 | +from sys import exit | |
18 | +from argparse import ArgumentParser, FileType | |
19 | +from os import rename | |
20 | +from os.path import basename | |
21 | +from struct import unpack, calcsize | |
22 | + | |
23 | +class Bunch: | |
24 | + def __init__(self, **kwds): | |
25 | + self.__dict__.update(kwds) | |
26 | + | |
27 | +def auto_unpack(fmt, f): | |
28 | + size = calcsize(fmt) | |
29 | + data = f.read(size) | |
30 | + return unpack(fmt, data[0:size]) | |
31 | + | |
32 | +def get_magic_off(f): | |
33 | + BOOT_MAGIC = 'ANDROID!'.encode() | |
34 | + | |
35 | + for i in range(513): | |
36 | + f.seek(i) | |
37 | + tmp = f.read(len(BOOT_MAGIC)) | |
38 | + if tmp == BOOT_MAGIC: | |
39 | + print('Android magic found at: %d' % i) | |
40 | + return i | |
41 | + | |
42 | + print('Android boot magic not found.'); | |
43 | + exit(1) | |
44 | + | |
45 | +def read_header(args, off): | |
46 | + args.input.seek(off) | |
47 | + fmt = '8s10I16s512s32s1024s' | |
48 | + unpacked = auto_unpack(fmt, args.input) | |
49 | + | |
50 | + parsed = Bunch() | |
51 | + parsed.headersz = calcsize(fmt) | |
52 | + parsed.magic = unpacked[0] | |
53 | + parsed.kernel_size = unpacked[1] | |
54 | + parsed.kernel_addr = unpacked[2] | |
55 | + parsed.ramdisk_size = unpacked[3] | |
56 | + parsed.ramdisk_addr = unpacked[4] | |
57 | + parsed.second_size = unpacked[5] | |
58 | + parsed.second_addr = unpacked[6] | |
59 | + parsed.tags_addr = unpacked[7] | |
60 | + parsed.pagesize = unpacked[8] | |
61 | + parsed.dt_size = unpacked[9] | |
62 | + parsed.name = unpacked[11].partition(b'\0')[0].decode() | |
63 | + parsed.cmdline = unpacked[12].partition(b'\0')[0].decode() | |
64 | + parsed.id = unpacked[13] | |
65 | + parsed.cmdline += unpacked[14].partition(b'\0')[0].decode() | |
66 | + | |
67 | + os_version = unpacked[10]>>11 | |
68 | + os_patch_level = unpacked[10]&0x7ff | |
69 | + | |
70 | + a = (os_version>>14)&0x7f | |
71 | + b = (os_version>>7)&0x7f | |
72 | + c = os_version&0x7f | |
73 | + parsed.os_version = '%d.%d.%d' % (a,b,c) | |
74 | + | |
75 | + y = (os_patch_level>>4) + 2000 | |
76 | + m = os_patch_level&0xf | |
77 | + parsed.os_patch_level = '%04d-%02d-%02d' % (y,m,0) | |
78 | + | |
79 | + return parsed | |
80 | + | |
81 | +def write_str_to_file(filename, s): | |
82 | + with open(filename, 'wb') as f: | |
83 | + f.write(s.encode()) | |
84 | + | |
85 | +def parse_int(x): | |
86 | + return int(x, 0) | |
87 | + | |
88 | +def parse_cmdline(): | |
89 | + parser = ArgumentParser() | |
90 | + parser.add_argument('-i', '--input', help='input file name', type=FileType('rb'), | |
91 | + required=True) | |
92 | + parser.add_argument('-o', '--output', help='output directory', default='') | |
93 | + parser.add_argument('--pagesize', help='page size', type=parse_int, | |
94 | + choices=[2**i for i in range(11,15)], default=0) | |
95 | + return parser.parse_args() | |
96 | + | |
97 | +def seek_padding(f, size, pagesize): | |
98 | + pagemask = pagesize - 1; | |
99 | + if((size & pagemask) != 0): | |
100 | + count = pagesize - (size & pagemask); | |
101 | + f.seek(count, 1); | |
102 | + | |
103 | +def write_input_to_file(args, filename, size): | |
104 | + with open(filename, 'wb') as f_out: | |
105 | + f_out.write(args.input.read(size)) | |
106 | + | |
107 | + seek_padding(args.input, size, args.pagesize) | |
108 | + | |
109 | +def fix_ramdisk_extension(filename): | |
110 | + bytes = [] | |
111 | + with open(filename, 'rb') as f: | |
112 | + data = f.read(2) | |
113 | + if(len(data))!=2: | |
114 | + return | |
115 | + bytes = unpack('BB', data) | |
116 | + | |
117 | + if bytes[0]==0x02 and bytes[1]==0x21: | |
118 | + rename(filename, filename+'.lz4') | |
119 | + else: | |
120 | + rename(filename, filename+'.gz') | |
121 | + | |
122 | +def write_data(args, header, off): | |
123 | + file_prefix = args.output | |
124 | + if file_prefix and file_prefix[-1]!='/': | |
125 | + file_prefix += '/' | |
126 | + file_prefix += basename(args.input.name) + '-' | |
127 | + | |
128 | + write_str_to_file(file_prefix+'cmdline', header.cmdline) | |
129 | + write_str_to_file(file_prefix+'base', '%08x' % (header.kernel_addr - 0x00008000)) | |
130 | + write_str_to_file(file_prefix+'ramdisk_offset', '%08x' % (header.ramdisk_addr - header.kernel_addr + 0x00008000)) | |
131 | + write_str_to_file(file_prefix+'second_offset', '%08x' % (header.second_addr - header.kernel_addr + 0x00008000)) | |
132 | + write_str_to_file(file_prefix+'tags_offset', '%08x' % (header.tags_addr - header.kernel_addr + 0x00008000)) | |
133 | + write_str_to_file(file_prefix+'pagesize', '%d' % header.pagesize) | |
134 | + write_str_to_file(file_prefix+'name', header.name) | |
135 | + write_str_to_file(file_prefix+'os_version', header.os_version) | |
136 | + write_str_to_file(file_prefix+'os_patch_level', header.os_patch_level) | |
137 | + | |
138 | + seek_padding(args.input, header.headersz, args.pagesize) | |
139 | + | |
140 | + write_input_to_file(args, file_prefix+'zImage', header.kernel_size) | |
141 | + write_input_to_file(args, file_prefix+'ramdisk', header.ramdisk_size) | |
142 | + write_input_to_file(args, file_prefix+'second', header.second_size) | |
143 | + write_input_to_file(args, file_prefix+'dt', header.dt_size) | |
144 | + | |
145 | + fix_ramdisk_extension(file_prefix+'ramdisk') | |
146 | + | |
147 | +def main(): | |
148 | + args = parse_cmdline() | |
149 | + off = get_magic_off(args.input) | |
150 | + header = read_header(args, off) | |
151 | + | |
152 | + print('BOARD_KERNEL_CMDLINE %s' % header.cmdline) | |
153 | + print('BOARD_KERNEL_BASE %08x' % (header.kernel_addr - 0x00008000)) | |
154 | + print('BOARD_RAMDISK_OFFSET %08x' % (header.ramdisk_addr - header.kernel_addr + 0x00008000)) | |
155 | + print('BOARD_SECOND_OFFSET %08x' % (header.second_addr - header.kernel_addr + 0x00008000)) | |
156 | + print('BOARD_TAGS_OFFSET %08x' % (header.tags_addr - header.kernel_addr + 0x00008000)) | |
157 | + print('BOARD_PAGE_SIZE %d' % header.pagesize) | |
158 | + print('BOARD_SECOND_SIZE %d' % header.second_size) | |
159 | + print('BOARD_DT_SIZE %d' % header.dt_size) | |
160 | + | |
161 | + if args.pagesize == 0: | |
162 | + args.pagesize = header.pagesize | |
163 | + | |
164 | + write_data(args, header, off) | |
165 | + | |
166 | +if __name__ == '__main__': | |
167 | + main() |
@@ -1,211 +0,0 @@ | ||
1 | -#include <stdio.h> | |
2 | -#include <stdlib.h> | |
3 | -#include <string.h> | |
4 | -#include <unistd.h> | |
5 | -#include <fcntl.h> | |
6 | -#include <errno.h> | |
7 | -#include <limits.h> | |
8 | -#include <libgen.h> | |
9 | - | |
10 | -#include "mincrypt/sha.h" | |
11 | -#include "bootimg.h" | |
12 | - | |
13 | -typedef unsigned char byte; | |
14 | - | |
15 | -int read_padding(FILE* f, unsigned itemsize, int pagesize) | |
16 | -{ | |
17 | - byte* buf = (byte*)malloc(sizeof(byte) * pagesize); | |
18 | - unsigned pagemask = pagesize - 1; | |
19 | - unsigned count; | |
20 | - | |
21 | - if((itemsize & pagemask) == 0) { | |
22 | - free(buf); | |
23 | - return 0; | |
24 | - } | |
25 | - | |
26 | - count = pagesize - (itemsize & pagemask); | |
27 | - | |
28 | - fread(buf, count, 1, f); | |
29 | - free(buf); | |
30 | - return count; | |
31 | -} | |
32 | - | |
33 | -void write_string_to_file(char* file, char* string) | |
34 | -{ | |
35 | - FILE* f = fopen(file, "w"); | |
36 | - fwrite(string, strlen(string), 1, f); | |
37 | - fwrite("\n", 1, 1, f); | |
38 | - fclose(f); | |
39 | -} | |
40 | - | |
41 | -int usage() { | |
42 | - printf("usage: unpackbootimg\n"); | |
43 | - printf("\t-i|--input boot.img\n"); | |
44 | - printf("\t[ -o|--output output_directory]\n"); | |
45 | - printf("\t[ -p|--pagesize <size-in-hexadecimal> ]\n"); | |
46 | - return 0; | |
47 | -} | |
48 | - | |
49 | -int main(int argc, char** argv) | |
50 | -{ | |
51 | - char tmp[PATH_MAX]; | |
52 | - char* directory = "./"; | |
53 | - char* filename = NULL; | |
54 | - int pagesize = 0; | |
55 | - | |
56 | - argc--; | |
57 | - argv++; | |
58 | - while(argc > 0){ | |
59 | - char *arg = argv[0]; | |
60 | - char *val = argv[1]; | |
61 | - argc -= 2; | |
62 | - argv += 2; | |
63 | - if(!strcmp(arg, "--input") || !strcmp(arg, "-i")) { | |
64 | - filename = val; | |
65 | - } else if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) { | |
66 | - directory = val; | |
67 | - } else if(!strcmp(arg, "--pagesize") || !strcmp(arg, "-p")) { | |
68 | - pagesize = strtoul(val, 0, 16); | |
69 | - } else { | |
70 | - return usage(); | |
71 | - } | |
72 | - } | |
73 | - | |
74 | - if (filename == NULL) { | |
75 | - return usage(); | |
76 | - } | |
77 | - | |
78 | - int total_read = 0; | |
79 | - FILE* f = fopen(filename, "rb"); | |
80 | - boot_img_hdr header; | |
81 | - | |
82 | - //printf("Reading header...\n"); | |
83 | - int i; | |
84 | - for (i = 0; i <= 512; i++) { | |
85 | - fseek(f, i, SEEK_SET); | |
86 | - fread(tmp, BOOT_MAGIC_SIZE, 1, f); | |
87 | - if (memcmp(tmp, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) | |
88 | - break; | |
89 | - } | |
90 | - total_read = i; | |
91 | - if (i > 512) { | |
92 | - printf("Android boot magic not found.\n"); | |
93 | - return 1; | |
94 | - } | |
95 | - fseek(f, i, SEEK_SET); | |
96 | - printf("Android magic found at: %d\n", i); | |
97 | - | |
98 | - fread(&header, sizeof(header), 1, f); | |
99 | - printf("BOARD_KERNEL_CMDLINE %s\n", header.cmdline); | |
100 | - printf("BOARD_KERNEL_BASE %08x\n", header.kernel_addr - 0x00008000); | |
101 | - printf("BOARD_RAMDISK_OFFSET %08x\n", header.ramdisk_addr - header.kernel_addr + 0x00008000); | |
102 | - printf("BOARD_SECOND_OFFSET %08x\n", header.second_addr - header.kernel_addr + 0x00008000); | |
103 | - printf("BOARD_TAGS_OFFSET %08x\n",header.tags_addr - header.kernel_addr + 0x00008000); | |
104 | - printf("BOARD_PAGE_SIZE %d\n", header.page_size); | |
105 | - printf("BOARD_SECOND_SIZE %d\n", header.second_size); | |
106 | - printf("BOARD_DT_SIZE %d\n", header.dt_size); | |
107 | - | |
108 | - if (pagesize == 0) { | |
109 | - pagesize = header.page_size; | |
110 | - } | |
111 | - | |
112 | - //printf("cmdline...\n"); | |
113 | - sprintf(tmp, "%s/%s", directory, basename(filename)); | |
114 | - strcat(tmp, "-cmdline"); | |
115 | - write_string_to_file(tmp, header.cmdline); | |
116 | - | |
117 | - //printf("base...\n"); | |
118 | - sprintf(tmp, "%s/%s", directory, basename(filename)); | |
119 | - strcat(tmp, "-base"); | |
120 | - char basetmp[200]; | |
121 | - sprintf(basetmp, "%08x", header.kernel_addr - 0x00008000); | |
122 | - write_string_to_file(tmp, basetmp); | |
123 | - | |
124 | - //printf("ramdisk_offset...\n"); | |
125 | - sprintf(tmp, "%s/%s", directory, basename(filename)); | |
126 | - strcat(tmp, "-ramdisk_offset"); | |
127 | - char ramdisktmp[200]; | |
128 | - sprintf(ramdisktmp, "%08x", header.ramdisk_addr - header.kernel_addr + 0x00008000); | |
129 | - write_string_to_file(tmp, ramdisktmp); | |
130 | - | |
131 | - //printf("second_offset...\n"); | |
132 | - sprintf(tmp, "%s/%s", directory, basename(filename)); | |
133 | - strcat(tmp, "-second_offset"); | |
134 | - char secondtmp[200]; | |
135 | - sprintf(secondtmp, "%08x", header.second_addr - header.kernel_addr + 0x00008000); | |
136 | - write_string_to_file(tmp, secondtmp); | |
137 | - | |
138 | - //printf("tags_offset...\n"); | |
139 | - sprintf(tmp, "%s/%s", directory, basename(filename)); | |
140 | - strcat(tmp, "-tags_offset"); | |
141 | - char tagstmp[200]; | |
142 | - sprintf(tagstmp, "%08x", header.tags_addr - header.kernel_addr + 0x00008000); | |
143 | - write_string_to_file(tmp, tagstmp); | |
144 | - | |
145 | - //printf("pagesize...\n"); | |
146 | - sprintf(tmp, "%s/%s", directory, basename(filename)); | |
147 | - strcat(tmp, "-pagesize"); | |
148 | - char pagesizetmp[200]; | |
149 | - sprintf(pagesizetmp, "%d", header.page_size); | |
150 | - write_string_to_file(tmp, pagesizetmp); | |
151 | - | |
152 | - total_read += sizeof(header); | |
153 | - //printf("total read: %d\n", total_read); | |
154 | - total_read += read_padding(f, sizeof(header), pagesize); | |
155 | - | |
156 | - sprintf(tmp, "%s/%s", directory, basename(filename)); | |
157 | - strcat(tmp, "-zImage"); | |
158 | - FILE *k = fopen(tmp, "wb"); | |
159 | - byte* kernel = (byte*)malloc(header.kernel_size); | |
160 | - //printf("Reading kernel...\n"); | |
161 | - fread(kernel, header.kernel_size, 1, f); | |
162 | - total_read += header.kernel_size; | |
163 | - fwrite(kernel, header.kernel_size, 1, k); | |
164 | - fclose(k); | |
165 | - | |
166 | - //printf("total read: %d\n", header.kernel_size); | |
167 | - total_read += read_padding(f, header.kernel_size, pagesize); | |
168 | - | |
169 | - | |
170 | - byte* ramdisk = (byte*)malloc(header.ramdisk_size); | |
171 | - //printf("Reading ramdisk...\n"); | |
172 | - fread(ramdisk, header.ramdisk_size, 1, f); | |
173 | - total_read += header.ramdisk_size; | |
174 | - sprintf(tmp, "%s/%s", directory, basename(filename)); | |
175 | - if(ramdisk[0] == 0x02 && ramdisk[1]== 0x21) | |
176 | - strcat(tmp, "-ramdisk.lz4"); | |
177 | - else | |
178 | - strcat(tmp, "-ramdisk.gz"); | |
179 | - FILE *r = fopen(tmp, "wb"); | |
180 | - fwrite(ramdisk, header.ramdisk_size, 1, r); | |
181 | - fclose(r); | |
182 | - | |
183 | - total_read += read_padding(f, header.ramdisk_size, pagesize); | |
184 | - | |
185 | - sprintf(tmp, "%s/%s", directory, basename(filename)); | |
186 | - strcat(tmp, "-second"); | |
187 | - FILE *s = fopen(tmp, "wb"); | |
188 | - byte* second = (byte*)malloc(header.second_size); | |
189 | - //printf("Reading second...\n"); | |
190 | - fread(second, header.second_size, 1, f); | |
191 | - total_read += header.second_size; | |
192 | - fwrite(second, header.second_size, 1, r); | |
193 | - fclose(s); | |
194 | - | |
195 | - total_read += read_padding(f, header.second_size, pagesize); | |
196 | - | |
197 | - sprintf(tmp, "%s/%s", directory, basename(filename)); | |
198 | - strcat(tmp, "-dt"); | |
199 | - FILE *d = fopen(tmp, "wb"); | |
200 | - byte* dt = (byte*)malloc(header.dt_size); | |
201 | - //printf("Reading dt...\n"); | |
202 | - fread(dt, header.dt_size, 1, f); | |
203 | - total_read += header.dt_size; | |
204 | - fwrite(dt, header.dt_size, 1, r); | |
205 | - fclose(d); | |
206 | - | |
207 | - fclose(f); | |
208 | - | |
209 | - //printf("Total Read: %d\n", total_read); | |
210 | - return 0; | |
211 | -} |