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
3c75f474
Commit
3c75f474
authored
Jun 19, 2022
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Embed version info in prop format
parent
db1f5b03
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
73 additions
and
51 deletions
+73
-51
Setup.kt
buildSrc/src/main/java/Setup.kt
+1
-1
files.cpp
native/jni/base/files.cpp
+15
-3
files.hpp
native/jni/base/files.hpp
+3
-11
xwrap.cpp
native/jni/base/xwrap.cpp
+8
-0
xwrap.hpp
native/jni/base/xwrap.hpp
+1
-0
cert.cpp
native/jni/core/cert.cpp
+45
-36
No files found.
buildSrc/src/main/java/Setup.kt
View file @
3c75f474
...
...
@@ -138,7 +138,7 @@ private fun Project.setupAppCommon() {
val
apkDir
=
if
(
properties
[
"android.injected.invoked.from.ide"
]
==
"true"
)
"intermediates"
else
"outputs"
val
apk
=
File
(
buildDir
,
"${apkDir}/apk/${variant}/$projectName-${variant}.apk"
)
val
comment
=
"${Config.versionCode}"
val
comment
=
"
version=${Config.version}\nversionCode=
${Config.versionCode}"
addComment
(
apk
,
signingConfig
,
android
.
defaultConfig
.
minSdk
!!
,
comment
)
}
}
...
...
native/jni/base/files.cpp
View file @
3c75f474
...
...
@@ -338,12 +338,19 @@ void file_readline(bool trim, FILE *fp, const function<bool(string_view)> &fn) {
if
(
!
fn
(
start
))
break
;
}
fclose
(
fp
);
free
(
buf
);
}
void
parse_prop_file
(
const
char
*
file
,
const
function
<
bool
(
string_view
,
string_view
)
>
&
fn
)
{
file_readline
(
true
,
file
,
[
&
](
string_view
line_view
)
->
bool
{
void
file_readline
(
bool
trim
,
const
char
*
file
,
const
function
<
bool
(
string_view
)
>
&
fn
)
{
if
(
auto
fp
=
open_file
(
file
,
"re"
))
file_readline
(
trim
,
fp
.
get
(),
fn
);
}
void
file_readline
(
const
char
*
file
,
const
function
<
bool
(
string_view
)
>
&
fn
)
{
file_readline
(
false
,
file
,
fn
);
}
void
parse_prop_file
(
FILE
*
fp
,
const
function
<
bool
(
string_view
,
string_view
)
>
&
fn
)
{
file_readline
(
true
,
fp
,
[
&
](
string_view
line_view
)
->
bool
{
char
*
line
=
(
char
*
)
line_view
.
data
();
if
(
line
[
0
]
==
'#'
)
return
true
;
...
...
@@ -355,6 +362,11 @@ void parse_prop_file(const char *file, const function<bool(string_view, string_v
});
}
void
parse_prop_file
(
const
char
*
file
,
const
function
<
bool
(
string_view
,
string_view
)
>
&
fn
)
{
if
(
auto
fp
=
open_file
(
file
,
"re"
))
parse_prop_file
(
fp
.
get
(),
fn
);
}
// Original source: https://android.googlesource.com/platform/bionic/+/master/libc/bionic/mntent.cpp
// License: AOSP, full copyright notice please check original source
static
struct
mntent
*
compat_getmntent_r
(
FILE
*
fp
,
struct
mntent
*
e
,
char
*
buf
,
int
buf_len
)
{
...
...
native/jni/base/files.hpp
View file @
3c75f474
...
...
@@ -81,17 +81,9 @@ std::string full_read(int fd);
std
::
string
full_read
(
const
char
*
filename
);
void
write_zero
(
int
fd
,
size_t
size
);
void
file_readline
(
bool
trim
,
FILE
*
fp
,
const
std
::
function
<
bool
(
std
::
string_view
)
>
&
fn
);
static
inline
void
file_readline
(
bool
trim
,
const
char
*
file
,
const
std
::
function
<
bool
(
std
::
string_view
)
>
&
fn
)
{
FILE
*
fp
=
xfopen
(
file
,
"re"
);
if
(
fp
==
nullptr
)
return
;
file_readline
(
trim
,
fp
,
fn
);
}
static
inline
void
file_readline
(
const
char
*
file
,
const
std
::
function
<
bool
(
std
::
string_view
)
>
&
fn
)
{
file_readline
(
false
,
file
,
fn
);
}
void
file_readline
(
bool
trim
,
const
char
*
file
,
const
std
::
function
<
bool
(
std
::
string_view
)
>
&
fn
);
void
file_readline
(
const
char
*
file
,
const
std
::
function
<
bool
(
std
::
string_view
)
>
&
fn
);
void
parse_prop_file
(
FILE
*
fp
,
const
std
::
function
<
bool
(
std
::
string_view
,
std
::
string_view
)
>
&
fn
);
void
parse_prop_file
(
const
char
*
file
,
const
std
::
function
<
bool
(
std
::
string_view
,
std
::
string_view
)
>
&
fn
);
void
frm_rf
(
int
dirfd
);
...
...
native/jni/base/xwrap.cpp
View file @
3c75f474
...
...
@@ -111,6 +111,14 @@ ssize_t xxread(int fd, void *buf, size_t count) {
return
read_sz
;
}
off_t
xlseek
(
int
fd
,
off_t
offset
,
int
whence
)
{
off_t
ret
=
lseek
(
fd
,
offset
,
whence
);
if
(
ret
<
0
)
{
PLOGE
(
"lseek"
);
}
return
ret
;
}
int
xpipe2
(
int
pipefd
[
2
],
int
flags
)
{
int
ret
=
pipe2
(
pipefd
,
flags
);
if
(
ret
<
0
)
{
...
...
native/jni/base/xwrap.hpp
View file @
3c75f474
...
...
@@ -14,6 +14,7 @@ int xopenat(int dirfd, const char *pathname, int flags, mode_t mode);
ssize_t
xwrite
(
int
fd
,
const
void
*
buf
,
size_t
count
);
ssize_t
xread
(
int
fd
,
void
*
buf
,
size_t
count
);
ssize_t
xxread
(
int
fd
,
void
*
buf
,
size_t
count
);
off_t
xlseek
(
int
fd
,
off_t
offset
,
int
whence
);
int
xpipe2
(
int
pipefd
[
2
],
int
flags
);
int
xsetns
(
int
fd
,
int
nstype
);
int
xunshare
(
int
flags
);
...
...
native/jni/core/cert.cpp
View file @
3c75f474
...
...
@@ -96,26 +96,27 @@ struct EOCD {
* within the APK v2 signature block.
*/
string
read_certificate
(
int
fd
,
int
version
)
{
uint32_t
size4
;
uint64_t
size8
;
uint32_t
u32
;
uint64_t
u64
;
// Find EOCD
for
(
int
i
=
0
;;
i
++
)
{
// i is the absolute offset to end of file
uint16_t
comment_sz
=
0
;
lseek
(
fd
,
-
((
off_t
)
sizeof
(
comment_sz
))
-
i
,
SEEK_END
);
read
(
fd
,
&
comment_sz
,
sizeof
(
comment_sz
));
xlseek
(
fd
,
-
static_cast
<
off_t
>
(
sizeof
(
comment_sz
))
-
i
,
SEEK_END
);
xx
read
(
fd
,
&
comment_sz
,
sizeof
(
comment_sz
));
if
(
comment_sz
==
i
)
{
// Double check if we actually found the structure
lseek
(
fd
,
-
((
off_t
)
sizeof
(
EOCD
)),
SEEK_CUR
);
xlseek
(
fd
,
-
static_cast
<
off_t
>
(
sizeof
(
EOCD
)),
SEEK_CUR
);
uint32_t
magic
=
0
;
read
(
fd
,
&
magic
,
sizeof
(
magic
));
xx
read
(
fd
,
&
magic
,
sizeof
(
magic
));
if
(
magic
==
EOCD_MAGIC
)
{
break
;
}
}
if
(
i
==
0xffff
)
{
// Comments cannot be longer than 0xffff (overflow), abort
LOGE
(
"cert: invalid APK format
\n
"
);
return
{};
}
}
...
...
@@ -125,19 +126,25 @@ string read_certificate(int fd, int version) {
uint32_t
central_dir_off
=
0
;
{
constexpr
off_t
off
=
offsetof
(
EOCD
,
central_dir_off
)
-
sizeof
(
EOCD
::
magic
);
lseek
(
fd
,
off
,
SEEK_CUR
);
x
lseek
(
fd
,
off
,
SEEK_CUR
);
}
read
(
fd
,
&
central_dir_off
,
sizeof
(
central_dir_off
));
xx
read
(
fd
,
&
central_dir_off
,
sizeof
(
central_dir_off
));
//
Read comment
//
Parse APK comment to get version code
if
(
version
>=
0
)
{
uint16_t
comment_sz
=
0
;
read
(
fd
,
&
comment_sz
,
sizeof
(
comment_sz
));
string
comment
;
comment
.
resize
(
comment_sz
);
read
(
fd
,
comment
.
data
(),
comment_sz
);
if
(
version
>
parse_int
(
comment
))
{
// Older version of magisk app is not supported
xlseek
(
fd
,
sizeof
(
EOCD
::
comment_sz
),
SEEK_CUR
);
FILE
*
fp
=
fdopen
(
fd
,
"r"
);
// DO NOT close this file pointer
int
apk_ver
=
-
1
;
parse_prop_file
(
fp
,
[
&
](
string_view
key
,
string_view
value
)
->
bool
{
if
(
key
==
"versionCode"
)
{
apk_ver
=
parse_int
(
value
);
return
false
;
}
return
true
;
});
if
(
version
>
apk_ver
)
{
// Enforce the magisk app to always be newer than magiskd
LOGE
(
"cert: APK version too low
\n
"
);
return
{};
}
}
...
...
@@ -145,55 +152,57 @@ string read_certificate(int fd, int version) {
// Next, find the start of the APK signing block
{
constexpr
int
off
=
sizeof
(
signing_block
::
block_sz_
)
+
sizeof
(
signing_block
::
magic
);
lseek
(
fd
,
(
off_t
)
(
central_dir_off
-
off
),
SEEK_SET
);
x
lseek
(
fd
,
(
off_t
)
(
central_dir_off
-
off
),
SEEK_SET
);
}
read
(
fd
,
&
size8
,
sizeof
(
size8
));
// size8
= block_sz_
xxread
(
fd
,
&
u64
,
sizeof
(
u64
));
// u64
= block_sz_
char
magic
[
sizeof
(
signing_block
::
magic
)]
=
{
0
};
read
(
fd
,
magic
,
sizeof
(
magic
));
xx
read
(
fd
,
magic
,
sizeof
(
magic
));
if
(
memcmp
(
magic
,
APK_SIGNING_BLOCK_MAGIC
,
sizeof
(
magic
))
!=
0
)
{
// Invalid signing block magic, abort
LOGE
(
"cert: invalid signing block magic
\n
"
);
return
{};
}
uint64_t
signing_blk_sz
=
0
;
lseek
(
fd
,
(
off_t
)
(
central_dir_off
-
size8
-
sizeof
(
signing_blk_sz
)),
SEEK_SET
);
read
(
fd
,
&
signing_blk_sz
,
sizeof
(
signing_blk_sz
));
if
(
signing_blk_sz
!=
size8
)
{
xlseek
(
fd
,
-
static_cast
<
off_t
>
(
u64
+
sizeof
(
signing_blk_sz
)),
SEEK_CUR
);
xx
read
(
fd
,
&
signing_blk_sz
,
sizeof
(
signing_blk_sz
));
if
(
signing_blk_sz
!=
u64
)
{
// block_sz != block_sz_, invalid signing block format, abort
LOGE
(
"cert: invalid signing block format
\n
"
);
return
{};
}
// Finally, we are now at the beginning of the id-value pair sequence
for
(;;)
{
read
(
fd
,
&
size8
,
sizeof
(
size8
));
// id-value pair length
if
(
size8
==
signing_blk_sz
)
{
xxread
(
fd
,
&
u64
,
sizeof
(
u64
));
// id-value pair length
if
(
u64
==
signing_blk_sz
)
{
// Outside of the id-value pair sequence; actually reading block_sz_
break
;
}
uint32_t
id
;
read
(
fd
,
&
id
,
sizeof
(
id
));
xx
read
(
fd
,
&
id
,
sizeof
(
id
));
if
(
id
==
SIGNATURE_SCHEME_V2_MAGIC
)
{
read
(
fd
,
&
size4
,
sizeof
(
size4
));
// signer sequence length
// Skip [signer sequence length] + [1st signer length] + [signed data length]
xlseek
(
fd
,
sizeof
(
uint32_t
)
*
3
,
SEEK_CUR
);
read
(
fd
,
&
size4
,
sizeof
(
size4
));
// signer
length
read
(
fd
,
&
size4
,
sizeof
(
size4
));
// signed data length
xxread
(
fd
,
&
u32
,
sizeof
(
u32
));
// digest sequence
length
xlseek
(
fd
,
u32
,
SEEK_CUR
);
// skip all digests
read
(
fd
,
&
size4
,
sizeof
(
size4
));
// digest sequence length
lseek
(
fd
,
(
off_t
)
(
size4
),
SEEK_CUR
);
// skip all digests
read
(
fd
,
&
size4
,
sizeof
(
size4
));
// cert sequence length
read
(
fd
,
&
size4
,
sizeof
(
size4
));
// cert length
xlseek
(
fd
,
sizeof
(
uint32_t
),
SEEK_CUR
);
// cert sequence length
xxread
(
fd
,
&
u32
,
sizeof
(
u32
));
// 1st cert length
string
cert
;
cert
.
resize
(
size4
);
read
(
fd
,
cert
.
data
(),
size4
);
cert
.
resize
(
u32
);
xxread
(
fd
,
cert
.
data
(),
u32
);
return
cert
;
}
else
{
// Skip this id-value pair
lseek
(
fd
,
(
off_t
)
(
size8
-
sizeof
(
id
)
),
SEEK_CUR
);
xlseek
(
fd
,
u64
-
sizeof
(
id
),
SEEK_CUR
);
}
}
LOGE
(
"cert: cannot find certificate
\n
"
);
return
{};
}
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