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
05d6d2b5
Commit
05d6d2b5
authored
Apr 08, 2022
by
vvb2060
Committed by
John Wu
May 12, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Verify app signature
parent
4cff0384
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
205 additions
and
30 deletions
+205
-30
Config.kt
app/src/main/java/com/topjohnwu/magisk/core/Config.kt
+2
-0
HideAPK.kt
app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt
+1
-0
Keygen.kt
app/src/main/java/com/topjohnwu/magisk/core/utils/Keygen.kt
+4
-0
Android.mk
native/jni/Android.mk
+2
-1
bootstages.cpp
native/jni/core/bootstages.cpp
+2
-0
db.cpp
native/jni/core/db.cpp
+61
-14
scripting.cpp
native/jni/core/scripting.cpp
+2
-1
db.hpp
native/jni/include/db.hpp
+3
-2
magisk.hpp
native/jni/include/magisk.hpp
+1
-0
files.cpp
native/jni/utils/files.cpp
+124
-12
files.hpp
native/jni/utils/files.hpp
+3
-0
No files found.
app/src/main/java/com/topjohnwu/magisk/core/Config.kt
View file @
05d6d2b5
...
@@ -41,6 +41,7 @@ object Config : PreferenceModel, DBConfig {
...
@@ -41,6 +41,7 @@ object Config : PreferenceModel, DBConfig {
const
val
DENYLIST
=
"denylist"
const
val
DENYLIST
=
"denylist"
const
val
SU_MANAGER
=
"requester"
const
val
SU_MANAGER
=
"requester"
const
val
KEYSTORE
=
"keystore"
const
val
KEYSTORE
=
"keystore"
const
val
CERTDIGEST
=
"cert_digest"
// prefs
// prefs
const
val
SU_REQUEST_TIMEOUT
=
"su_request_timeout"
const
val
SU_REQUEST_TIMEOUT
=
"su_request_timeout"
...
@@ -152,6 +153,7 @@ object Config : PreferenceModel, DBConfig {
...
@@ -152,6 +153,7 @@ object Config : PreferenceModel, DBConfig {
var
denyList
by
DBBoolSettingsNoWrite
(
Key
.
DENYLIST
,
false
)
var
denyList
by
DBBoolSettingsNoWrite
(
Key
.
DENYLIST
,
false
)
var
suManager
by
dbStrings
(
Key
.
SU_MANAGER
,
""
,
true
)
var
suManager
by
dbStrings
(
Key
.
SU_MANAGER
,
""
,
true
)
var
keyStoreRaw
by
dbStrings
(
Key
.
KEYSTORE
,
""
,
true
)
var
keyStoreRaw
by
dbStrings
(
Key
.
KEYSTORE
,
""
,
true
)
var
certDigest
by
dbStrings
(
Key
.
CERTDIGEST
,
""
,
true
)
private
const
val
SU_FINGERPRINT
=
"su_fingerprint"
private
const
val
SU_FINGERPRINT
=
"su_fingerprint"
...
...
app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt
View file @
05d6d2b5
...
@@ -121,6 +121,7 @@ object HideAPK {
...
@@ -121,6 +121,7 @@ object HideAPK {
val
repack
=
File
(
activity
.
cacheDir
,
"patched.apk"
)
val
repack
=
File
(
activity
.
cacheDir
,
"patched.apk"
)
val
pkg
=
genPackageName
()
val
pkg
=
genPackageName
()
Config
.
keyStoreRaw
=
""
Config
.
keyStoreRaw
=
""
Config
.
certDigest
=
""
if
(!
patch
(
activity
,
stub
,
FileOutputStream
(
repack
),
pkg
,
label
))
if
(!
patch
(
activity
,
stub
,
FileOutputStream
(
repack
),
pkg
,
label
))
return
false
return
false
...
...
app/src/main/java/com/topjohnwu/magisk/core/utils/Keygen.kt
View file @
05d6d2b5
...
@@ -12,6 +12,7 @@ import java.io.ByteArrayOutputStream
...
@@ -12,6 +12,7 @@ import java.io.ByteArrayOutputStream
import
java.math.BigInteger
import
java.math.BigInteger
import
java.security.KeyPairGenerator
import
java.security.KeyPairGenerator
import
java.security.KeyStore
import
java.security.KeyStore
import
java.security.MessageDigest
import
java.security.PrivateKey
import
java.security.PrivateKey
import
java.security.cert.X509Certificate
import
java.security.cert.X509Certificate
import
java.util.*
import
java.util.*
...
@@ -73,6 +74,9 @@ class Keygen : CertKeyProvider {
...
@@ -73,6 +74,9 @@ class Keygen : CertKeyProvider {
}
}
Config
.
keyStoreRaw
=
bytes
.
toString
(
"UTF-8"
)
Config
.
keyStoreRaw
=
bytes
.
toString
(
"UTF-8"
)
val
digest
=
MessageDigest
.
getInstance
(
"SHA-256"
).
digest
(
cert
.
encoded
)
Config
.
certDigest
=
digest
.
joinToString
(
""
)
{
"%02x"
.
format
(
it
)
}
return
ks
return
ks
}
}
}
}
native/jni/Android.mk
View file @
05d6d2b5
...
@@ -13,7 +13,8 @@ LOCAL_STATIC_LIBRARIES := \
...
@@ -13,7 +13,8 @@ LOCAL_STATIC_LIBRARIES := \
libnanopb \
libnanopb \
libsystemproperties \
libsystemproperties \
libphmap \
libphmap \
libxhook
libxhook \
libmincrypt
LOCAL_SRC_FILES := \
LOCAL_SRC_FILES := \
core/applets.cpp \
core/applets.cpp \
...
...
native/jni/core/bootstages.cpp
View file @
05d6d2b5
...
@@ -20,6 +20,7 @@ using namespace std;
...
@@ -20,6 +20,7 @@ using namespace std;
static
bool
safe_mode
=
false
;
static
bool
safe_mode
=
false
;
static
int
stub_fd
=
-
1
;
static
int
stub_fd
=
-
1
;
bool
zygisk_enabled
=
false
;
bool
zygisk_enabled
=
false
;
string
APKCERT
;
/*********
/*********
* Setup *
* Setup *
...
@@ -124,6 +125,7 @@ static bool magisk_env() {
...
@@ -124,6 +125,7 @@ static bool magisk_env() {
LOGI
(
"* Initializing Magisk environment
\n
"
);
LOGI
(
"* Initializing Magisk environment
\n
"
);
string
stub_path
=
MAGISKTMP
+
"/stub.apk"
;
string
stub_path
=
MAGISKTMP
+
"/stub.apk"
;
APKCERT
=
read_certificate
(
stub_path
);
stub_fd
=
xopen
(
stub_path
.
data
(),
O_RDONLY
|
O_CLOEXEC
);
stub_fd
=
xopen
(
stub_path
.
data
(),
O_RDONLY
|
O_CLOEXEC
);
unlink
(
stub_path
.
data
());
unlink
(
stub_path
.
data
());
...
...
native/jni/core/db.cpp
View file @
05d6d2b5
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
#include <db.hpp>
#include <db.hpp>
#include <socket.hpp>
#include <socket.hpp>
#include <utils.hpp>
#include <utils.hpp>
#include <mincrypt/sha256.h>
#define DB_VERSION 12
#define DB_VERSION 12
...
@@ -359,43 +360,89 @@ int get_db_strings(db_strings &str, int key) {
...
@@ -359,43 +360,89 @@ int get_db_strings(db_strings &str, int key) {
return
0
;
return
0
;
}
}
static
bool
is_stub_trusted
(
const
char
*
pkg
,
const
char
*
trust_hash
)
{
// TODO: Remove when next stable released
if
(
trust_hash
[
0
]
==
0
)
{
LOGW
(
"su: skip check stub.apk signature
\n
"
);
return
true
;
}
string
cert
=
read_certificate
(
find_apk_path
(
pkg
));
if
(
cert
.
empty
())
return
false
;
uint8_t
hash
[
SHA256_DIGEST_SIZE
];
SHA256_hash
(
cert
.
data
(),
cert
.
length
(),
hash
);
char
hash_hex
[
SHA256_DIGEST_SIZE
*
2
+
1
];
char
*
ptr
=
&
hash_hex
[
0
];
for
(
uint8_t
i
:
hash
)
{
ptr
+=
sprintf
(
ptr
,
"%02x"
,
i
);
}
return
strcmp
(
trust_hash
,
hash_hex
)
==
0
;
}
bool
get_manager
(
int
user_id
,
std
::
string
*
pkg
,
struct
stat
*
st
)
{
bool
get_manager
(
int
user_id
,
std
::
string
*
pkg
,
struct
stat
*
st
)
{
db_strings
str
;
db_strings
str
;
get_db_strings
(
str
,
SU_MANAGER
);
get_db_strings
(
str
,
SU_MANAGER
);
get_db_strings
(
str
,
CERT_DIGEST
);
char
app_path
[
128
];
char
app_path
[
128
];
if
(
APKCERT
.
empty
())
LOGW
(
"su: skip check app signature
\n
"
);
if
(
!
str
[
SU_MANAGER
].
empty
())
{
if
(
!
str
[
SU_MANAGER
].
empty
())
{
// App is repackaged
// App is repackaged
sprintf
(
app_path
,
"%s/%d/%s"
,
APP_DATA_DIR
,
user_id
,
str
[
SU_MANAGER
].
data
());
sprintf
(
app_path
,
"%s/%d/%s"
,
APP_DATA_DIR
,
user_id
,
str
[
SU_MANAGER
].
data
());
if
(
stat
(
app_path
,
st
)
==
0
)
{
if
(
stat
(
app_path
,
st
)
==
0
)
{
if
(
pkg
)
if
(
is_stub_trusted
(
str
[
SU_MANAGER
].
data
(),
str
[
CERT_DIGEST
].
data
()))
{
pkg
->
swap
(
str
[
SU_MANAGER
]);
strcpy
(
app_path
,
"/dyn/current.apk"
);
return
true
;
if
(
!
APKCERT
.
empty
()
&&
access
(
app_path
,
F_OK
)
==
0
)
{
if
(
read_certificate
(
app_path
)
==
APKCERT
)
{
if
(
pkg
)
pkg
->
swap
(
str
[
SU_MANAGER
]);
return
true
;
}
else
{
LOGW
(
"su: current.apk signature mismatch
\n
"
);
}
}
else
{
if
(
pkg
)
pkg
->
swap
(
str
[
SU_MANAGER
]);
return
true
;
}
}
else
{
LOGW
(
"su: stub.apk signature mismatch
\n
"
);
}
}
}
}
}
// Check the official package name
// Check the official package name
sprintf
(
app_path
,
"%s/%d/"
JAVA_PACKAGE_NAME
,
APP_DATA_DIR
,
user_id
);
sprintf
(
app_path
,
"%s/%d/"
JAVA_PACKAGE_NAME
,
APP_DATA_DIR
,
user_id
);
if
(
stat
(
app_path
,
st
)
==
0
)
{
if
(
stat
(
app_path
,
st
)
==
0
)
{
if
(
pkg
)
string
cert
=
read_certificate
(
find_apk_path
(
JAVA_PACKAGE_NAME
));
*
pkg
=
JAVA_PACKAGE_NAME
;
if
(
APKCERT
.
empty
())
return
true
;
cert
.
clear
();
}
else
{
if
(
cert
==
APKCERT
)
{
LOGE
(
"su: cannot find manager
\n
"
);
if
(
pkg
)
memset
(
st
,
0
,
sizeof
(
*
st
));
*
pkg
=
JAVA_PACKAGE_NAME
;
if
(
pkg
)
return
true
;
pkg
->
clear
();
}
else
{
return
false
;
LOGW
(
"su: app signature mismatch
\n
"
);
}
}
}
LOGE
(
"su: cannot find trusted app
\n
"
);
memset
(
st
,
0
,
sizeof
(
*
st
));
if
(
pkg
)
pkg
->
clear
();
return
false
;
}
}
bool
get_manager
(
string
*
pkg
)
{
bool
get_manager
(
string
*
pkg
)
{
struct
stat
st
;
struct
stat
st
{}
;
return
get_manager
(
0
,
pkg
,
&
st
);
return
get_manager
(
0
,
pkg
,
&
st
);
}
}
int
get_manager_app_id
()
{
int
get_manager_app_id
()
{
struct
stat
st
;
struct
stat
st
{}
;
if
(
get_manager
(
0
,
nullptr
,
&
st
))
if
(
get_manager
(
0
,
nullptr
,
&
st
))
return
to_app_id
(
st
.
st_uid
);
return
to_app_id
(
st
.
st_uid
);
return
-
1
;
return
-
1
;
...
...
native/jni/core/scripting.cpp
View file @
05d6d2b5
...
@@ -152,6 +152,7 @@ void exec_module_scripts(const char *stage, const vector<string_view> &modules)
...
@@ -152,6 +152,7 @@ void exec_module_scripts(const char *stage, const vector<string_view> &modules)
constexpr
char
install_script
[]
=
R"EOF(
constexpr
char
install_script
[]
=
R"EOF(
APK=%s
APK=%s
log -t Magisk "apk_uninstall: $(pm uninstall %s 2>&1)"
log -t Magisk "apk_install: $APK"
log -t Magisk "apk_install: $APK"
log -t Magisk "apk_install: $(pm install -r $APK 2>&1)"
log -t Magisk "apk_install: $(pm install -r $APK 2>&1)"
rm -f $APK
rm -f $APK
...
@@ -163,7 +164,7 @@ void install_apk(const char *apk) {
...
@@ -163,7 +164,7 @@ void install_apk(const char *apk) {
.
fork
=
fork_no_orphan
.
fork
=
fork_no_orphan
};
};
char
cmds
[
sizeof
(
install_script
)
+
4096
];
char
cmds
[
sizeof
(
install_script
)
+
4096
];
sprintf
(
cmds
,
install_script
,
apk
);
sprintf
(
cmds
,
install_script
,
apk
,
JAVA_PACKAGE_NAME
);
exec_command_sync
(
exec
,
"/system/bin/sh"
,
"-c"
,
cmds
);
exec_command_sync
(
exec
,
"/system/bin/sh"
,
"-c"
,
cmds
);
}
}
...
...
native/jni/include/db.hpp
View file @
05d6d2b5
...
@@ -84,11 +84,12 @@ protected:
...
@@ -84,11 +84,12 @@ protected:
* DB Strings *
* DB Strings *
**************/
**************/
constexpr
const
char
*
DB_STRING_KEYS
[]
=
{
"requester"
};
constexpr
const
char
*
DB_STRING_KEYS
[]
=
{
"requester"
,
"cert_digest"
};
// Strings keys indices
// Strings keys indices
enum
{
enum
{
SU_MANAGER
=
0
SU_MANAGER
=
0
,
CERT_DIGEST
};
};
class
db_strings
:
public
db_dict
<
std
::
string
,
std
::
size
(
DB_STRING_KEYS
)
>
{
class
db_strings
:
public
db_dict
<
std
::
string
,
std
::
size
(
DB_STRING_KEYS
)
>
{
...
...
native/jni/include/magisk.hpp
View file @
05d6d2b5
...
@@ -35,6 +35,7 @@ constexpr const char *applet_names[] = { "su", "resetprop", nullptr };
...
@@ -35,6 +35,7 @@ constexpr const char *applet_names[] = { "su", "resetprop", nullptr };
extern
int
SDK_INT
;
extern
int
SDK_INT
;
#define APP_DATA_DIR (SDK_INT >= 24 ? "/data/user_de" : "/data/user")
#define APP_DATA_DIR (SDK_INT >= 24 ? "/data/user_de" : "/data/user")
extern
std
::
string
APKCERT
;
// Multi-call entrypoints
// Multi-call entrypoints
int
magisk_main
(
int
argc
,
char
*
argv
[]);
int
magisk_main
(
int
argc
,
char
*
argv
[]);
...
...
native/jni/utils/files.cpp
View file @
05d6d2b5
...
@@ -57,17 +57,33 @@ static void post_order_walk(int dirfd, const Func &fn) {
...
@@ -57,17 +57,33 @@ static void post_order_walk(int dirfd, const Func &fn) {
}
}
}
}
enum
visit_result
{
CONTINUE
,
SKIP
,
TERMINATE
};
template
<
typename
Func
>
template
<
typename
Func
>
static
v
oid
pre_order_walk
(
int
dirfd
,
const
Func
&
fn
)
{
static
v
isit_result
pre_order_walk
(
int
dirfd
,
const
Func
&
fn
)
{
auto
dir
=
xopen_dir
(
dirfd
);
auto
dir
=
xopen_dir
(
dirfd
);
if
(
!
dir
)
return
;
if
(
!
dir
)
{
close
(
dirfd
);
return
SKIP
;
}
for
(
dirent
*
entry
;
(
entry
=
xreaddir
(
dir
.
get
()));)
{
for
(
dirent
*
entry
;
(
entry
=
xreaddir
(
dir
.
get
()));)
{
if
(
!
fn
(
dirfd
,
entry
))
switch
(
fn
(
dirfd
,
entry
))
{
continue
;
case
CONTINUE
:
if
(
entry
->
d_type
==
DT_DIR
)
break
;
pre_order_walk
(
xopenat
(
dirfd
,
entry
->
d_name
,
O_RDONLY
|
O_CLOEXEC
),
fn
);
case
SKIP
:
continue
;
case
TERMINATE
:
return
TERMINATE
;
}
if
(
entry
->
d_type
==
DT_DIR
)
{
int
fd
=
xopenat
(
dirfd
,
entry
->
d_name
,
O_RDONLY
|
O_CLOEXEC
);
if
(
pre_order_walk
(
fd
,
fn
)
==
TERMINATE
)
return
TERMINATE
;
}
}
}
return
CONTINUE
;
}
}
static
void
remove_at
(
int
dirfd
,
struct
dirent
*
entry
)
{
static
void
remove_at
(
int
dirfd
,
struct
dirent
*
entry
)
{
...
@@ -400,20 +416,20 @@ void parse_mnt(const char *file, const function<bool(mntent*)> &fn) {
...
@@ -400,20 +416,20 @@ void parse_mnt(const char *file, const function<bool(mntent*)> &fn) {
}
}
void
backup_folder
(
const
char
*
dir
,
vector
<
raw_file
>
&
files
)
{
void
backup_folder
(
const
char
*
dir
,
vector
<
raw_file
>
&
files
)
{
char
path
[
4096
];
char
path
[
PATH_MAX
];
xrealpath
(
dir
,
path
);
xrealpath
(
dir
,
path
);
int
len
=
strlen
(
path
);
int
len
=
strlen
(
path
);
pre_order_walk
(
xopen
(
dir
,
O_RDONLY
),
[
&
](
int
dfd
,
dirent
*
entry
)
->
bool
{
pre_order_walk
(
xopen
(
dir
,
O_RDONLY
),
[
&
](
int
dfd
,
dirent
*
entry
)
->
visit_result
{
int
fd
=
xopenat
(
dfd
,
entry
->
d_name
,
O_RDONLY
);
int
fd
=
xopenat
(
dfd
,
entry
->
d_name
,
O_RDONLY
);
if
(
fd
<
0
)
if
(
fd
<
0
)
return
false
;
return
SKIP
;
run_finally
f
([
&
]{
close
(
fd
);
});
run_finally
f
([
&
]{
close
(
fd
);
});
if
(
fd_path
(
fd
,
path
,
sizeof
(
path
))
<
0
)
if
(
fd_path
(
fd
,
path
,
sizeof
(
path
))
<
0
)
return
false
;
return
SKIP
;
raw_file
file
;
raw_file
file
;
file
.
path
=
path
+
len
+
1
;
file
.
path
=
path
+
len
+
1
;
if
(
fgetattr
(
fd
,
&
file
.
attr
)
<
0
)
if
(
fgetattr
(
fd
,
&
file
.
attr
)
<
0
)
return
false
;
return
SKIP
;
if
(
entry
->
d_type
==
DT_REG
)
{
if
(
entry
->
d_type
==
DT_REG
)
{
fd_full_read
(
fd
,
file
.
buf
,
file
.
sz
);
fd_full_read
(
fd
,
file
.
buf
,
file
.
sz
);
}
else
if
(
entry
->
d_type
==
DT_LNK
)
{
}
else
if
(
entry
->
d_type
==
DT_LNK
)
{
...
@@ -423,7 +439,7 @@ void backup_folder(const char *dir, vector<raw_file> &files) {
...
@@ -423,7 +439,7 @@ void backup_folder(const char *dir, vector<raw_file> &files) {
memcpy
(
file
.
buf
,
path
,
file
.
sz
);
memcpy
(
file
.
buf
,
path
,
file
.
sz
);
}
}
files
.
emplace_back
(
std
::
move
(
file
));
files
.
emplace_back
(
std
::
move
(
file
));
return
true
;
return
CONTINUE
;
});
});
}
}
...
@@ -507,3 +523,99 @@ mmap_data::mmap_data(const char *name, bool rw) {
...
@@ -507,3 +523,99 @@ mmap_data::mmap_data(const char *name, bool rw) {
close
(
fd
);
close
(
fd
);
buf
=
static_cast
<
uint8_t
*>
(
b
);
buf
=
static_cast
<
uint8_t
*>
(
b
);
}
}
string
find_apk_path
(
const
char
*
pkg
)
{
char
buf
[
PATH_MAX
];
pre_order_walk
(
xopen
(
"/data/app"
,
O_RDONLY
),
[
&
](
int
dfd
,
dirent
*
entry
)
->
visit_result
{
if
(
entry
->
d_type
!=
DT_DIR
)
return
SKIP
;
size_t
len
=
strlen
(
pkg
);
if
(
strncmp
(
entry
->
d_name
,
pkg
,
len
)
==
0
&&
entry
->
d_name
[
len
]
==
'-'
)
{
fd_pathat
(
dfd
,
entry
->
d_name
,
buf
,
sizeof
(
buf
));
return
TERMINATE
;
}
else
if
(
strncmp
(
entry
->
d_name
,
"~~"
,
2
)
==
0
)
{
return
CONTINUE
;
}
else
return
SKIP
;
});
string
path
(
buf
);
return
path
.
append
(
"/base.apk"
);
}
string
read_certificate
(
string
app_path
)
{
string
certificate
;
uint32_t
size4
;
uint64_t
size8
,
size_of_block
;
int
fd
=
xopen
(
app_path
.
data
(),
O_RDONLY
);
if
(
fd
<
0
)
{
return
certificate
;
}
run_finally
f
([
&
]
{
close
(
fd
);
});
for
(
int
i
=
0
;;
i
++
)
{
unsigned
short
n
;
lseek
(
fd
,
-
i
-
2
,
SEEK_END
);
read
(
fd
,
&
n
,
2
);
if
(
n
==
i
)
{
lseek
(
fd
,
-
22
,
SEEK_CUR
);
read
(
fd
,
&
size4
,
4
);
if
(
size4
==
0x6054b50u
)
{
// central directory end magic
break
;
}
}
if
(
i
==
0xffff
)
{
return
certificate
;
}
}
lseek
(
fd
,
12
,
SEEK_CUR
);
read
(
fd
,
&
size4
,
0x4
);
lseek
(
fd
,
(
off_t
)
(
size4
-
0x18
),
SEEK_SET
);
read
(
fd
,
&
size8
,
0x8
);
unsigned
char
buffer
[
0x10
]
=
{
0
};
read
(
fd
,
buffer
,
0x10
);
if
(
memcmp
(
buffer
,
"APK Sig Block 42"
,
0x10
)
!=
0
)
{
return
certificate
;
}
lseek
(
fd
,
(
off_t
)
(
size4
-
(
size8
+
0x8
)),
SEEK_SET
);
read
(
fd
,
&
size_of_block
,
0x8
);
if
(
size_of_block
!=
size8
)
{
return
certificate
;
}
for
(;;)
{
uint32_t
id
;
uint32_t
offset
;
read
(
fd
,
&
size8
,
0x8
);
// sequence length
if
(
size8
==
size_of_block
)
{
break
;
}
read
(
fd
,
&
id
,
0x4
);
// id
offset
=
4
;
if
(
id
==
0x7109871au
)
{
read
(
fd
,
&
size4
,
0x4
);
// signer-sequence length
read
(
fd
,
&
size4
,
0x4
);
// signer length
read
(
fd
,
&
size4
,
0x4
);
// signed data length
offset
+=
0x4
*
3
;
read
(
fd
,
&
size4
,
0x4
);
// digests-sequence length
lseek
(
fd
,
(
off_t
)
(
size4
),
SEEK_CUR
);
// skip digests
offset
+=
0x4
+
size4
;
read
(
fd
,
&
size4
,
0x4
);
// certificates length
read
(
fd
,
&
size4
,
0x4
);
// certificate length
offset
+=
0x4
*
2
;
certificate
.
resize
(
size4
);
read
(
fd
,
certificate
.
data
(),
size4
);
offset
+=
size4
;
}
lseek
(
fd
,
(
off_t
)
(
size8
-
offset
),
SEEK_CUR
);
}
return
certificate
;
}
native/jni/utils/files.hpp
View file @
05d6d2b5
...
@@ -102,6 +102,9 @@ void parse_mnt(const char *file, const std::function<bool(mntent*)> &fn);
...
@@ -102,6 +102,9 @@ void parse_mnt(const char *file, const std::function<bool(mntent*)> &fn);
void
backup_folder
(
const
char
*
dir
,
std
::
vector
<
raw_file
>
&
files
);
void
backup_folder
(
const
char
*
dir
,
std
::
vector
<
raw_file
>
&
files
);
void
restore_folder
(
const
char
*
dir
,
std
::
vector
<
raw_file
>
&
files
);
void
restore_folder
(
const
char
*
dir
,
std
::
vector
<
raw_file
>
&
files
);
std
::
string
find_apk_path
(
const
char
*
pkg
);
std
::
string
read_certificate
(
std
::
string
app_path
);
template
<
typename
T
>
template
<
typename
T
>
void
full_read
(
const
char
*
filename
,
T
&
buf
,
size_t
&
size
)
{
void
full_read
(
const
char
*
filename
,
T
&
buf
,
size_t
&
size
)
{
static_assert
(
std
::
is_pointer
<
T
>::
value
);
static_assert
(
std
::
is_pointer
<
T
>::
value
);
...
...
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