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
7ef0746c
Commit
7ef0746c
authored
Feb 24, 2017
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add ELF support
parent
6f609f0d
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
527 additions
and
157 deletions
+527
-157
Android.mk
jni/bootimgtools/Android.mk
+1
-1
bootimg.h
jni/bootimgtools/bootimg.h
+12
-0
elf.h
jni/bootimgtools/elf.h
+149
-0
main.c
jni/bootimgtools/main.c
+29
-23
parseimg.c
jni/bootimgtools/parseimg.c
+232
-0
repack.c
jni/bootimgtools/repack.c
+52
-62
unpack.c
jni/bootimgtools/unpack.c
+52
-71
No files found.
jni/bootimgtools/Android.mk
View file @
7ef0746c
...
...
@@ -3,6 +3,6 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := bootimgtools
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := main.c unpack.c repack.c hexpatch.c
LOCAL_SRC_FILES := main.c unpack.c repack.c hexpatch.c
parseimg.c
LOCAL_CFLAGS += -std=gnu11
include $(BUILD_EXECUTABLE)
jni/bootimgtools/bootimg.h
View file @
7ef0746c
...
...
@@ -93,8 +93,20 @@ struct boot_img_hdr
** else: jump to kernel_addr
*/
/* Self defined stuffs */
// Global pointers to mmap
unsigned
char
*
base
,
*
kernel
,
*
ramdisk
,
*
second
,
*
dtb
;
// Parsed header
boot_img_hdr
hdr
;
int
unpack
(
const
char
*
image
);
int
repack
(
const
char
*
image
);
int
hexpatch
(
char
*
image
,
char
*
from
,
char
*
to
);
void
error
(
int
rc
,
const
char
*
msg
,
...);
void
print_header
();
void
parse_elf
();
void
parse_aosp
();
#endif
jni/bootimgtools/elf.h
0 → 100644
View file @
7ef0746c
#ifndef _ELF_H_
#define _ELF_H_
#include <stdint.h>
/*
** ELF structure
**
** +-----------------+
** | ELF magic | | 4 bytes
** +------------ +
** | ELF class | | 1 byte
** +------------ +
** | ELF header |
** +-----------------+
** ~
** +-----------------+
** | program header | kernel info
** +-----------------+
** | program header | ramdisk info
** +-----------------+
** | program header | dtb info
** +-----------------+
** ~
** +-----------------+
** | section header | cmdline info
** +-----------------+
** ~
** +-----------------+
** | |
** | Data |
** | |
** +-----------------+
*/
typedef
uint32_t
elf32_addr
;
typedef
uint16_t
elf32_half
;
typedef
uint32_t
elf32_off
;
typedef
uint32_t
elf32_word
;
typedef
uint64_t
elf64_addr
;
typedef
uint16_t
elf64_half
;
typedef
uint64_t
elf64_off
;
typedef
uint32_t
elf64_word
;
typedef
uint64_t
elf64_xword
;
#define ELF_MAGIC "\x7f""ELF"
#define ELF_MAGIC_SIZE 4
#define EI_CLASS 4
#define EI_DATA 5
#define EI_VERSION 6
#define EI_OSABI 7
#define EI_PAD 8
#define ELFCLASSNONE 0
#define ELFCLASS32 1
#define ELFCLASS64 2
#define ELFCLASSNUM 3
#define ET_EXEC 2
#define EM_ARM 40
#define EI_NIDENT 16
typedef
struct
elf32_ehdr
{
unsigned
char
e_ident
[
EI_NIDENT
];
elf32_half
e_type
;
elf32_half
e_machine
;
elf32_word
e_version
;
elf32_addr
e_entry
;
/* Entry point */
elf32_off
e_phoff
;
elf32_off
e_shoff
;
elf32_word
e_flags
;
elf32_half
e_ehsize
;
elf32_half
e_phentsize
;
elf32_half
e_phnum
;
elf32_half
e_shentsize
;
elf32_half
e_shnum
;
elf32_half
e_shstrndx
;
}
elf32_ehdr
;
typedef
struct
elf64_ehdr
{
unsigned
char
e_ident
[
EI_NIDENT
];
/* ELF "magic number" */
elf64_half
e_type
;
elf64_half
e_machine
;
elf64_word
e_version
;
elf64_addr
e_entry
;
/* Entry point virtual address */
elf64_off
e_phoff
;
/* Program header table file offset */
elf64_off
e_shoff
;
/* Section header table file offset */
elf64_word
e_flags
;
elf64_half
e_ehsize
;
elf64_half
e_phentsize
;
elf64_half
e_phnum
;
elf64_half
e_shentsize
;
elf64_half
e_shnum
;
elf64_half
e_shstrndx
;
}
elf64_ehdr
;
typedef
struct
elf32_phdr
{
elf32_word
p_type
;
elf32_off
p_offset
;
elf32_addr
p_vaddr
;
elf32_addr
p_paddr
;
elf32_word
p_filesz
;
elf32_word
p_memsz
;
elf32_word
p_flags
;
elf32_word
p_align
;
}
elf32_phdr
;
typedef
struct
elf64_phdr
{
elf64_word
p_type
;
elf64_word
p_flags
;
elf64_off
p_offset
;
/* Segment file offset */
elf64_addr
p_vaddr
;
/* Segment virtual address */
elf64_addr
p_paddr
;
/* Segment physical address */
elf64_xword
p_filesz
;
/* Segment size in file */
elf64_xword
p_memsz
;
/* Segment size in memory */
elf64_xword
p_align
;
/* Segment alignment, file & memory */
}
elf64_phdr
;
typedef
struct
elf32_shdr
{
elf32_word
s_name
;
elf32_word
s_type
;
elf32_word
s_flags
;
elf32_addr
s_addr
;
elf32_off
s_offset
;
elf32_word
s_size
;
elf32_word
s_link
;
elf32_word
s_info
;
elf32_word
s_addralign
;
elf32_word
s_entsize
;
}
elf32_shdr
;
typedef
struct
elf64_shdr
{
elf64_word
s_name
;
/* Section name, index in string tbl */
elf64_word
s_type
;
/* Type of section */
elf64_xword
s_flags
;
/* Miscellaneous section attributes */
elf64_addr
s_addr
;
/* Section virtual addr at execution */
elf64_off
s_offset
;
/* Section file offset */
elf64_xword
s_size
;
/* Size of section in bytes */
elf64_word
s_link
;
/* Index of another section */
elf64_word
s_info
;
/* Additional section information */
elf64_xword
s_addralign
;
/* Section alignment */
elf64_xword
s_entsize
;
/* Entry size if section holds table */
}
elf64_shdr
;
#endif
jni/bootimgtools/main.c
View file @
7ef0746c
#include <getopt.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "bootimg.h"
...
...
@@ -7,7 +9,7 @@
Patch Boot Image
*********************/
static
int
usage
(
char
*
arg0
)
{
static
void
usage
(
char
*
arg0
)
{
fprintf
(
stderr
,
"Boot Image Unpack/Repack Tool
\n
"
);
fprintf
(
stderr
,
"%s --unpack <bootimage>
\n
"
,
arg0
);
fprintf
(
stderr
,
" Unpack <bootimage> into current directory
\n\n
"
);
...
...
@@ -15,30 +17,34 @@ static int usage(char *arg0) {
fprintf
(
stderr
,
" Repack kernel, dtb, ramdisk... from current directory to new-image.img
\n
<bootimage> is the image you've just unpacked
\n\n
"
);
fprintf
(
stderr
,
"%s --hexpatch <bootimage> <hexpattern1> <hexpattern2>
\n
"
,
arg0
);
fprintf
(
stderr
,
" Search <hexpattern1> in <bootimage>, and replace with <hexpattern2>
\n\n
"
);
return
1
;
exit
(
1
);
}
void
error
(
int
rc
,
const
char
*
msg
,
...)
{
va_list
ap
;
va_start
(
ap
,
msg
);
vfprintf
(
stderr
,
msg
,
ap
);
fprintf
(
stderr
,
"
\n\n
"
);
va_end
(
ap
);
exit
(
rc
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
char
ch
;
struct
option
long_options
[]
=
{
{
"unpack"
,
required_argument
,
NULL
,
'u'
},
{
"repack"
,
required_argument
,
NULL
,
'r'
},
{
"hexpatch"
,
required_argument
,
NULL
,
'p'
},
{
NULL
,
0
,
NULL
,
0
}
};
while
((
ch
=
getopt_long
(
argc
,
argv
,
"e:r:p:"
,
long_options
,
NULL
))
!=
-
1
)
{
switch
(
ch
)
{
case
'e'
:
return
unpack
(
optarg
);
case
'r'
:
return
repack
(
optarg
);
case
'p'
:
if
(
argc
<
5
)
return
usage
(
argv
[
0
]);
optind
+=
2
;
return
hexpatch
(
argv
[
optind
-
3
],
argv
[
optind
-
2
],
argv
[
optind
-
1
]);
default:
return
usage
(
argv
[
0
]);
}
if
(
argc
<
3
)
usage
(
argv
[
0
]);
if
(
strcmp
(
argv
[
1
],
"--unpack"
)
==
0
)
{
unpack
(
argv
[
2
]);
}
else
if
(
strcmp
(
argv
[
1
],
"--repack"
)
==
0
)
{
repack
(
argv
[
2
]);
}
else
if
(
strcmp
(
argv
[
1
],
"--hexpatch"
)
==
0
)
{
if
(
argc
<
5
)
usage
(
argv
[
0
]);
hexpatch
(
argv
[
2
],
argv
[
3
],
argv
[
4
]);
}
else
{
usage
(
argv
[
0
]);
}
return
0
;
}
jni/bootimgtools/parseimg.c
0 → 100644
View file @
7ef0746c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include "bootimg.h"
#include "elf.h"
void
print_header
()
{
printf
(
"KERNEL [%d] @ 0x%08x
\n
"
,
hdr
.
kernel_size
,
hdr
.
kernel_addr
);
printf
(
"RAMDISK [%d] @ 0x%08x
\n
"
,
hdr
.
ramdisk_size
,
hdr
.
ramdisk_addr
);
printf
(
"SECOND [%d] @ 0x%08x
\n
"
,
hdr
.
second_size
,
hdr
.
second_addr
);
printf
(
"DTB [%d] @ 0x%08x
\n
"
,
hdr
.
dt_size
,
hdr
.
tags_addr
);
printf
(
"PAGESIZE [%d]
\n
"
,
hdr
.
page_size
);
if
(
hdr
.
os_version
!=
0
)
{
int
a
,
b
,
c
,
y
,
m
=
0
;
int
os_version
,
os_patch_level
;
os_version
=
hdr
.
os_version
>>
11
;
os_patch_level
=
hdr
.
os_version
&
0x7ff
;
a
=
(
os_version
>>
14
)
&
0x7f
;
b
=
(
os_version
>>
7
)
&
0x7f
;
c
=
os_version
&
0x7f
;
printf
(
"OS_VERSION [%d.%d.%d]
\n
"
,
a
,
b
,
c
);
y
=
(
os_patch_level
>>
4
)
+
2000
;
m
=
os_patch_level
&
0xf
;
printf
(
"PATCH_LEVEL [%d-%02d]
\n
"
,
y
,
m
);
}
printf
(
"NAME [%s]
\n
"
,
hdr
.
name
);
printf
(
"CMDLINE [%s]
\n
"
,
hdr
.
cmdline
);
}
static
void
page_align
(
unsigned
char
**
pos
)
{
uint32_t
itemsize
=
*
pos
-
base
,
pagemask
=
hdr
.
page_size
-
1L
;
if
(
itemsize
&
pagemask
)
{
*
pos
+=
hdr
.
page_size
-
(
itemsize
&
pagemask
);
}
}
static
void
elf_header_check
(
void
*
elf
,
int
is64
)
{
size_t
e_size
,
mach
,
ver
,
p_size
,
p_num
,
s_size
,
s_num
;
size_t
r_e_size
,
r_p_size
,
r_s_size
;
if
(
is64
)
{
e_size
=
((
elf64_ehdr
*
)
elf
)
->
e_ehsize
;
mach
=
((
elf64_ehdr
*
)
elf
)
->
e_machine
;
ver
=
((
elf64_ehdr
*
)
elf
)
->
e_version
;
p_size
=
((
elf64_ehdr
*
)
elf
)
->
e_phentsize
;
p_num
=
((
elf64_ehdr
*
)
elf
)
->
e_phnum
;
s_size
=
((
elf64_ehdr
*
)
elf
)
->
e_shentsize
;
s_num
=
((
elf64_ehdr
*
)
elf
)
->
e_shnum
;
r_e_size
=
sizeof
(
elf64_ehdr
);
r_p_size
=
sizeof
(
elf64_phdr
);
r_s_size
=
sizeof
(
elf64_shdr
);
}
else
{
e_size
=
((
elf32_ehdr
*
)
elf
)
->
e_ehsize
;
mach
=
((
elf32_ehdr
*
)
elf
)
->
e_machine
;
ver
=
((
elf32_ehdr
*
)
elf
)
->
e_version
;
p_size
=
((
elf32_ehdr
*
)
elf
)
->
e_phentsize
;
p_num
=
((
elf32_ehdr
*
)
elf
)
->
e_phnum
;
s_size
=
((
elf32_ehdr
*
)
elf
)
->
e_shentsize
;
s_num
=
((
elf32_ehdr
*
)
elf
)
->
e_shnum
;
r_e_size
=
sizeof
(
elf32_ehdr
);
r_p_size
=
sizeof
(
elf32_phdr
);
r_s_size
=
sizeof
(
elf32_shdr
);
}
if
(
e_size
!=
r_e_size
)
error
(
1
,
"Header size not %d"
,
r_e_size
);
if
(
mach
!=
EM_ARM
)
error
(
1
,
"ELF machine is not ARM"
);
if
(
ver
!=
1
)
error
(
1
,
"Unknown ELF version"
);
if
(
p_size
!=
r_p_size
)
error
(
1
,
"Program header size not %d"
,
r_p_size
);
if
(
p_num
<
2
||
p_num
>
4
)
error
(
1
,
"Unexpected number of elements: %d"
,
p_num
);
if
(
s_num
&&
s_size
!=
r_s_size
)
error
(
1
,
"Section header size not %d"
,
r_s_size
);
if
(
s_num
>
1
)
error
(
1
,
"More than one section header"
);
}
static
void
elf_set
(
int
i
,
size_t
size
,
size_t
offset
,
size_t
addr
)
{
if
(
size
<=
4096
)
{
// Possible cmdline
memset
(
hdr
.
cmdline
,
0
,
BOOT_ARGS_SIZE
);
strncpy
((
char
*
)
hdr
.
cmdline
,
(
char
*
)
(
base
+
offset
),
BOOT_ARGS_SIZE
);
hdr
.
cmdline
[
strcspn
((
char
*
)
hdr
.
cmdline
,
"
\n
"
)]
=
'\0'
;
return
;
}
switch
(
i
)
{
case
0
:
// kernel
kernel
=
base
+
offset
;
hdr
.
kernel_size
=
size
;
hdr
.
kernel_addr
=
addr
;
break
;
case
1
:
// ramdisk
ramdisk
=
base
+
offset
;
hdr
.
ramdisk_size
=
size
;
hdr
.
ramdisk_addr
=
addr
;
break
;
case
2
:
// dtb
dtb
=
base
+
offset
;
hdr
.
dt_size
=
size
;
hdr
.
tags_addr
=
addr
;
break
;
}
}
void
parse_elf
()
{
// Reset boot image header
memset
(
&
hdr
,
0
,
sizeof
(
hdr
));
// Hardcode pagesize
hdr
.
page_size
=
4096
;
switch
(
base
[
EI_CLASS
])
{
case
ELFCLASS32
:
{
elf32_ehdr
*
elf32
;
elf32_phdr
*
ph32
;
elf32_shdr
*
sh32
;
printf
(
"IMAGE [ELF32]
\n
"
);
elf32
=
(
elf32_ehdr
*
)
base
;
elf_header_check
(
elf32
,
0
);
ph32
=
(
elf32_phdr
*
)
(
base
+
elf32
->
e_phoff
);
sh32
=
(
elf32_shdr
*
)
(
base
+
elf32
->
e_shoff
);
for
(
int
i
=
0
;
i
<
elf32
->
e_phnum
;
++
i
)
{
elf_set
(
i
,
ph32
[
i
].
p_filesz
,
ph32
[
i
].
p_offset
,
ph32
[
i
].
p_paddr
);
}
if
(
elf32
->
e_shnum
)
{
// cmdline
memset
(
hdr
.
cmdline
,
0
,
BOOT_ARGS_SIZE
);
strncpy
((
char
*
)
hdr
.
cmdline
,
(
char
*
)
(
base
+
sh32
->
s_offset
+
8
),
BOOT_ARGS_SIZE
);
hdr
.
cmdline
[
strcspn
((
char
*
)
hdr
.
cmdline
,
"
\n
"
)]
=
'\0'
;
}
break
;
}
case
ELFCLASS64
:
{
elf64_ehdr
*
elf64
;
elf64_phdr
*
ph64
;
elf64_shdr
*
sh64
;
printf
(
"IMAGE [ELF64]
\n
"
);
elf64
=
(
elf64_ehdr
*
)
base
;
elf_header_check
(
elf64
,
1
);
ph64
=
(
elf64_phdr
*
)
(
base
+
elf64
->
e_phoff
);
sh64
=
(
elf64_shdr
*
)
(
base
+
elf64
->
e_shoff
);
for
(
int
i
=
0
;
i
<
elf64
->
e_phnum
;
++
i
)
{
elf_set
(
i
,
ph64
[
i
].
p_filesz
,
ph64
[
i
].
p_offset
,
ph64
[
i
].
p_paddr
);
}
if
(
elf64
->
e_shnum
)
{
// cmdline
memset
(
hdr
.
cmdline
,
0
,
BOOT_ARGS_SIZE
);
strncpy
((
char
*
)
hdr
.
cmdline
,
(
char
*
)
(
base
+
sh64
->
s_offset
+
8
),
BOOT_ARGS_SIZE
);
hdr
.
cmdline
[
strcspn
((
char
*
)
hdr
.
cmdline
,
"
\n
"
)]
=
'\0'
;
}
break
;
}
default:
error
(
1
,
"ELF format error!"
);
}
print_header
();
}
void
parse_aosp
()
{
printf
(
"IMG [AOSP]
\n
"
);
unsigned
char
*
pos
=
base
;
// Read the header
memcpy
(
&
hdr
,
pos
,
sizeof
(
hdr
));
pos
+=
hdr
.
page_size
;
// Kernel position
kernel
=
pos
;
pos
+=
hdr
.
kernel_size
;
page_align
(
&
pos
);
// Ramdisk position
ramdisk
=
pos
;
pos
+=
hdr
.
ramdisk_size
;
page_align
(
&
pos
);
if
(
hdr
.
second_size
)
{
// Second position
second
=
pos
;
pos
+=
hdr
.
second_size
;
page_align
(
&
pos
);
}
if
(
hdr
.
dt_size
)
{
// dtb position
dtb
=
pos
;
pos
+=
hdr
.
dt_size
;
page_align
(
&
pos
);
}
print_header
();
}
\ No newline at end of file
jni/bootimgtools/repack.c
View file @
7ef0746c
...
...
@@ -10,12 +10,12 @@
#include <string.h>
#include "bootimg.h"
#include "elf.h"
// Global pointer of current positions
static
void
*
ibase
,
*
ipos
;
static
int
ofd
,
opos
;
static
size_t
dump
(
const
char
*
filename
)
{
static
size_t
restore
(
const
char
*
filename
)
{
int
fd
=
open
(
filename
,
O_RDONLY
);
if
(
fd
<
0
)
{
fprintf
(
stderr
,
"Cannot open %s
\n
"
,
filename
);
...
...
@@ -32,67 +32,76 @@ static size_t dump(const char *filename) {
return
size
;
}
static
void
dump
_buf
(
size_t
size
,
const
void
*
buf
)
{
if
(
write
(
ofd
,
buf
,
size
)
<
0
)
{
static
void
restore
_buf
(
size_t
size
,
const
void
*
buf
)
{
if
(
write
(
ofd
,
buf
,
size
)
!=
size
)
{
fprintf
(
stderr
,
"Cannot dump from input file
\n
"
);
exit
(
1
);
}
opos
+=
size
;
}
static
void
in_page_align
(
uint32_t
pagesize
)
{
uint32_t
itemsize
=
ipos
-
ibase
,
pagemask
=
pagesize
-
1L
;
if
(
itemsize
&
pagemask
)
{
ipos
+=
pagesize
-
(
itemsize
&
pagemask
);
}
}
static
void
out_page_align
(
uint32_t
pagesize
)
{
uint32_t
pagemask
=
pagesize
-
1L
;
static
void
page_align
()
{
uint32_t
pagemask
=
hdr
.
page_size
-
1L
;
if
(
opos
&
pagemask
)
{
opos
+=
page
size
-
(
opos
&
pagemask
);
opos
+=
hdr
.
page_
size
-
(
opos
&
pagemask
);
}
ftruncate
(
ofd
,
opos
);
lseek
(
ofd
,
0
,
SEEK_END
);
}
static
int
aosp
()
{
printf
(
"AOSP Boot Image Detected
\n
"
);
int
repack
(
const
char
*
image
)
{
// Load original boot
int
ifd
=
open
(
image
,
O_RDONLY
),
ret
=
-
1
;
if
(
ifd
<
0
)
error
(
1
,
"Cannot open %s"
,
image
);
char
*
name
;
boot_img_hdr
hdr
,
ihdr
;
size_t
isize
=
lseek
(
ifd
,
0
,
SEEK_END
);
lseek
(
ifd
,
0
,
SEEK_SET
);
unsigned
char
*
orig
=
mmap
(
NULL
,
isize
,
PROT_READ
,
MAP_SHARED
,
ifd
,
0
);
// Create new boot image
unlink
(
"new-boot.img"
);
ofd
=
open
(
"new-boot.img"
,
O_RDWR
|
O_CREAT
,
0644
);
// Parse images
for
(
base
=
orig
;
base
<
(
orig
+
isize
);
base
+=
256
)
{
if
(
memcmp
(
base
,
BOOT_MAGIC
,
BOOT_MAGIC_SIZE
)
==
0
)
{
parse_aosp
();
break
;
}
else
if
(
memcmp
(
base
,
ELF_MAGIC
,
ELF_MAGIC_SIZE
)
==
0
)
{
parse_elf
();
break
;
}
}
// Read the original header
memcpy
(
&
ihdr
,
ibase
,
sizeof
(
ihdr
));
hdr
=
ihdr
;
printf
(
"
\n
"
);
char
*
name
;
// Set all sizes to 0
hdr
.
kernel_size
=
0
;
hdr
.
ramdisk_size
=
0
;
hdr
.
second_size
=
0
;
hdr
.
dt_size
=
0
;
// Skip a page
// Skip a page
for header
ftruncate
(
ofd
,
hdr
.
page_size
);
lseek
(
ofd
,
0
,
SEEK_END
);
opos
+=
hdr
.
page_size
;
ipos
=
ibase
+
hdr
.
page_size
;
//
Dump zImage
if
(
memcmp
(
ipos
,
"
\x88\x16\x88\x58
"
,
4
)
==
0
)
{
printf
(
"Dumping MTK header back to
zImage
\n
"
);
dump_buf
(
512
,
ipos
);
//
Restore kernel
if
(
memcmp
(
kernel
,
"
\x88\x16\x88\x58
"
,
4
)
==
0
)
{
printf
(
"Dumping MTK header back to
kernel
\n
"
);
restore_buf
(
512
,
kernel
);
hdr
.
kernel_size
+=
512
;
}
hdr
.
kernel_size
+=
dump
(
"kernel"
);
ipos
+=
ihdr
.
kernel_size
;
in_page_align
(
hdr
.
page_size
);
out_page_align
(
hdr
.
page_size
);
hdr
.
kernel_size
+=
restore
(
"kernel"
);
page_align
();
// Dump ramdisk
if
(
memcmp
(
ipos
,
"
\x88\x16\x88\x58
"
,
4
)
==
0
)
{
if
(
memcmp
(
ramdisk
,
"
\x88\x16\x88\x58
"
,
4
)
==
0
)
{
printf
(
"Dumping MTK header back to ramdisk
\n
"
);
dump_buf
(
512
,
ipos
);
restore_buf
(
512
,
ramdisk
);
hdr
.
ramdisk_size
+=
512
;
}
if
(
access
(
"ramdisk.gz"
,
R_OK
)
==
0
)
{
...
...
@@ -108,50 +117,31 @@ static int aosp() {
}
else
if
(
access
(
"ramdisk.lz4"
,
R_OK
)
==
0
)
{
name
=
"ramdisk.lz4"
;
}
else
{
fprintf
(
stderr
,
"Ramdisk file doesn't exist!
\n
"
);
return
1
;
error
(
1
,
"Ramdisk file doesn't exist!"
);
}
hdr
.
ramdisk_size
+=
dump
(
name
);
out_page_align
(
hdr
.
page_size
);
hdr
.
ramdisk_size
+=
restore
(
name
);
page_align
(
);
// Dump second
if
(
access
(
"second"
,
R_OK
)
==
0
)
{
hdr
.
second_size
+=
dump
(
"second"
);
out_page_align
(
hdr
.
page_size
);
hdr
.
second_size
+=
restore
(
"second"
);
page_align
(
);
}
// Dump dtb
if
(
access
(
"dtb"
,
R_OK
)
==
0
)
{
hdr
.
dt_size
+=
dump
(
"dtb"
);
out_page_align
(
hdr
.
page_size
);
hdr
.
dt_size
+=
restore
(
"dtb"
);
page_align
(
);
}
print_header
();
// Write header back
lseek
(
ofd
,
0
,
SEEK_SET
);
write
(
ofd
,
&
hdr
,
sizeof
(
hdr
));
return
0
;
}
int
repack
(
const
char
*
image
)
{
// Load original boot
int
ifd
=
open
(
image
,
O_RDONLY
),
ret
=
-
1
;
size_t
isize
=
lseek
(
ifd
,
0
,
SEEK_END
);
lseek
(
ifd
,
0
,
SEEK_SET
);
void
*
orig
=
mmap
(
NULL
,
isize
,
PROT_READ
,
MAP_SHARED
,
ifd
,
0
);
// Create new boot image
unlink
(
"new-boot.img"
);
ofd
=
open
(
"new-boot.img"
,
O_RDWR
|
O_CREAT
,
0644
);
// Check headers
for
(
ibase
=
orig
;
ibase
<
(
orig
+
isize
);
ibase
+=
256
)
{
if
(
memcmp
(
ibase
,
BOOT_MAGIC
,
BOOT_MAGIC_SIZE
)
==
0
)
{
ret
=
aosp
();
break
;
}
}
munmap
(
orig
,
isize
);
close
(
ifd
);
close
(
ofd
);
return
ret
;
}
jni/bootimgtools/unpack.c
View file @
7ef0746c
...
...
@@ -10,119 +10,100 @@
#include <string.h>
#include "bootimg.h"
#include "elf.h"
// Global pointer of current positions
static
unsigned
char
*
base
,
*
pos
;
static
void
dump
(
size_t
size
,
const
char
*
filename
)
{
static
void
dump
(
unsigned
char
*
buf
,
size_t
size
,
const
char
*
filename
)
{
unlink
(
filename
);
int
ofd
=
open
(
filename
,
O_WRONLY
|
O_CREAT
,
0644
);
assert
(
ofd
>=
0
);
int
ret
=
write
(
ofd
,
pos
,
size
);
assert
(
ret
==
size
);
if
(
ofd
<
0
)
error
(
1
,
"Cannot open %s"
,
filename
);
if
(
write
(
ofd
,
buf
,
size
)
!=
size
)
error
(
1
,
"Cannot dump %s"
,
filename
);
close
(
ofd
);
pos
+=
size
;
}
static
void
page_align
(
uint32_t
pagesize
)
{
uint32_t
itemsize
=
pos
-
base
,
pagemask
=
pagesize
-
1L
;
if
(
itemsize
&
pagemask
)
{
pos
+=
pagesize
-
(
itemsize
&
pagemask
);
}
}
static
int
aosp
()
{
printf
(
"AOSP Boot Image Detected
\n
"
);
int
unpack
(
const
char
*
image
)
{
int
fd
=
open
(
image
,
O_RDONLY
),
ret
=
0
;
if
(
fd
<
0
)
error
(
1
,
"Cannot open %s"
,
image
);
char
name
[
PATH_MAX
],
*
ext
;
size_t
size
=
lseek
(
fd
,
0
,
SEEK_END
);
lseek
(
fd
,
0
,
SEEK_SET
);
unsigned
char
*
orig
=
mmap
(
NULL
,
size
,
PROT_READ
,
MAP_SHARED
,
fd
,
0
);
// Read the header
boot_img_hdr
hdr
;
memcpy
(
&
hdr
,
base
,
sizeof
(
hdr
));
// Parse images
for
(
base
=
orig
;
base
<
(
orig
+
size
);
base
+=
256
)
{
if
(
memcmp
(
base
,
CHROMEOS_MAGIC
,
CHROMEOS_MAGIC_SIZE
)
==
0
)
{
dump
(
base
,
0
,
"chromeos"
);
}
else
if
(
memcmp
(
base
,
BOOT_MAGIC
,
BOOT_MAGIC_SIZE
)
==
0
)
{
parse_aosp
();
break
;
}
else
if
(
memcmp
(
base
,
ELF_MAGIC
,
ELF_MAGIC_SIZE
)
==
0
)
{
parse_elf
();
break
;
}
}
pos
=
base
+
hdr
.
page_size
;
char
name
[
PATH_MAX
],
*
ext
;
// Dump
zImage
if
(
memcmp
(
pos
,
"
\x88\x16\x88\x58
"
,
4
)
==
0
)
{
printf
(
"MTK header found in
zImage
\n
"
);
pos
+=
512
;
// Dump
kernel
if
(
memcmp
(
kernel
,
"
\x88\x16\x88\x58
"
,
4
)
==
0
)
{
printf
(
"MTK header found in
kernel
\n
"
);
kernel
+=
512
;
hdr
.
kernel_size
-=
512
;
}
dump
(
hdr
.
kernel_size
,
"kernel"
);
page_align
(
hdr
.
page_size
);
dump
(
kernel
,
hdr
.
kernel_size
,
"kernel"
);
// Dump ramdisk
if
(
memcmp
(
pos
,
"
\x88\x16\x88\x58
"
,
4
)
==
0
)
{
if
(
memcmp
(
ramdisk
,
"
\x88\x16\x88\x58
"
,
4
)
==
0
)
{
printf
(
"MTK header found in ramdisk
\n
"
);
pos
+=
512
;
ramdisk
+=
512
;
hdr
.
ramdisk_size
-=
512
;
}
// Compression detection
if
(
memcmp
(
pos
,
"
\x1f\x8b\x08\x00
"
,
4
)
==
0
)
{
if
(
memcmp
(
ramdisk
,
"
\x1f\x8b\x08\x00
"
,
4
)
==
0
)
{
// gzip header
printf
(
"
gzip ramdisk format detected!
\n
"
);
printf
(
"
COMPRESSION [gzip]
\n
"
);
ext
=
"gz"
;
}
else
if
(
memcmp
(
pos
,
"
\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a
"
,
9
)
==
0
)
{
}
else
if
(
memcmp
(
ramdisk
,
"
\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a
"
,
9
)
==
0
)
{
// lzop header
printf
(
"
lzop ramdisk format detected!
\n
"
);
printf
(
"
COMPRESSION [lzop]
\n
"
);
ext
=
"lzo"
;
}
else
if
(
memcmp
(
pos
,
"
\xfd
""7zXZ
\x00
"
,
6
)
==
0
)
{
}
else
if
(
memcmp
(
ramdisk
,
"
\xfd
""7zXZ
\x00
"
,
6
)
==
0
)
{
// xz header
printf
(
"
xz ramdisk format detected!
\n
"
);
printf
(
"
COMPRESSION [xz]
\n
"
);
ext
=
"xz"
;
}
else
if
(
memcmp
(
pos
,
"
\x5d\x00\x00
"
,
3
)
==
0
&&
(
pos
[
12
]
==
(
unsigned
char
)
'\xff'
||
pos
[
12
]
==
(
unsigned
char
)
'\x00'
))
{
}
else
if
(
memcmp
(
ramdisk
,
"
\x5d\x00\x00
"
,
3
)
==
0
&&
(
ramdisk
[
12
]
==
(
unsigned
char
)
'\xff'
||
ramdisk
[
12
]
==
(
unsigned
char
)
'\x00'
))
{
// lzma header
printf
(
"
lzma ramdisk format detected!
\n
"
);
printf
(
"
COMPRESSION [lzma]
\n
"
);
ext
=
"lzma"
;
}
else
if
(
memcmp
(
pos
,
"BZh"
,
3
)
==
0
)
{
}
else
if
(
memcmp
(
ramdisk
,
"BZh"
,
3
)
==
0
)
{
// bzip2 header
printf
(
"
bzip2 ramdisk format detected!
\n
"
);
printf
(
"
COMPRESSION [bzip2]
\n
"
);
ext
=
"bz2"
;
}
else
if
(
(
memcmp
(
pos
,
"
\x04\x22\x4d\x18
"
,
4
)
==
0
||
memcmp
(
pos
,
"
\x03\x21\x4c\x18
"
,
4
)
==
0
)
||
memcmp
(
pos
,
"
\x02\x21\x4c\x18
"
,
4
)
==
0
)
{
}
else
if
(
(
memcmp
(
ramdisk
,
"
\x04\x22\x4d\x18
"
,
4
)
==
0
||
memcmp
(
ramdisk
,
"
\x03\x21\x4c\x18
"
,
4
)
==
0
)
||
memcmp
(
ramdisk
,
"
\x02\x21\x4c\x18
"
,
4
)
==
0
)
{
// lz4 header
printf
(
"
lz4 ramdisk format detected!
\n
"
);
printf
(
"
COMPRESSION [lz4]
\n
"
);
ext
=
"lz4"
;
}
else
{
fprintf
(
stderr
,
"Unknown ramdisk format!
\n
"
);
return
1
;
error
(
1
,
"Unknown ramdisk format!"
);
}
sprintf
(
name
,
"%s.%s"
,
"ramdisk"
,
ext
);
dump
(
hdr
.
ramdisk_size
,
name
);
page_align
(
hdr
.
page_size
);
dump
(
ramdisk
,
hdr
.
ramdisk_size
,
name
);
if
(
hdr
.
second_size
)
{
// Dump second
dump
(
hdr
.
second_size
,
"second"
);
page_align
(
hdr
.
page_size
);
dump
(
second
,
hdr
.
second_size
,
"second"
);
}
if
(
hdr
.
dt_size
)
{
// Dump dtb
dump
(
hdr
.
dt_size
,
"dtb"
);
page_align
(
hdr
.
page_size
);
dump
(
dtb
,
hdr
.
dt_size
,
"dtb"
);
}
return
0
;
}
int
unpack
(
const
char
*
image
)
{
int
fd
=
open
(
image
,
O_RDONLY
),
ret
=
0
;
size_t
size
=
lseek
(
fd
,
0
,
SEEK_END
);
lseek
(
fd
,
0
,
SEEK_SET
);
unsigned
char
*
orig
=
mmap
(
NULL
,
size
,
PROT_READ
,
MAP_SHARED
,
fd
,
0
);
// Check headers
for
(
base
=
orig
;
base
<
(
orig
+
size
);
base
+=
256
)
{
if
(
memcmp
(
base
,
CHROMEOS_MAGIC
,
CHROMEOS_MAGIC_SIZE
)
==
0
)
{
dump
(
0
,
"chromeos"
);
}
else
if
(
memcmp
(
base
,
BOOT_MAGIC
,
BOOT_MAGIC_SIZE
)
==
0
)
{
ret
=
aosp
();
break
;
}
}
munmap
(
orig
,
size
);
close
(
fd
);
return
ret
;
...
...
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