Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
3e30ccde
Commit
3e30ccde
authored
Sep 17, 2019
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make parsing behaves according to header
Close #1778. Close #1848
parent
baaaf7d5
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
228 additions
and
173 deletions
+228
-173
bootimg.cpp
native/jni/magiskboot/bootimg.cpp
+105
-98
bootimg.h
native/jni/magiskboot/bootimg.h
+123
-75
No files found.
native/jni/magiskboot/bootimg.cpp
View file @
3e30ccde
...
...
@@ -59,6 +59,7 @@ static void restore_buf(int fd, const void *buf, size_t size) {
boot_img
::~
boot_img
()
{
munmap
(
map_addr
,
map_size
);
delete
hdr
;
delete
k_hdr
;
delete
r_hdr
;
delete
b_hdr
;
...
...
@@ -97,13 +98,12 @@ int boot_img::parse_file(const char *image) {
exit
(
UNSUPP_RET
);
}
#define pos_align() pos = do_align(pos, hdr
.
page_size())
#define pos_align() pos = do_align(pos, hdr
->
page_size())
int
boot_img
::
parse_image
(
uint8_t
*
head
)
{
auto
hp
=
(
boot_img_hdr
*
)
head
;
auto
hp
=
reinterpret_cast
<
boot_img_hdr
*>
(
head
)
;
if
(
hp
->
page_size
>=
0x02000000
)
{
fprintf
(
stderr
,
"PXA_BOOT_HDR
\n
"
);
hdr
.
set_hdr
(
new
boot_img_hdr_pxa
());
memcpy
(
*
hdr
,
head
,
sizeof
(
boot_img_hdr_pxa
));
hdr
=
new
dyn_img_pxa
(
head
);
}
else
{
if
(
memcmp
(
hp
->
cmdline
,
NOOKHD_RL_MAGIC
,
10
)
==
0
||
memcmp
(
hp
->
cmdline
,
NOOKHD_GL_MAGIC
,
12
)
==
0
||
...
...
@@ -118,38 +118,43 @@ int boot_img::parse_image(uint8_t *head) {
fprintf
(
stderr
,
"ACCLAIM_LOADER
\n
"
);
head
+=
ACCLAIM_PRE_HEADER_SZ
;
}
hdr
.
set_hdr
(
new
boot_img_hdr
());
memcpy
(
*
hdr
,
head
,
sizeof
(
boot_img_hdr
));
if
(
hp
->
header_version
==
1
)
hdr
=
new
dyn_img_v1
(
head
);
else
if
(
hp
->
header_version
==
2
)
hdr
=
new
dyn_img_v2
(
head
);
else
hdr
=
new
dyn_img_v0
(
head
);
}
size_t
pos
=
hdr
.
page_size
();
size_t
pos
=
hdr
->
page_size
();
flags
|=
hdr
.
id
()[
SHA_DIGEST_SIZE
]
?
SHA256_FLAG
:
0
;
flags
|=
hdr
->
id
()[
SHA_DIGEST_SIZE
]
?
SHA256_FLAG
:
0
;
print_hdr
();
kernel
=
head
+
pos
;
pos
+=
hdr
->
kernel_size
;
pos
+=
hdr
->
kernel_size
()
;
pos_align
();
ramdisk
=
head
+
pos
;
pos
+=
hdr
->
ramdisk_size
;
pos
+=
hdr
->
ramdisk_size
()
;
pos_align
();
second
=
head
+
pos
;
pos
+=
hdr
->
second_size
;
pos
+=
hdr
->
second_size
()
;
pos_align
();
extra
=
head
+
pos
;
pos
+=
hdr
.
extra_size
();
pos
+=
hdr
->
extra_size
();
pos_align
();
recov_dtbo
=
head
+
pos
;
pos
+=
hdr
.
recovery_dtbo_size
();
pos
+=
hdr
->
recovery_dtbo_size
();
pos_align
();
dtb
=
head
+
pos
;
pos
+=
hdr
.
dtb_size
();
pos
+=
hdr
->
dtb_size
();
pos_align
();
if
(
head
+
pos
<
map_addr
+
map_size
)
{
...
...
@@ -166,8 +171,8 @@ int boot_img::parse_image(uint8_t *head) {
find_dtb
();
k_fmt
=
check_fmt
(
kernel
,
hdr
->
kernel_size
);
r_fmt
=
check_fmt
(
ramdisk
,
hdr
->
ramdisk_size
);
k_fmt
=
check_fmt
(
kernel
,
hdr
->
kernel_size
()
);
r_fmt
=
check_fmt
(
ramdisk
,
hdr
->
ramdisk_size
()
);
// Check MTK
if
(
k_fmt
==
MTK
)
{
...
...
@@ -178,8 +183,8 @@ int boot_img::parse_image(uint8_t *head) {
fprintf
(
stderr
,
"KERNEL [%u]
\n
"
,
k_hdr
->
size
);
fprintf
(
stderr
,
"NAME [%s]
\n
"
,
k_hdr
->
name
);
kernel
+=
512
;
hdr
->
kernel_size
-=
512
;
k_fmt
=
check_fmt
(
kernel
,
hdr
->
kernel_size
);
hdr
->
kernel_size
()
-=
512
;
k_fmt
=
check_fmt
(
kernel
,
hdr
->
kernel_size
()
);
}
if
(
r_fmt
==
MTK
)
{
fprintf
(
stderr
,
"MTK_RAMDISK_HDR
\n
"
);
...
...
@@ -189,8 +194,8 @@ int boot_img::parse_image(uint8_t *head) {
fprintf
(
stderr
,
"RAMDISK [%u]
\n
"
,
r_hdr
->
size
);
fprintf
(
stderr
,
"NAME [%s]
\n
"
,
r_hdr
->
name
);
ramdisk
+=
512
;
hdr
->
ramdisk_size
-=
512
;
r_fmt
=
check_fmt
(
ramdisk
,
hdr
->
ramdisk_size
);
hdr
->
ramdisk_size
()
-=
512
;
r_fmt
=
check_fmt
(
ramdisk
,
hdr
->
ramdisk_size
()
);
}
fprintf
(
stderr
,
"KERNEL_FMT [%s]
\n
"
,
fmt2name
[
k_fmt
]);
...
...
@@ -200,25 +205,25 @@ int boot_img::parse_image(uint8_t *head) {
}
void
boot_img
::
find_dtb
()
{
for
(
uint32_t
i
=
0
;
i
<
hdr
->
kernel_size
;
++
i
)
{
for
(
uint32_t
i
=
0
;
i
<
hdr
->
kernel_size
()
;
++
i
)
{
auto
fdt_hdr
=
reinterpret_cast
<
fdt_header
*>
(
kernel
+
i
);
if
(
fdt32_to_cpu
(
fdt_hdr
->
magic
)
!=
FDT_MAGIC
)
continue
;
// Check that fdt_header.totalsize does not overflow kernel image size
uint32_t
totalsize
=
fdt32_to_cpu
(
fdt_hdr
->
totalsize
);
if
(
totalsize
>
hdr
->
kernel_size
-
i
)
{
if
(
totalsize
>
hdr
->
kernel_size
()
-
i
)
{
fprintf
(
stderr
,
"Invalid DTB detection at 0x%x: size (%u) > remaining (%u)
\n
"
,
i
,
totalsize
,
hdr
->
kernel_size
-
i
);
i
,
totalsize
,
hdr
->
kernel_size
()
-
i
);
continue
;
}
// Check that fdt_header.off_dt_struct does not overflow kernel image size
uint32_t
off_dt_struct
=
fdt32_to_cpu
(
fdt_hdr
->
off_dt_struct
);
if
(
off_dt_struct
>
hdr
->
kernel_size
-
i
)
{
if
(
off_dt_struct
>
hdr
->
kernel_size
()
-
i
)
{
fprintf
(
stderr
,
"Invalid DTB detection at 0x%x: "
"struct offset (%u) > remaining (%u)
\n
"
,
i
,
off_dt_struct
,
hdr
->
kernel_size
-
i
);
i
,
off_dt_struct
,
hdr
->
kernel_size
()
-
i
);
continue
;
}
...
...
@@ -231,23 +236,23 @@ void boot_img::find_dtb() {
}
kernel_dtb
=
kernel
+
i
;
kernel_dt_size
=
hdr
->
kernel_size
-
i
;
hdr
->
kernel_size
=
i
;
kernel_dt_size
=
hdr
->
kernel_size
()
-
i
;
hdr
->
kernel_size
()
=
i
;
fprintf
(
stderr
,
"KERNEL_DTB [%u]
\n
"
,
kernel_dt_size
);
break
;
}
}
void
boot_img
::
print_hdr
()
{
fprintf
(
stderr
,
"HEADER_VER [%u]
\n
"
,
hdr
.
header_version
());
fprintf
(
stderr
,
"KERNEL_SZ [%u]
\n
"
,
hdr
->
kernel_size
);
fprintf
(
stderr
,
"RAMDISK_SZ [%u]
\n
"
,
hdr
->
ramdisk_size
);
fprintf
(
stderr
,
"SECOND_SZ [%u]
\n
"
,
hdr
->
second_size
);
fprintf
(
stderr
,
"EXTRA_SZ [%u]
\n
"
,
hdr
.
extra_size
());
fprintf
(
stderr
,
"RECOV_DTBO_SZ [%u]
\n
"
,
hdr
.
recovery_dtbo_size
());
fprintf
(
stderr
,
"DTB [%u]
\n
"
,
hdr
.
dtb_size
());
uint32_t
ver
=
hdr
.
os_version
();
fprintf
(
stderr
,
"HEADER_VER [%u]
\n
"
,
hdr
->
header_version
());
fprintf
(
stderr
,
"KERNEL_SZ [%u]
\n
"
,
hdr
->
kernel_size
()
);
fprintf
(
stderr
,
"RAMDISK_SZ [%u]
\n
"
,
hdr
->
ramdisk_size
()
);
fprintf
(
stderr
,
"SECOND_SZ [%u]
\n
"
,
hdr
->
second_size
()
);
fprintf
(
stderr
,
"EXTRA_SZ [%u]
\n
"
,
hdr
->
extra_size
());
fprintf
(
stderr
,
"RECOV_DTBO_SZ [%u]
\n
"
,
hdr
->
recovery_dtbo_size
());
fprintf
(
stderr
,
"DTB [%u]
\n
"
,
hdr
->
dtb_size
());
uint32_t
ver
=
hdr
->
os_version
();
if
(
ver
)
{
int
a
,
b
,
c
,
y
,
m
=
0
;
int
version
,
patch_level
;
...
...
@@ -264,12 +269,12 @@ void boot_img::print_hdr() {
fprintf
(
stderr
,
"OS_PATCH_LEVEL [%d-%02d]
\n
"
,
y
,
m
);
}
fprintf
(
stderr
,
"PAGESIZE [%u]
\n
"
,
hdr
.
page_size
());
fprintf
(
stderr
,
"NAME [%s]
\n
"
,
hdr
.
name
());
fprintf
(
stderr
,
"CMDLINE [%.512s%.1024s]
\n
"
,
hdr
.
cmdline
(),
hdr
.
extra_cmdline
());
fprintf
(
stderr
,
"PAGESIZE [%u]
\n
"
,
hdr
->
page_size
());
fprintf
(
stderr
,
"NAME [%s]
\n
"
,
hdr
->
name
());
fprintf
(
stderr
,
"CMDLINE [%.512s%.1024s]
\n
"
,
hdr
->
cmdline
(),
hdr
->
extra_cmdline
());
fprintf
(
stderr
,
"CHECKSUM ["
);
for
(
int
i
=
0
;
hdr
.
id
()[
i
];
++
i
)
fprintf
(
stderr
,
"%02x"
,
hdr
.
id
()[
i
]);
for
(
int
i
=
0
;
hdr
->
id
()[
i
];
++
i
)
fprintf
(
stderr
,
"%02x"
,
hdr
->
id
()[
i
]);
fprintf
(
stderr
,
"]
\n
"
);
}
...
...
@@ -280,10 +285,10 @@ int unpack(const char *image, bool hdr) {
if
(
hdr
)
{
FILE
*
fp
=
xfopen
(
HEADER_FILE
,
"w"
);
fprintf
(
fp
,
"pagesize=%u
\n
"
,
boot
.
hdr
.
page_size
());
fprintf
(
fp
,
"name=%s
\n
"
,
boot
.
hdr
.
name
());
fprintf
(
fp
,
"cmdline=%.512s%.1024s
\n
"
,
boot
.
hdr
.
cmdline
(),
boot
.
hdr
.
extra_cmdline
());
uint32_t
ver
=
boot
.
hdr
.
os_version
();
fprintf
(
fp
,
"pagesize=%u
\n
"
,
boot
.
hdr
->
page_size
());
fprintf
(
fp
,
"name=%s
\n
"
,
boot
.
hdr
->
name
());
fprintf
(
fp
,
"cmdline=%.512s%.1024s
\n
"
,
boot
.
hdr
->
cmdline
(),
boot
.
hdr
->
extra_cmdline
());
uint32_t
ver
=
boot
.
hdr
->
os_version
();
if
(
ver
)
{
int
a
,
b
,
c
,
y
,
m
=
0
;
int
version
,
patch_level
;
...
...
@@ -305,11 +310,11 @@ int unpack(const char *image, bool hdr) {
// Dump kernel
if
(
COMPRESSED
(
boot
.
k_fmt
))
{
fd
=
creat
(
KERNEL_FILE
,
0644
);
decompress
(
boot
.
k_fmt
,
fd
,
boot
.
kernel
,
boot
.
hdr
->
kernel_size
);
decompress
(
boot
.
k_fmt
,
fd
,
boot
.
kernel
,
boot
.
hdr
->
kernel_size
()
);
close
(
fd
);
}
else
{
fprintf
(
stderr
,
"Kernel is uncompressed or not a supported compressed type!
\n
"
);
dump
(
boot
.
kernel
,
boot
.
hdr
->
kernel_size
,
KERNEL_FILE
);
dump
(
boot
.
kernel
,
boot
.
hdr
->
kernel_size
()
,
KERNEL_FILE
);
}
// Dump dtb
...
...
@@ -318,28 +323,30 @@ int unpack(const char *image, bool hdr) {
// Dump ramdisk
if
(
COMPRESSED
(
boot
.
r_fmt
))
{
fd
=
creat
(
RAMDISK_FILE
,
0644
);
decompress
(
boot
.
r_fmt
,
fd
,
boot
.
ramdisk
,
boot
.
hdr
->
ramdisk_size
);
decompress
(
boot
.
r_fmt
,
fd
,
boot
.
ramdisk
,
boot
.
hdr
->
ramdisk_size
()
);
close
(
fd
);
}
else
{
fprintf
(
stderr
,
"Ramdisk is uncompressed or not a supported compressed type!
\n
"
);
dump
(
boot
.
ramdisk
,
boot
.
hdr
->
ramdisk_size
,
RAMDISK_FILE
);
dump
(
boot
.
ramdisk
,
boot
.
hdr
->
ramdisk_size
()
,
RAMDISK_FILE
);
}
// Dump second
dump
(
boot
.
second
,
boot
.
hdr
->
second_size
,
SECOND_FILE
);
dump
(
boot
.
second
,
boot
.
hdr
->
second_size
()
,
SECOND_FILE
);
// Dump extra
dump
(
boot
.
extra
,
boot
.
hdr
.
extra_size
(),
EXTRA_FILE
);
dump
(
boot
.
extra
,
boot
.
hdr
->
extra_size
(),
EXTRA_FILE
);
// Dump recovery_dtbo
dump
(
boot
.
recov_dtbo
,
boot
.
hdr
.
recovery_dtbo_size
(),
RECV_DTBO_FILE
);
dump
(
boot
.
recov_dtbo
,
boot
.
hdr
->
recovery_dtbo_size
(),
RECV_DTBO_FILE
);
// Dump dtb
dump
(
boot
.
dtb
,
boot
.
hdr
.
dtb_size
(),
DTB_FILE
);
dump
(
boot
.
dtb
,
boot
.
hdr
->
dtb_size
(),
DTB_FILE
);
return
ret
;
}
#define file_align() write_zero(fd, align_off(lseek(fd, 0, SEEK_CUR) - header_off, boot.hdr.page_size()))
#define file_align() \
write_zero(fd, align_off(lseek(fd, 0, SEEK_CUR) - header_off, boot.hdr->page_size()))
void
repack
(
const
char
*
orig_image
,
const
char
*
out_image
,
bool
force_nocomp
)
{
boot_img
boot
{};
...
...
@@ -349,10 +356,10 @@ void repack(const char* orig_image, const char* out_image, bool force_nocomp) {
boot
.
parse_file
(
orig_image
);
// Reset sizes
boot
.
hdr
->
kernel_size
=
0
;
boot
.
hdr
->
ramdisk_size
=
0
;
boot
.
hdr
->
second_size
=
0
;
boot
.
hdr
.
dtb_size
()
=
0
;
boot
.
hdr
->
kernel_size
()
=
0
;
boot
.
hdr
->
ramdisk_size
()
=
0
;
boot
.
hdr
->
second_size
()
=
0
;
boot
.
hdr
->
dtb_size
()
=
0
;
boot
.
kernel_dt_size
=
0
;
fprintf
(
stderr
,
"Repack to boot image: [%s]
\n
"
,
out_image
);
...
...
@@ -376,30 +383,30 @@ void repack(const char* orig_image, const char* out_image, bool force_nocomp) {
if
(
access
(
HEADER_FILE
,
R_OK
)
==
0
)
{
parse_prop_file
(
HEADER_FILE
,
[
&
](
string_view
key
,
string_view
value
)
->
bool
{
if
(
key
==
"page_size"
)
{
boot
.
hdr
.
page_size
()
=
parse_int
(
value
);
boot
.
hdr
->
page_size
()
=
parse_int
(
value
);
}
else
if
(
key
==
"name"
)
{
memset
(
boot
.
hdr
.
name
(),
0
,
16
);
memcpy
(
boot
.
hdr
.
name
(),
value
.
data
(),
value
.
length
()
>
15
?
15
:
value
.
length
());
memset
(
boot
.
hdr
->
name
(),
0
,
16
);
memcpy
(
boot
.
hdr
->
name
(),
value
.
data
(),
value
.
length
()
>
15
?
15
:
value
.
length
());
}
else
if
(
key
==
"cmdline"
)
{
memset
(
boot
.
hdr
.
cmdline
(),
0
,
512
);
memset
(
boot
.
hdr
.
extra_cmdline
(),
0
,
1024
);
memset
(
boot
.
hdr
->
cmdline
(),
0
,
512
);
memset
(
boot
.
hdr
->
extra_cmdline
(),
0
,
1024
);
if
(
value
.
length
()
>
512
)
{
memcpy
(
boot
.
hdr
.
cmdline
(),
value
.
data
(),
512
);
memcpy
(
boot
.
hdr
.
extra_cmdline
(),
&
value
[
512
],
value
.
length
()
-
511
);
memcpy
(
boot
.
hdr
->
cmdline
(),
value
.
data
(),
512
);
memcpy
(
boot
.
hdr
->
extra_cmdline
(),
&
value
[
512
],
value
.
length
()
-
511
);
}
else
{
memcpy
(
boot
.
hdr
.
cmdline
(),
value
.
data
(),
value
.
length
());
memcpy
(
boot
.
hdr
->
cmdline
(),
value
.
data
(),
value
.
length
());
}
}
else
if
(
key
==
"os_version"
)
{
int
patch_level
=
boot
.
hdr
.
os_version
()
&
0x7ff
;
int
patch_level
=
boot
.
hdr
->
os_version
()
&
0x7ff
;
int
a
,
b
,
c
;
sscanf
(
value
.
data
(),
"%d.%d.%d"
,
&
a
,
&
b
,
&
c
);
boot
.
hdr
.
os_version
()
=
(((
a
<<
14
)
|
(
b
<<
7
)
|
c
)
<<
11
)
|
patch_level
;
boot
.
hdr
->
os_version
()
=
(((
a
<<
14
)
|
(
b
<<
7
)
|
c
)
<<
11
)
|
patch_level
;
}
else
if
(
key
==
"os_patch_level"
)
{
int
os_version
=
boot
.
hdr
.
os_version
()
>>
11
;
int
os_version
=
boot
.
hdr
->
os_version
()
>>
11
;
int
y
,
m
;
sscanf
(
value
.
data
(),
"%d-%d"
,
&
y
,
&
m
);
y
-=
2000
;
boot
.
hdr
.
os_version
()
=
(
os_version
<<
11
)
|
(
y
<<
4
)
|
m
;
boot
.
hdr
->
os_version
()
=
(
os_version
<<
11
)
|
(
y
<<
4
)
|
m
;
}
return
true
;
});
...
...
@@ -407,7 +414,7 @@ void repack(const char* orig_image, const char* out_image, bool force_nocomp) {
// Skip a page for header
header_off
=
lseek
(
fd
,
0
,
SEEK_CUR
);
write_zero
(
fd
,
boot
.
hdr
.
page_size
());
write_zero
(
fd
,
boot
.
hdr
->
page_size
());
// kernel
kernel_off
=
lseek
(
fd
,
0
,
SEEK_CUR
);
...
...
@@ -420,16 +427,16 @@ void repack(const char* orig_image, const char* out_image, bool force_nocomp) {
void
*
raw_buf
;
mmap_ro
(
KERNEL_FILE
,
raw_buf
,
raw_size
);
if
(
!
COMPRESSED_ANY
(
check_fmt
(
raw_buf
,
raw_size
))
&&
COMPRESSED
(
boot
.
k_fmt
))
{
boot
.
hdr
->
kernel_size
=
compress
(
boot
.
k_fmt
,
fd
,
raw_buf
,
raw_size
);
boot
.
hdr
->
kernel_size
()
=
compress
(
boot
.
k_fmt
,
fd
,
raw_buf
,
raw_size
);
}
else
{
boot
.
hdr
->
kernel_size
=
write
(
fd
,
raw_buf
,
raw_size
);
boot
.
hdr
->
kernel_size
()
=
write
(
fd
,
raw_buf
,
raw_size
);
}
munmap
(
raw_buf
,
raw_size
);
}
// kernel dtb
if
(
access
(
KER_DTB_FILE
,
R_OK
)
==
0
)
boot
.
hdr
->
kernel_size
+=
restore
(
KER_DTB_FILE
,
fd
);
boot
.
hdr
->
kernel_size
()
+=
restore
(
KER_DTB_FILE
,
fd
);
file_align
();
// ramdisk
...
...
@@ -443,9 +450,9 @@ void repack(const char* orig_image, const char* out_image, bool force_nocomp) {
void
*
raw_buf
;
mmap_ro
(
RAMDISK_FILE
,
raw_buf
,
raw_size
);
if
(
!
COMPRESSED_ANY
(
check_fmt
(
raw_buf
,
raw_size
))
&&
COMPRESSED
(
boot
.
r_fmt
)
&&
!
force_nocomp
)
{
boot
.
hdr
->
ramdisk_size
=
compress
(
boot
.
r_fmt
,
fd
,
raw_buf
,
raw_size
);
boot
.
hdr
->
ramdisk_size
()
=
compress
(
boot
.
r_fmt
,
fd
,
raw_buf
,
raw_size
);
}
else
{
boot
.
hdr
->
ramdisk_size
=
write
(
fd
,
raw_buf
,
raw_size
);
boot
.
hdr
->
ramdisk_size
()
=
write
(
fd
,
raw_buf
,
raw_size
);
}
munmap
(
raw_buf
,
raw_size
);
file_align
();
...
...
@@ -454,28 +461,28 @@ void repack(const char* orig_image, const char* out_image, bool force_nocomp) {
// second
second_off
=
lseek
(
fd
,
0
,
SEEK_CUR
);
if
(
access
(
SECOND_FILE
,
R_OK
)
==
0
)
{
boot
.
hdr
->
second_size
=
restore
(
SECOND_FILE
,
fd
);
boot
.
hdr
->
second_size
()
=
restore
(
SECOND_FILE
,
fd
);
file_align
();
}
// extra
extra_off
=
lseek
(
fd
,
0
,
SEEK_CUR
);
if
(
access
(
EXTRA_FILE
,
R_OK
)
==
0
)
{
boot
.
hdr
.
extra_size
()
=
restore
(
EXTRA_FILE
,
fd
);
boot
.
hdr
->
extra_size
()
=
restore
(
EXTRA_FILE
,
fd
);
file_align
();
}
// recovery_dtbo
if
(
access
(
RECV_DTBO_FILE
,
R_OK
)
==
0
)
{
boot
.
hdr
.
recovery_dtbo_offset
()
=
lseek
(
fd
,
0
,
SEEK_CUR
);
boot
.
hdr
.
recovery_dtbo_size
()
=
restore
(
RECV_DTBO_FILE
,
fd
);
boot
.
hdr
->
recovery_dtbo_offset
()
=
lseek
(
fd
,
0
,
SEEK_CUR
);
boot
.
hdr
->
recovery_dtbo_size
()
=
restore
(
RECV_DTBO_FILE
,
fd
);
file_align
();
}
// dtb
dtb_off
=
lseek
(
fd
,
0
,
SEEK_CUR
);
if
(
access
(
DTB_FILE
,
R_OK
)
==
0
)
{
boot
.
hdr
.
dtb_size
()
=
restore
(
DTB_FILE
,
fd
);
boot
.
hdr
->
dtb_size
()
=
restore
(
DTB_FILE
,
fd
);
file_align
();
}
...
...
@@ -495,56 +502,56 @@ void repack(const char* orig_image, const char* out_image, bool force_nocomp) {
// MTK headers
if
(
boot
.
flags
&
MTK_KERNEL
)
{
boot
.
k_hdr
->
size
=
boot
.
hdr
->
kernel_size
;
boot
.
hdr
->
kernel_size
+=
512
;
boot
.
k_hdr
->
size
=
boot
.
hdr
->
kernel_size
()
;
boot
.
hdr
->
kernel_size
()
+=
512
;
memcpy
(
boot
.
map_addr
+
kernel_off
,
boot
.
k_hdr
,
sizeof
(
mtk_hdr
));
}
if
(
boot
.
flags
&
MTK_RAMDISK
)
{
boot
.
r_hdr
->
size
=
boot
.
hdr
->
ramdisk_size
;
boot
.
hdr
->
ramdisk_size
+=
512
;
boot
.
r_hdr
->
size
=
boot
.
hdr
->
ramdisk_size
()
;
boot
.
hdr
->
ramdisk_size
()
+=
512
;
memcpy
(
boot
.
map_addr
+
ramdisk_off
,
boot
.
r_hdr
,
sizeof
(
mtk_hdr
));
}
// Update checksum
HASH_CTX
ctx
;
(
boot
.
flags
&
SHA256_FLAG
)
?
SHA256_init
(
&
ctx
)
:
SHA_init
(
&
ctx
);
uint32_t
size
=
boot
.
hdr
->
kernel_size
;
uint32_t
size
=
boot
.
hdr
->
kernel_size
()
;
HASH_update
(
&
ctx
,
boot
.
map_addr
+
kernel_off
,
size
);
HASH_update
(
&
ctx
,
&
size
,
sizeof
(
size
));
size
=
boot
.
hdr
->
ramdisk_size
;
size
=
boot
.
hdr
->
ramdisk_size
()
;
HASH_update
(
&
ctx
,
boot
.
map_addr
+
ramdisk_off
,
size
);
HASH_update
(
&
ctx
,
&
size
,
sizeof
(
size
));
size
=
boot
.
hdr
->
second_size
;
size
=
boot
.
hdr
->
second_size
()
;
HASH_update
(
&
ctx
,
boot
.
map_addr
+
second_off
,
size
);
HASH_update
(
&
ctx
,
&
size
,
sizeof
(
size
));
size
=
boot
.
hdr
.
extra_size
();
size
=
boot
.
hdr
->
extra_size
();
if
(
size
)
{
HASH_update
(
&
ctx
,
boot
.
map_addr
+
extra_off
,
size
);
HASH_update
(
&
ctx
,
&
size
,
sizeof
(
size
));
}
if
(
boot
.
hdr
.
header_version
())
{
size
=
boot
.
hdr
.
recovery_dtbo_size
();
HASH_update
(
&
ctx
,
boot
.
map_addr
+
boot
.
hdr
.
recovery_dtbo_offset
(),
size
);
if
(
boot
.
hdr
->
header_version
())
{
size
=
boot
.
hdr
->
recovery_dtbo_size
();
HASH_update
(
&
ctx
,
boot
.
map_addr
+
boot
.
hdr
->
recovery_dtbo_offset
(),
size
);
HASH_update
(
&
ctx
,
&
size
,
sizeof
(
size
));
size
=
boot
.
hdr
.
dtb_size
();
size
=
boot
.
hdr
->
dtb_size
();
if
(
size
)
{
HASH_update
(
&
ctx
,
boot
.
map_addr
+
dtb_off
,
size
);
HASH_update
(
&
ctx
,
&
size
,
sizeof
(
size
));
}
}
memset
(
boot
.
hdr
.
id
(),
0
,
32
);
memcpy
(
boot
.
hdr
.
id
(),
HASH_final
(
&
ctx
),
memset
(
boot
.
hdr
->
id
(),
0
,
32
);
memcpy
(
boot
.
hdr
->
id
(),
HASH_final
(
&
ctx
),
(
boot
.
flags
&
SHA256_FLAG
)
?
SHA256_DIGEST_SIZE
:
SHA_DIGEST_SIZE
);
// Print new image info
boot
.
print_hdr
();
// Try to fix the header
if
(
boot
.
hdr
.
header_version
()
&&
boot
.
hdr
.
header_size
()
==
0
)
boot
.
hdr
.
header_size
()
=
sizeof
(
boot_img_hdr
);
if
(
boot
.
hdr
->
header_version
()
&&
boot
.
hdr
->
header_size
()
==
0
)
boot
.
hdr
->
header_size
()
=
sizeof
(
boot_img_hdr
);
// Main header
memcpy
(
boot
.
map_addr
+
header_off
,
*
boot
.
hdr
,
boot
.
hdr
.
hdr_size
());
memcpy
(
boot
.
map_addr
+
header_off
,
*
*
boot
.
hdr
,
boot
.
hdr
->
hdr_size
());
if
(
boot
.
flags
&
DHTB_FLAG
)
{
// DHTB header
...
...
native/jni/magiskboot/bootimg.h
View file @
3e30ccde
#pragma once
#include <stdint.h>
#include <utility>
#include "format.h"
struct
boot_img_hdr_base
{
...
...
@@ -55,7 +56,7 @@ struct boot_img_hdr_v2 : public boot_img_hdr_v1 {
uint64_t
dtb_addr
;
/* physical load address for DTB image */
}
__attribute__
((
packed
));
// Default to hdr v
1
// Default to hdr v
2
typedef
boot_img_hdr_v2
boot_img_hdr
;
// Special Samsung header
...
...
@@ -138,107 +139,154 @@ struct blob_hdr {
uint32_t
version
;
/* 0x00000001 */
}
__attribute__
((
packed
));
// Flags
#define MTK_KERNEL 1 << 1
#define MTK_RAMDISK 1 << 2
#define CHROMEOS_FLAG 1 << 3
#define DHTB_FLAG 1 << 4
#define SEANDROID_FLAG 1 << 5
#define LG_BUMP_FLAG 1 << 6
#define SHA256_FLAG 1 << 7
#define BLOB_FLAG 1 << 8
#define NOOKHD_FLAG 1 << 9
#define ACCLAIM_FLAG 1 << 10
#define drct_var(name) \
auto &name() { return img_hdr->name; }
#define decl_var(name, len) \
virtual uint##len##_t &name() { j##len = 0; return j##len; }
#define decl_val(name, type) \
virtual type name() { return 0; }
struct
dyn_img_hdr
{
#define dyn_access(x) (pxa ? hdr_pxa->x : v2_hdr->x)
#define dyn_get(name, type) \
type name() const { return dyn_access(name); }
#define dyn_ref(name, type) \
type &name() { return dyn_access(name); }
#define v2_ref(name, type, alt) \
type &name() { if (pxa) { alt = 0; return alt; } return v2_hdr->name; }
dyn_ref
(
page_size
,
uint32_t
);
dyn_get
(
name
,
char
*
);
dyn_get
(
cmdline
,
char
*
);
dyn_get
(
id
,
char
*
);
dyn_get
(
extra_cmdline
,
char
*
);
v2_ref
(
os_version
,
uint32_t
,
j32
);
v2_ref
(
recovery_dtbo_size
,
uint32_t
,
j32
);
v2_ref
(
recovery_dtbo_offset
,
uint64_t
,
j64
);
v2_ref
(
header_size
,
uint32_t
,
j32
);
v2_ref
(
dtb_size
,
uint32_t
,
j32
);
dyn_img_hdr
()
:
pxa
(
false
),
img_hdr
(
nullptr
)
{}
~
dyn_img_hdr
()
{
if
(
pxa
)
delete
hdr_pxa
;
else
delete
v2_hdr
;
// Direct entries
drct_var
(
kernel_size
)
drct_var
(
ramdisk_size
)
drct_var
(
second_size
)
// Standard entries
decl_var
(
page_size
,
32
)
decl_val
(
header_version
,
uint32_t
)
decl_var
(
extra_size
,
32
)
decl_var
(
os_version
,
32
)
decl_val
(
name
,
char
*
)
decl_val
(
cmdline
,
char
*
)
decl_val
(
id
,
char
*
)
decl_val
(
extra_cmdline
,
char
*
)
// v1/v2 specific
decl_var
(
recovery_dtbo_size
,
32
)
decl_var
(
recovery_dtbo_offset
,
64
)
decl_var
(
header_size
,
32
)
decl_var
(
dtb_size
,
32
)
virtual
~
dyn_img_hdr
()
{
free
(
raw
);
}
uint32_t
header_version
()
{
// There won't be v4 header any time soon...
// If larger than 4, assume this field will be treated as extra_size
return
pxa
||
v2_hdr
->
header_version
>
4
?
0
:
v2_hdr
->
header_version
;
virtual
size_t
hdr_size
()
=
0
;
boot_img_hdr_base
*
const
&
operator
*
()
const
{
return
img_hdr
;
}
uint32_t
&
extra_size
()
{
// If header version > 0, we should treat this field as header_version
if
(
header_version
())
{
j32
=
0
;
return
j32
;
}
return
dyn_access
(
extra_size
);
protected
:
union
{
/* Main header could be either AOSP or PXA,
* but both of them are base headers. */
boot_img_hdr_base
*
img_hdr
;
/* Common base header */
boot_img_hdr_v2
*
v2_hdr
;
/* AOSP v2 header */
boot_img_hdr_pxa
*
hdr_pxa
;
/* Samsung PXA header */
void
*
raw
;
/* Raw pointer */
};
private
:
// Junk for references
static
uint32_t
j32
;
static
uint64_t
j64
;
};
#undef drct_var
#undef decl_var
#undef decl_val
#define impl_val(name) \
decltype(std::declval<dyn_img_hdr>().name()) name() override { return hdr_pxa->name; }
struct
dyn_img_pxa
:
public
dyn_img_hdr
{
impl_val
(
extra_size
)
impl_val
(
page_size
)
impl_val
(
name
)
impl_val
(
cmdline
)
impl_val
(
id
)
impl_val
(
extra_cmdline
)
dyn_img_pxa
(
void
*
ptr
)
{
raw
=
xmalloc
(
sizeof
(
boot_img_hdr_pxa
));
memcpy
(
raw
,
ptr
,
sizeof
(
boot_img_hdr_pxa
));
}
size_t
hdr_size
()
{
return
pxa
?
sizeof
(
boot_img_hdr_pxa
)
:
sizeof
(
boot_img_hdr
);
size_t
hdr_size
()
override
{
return
sizeof
(
boot_img_hdr_pxa
);
}
};
#undef impl_val
#define impl_val(name) \
decltype(std::declval<dyn_img_hdr>().name()) name() override { return v2_hdr->name; }
struct
dyn_img_v0
:
public
dyn_img_hdr
{
void
set_hdr
(
boot_img_hdr
*
h
)
{
v2_hdr
=
h
;
impl_val
(
page_size
)
impl_val
(
extra_size
)
impl_val
(
os_version
)
impl_val
(
name
)
impl_val
(
cmdline
)
impl_val
(
id
)
impl_val
(
extra_cmdline
)
dyn_img_v0
(
void
*
ptr
)
{
raw
=
xmalloc
(
sizeof
(
boot_img_hdr_v2
));
memcpy
(
raw
,
ptr
,
sizeof
(
boot_img_hdr_v2
));
}
void
set_hdr
(
boot_img_hdr_pxa
*
h
)
{
hdr_pxa
=
h
;
pxa
=
true
;
size_t
hdr_size
()
override
{
return
sizeof
(
boot_img_hdr_v2
);
}
};
boot_img_hdr_base
*
operator
->
()
const
{
return
img_hdr
;
};
struct
dyn_img_v1
:
public
dyn_img_v0
{
boot_img_hdr_base
*
const
&
operator
*
()
const
{
return
img_hdr
;
impl_val
(
header_version
)
impl_val
(
recovery_dtbo_size
)
impl_val
(
recovery_dtbo_offset
)
impl_val
(
header_size
)
dyn_img_v1
(
void
*
ptr
)
:
dyn_img_v0
(
ptr
)
{}
uint32_t
&
extra_size
()
override
{
return
dyn_img_hdr
::
extra_size
();
}
};
private
:
bool
pxa
;
union
{
/* Main header could be either AOSP or PXA,
* but both of them is a base header.
* Same address can be interpreted in 3 ways */
boot_img_hdr_base
*
img_hdr
;
/* Common base header */
boot_img_hdr
*
v2_hdr
;
/* AOSP v2 header */
boot_img_hdr_pxa
*
hdr_pxa
;
/* Samsung PXA header */
};
struct
dyn_img_v2
:
public
dyn_img_v1
{
static
uint32_t
j32
;
static
uint64_t
j64
;
impl_val
(
dtb_size
)
dyn_img_v2
(
void
*
ptr
)
:
dyn_img_v1
(
ptr
)
{}
};
#undef impl_val
// Flags
#define MTK_KERNEL 1 << 1
#define MTK_RAMDISK 1 << 2
#define CHROMEOS_FLAG 1 << 3
#define DHTB_FLAG 1 << 4
#define SEANDROID_FLAG 1 << 5
#define LG_BUMP_FLAG 1 << 6
#define SHA256_FLAG 1 << 7
#define BLOB_FLAG 1 << 8
#define NOOKHD_FLAG 1 << 9
#define ACCLAIM_FLAG 1 << 10
struct
boot_img
{
// Memory map of the whole image
uint8_t
*
map_addr
;
size_t
map_size
;
// Headers
dyn_img_hdr
hdr
;
/* Android image header */
dyn_img_hdr
*
hdr
;
/* Android image header */
mtk_hdr
*
k_hdr
;
/* MTK kernel header */
mtk_hdr
*
r_hdr
;
/* MTK ramdisk header */
blob_hdr
*
b_hdr
;
/* Tegra blob header */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment