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
7c12bf7f
Commit
7c12bf7f
authored
Nov 07, 2018
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Modernize code base
parent
ca35a968
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
421 additions
and
287 deletions
+421
-287
bootstages.cpp
native/jni/daemon/bootstages.cpp
+89
-105
daemon.cpp
native/jni/daemon/daemon.cpp
+1
-1
resetprop.h
native/jni/include/resetprop.h
+3
-1
cpio.cpp
native/jni/magiskboot/cpio.cpp
+42
-53
cpio.h
native/jni/magiskboot/cpio.h
+4
-2
ramdisk.cpp
native/jni/magiskboot/ramdisk.cpp
+46
-46
hide_utils.cpp
native/jni/magiskhide/hide_utils.cpp
+25
-39
magiskhide.cpp
native/jni/magiskhide/magiskhide.cpp
+2
-2
magiskhide.h
native/jni/magiskhide/magiskhide.h
+4
-4
proc_monitor.cpp
native/jni/magiskhide/proc_monitor.cpp
+6
-9
_resetprop.h
native/jni/resetprop/_resetprop.h
+2
-1
persist_properties.cpp
native/jni/resetprop/persist_properties.cpp
+4
-4
resetprop.cpp
native/jni/resetprop/resetprop.cpp
+10
-10
Android.mk
native/jni/utils/Android.mk
+1
-0
CharArray.cpp
native/jni/utils/CharArray.cpp
+99
-0
file.cpp
native/jni/utils/file.cpp
+2
-2
CharArray.h
native/jni/utils/include/CharArray.h
+39
-0
array.h
native/jni/utils/include/array.h
+14
-6
cpputils.h
native/jni/utils/include/cpputils.h
+12
-0
utils.h
native/jni/utils/include/utils.h
+8
-2
misc.cpp
native/jni/utils/misc.cpp
+8
-0
No files found.
native/jni/daemon/bootstages.cpp
View file @
7c12bf7f
This diff is collapsed.
Click to expand it.
native/jni/daemon/daemon.cpp
View file @
7c12bf7f
...
@@ -82,7 +82,7 @@ static void *request_handler(void *args) {
...
@@ -82,7 +82,7 @@ static void *request_handler(void *args) {
close
(
client
);
close
(
client
);
break
;
break
;
}
}
return
NULL
;
return
nullptr
;
}
}
static
void
main_daemon
()
{
static
void
main_daemon
()
{
...
...
native/jni/include/resetprop.h
View file @
7c12bf7f
...
@@ -3,9 +3,11 @@
...
@@ -3,9 +3,11 @@
#pragma once
#pragma once
#include "CharArray.h"
int
prop_exist
(
const
char
*
name
);
int
prop_exist
(
const
char
*
name
);
int
setprop
(
const
char
*
name
,
const
char
*
value
,
const
bool
trigger
=
true
);
int
setprop
(
const
char
*
name
,
const
char
*
value
,
const
bool
trigger
=
true
);
char
*
getprop
(
const
char
*
name
,
bool
persist
=
false
);
CharArray
getprop
(
const
char
*
name
,
bool
persist
=
false
);
void
getprop
(
void
(
*
callback
)(
const
char
*
,
const
char
*
,
void
*
),
void
*
cookie
,
bool
persist
=
false
);
void
getprop
(
void
(
*
callback
)(
const
char
*
,
const
char
*
,
void
*
),
void
*
cookie
,
bool
persist
=
false
);
int
deleteprop
(
const
char
*
name
,
bool
persist
=
false
);
int
deleteprop
(
const
char
*
name
,
bool
persist
=
false
);
int
load_prop_file
(
const
char
*
filename
,
const
bool
trigger
=
true
);
int
load_prop_file
(
const
char
*
filename
,
const
bool
trigger
=
true
);
...
...
native/jni/magiskboot/cpio.cpp
View file @
7c12bf7f
...
@@ -40,8 +40,8 @@ cpio_entry::cpio_entry(int fd, cpio_newc_header &header) {
...
@@ -40,8 +40,8 @@ cpio_entry::cpio_entry(int fd, cpio_newc_header &header) {
// rdevminor = x8u(header.rdevminor);
// rdevminor = x8u(header.rdevminor);
uint32_t
namesize
=
x8u
(
header
.
namesize
);
uint32_t
namesize
=
x8u
(
header
.
namesize
);
// check = x8u(header.check);
// check = x8u(header.check);
filename
=
(
char
*
)
xmalloc
(
namesize
);
filename
=
CharArray
(
namesize
);
xxread
(
fd
,
filename
,
namesize
);
xxread
(
fd
,
filename
,
filename
.
size
()
);
parse_align
();
parse_align
();
if
(
filesize
)
{
if
(
filesize
)
{
data
=
xmalloc
(
filesize
);
data
=
xmalloc
(
filesize
);
...
@@ -51,7 +51,6 @@ cpio_entry::cpio_entry(int fd, cpio_newc_header &header) {
...
@@ -51,7 +51,6 @@ cpio_entry::cpio_entry(int fd, cpio_newc_header &header) {
}
}
cpio_entry
::~
cpio_entry
()
{
cpio_entry
::~
cpio_entry
()
{
free
(
filename
);
free
(
data
);
free
(
data
);
}
}
...
@@ -61,7 +60,7 @@ int(*Array<cpio_entry*>::_cmp)(cpio_entry*&, cpio_entry*&) = [](auto a, auto b)
...
@@ -61,7 +60,7 @@ int(*Array<cpio_entry*>::_cmp)(cpio_entry*&, cpio_entry*&) = [](auto a, auto b)
if
(
a
==
b
)
return
0
;
if
(
a
==
b
)
return
0
;
if
(
a
==
nullptr
)
return
1
;
if
(
a
==
nullptr
)
return
1
;
if
(
b
==
nullptr
)
return
-
1
;
if
(
b
==
nullptr
)
return
-
1
;
return
strcmp
(
a
->
filename
,
b
->
filename
);
return
a
->
filename
.
compare
(
b
->
filename
);
};
};
...
@@ -73,12 +72,11 @@ cpio::cpio(const char *filename) {
...
@@ -73,12 +72,11 @@ cpio::cpio(const char *filename) {
cpio_entry
*
entry
;
cpio_entry
*
entry
;
while
(
xxread
(
fd
,
&
header
,
sizeof
(
cpio_newc_header
))
!=
-
1
)
{
while
(
xxread
(
fd
,
&
header
,
sizeof
(
cpio_newc_header
))
!=
-
1
)
{
entry
=
new
cpio_entry
(
fd
,
header
);
entry
=
new
cpio_entry
(
fd
,
header
);
if
(
strcmp
(
entry
->
filename
,
"."
)
==
0
||
strcmp
(
entry
->
filename
,
".."
)
==
0
||
if
(
entry
->
filename
==
"."
||
entry
->
filename
==
".."
||
entry
->
filename
==
"TRAILER!!!"
)
{
strcmp
(
entry
->
filename
,
"TRAILER!!!"
)
==
0
)
{
bool
trailer
=
entry
->
filename
[
0
]
==
'T'
;
delete
entry
;
delete
entry
;
if
(
entry
->
filename
[
0
]
==
'T'
)
if
(
trailer
)
break
;
break
;
continue
;
}
}
arr
.
push_back
(
entry
);
arr
.
push_back
(
entry
);
}
}
...
@@ -110,11 +108,11 @@ void cpio::dump(const char *file) {
...
@@ -110,11 +108,11 @@ void cpio::dump(const char *file) {
0
,
// e->devminor
0
,
// e->devminor
0
,
// e->rdevmajor
0
,
// e->rdevmajor
0
,
// e->rdevminor
0
,
// e->rdevminor
(
uint32_t
)
strlen
(
e
->
filename
)
+
1
,
(
uint32_t
)
e
->
filename
.
size
()
,
0
// e->check
0
// e->check
);
);
xwrite
(
fd
,
header
,
110
);
xwrite
(
fd
,
header
,
110
);
xwrite
(
fd
,
e
->
filename
,
strlen
(
e
->
filename
)
+
1
);
xwrite
(
fd
,
e
->
filename
,
e
->
filename
.
size
()
);
dump_align
();
dump_align
();
if
(
e
->
filesize
)
{
if
(
e
->
filesize
)
{
xwrite
(
fd
,
e
->
data
,
e
->
filesize
);
xwrite
(
fd
,
e
->
data
,
e
->
filesize
);
...
@@ -134,7 +132,7 @@ int cpio::find(const char *name) {
...
@@ -134,7 +132,7 @@ int cpio::find(const char *name) {
for
(
int
i
=
0
;
i
<
arr
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
arr
.
size
();
++
i
)
{
if
(
!
arr
[
i
])
if
(
!
arr
[
i
])
continue
;
continue
;
if
(
strcmp
(
arr
[
i
]
->
filename
,
name
)
==
0
)
if
(
arr
[
i
]
->
filename
==
name
)
return
i
;
return
i
;
}
}
return
-
1
;
return
-
1
;
...
@@ -143,12 +141,11 @@ int cpio::find(const char *name) {
...
@@ -143,12 +141,11 @@ int cpio::find(const char *name) {
void
cpio
::
insert
(
cpio_entry
*
e
)
{
void
cpio
::
insert
(
cpio_entry
*
e
)
{
int
i
=
find
(
e
->
filename
);
int
i
=
find
(
e
->
filename
);
if
(
i
>=
0
)
{
if
(
i
>=
0
)
{
// Replace, then all is done
delete
arr
[
i
];
delete
arr
[
i
];
arr
[
i
]
=
e
;
arr
[
i
]
=
e
;
return
;
}
else
{
arr
.
push_back
(
e
);
}
}
arr
.
push_back
(
e
);
}
}
void
cpio
::
insert
(
Array
<
cpio_entry
*>
&
arr
)
{
void
cpio
::
insert
(
Array
<
cpio_entry
*>
&
arr
)
{
...
@@ -156,17 +153,17 @@ void cpio::insert(Array<cpio_entry *> &arr) {
...
@@ -156,17 +153,17 @@ void cpio::insert(Array<cpio_entry *> &arr) {
insert
(
e
);
insert
(
e
);
}
}
void
cpio
::
rm
(
int
recur
,
const
char
*
name
)
{
void
cpio
::
rm
(
const
char
*
name
,
bool
r
)
{
size_t
len
=
strlen
(
name
);
size_t
len
=
strlen
(
name
);
for
(
auto
&
e
:
arr
)
{
for
(
auto
&
e
:
arr
)
{
if
(
!
e
)
if
(
!
e
)
continue
;
continue
;
if
(
strncmp
(
e
->
filename
,
name
,
len
)
==
0
&&
if
(
e
->
filename
.
compare
(
name
,
len
)
==
0
&&
((
r
ecur
&&
e
->
filename
[
len
]
==
'/'
)
||
e
->
filename
[
len
]
==
'\0'
))
{
((
r
&&
e
->
filename
[
len
]
==
'/'
)
||
e
->
filename
[
len
]
==
'\0'
))
{
fprintf
(
stderr
,
"Remove [%s]
\n
"
,
e
->
filename
);
fprintf
(
stderr
,
"Remove [%s]
\n
"
,
e
->
filename
.
c_str
()
);
delete
e
;
delete
e
;
e
=
nullptr
;
e
=
nullptr
;
if
(
!
r
ecur
)
if
(
!
r
)
return
;
return
;
}
}
}
}
...
@@ -175,7 +172,7 @@ void cpio::rm(int recur, const char *name) {
...
@@ -175,7 +172,7 @@ void cpio::rm(int recur, const char *name) {
void
cpio
::
makedir
(
mode_t
mode
,
const
char
*
name
)
{
void
cpio
::
makedir
(
mode_t
mode
,
const
char
*
name
)
{
auto
e
=
new
cpio_entry
();
auto
e
=
new
cpio_entry
();
e
->
mode
=
S_IFDIR
|
mode
;
e
->
mode
=
S_IFDIR
|
mode
;
e
->
filename
=
strdup
(
name
)
;
e
->
filename
=
name
;
insert
(
e
);
insert
(
e
);
fprintf
(
stderr
,
"Create directory [%s] (%04o)
\n
"
,
name
,
mode
);
fprintf
(
stderr
,
"Create directory [%s] (%04o)
\n
"
,
name
,
mode
);
}
}
...
@@ -183,7 +180,7 @@ void cpio::makedir(mode_t mode, const char *name) {
...
@@ -183,7 +180,7 @@ void cpio::makedir(mode_t mode, const char *name) {
void
cpio
::
ln
(
const
char
*
target
,
const
char
*
name
)
{
void
cpio
::
ln
(
const
char
*
target
,
const
char
*
name
)
{
auto
e
=
new
cpio_entry
();
auto
e
=
new
cpio_entry
();
e
->
mode
=
S_IFLNK
;
e
->
mode
=
S_IFLNK
;
e
->
filename
=
strdup
(
name
)
;
e
->
filename
=
name
;
e
->
filesize
=
strlen
(
target
);
e
->
filesize
=
strlen
(
target
);
e
->
data
=
strdup
(
target
);
e
->
data
=
strdup
(
target
);
insert
(
e
);
insert
(
e
);
...
@@ -194,7 +191,7 @@ void cpio::add(mode_t mode, const char *name, const char *file) {
...
@@ -194,7 +191,7 @@ void cpio::add(mode_t mode, const char *name, const char *file) {
int
fd
=
xopen
(
file
,
O_RDONLY
);
int
fd
=
xopen
(
file
,
O_RDONLY
);
auto
e
=
new
cpio_entry
();
auto
e
=
new
cpio_entry
();
e
->
mode
=
S_IFREG
|
mode
;
e
->
mode
=
S_IFREG
|
mode
;
e
->
filename
=
strdup
(
name
)
;
e
->
filename
=
name
;
e
->
filesize
=
lseek
(
fd
,
0
,
SEEK_END
);
e
->
filesize
=
lseek
(
fd
,
0
,
SEEK_END
);
lseek
(
fd
,
0
,
SEEK_SET
);
lseek
(
fd
,
0
,
SEEK_SET
);
e
->
data
=
xmalloc
(
e
->
filesize
);
e
->
data
=
xmalloc
(
e
->
filesize
);
...
@@ -212,35 +209,38 @@ bool cpio::mv(const char *from, const char *to) {
...
@@ -212,35 +209,38 @@ bool cpio::mv(const char *from, const char *to) {
arr
[
t
]
=
nullptr
;
arr
[
t
]
=
nullptr
;
}
}
fprintf
(
stderr
,
"Move [%s] -> [%s]
\n
"
,
from
,
to
);
fprintf
(
stderr
,
"Move [%s] -> [%s]
\n
"
,
from
,
to
);
char
*
tmp
=
strdup
(
to
);
arr
[
f
]
->
filename
=
to
;
free
(
arr
[
f
]
->
filename
);
arr
[
f
]
->
filename
=
tmp
;
return
true
;
return
true
;
}
}
fprintf
(
stderr
,
"Cannot find entry %s
\n
"
,
from
);
fprintf
(
stderr
,
"Cannot find entry %s
\n
"
,
from
);
return
false
;
return
false
;
}
}
static
void
extract_entry
(
cpio_entry
*
e
,
const
char
*
file
)
{
fprintf
(
stderr
,
"Extract [%s] to [%s]
\n
"
,
e
->
filename
.
c_str
(),
file
);
unlink
(
file
);
rmdir
(
file
);
if
(
S_ISDIR
(
e
->
mode
))
{
mkdir
(
file
,
e
->
mode
&
0777
);
}
else
if
(
S_ISREG
(
e
->
mode
))
{
int
fd
=
creat
(
file
,
e
->
mode
&
0777
);
xwrite
(
fd
,
e
->
data
,
e
->
filesize
);
fchown
(
fd
,
e
->
uid
,
e
->
gid
);
close
(
fd
);
}
else
if
(
S_ISLNK
(
e
->
mode
))
{
auto
target
=
new
char
[
e
->
filesize
+
1
];
memcpy
(
target
,
e
->
data
,
e
->
filesize
);
target
[
e
->
filesize
]
=
'\0'
;
symlink
(
target
,
file
);
delete
[]
target
;
}
}
void
cpio
::
extract
()
{
void
cpio
::
extract
()
{
for
(
auto
&
e
:
arr
)
{
for
(
auto
&
e
:
arr
)
{
if
(
!
e
)
if
(
!
e
)
continue
;
continue
;
fprintf
(
stderr
,
"Extract [%s]
\n
"
,
e
->
filename
);
extract_entry
(
e
,
e
->
filename
);
unlink
(
e
->
filename
);
rmdir
(
e
->
filename
);
if
(
S_ISDIR
(
e
->
mode
))
{
mkdir
(
e
->
filename
,
e
->
mode
&
0777
);
}
else
if
(
S_ISREG
(
e
->
mode
))
{
int
fd
=
creat
(
e
->
filename
,
e
->
mode
&
0777
);
xwrite
(
fd
,
e
->
data
,
e
->
filesize
);
fchown
(
fd
,
e
->
uid
,
e
->
gid
);
close
(
fd
);
}
else
if
(
S_ISLNK
(
e
->
mode
))
{
char
*
target
=
new
char
[
e
->
filesize
+
1
];
memcpy
(
target
,
e
->
data
,
e
->
filesize
);
symlink
(
target
,
e
->
filename
);
delete
[]
target
;
}
}
}
}
}
...
@@ -248,18 +248,7 @@ bool cpio::extract(const char *name, const char *file) {
...
@@ -248,18 +248,7 @@ bool cpio::extract(const char *name, const char *file) {
int
i
=
find
(
name
);
int
i
=
find
(
name
);
if
(
i
>
0
)
{
if
(
i
>
0
)
{
auto
e
=
arr
[
i
];
auto
e
=
arr
[
i
];
fprintf
(
stderr
,
"Extract [%s] to [%s]
\n
"
,
name
,
file
);
extract_entry
(
e
,
file
);
if
(
S_ISREG
(
e
->
mode
))
{
int
fd
=
creat
(
file
,
e
->
mode
&
0777
);
xwrite
(
fd
,
e
->
data
,
e
->
filesize
);
fchown
(
fd
,
e
->
uid
,
e
->
gid
);
close
(
fd
);
}
else
if
(
S_ISLNK
(
e
->
mode
))
{
char
*
target
=
new
char
[
e
->
filesize
+
1
];
memcpy
(
target
,
e
->
data
,
e
->
filesize
);
symlink
(
target
,
e
->
filename
);
delete
[]
target
;
}
return
true
;
return
true
;
}
}
fprintf
(
stderr
,
"Cannot find the file entry [%s]
\n
"
,
name
);
fprintf
(
stderr
,
"Cannot find the file entry [%s]
\n
"
,
name
);
...
...
native/jni/magiskboot/cpio.h
View file @
7c12bf7f
...
@@ -4,6 +4,7 @@
...
@@ -4,6 +4,7 @@
#include <stdint.h>
#include <stdint.h>
#include "array.h"
#include "array.h"
#include "CharArray.h"
struct
cpio_newc_header
{
struct
cpio_newc_header
{
char
magic
[
6
];
char
magic
[
6
];
...
@@ -36,7 +37,8 @@ struct cpio_entry {
...
@@ -36,7 +37,8 @@ struct cpio_entry {
// uint32_t rdevminor;
// uint32_t rdevminor;
// uint32_t namesize;
// uint32_t namesize;
// uint32_t check;
// uint32_t check;
char
*
filename
=
nullptr
;
// char *filename = nullptr;
CharArray
filename
;
void
*
data
=
nullptr
;
void
*
data
=
nullptr
;
cpio_entry
()
{}
cpio_entry
()
{}
...
@@ -51,7 +53,7 @@ public:
...
@@ -51,7 +53,7 @@ public:
void
dump
(
const
char
*
file
);
void
dump
(
const
char
*
file
);
int
find
(
const
char
*
name
);
int
find
(
const
char
*
name
);
void
insert
(
cpio_entry
*
e
);
void
insert
(
cpio_entry
*
e
);
void
rm
(
int
recur
,
const
char
*
nam
e
);
void
rm
(
const
char
*
name
,
bool
r
=
fals
e
);
void
makedir
(
mode_t
mode
,
const
char
*
name
);
void
makedir
(
mode_t
mode
,
const
char
*
name
);
void
ln
(
const
char
*
target
,
const
char
*
name
);
void
ln
(
const
char
*
target
,
const
char
*
name
);
void
add
(
mode_t
mode
,
const
char
*
name
,
const
char
*
file
);
void
add
(
mode_t
mode
,
const
char
*
name
,
const
char
*
file
);
...
...
native/jni/magiskboot/ramdisk.cpp
View file @
7c12bf7f
...
@@ -23,10 +23,13 @@ void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
...
@@ -23,10 +23,13 @@ void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
for
(
auto
&
e
:
arr
)
{
for
(
auto
&
e
:
arr
)
{
if
(
!
e
)
if
(
!
e
)
continue
;
continue
;
bool
fstab
=
(
!
keepverity
||
!
keepforceencrypt
)
&&
!
e
->
filename
.
starts_with
(
".backup"
)
&&
e
->
filename
.
contains
(
"fstab"
)
&&
S_ISREG
(
e
->
mode
);
if
(
!
keepverity
)
{
if
(
!
keepverity
)
{
if
(
strncmp
(
e
->
filename
,
".backup"
,
7
)
&&
strstr
(
e
->
filename
,
"fstab"
)
&&
S_ISREG
(
e
->
mode
)
)
{
if
(
fstab
)
{
patch_verity
(
&
e
->
data
,
&
e
->
filesize
,
1
);
patch_verity
(
&
e
->
data
,
&
e
->
filesize
,
1
);
}
else
if
(
strcmp
(
e
->
filename
,
"verity_key"
)
==
0
)
{
}
else
if
(
e
->
filename
==
"verity_key"
)
{
fprintf
(
stderr
,
"Remove [verity_key]
\n
"
);
fprintf
(
stderr
,
"Remove [verity_key]
\n
"
);
delete
e
;
delete
e
;
e
=
nullptr
;
e
=
nullptr
;
...
@@ -34,7 +37,7 @@ void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
...
@@ -34,7 +37,7 @@ void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
}
}
}
}
if
(
!
keepforceencrypt
)
{
if
(
!
keepforceencrypt
)
{
if
(
strstr
(
e
->
filename
,
"fstab"
)
!=
NULL
&&
S_ISREG
(
e
->
mode
)
)
{
if
(
fstab
)
{
patch_encryption
(
&
e
->
data
,
&
e
->
filesize
);
patch_encryption
(
&
e
->
data
,
&
e
->
filesize
);
}
}
}
}
...
@@ -47,27 +50,26 @@ void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
...
@@ -47,27 +50,26 @@ void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
#define UNSUPPORT_PATCH 0x2
#define UNSUPPORT_PATCH 0x2
int
magisk_cpio
::
test
()
{
int
magisk_cpio
::
test
()
{
static
const
char
*
UNSUPPORT_LIST
[]
=
{
"sbin/launch_daemonsu.sh"
,
"sbin/su"
,
"init.xposed.rc"
,
static
const
char
*
UNSUPPORT_LIST
[]
=
{
"sbin/launch_daemonsu.sh"
,
"sbin/su"
,
"init.xposed.rc"
,
"boot/sbin/launch_daemonsu.sh"
,
nullptr
};
"boot/sbin/launch_daemonsu.sh"
};
static
const
char
*
MAGISK_LIST
[]
=
{
".backup/.magisk"
,
"init.magisk.rc"
,
static
const
char
*
MAGISK_LIST
[]
=
{
".backup/.magisk"
,
"init.magisk.rc"
,
"overlay/init.magisk.rc"
,
nullptr
};
"overlay/init.magisk.rc"
};
for
(
int
i
=
0
;
UNSUPPORT_LIST
[
i
];
++
i
)
for
(
auto
file
:
UNSUPPORT_LIST
)
if
(
find
(
UNSUPPORT_LIST
[
i
]
)
>=
0
)
if
(
find
(
file
)
>=
0
)
return
UNSUPPORT_PATCH
;
return
UNSUPPORT_PATCH
;
for
(
int
i
=
0
;
MAGISK_LIST
[
i
];
++
i
)
for
(
auto
file
:
MAGISK_LIST
)
if
(
find
(
MAGISK_LIST
[
i
]
)
>=
0
)
if
(
find
(
file
)
>=
0
)
return
MAGISK_PATCH
;
return
MAGISK_PATCH
;
return
STOCK_BOOT
;
return
STOCK_BOOT
;
}
}
char
*
magisk_cpio
::
sha1
()
{
char
*
magisk_cpio
::
sha1
()
{
char
sha1
[
41
];
char
sha1
[
41
];
for
(
auto
&
e
:
arr
)
{
for
(
auto
&
e
:
arr
)
{
if
(
!
e
)
continue
;
if
(
!
e
)
continue
;
if
(
strcmp
(
e
->
filename
,
"init.magisk.rc"
)
==
0
if
(
e
->
filename
==
"init.magisk.rc"
||
e
->
filename
==
"overlay/init.magisk.rc"
)
{
||
strcmp
(
e
->
filename
,
"overlay/init.magisk.rc"
)
==
0
)
{
for
(
char
*
pos
=
(
char
*
)
e
->
data
;
pos
<
(
char
*
)
e
->
data
+
e
->
filesize
;
for
(
char
*
pos
=
(
char
*
)
e
->
data
;
pos
<
(
char
*
)
e
->
data
+
e
->
filesize
;
pos
=
strchr
(
pos
+
1
,
'\n'
)
+
1
)
{
pos
=
strchr
(
pos
+
1
,
'\n'
)
+
1
)
{
if
(
memcmp
(
pos
,
"# STOCKSHA1="
,
12
)
==
0
)
{
if
(
memcmp
(
pos
,
"# STOCKSHA1="
,
12
)
==
0
)
{
...
@@ -77,7 +79,7 @@ char * magisk_cpio::sha1() {
...
@@ -77,7 +79,7 @@ char * magisk_cpio::sha1() {
return
strdup
(
sha1
);
return
strdup
(
sha1
);
}
}
}
}
}
else
if
(
strcmp
(
e
->
filename
,
".backup/.sha1"
)
==
0
)
{
}
else
if
(
e
->
filename
==
".backup/.sha1"
)
{
return
(
char
*
)
e
->
data
;
return
(
char
*
)
e
->
data
;
}
}
}
}
...
@@ -87,12 +89,12 @@ char * magisk_cpio::sha1() {
...
@@ -87,12 +89,12 @@ char * magisk_cpio::sha1() {
void
magisk_cpio
::
restore
()
{
void
magisk_cpio
::
restore
()
{
for
(
auto
&
e
:
arr
)
{
for
(
auto
&
e
:
arr
)
{
if
(
!
e
)
continue
;
if
(
!
e
)
continue
;
if
(
strncmp
(
e
->
filename
,
".backup"
,
7
)
==
0
)
{
if
(
e
->
filename
.
starts_with
(
".backup"
)
)
{
if
(
e
->
filename
[
7
]
==
'\0'
)
continue
;
if
(
e
->
filename
[
7
]
==
'\0'
)
continue
;
if
(
e
->
filename
[
8
]
==
'.'
)
{
if
(
e
->
filename
[
8
]
==
'.'
)
{
if
(
strcmp
(
e
->
filename
+
8
,
".rmlist"
)
==
0
)
{
if
(
strcmp
(
&
e
->
filename
[
8
]
,
".rmlist"
)
==
0
)
{
for
(
int
pos
=
0
;
pos
<
e
->
filesize
;
pos
+=
strlen
((
char
*
)
e
->
data
+
pos
)
+
1
)
for
(
int
pos
=
0
;
pos
<
e
->
filesize
;
pos
+=
strlen
((
char
*
)
e
->
data
+
pos
)
+
1
)
rm
(
false
,
(
char
*
)
e
->
data
+
pos
);
rm
(
(
char
*
)
e
->
data
+
pos
,
false
);
}
}
}
else
{
}
else
{
mv
(
e
->
filename
,
e
->
filename
+
8
);
mv
(
e
->
filename
,
e
->
filename
+
8
);
...
@@ -101,43 +103,41 @@ void magisk_cpio::restore() {
...
@@ -101,43 +103,41 @@ void magisk_cpio::restore() {
}
}
// Some known stuff we can remove
// Some known stuff we can remove
rm
(
true
,
".backup"
);
rm
(
".backup"
,
true
);
rm
(
true
,
"overlay"
);
rm
(
"overlay"
,
true
);
rm
(
false
,
"sbin/magic_mask.sh"
);
rm
(
"sbin/magic_mask.sh"
,
false
);
rm
(
false
,
"init.magisk.rc"
);
rm
(
"init.magisk.rc"
,
false
);
rm
(
true
,
"magisk"
);
rm
(
"magisk"
,
true
);
}
}
void
magisk_cpio
::
backup
(
Array
<
cpio_entry
*>
&
bak
,
const
char
*
orig
,
const
char
*
sha1
)
{
void
magisk_cpio
::
backup
(
Array
<
cpio_entry
*>
&
bak
,
const
char
*
orig
,
const
char
*
sha1
)
{
cpio_entry
*
m
,
*
n
,
*
rem
,
*
cksm
;
cpio_entry
*
m
,
*
n
,
*
rem
,
*
cksm
;
char
buf
[
PATH_MAX
];
char
buf
[
PATH_MAX
];
int
res
;
bool
backup
;
m
=
new
cpio_entry
();
m
=
new
cpio_entry
();
m
->
filename
=
strdup
(
".backup"
)
;
m
->
filename
=
".backup"
;
m
->
mode
=
S_IFDIR
;
m
->
mode
=
S_IFDIR
;
bak
.
push_back
(
m
);
bak
.
push_back
(
m
);
rem
=
new
cpio_entry
();
rem
=
new
cpio_entry
();
rem
->
filename
=
strdup
(
".backup/.rmlist"
)
;
rem
->
filename
=
".backup/.rmlist"
;
rem
->
mode
=
S_IFREG
;
rem
->
mode
=
S_IFREG
;
if
(
sha1
)
{
if
(
sha1
)
{
fprintf
(
stderr
,
"Save SHA1: [%s] -> [.backup/.sha1]
\n
"
,
sha1
);
fprintf
(
stderr
,
"Save SHA1: [%s] -> [.backup/.sha1]
\n
"
,
sha1
);
cksm
=
new
cpio_entry
();
cksm
=
new
cpio_entry
();
bak
.
push_back
(
cksm
);
cksm
->
filename
=
".backup/.sha1"
;
cksm
->
filename
=
strdup
(
".backup/.sha1"
);
cksm
->
mode
=
S_IFREG
;
cksm
->
mode
=
S_IFREG
;
cksm
->
data
=
strdup
(
sha1
);
cksm
->
data
=
strdup
(
sha1
);
cksm
->
filesize
=
strlen
(
sha1
)
+
1
;
cksm
->
filesize
=
strlen
(
sha1
)
+
1
;
bak
.
push_back
(
cksm
);
}
}
magisk_cpio
o
=
magisk_cpio
(
orig
);
magisk_cpio
o
(
orig
);
// Remove possible backups in original ramdisk
// Remove possible backups in original ramdisk
o
.
rm
(
true
,
".backup"
);
o
.
rm
(
".backup"
,
true
);
rm
(
true
,
".backup"
);
rm
(
".backup"
,
true
);
// Sort both CPIOs before comparing
// Sort both CPIOs before comparing
o
.
sort
();
o
.
sort
();
...
@@ -146,11 +146,12 @@ void magisk_cpio::backup(Array<cpio_entry*> &bak, const char *orig, const char *
...
@@ -146,11 +146,12 @@ void magisk_cpio::backup(Array<cpio_entry*> &bak, const char *orig, const char *
// Start comparing
// Start comparing
size_t
i
=
0
,
j
=
0
;
size_t
i
=
0
,
j
=
0
;
while
(
i
!=
o
.
arr
.
size
()
||
j
!=
arr
.
size
())
{
while
(
i
!=
o
.
arr
.
size
()
||
j
!=
arr
.
size
())
{
backup
=
false
;
int
res
;
bool
backup
=
false
;
if
(
i
!=
o
.
arr
.
size
()
&&
j
!=
arr
.
size
())
{
if
(
i
!=
o
.
arr
.
size
()
&&
j
!=
arr
.
size
())
{
m
=
o
.
arr
[
i
];
m
=
o
.
arr
[
i
];
n
=
arr
[
j
];
n
=
arr
[
j
];
res
=
strcmp
(
m
->
filename
,
n
->
filename
);
res
=
m
->
filename
.
compare
(
n
->
filename
);
}
else
if
(
i
==
o
.
arr
.
size
())
{
}
else
if
(
i
==
o
.
arr
.
size
())
{
n
=
arr
[
j
];
n
=
arr
[
j
];
res
=
1
;
res
=
1
;
...
@@ -174,16 +175,15 @@ void magisk_cpio::backup(Array<cpio_entry*> &bak, const char *orig, const char *
...
@@ -174,16 +175,15 @@ void magisk_cpio::backup(Array<cpio_entry*> &bak, const char *orig, const char *
}
else
{
}
else
{
// Something new in ramdisk, record in rem
// Something new in ramdisk, record in rem
++
j
;
++
j
;
rem
->
data
=
xrealloc
(
rem
->
data
,
rem
->
filesize
+
strlen
(
n
->
filename
)
+
1
);
rem
->
data
=
xrealloc
(
rem
->
data
,
rem
->
filesize
+
n
->
filename
.
size
()
);
memcpy
((
char
*
)
rem
->
data
+
rem
->
filesize
,
n
->
filename
,
strlen
(
n
->
filename
)
+
1
);
memcpy
((
char
*
)
rem
->
data
+
rem
->
filesize
,
n
->
filename
,
n
->
filename
.
size
()
);
rem
->
filesize
+=
strlen
(
n
->
filename
)
+
1
;
rem
->
filesize
+=
n
->
filename
.
size
()
;
fprintf
(
stderr
,
"Record new entry: [%s] -> [.backup/.rmlist]
\n
"
,
n
->
filename
);
fprintf
(
stderr
,
"Record new entry: [%s] -> [.backup/.rmlist]
\n
"
,
n
->
filename
.
c_str
()
);
}
}
if
(
backup
)
{
if
(
backup
)
{
sprintf
(
buf
,
".backup/%s"
,
m
->
filename
);
sprintf
(
buf
,
".backup/%s"
,
m
->
filename
.
c_str
());
fprintf
(
stderr
,
"[%s] -> [%s]
\n
"
,
m
->
filename
,
buf
);
fprintf
(
stderr
,
"[%s] -> [%s]
\n
"
,
m
->
filename
.
c_str
(),
buf
);
free
(
m
->
filename
);
m
->
filename
=
buf
;
m
->
filename
=
strdup
(
buf
);
bak
.
push_back
(
m
);
bak
.
push_back
(
m
);
// NULL the original entry, so it won't be freed
// NULL the original entry, so it won't be freed
o
.
arr
[
i
-
1
]
=
nullptr
;
o
.
arr
[
i
-
1
]
=
nullptr
;
...
@@ -202,7 +202,7 @@ int cpio_commands(int argc, char *argv[]) {
...
@@ -202,7 +202,7 @@ int cpio_commands(int argc, char *argv[]) {
++
argv
;
++
argv
;
--
argc
;
--
argc
;
magisk_cpio
cpio
=
magisk_cpio
(
incpio
);
magisk_cpio
cpio
(
incpio
);
int
cmdc
;
int
cmdc
;
char
*
cmdv
[
6
];
char
*
cmdv
[
6
];
...
@@ -230,17 +230,17 @@ int cpio_commands(int argc, char *argv[]) {
...
@@ -230,17 +230,17 @@ int cpio_commands(int argc, char *argv[]) {
free
(
sha1
);
free
(
sha1
);
return
0
;
return
0
;
}
else
if
(
cmdc
>=
2
&&
strcmp
(
cmdv
[
0
],
"backup"
)
==
0
)
{
}
else
if
(
cmdc
>=
2
&&
strcmp
(
cmdv
[
0
],
"backup"
)
==
0
)
{
auto
bak
=
Array
<
cpio_entry
*>
()
;
Array
<
cpio_entry
*>
bak
;
cpio
.
backup
(
bak
,
cmdv
[
1
],
cmdv
[
2
]);
cpio
.
backup
(
bak
,
cmdv
[
1
],
cmdv
[
2
]);
cpio
.
insert
(
bak
);
cpio
.
insert
(
bak
);
}
else
if
(
cmdc
>=
4
&&
strcmp
(
cmdv
[
0
],
"magisk"
)
==
0
)
{
}
else
if
(
cmdc
>=
4
&&
strcmp
(
cmdv
[
0
],
"magisk"
)
==
0
)
{
cpio
.
patch
(
strcmp
(
cmdv
[
2
],
"true"
)
==
0
,
strcmp
(
cmdv
[
3
],
"true"
)
==
0
);
cpio
.
patch
(
strcmp
(
cmdv
[
2
],
"true"
)
==
0
,
strcmp
(
cmdv
[
3
],
"true"
)
==
0
);
auto
bak
=
Array
<
cpio_entry
*>
()
;
Array
<
cpio_entry
*>
bak
;
cpio
.
backup
(
bak
,
cmdv
[
1
],
cmdv
[
4
]);
cpio
.
backup
(
bak
,
cmdv
[
1
],
cmdv
[
4
]);
auto
e
=
new
cpio_entry
();
auto
e
=
new
cpio_entry
();
e
->
filename
=
strdup
(
".backup/.magisk"
)
;
e
->
filename
=
".backup/.magisk"
;
e
->
mode
=
S_IFREG
;
e
->
mode
=
S_IFREG
;
e
->
data
=
xmalloc
(
50
);
e
->
data
=
xmalloc
(
50
);
snprintf
((
char
*
)
e
->
data
,
50
,
"KEEPVERITY=%s
\n
KEEPFORCEENCRYPT=%s
\n
"
,
cmdv
[
2
],
cmdv
[
3
]);
snprintf
((
char
*
)
e
->
data
,
50
,
"KEEPVERITY=%s
\n
KEEPFORCEENCRYPT=%s
\n
"
,
cmdv
[
2
],
cmdv
[
3
]);
...
@@ -249,8 +249,8 @@ int cpio_commands(int argc, char *argv[]) {
...
@@ -249,8 +249,8 @@ int cpio_commands(int argc, char *argv[]) {
cpio
.
insert
(
bak
);
cpio
.
insert
(
bak
);
cpio
.
insert
(
e
);
cpio
.
insert
(
e
);
}
else
if
(
cmdc
>=
2
&&
strcmp
(
cmdv
[
0
],
"rm"
)
==
0
)
{
}
else
if
(
cmdc
>=
2
&&
strcmp
(
cmdv
[
0
],
"rm"
)
==
0
)
{
int
recu
r
=
cmdc
>
2
&&
strcmp
(
cmdv
[
1
],
"-r"
)
==
0
;
bool
r
=
cmdc
>
2
&&
strcmp
(
cmdv
[
1
],
"-r"
)
==
0
;
cpio
.
rm
(
recur
,
cmdv
[
1
+
recur
]
);
cpio
.
rm
(
cmdv
[
1
+
r
],
r
);
}
else
if
(
cmdc
==
3
&&
strcmp
(
cmdv
[
0
],
"mv"
)
==
0
)
{
}
else
if
(
cmdc
==
3
&&
strcmp
(
cmdv
[
0
],
"mv"
)
==
0
)
{
cpio
.
mv
(
cmdv
[
1
],
cmdv
[
2
]);
cpio
.
mv
(
cmdv
[
1
],
cmdv
[
2
]);
}
else
if
(
cmdc
==
3
&&
strcmp
(
cmdv
[
0
],
"patch"
)
==
0
)
{
}
else
if
(
cmdc
==
3
&&
strcmp
(
cmdv
[
0
],
"patch"
)
==
0
)
{
...
...
native/jni/magiskhide/hide_utils.cpp
View file @
7c12bf7f
...
@@ -15,7 +15,7 @@
...
@@ -15,7 +15,7 @@
#include "daemon.h"
#include "daemon.h"
#include "db.h"
#include "db.h"
auto
hide_list
=
Array
<
char
*>
()
;
Array
<
CharArray
>
hide_list
;
static
const
char
*
prop_key
[]
=
static
const
char
*
prop_key
[]
=
{
"ro.boot.vbmeta.device_state"
,
"ro.boot.verifiedbootstate"
,
"ro.boot.flash.locked"
,
{
"ro.boot.vbmeta.device_state"
,
"ro.boot.verifiedbootstate"
,
"ro.boot.flash.locked"
,
...
@@ -46,14 +46,10 @@ void hide_sensitive_props() {
...
@@ -46,14 +46,10 @@ void hide_sensitive_props() {
LOGI
(
"hide_utils: Hiding sensitive props
\n
"
);
LOGI
(
"hide_utils: Hiding sensitive props
\n
"
);
// Hide all sensitive props
// Hide all sensitive props
char
*
value
;
for
(
int
i
=
0
;
prop_key
[
i
];
++
i
)
{
for
(
int
i
=
0
;
prop_key
[
i
];
++
i
)
{
value
=
getprop
(
prop_key
[
i
]);
CharArray
value
=
getprop
(
prop_key
[
i
]);
if
(
value
)
{
if
(
!
value
.
empty
()
&&
value
!=
prop_value
[
i
])
if
(
strcmp
(
value
,
prop_value
[
i
])
!=
0
)
setprop
(
prop_key
[
i
],
prop_value
[
i
],
false
);
setprop
(
prop_key
[
i
],
prop_value
[
i
],
false
);
free
(
value
);
}
}
}
}
}
...
@@ -139,13 +135,11 @@ void clean_magisk_props() {
...
@@ -139,13 +135,11 @@ void clean_magisk_props() {
},
nullptr
,
false
);
},
nullptr
,
false
);
}
}
static
int
add_list
(
sqlite3
*
db
,
char
*
proc
)
{
static
int
add_list
(
sqlite3
*
db
,
c
onst
c
har
*
proc
)
{
for
(
auto
&
s
:
hide_list
)
{
for
(
auto
&
s
:
hide_list
)
{
// They should be unique
// They should be unique
if
(
strcmp
(
s
,
proc
)
==
0
)
{
if
(
s
==
proc
)
free
(
proc
);
return
HIDE_ITEM_EXIST
;
return
HIDE_ITEM_EXIST
;
}
}
}
LOGI
(
"hide_list add: [%s]
\n
"
,
proc
);
LOGI
(
"hide_list add: [%s]
\n
"
,
proc
);
...
@@ -164,7 +158,7 @@ static int add_list(sqlite3 *db, char *proc) {
...
@@ -164,7 +158,7 @@ static int add_list(sqlite3 *db, char *proc) {
return
DAEMON_SUCCESS
;
return
DAEMON_SUCCESS
;
}
}
int
add_list
(
char
*
proc
)
{
int
add_list
(
c
onst
c
har
*
proc
)
{
sqlite3
*
db
=
get_magiskdb
();
sqlite3
*
db
=
get_magiskdb
();
if
(
db
)
{
if
(
db
)
{
int
ret
=
add_list
(
db
,
proc
);
int
ret
=
add_list
(
db
,
proc
);
...
@@ -175,20 +169,20 @@ int add_list(char *proc) {
...
@@ -175,20 +169,20 @@ int add_list(char *proc) {
}
}
int
add_list
(
int
client
)
{
int
add_list
(
int
client
)
{
return
add_list
(
read_string
(
client
));
char
*
proc
=
read_string
(
client
);
int
ret
=
add_list
(
proc
);
free
(
proc
);
return
ret
;
}
}
static
int
rm_list
(
char
*
proc
)
{
static
int
rm_list
(
const
char
*
proc
)
{
int
ret
=
DAEMON_ERROR
;
// Update list in critical region
// Update list in critical region
bool
do_rm
=
false
;
bool
do_rm
=
false
;
pthread_mutex_lock
(
&
list_lock
);
pthread_mutex_lock
(
&
list_lock
);
for
(
auto
it
=
hide_list
.
begin
();
it
!=
hide_list
.
end
();
++
it
)
{
for
(
auto
it
=
hide_list
.
begin
();
it
!=
hide_list
.
end
();
++
it
)
{
if
(
strcmp
(
*
it
,
proc
)
==
0
)
{
if
(
*
it
==
proc
)
{
do_rm
=
true
;
do_rm
=
true
;
LOGI
(
"hide_list rm: [%s]
\n
"
,
proc
);
LOGI
(
"hide_list rm: [%s]
\n
"
,
proc
);
free
(
*
it
);
hide_list
.
erase
(
it
);
hide_list
.
erase
(
it
);
break
;
break
;
}
}
...
@@ -199,45 +193,44 @@ static int rm_list(char *proc) {
...
@@ -199,45 +193,44 @@ static int rm_list(char *proc) {
kill_process
(
proc
);
kill_process
(
proc
);
sqlite3
*
db
=
get_magiskdb
();
sqlite3
*
db
=
get_magiskdb
();
if
(
db
==
nullptr
)
if
(
db
==
nullptr
)
goto
error
;
return
DAEMON_ERROR
;
char
sql
[
128
];
char
sql
[
128
];
sprintf
(
sql
,
"DELETE FROM hidelist WHERE process='%s'"
,
proc
);
sprintf
(
sql
,
"DELETE FROM hidelist WHERE process='%s'"
,
proc
);
sqlite3_exec
(
db
,
sql
,
nullptr
,
nullptr
,
nullptr
);
sqlite3_exec
(
db
,
sql
,
nullptr
,
nullptr
,
nullptr
);
sqlite3_close_v2
(
db
);
sqlite3_close_v2
(
db
);
ret
=
DAEMON_SUCCESS
;
ret
urn
DAEMON_SUCCESS
;
}
else
{
}
else
{
ret
=
HIDE_ITEM_NOT_EXIST
;
ret
urn
HIDE_ITEM_NOT_EXIST
;
}
}
error:
free
(
proc
);
return
ret
;
}
}
int
rm_list
(
int
client
)
{
int
rm_list
(
int
client
)
{
return
rm_list
(
read_string
(
client
));
char
*
proc
=
read_string
(
client
);
int
ret
=
rm_list
(
proc
);
free
(
proc
);
return
ret
;
}
}
#define LEGACY_LIST MOUNTPOINT "/.core/hidelist"
#define LEGACY_LIST MOUNTPOINT "/.core/hidelist"
int
init_list
()
{
bool
init_list
()
{
LOGD
(
"hide_list: initialize
\n
"
);
LOGD
(
"hide_list: initialize
\n
"
);
sqlite3
*
db
=
get_magiskdb
();
sqlite3
*
db
=
get_magiskdb
();
if
(
db
==
nullptr
)
if
(
db
==
nullptr
)
return
1
;
return
false
;
sqlite3_exec
(
db
,
"SELECT process FROM hidelist"
,
sqlite3_exec
(
db
,
"SELECT process FROM hidelist"
,
[]
(
auto
,
auto
,
char
**
data
,
auto
)
->
int
[]
(
auto
,
auto
,
char
**
data
,
auto
)
->
int
{
{
LOGI
(
"hide_list: [%s]
\n
"
,
data
[
0
]);
LOGI
(
"hide_list: [%s]
\n
"
,
data
[
0
]);
hide_list
.
push_back
(
strdup
(
data
[
0
])
);
hide_list
.
push_back
(
data
[
0
]
);
return
0
;
return
0
;
},
nullptr
,
nullptr
);
},
nullptr
,
nullptr
);
// Migrate old hide list into database
// Migrate old hide list into database
if
(
access
(
LEGACY_LIST
,
R_OK
)
==
0
)
{
if
(
access
(
LEGACY_LIST
,
R_OK
)
==
0
)
{
auto
tmp
=
Array
<
char
*>
()
;
Array
<
CharArray
>
tmp
;
file_to_array
(
LEGACY_LIST
,
tmp
);
file_to_array
(
LEGACY_LIST
,
tmp
);
for
(
auto
&
s
:
tmp
)
for
(
auto
&
s
:
tmp
)
add_list
(
db
,
s
);
add_list
(
db
,
s
);
...
@@ -245,14 +238,7 @@ int init_list() {
...
@@ -245,14 +238,7 @@ int init_list() {
}
}
sqlite3_close_v2
(
db
);
sqlite3_close_v2
(
db
);
return
0
;
return
true
;
}
int
destroy_list
()
{
for
(
auto
&
str
:
hide_list
)
free
(
str
);
hide_list
.
clear
();
return
0
;
}
}
void
ls_list
(
int
client
)
{
void
ls_list
(
int
client
)
{
...
...
native/jni/magiskhide/magiskhide.cpp
View file @
7c12bf7f
...
@@ -54,11 +54,11 @@ int launch_magiskhide() {
...
@@ -54,11 +54,11 @@ int launch_magiskhide() {
pthread_mutex_init
(
&
list_lock
,
nullptr
);
pthread_mutex_init
(
&
list_lock
,
nullptr
);
// Initialize the hide list
// Initialize the hide list
if
(
init_list
())
if
(
!
init_list
())
goto
error
;
goto
error
;
// Add SafetyNet by default
// Add SafetyNet by default
add_list
(
strdup
(
"com.google.android.gms.unstable"
)
);
add_list
(
"com.google.android.gms.unstable"
);
// Get thread reference
// Get thread reference
proc_monitor_thread
=
pthread_self
();
proc_monitor_thread
=
pthread_self
();
...
...
native/jni/magiskhide/magiskhide.h
View file @
7c12bf7f
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
#include "daemon.h"
#include "daemon.h"
#include "array.h"
#include "array.h"
#include "CharArray.h"
#define TERM_THREAD SIGUSR1
#define TERM_THREAD SIGUSR1
...
@@ -24,13 +25,12 @@ void hide_sensitive_props();
...
@@ -24,13 +25,12 @@ void hide_sensitive_props();
void
clean_magisk_props
();
void
clean_magisk_props
();
// List managements
// List managements
int
add_list
(
char
*
proc
);
int
add_list
(
const
char
*
proc
);
int
init_list
();
bool
init_list
();
int
destroy_list
();
extern
int
hide_enabled
;
extern
int
hide_enabled
;
extern
pthread_mutex_t
list_lock
;
extern
pthread_mutex_t
list_lock
;
extern
Array
<
char
*
>
hide_list
;
extern
Array
<
CharArray
>
hide_list
;
enum
{
enum
{
LAUNCH_MAGISKHIDE
,
LAUNCH_MAGISKHIDE
,
...
...
native/jni/magiskhide/proc_monitor.cpp
View file @
7c12bf7f
...
@@ -27,13 +27,13 @@ static int sockfd = -1;
...
@@ -27,13 +27,13 @@ static int sockfd = -1;
// Workaround for the lack of pthread_cancel
// Workaround for the lack of pthread_cancel
static
void
term_thread
(
int
)
{
static
void
term_thread
(
int
)
{
LOGD
(
"proc_monitor: running cleanup
\n
"
);
LOGD
(
"proc_monitor: running cleanup
\n
"
);
destroy_list
(
);
hide_list
.
clear
(
true
);
hide_enabled
=
0
;
hide_enabled
=
0
;
close
(
sockfd
);
close
(
sockfd
);
sockfd
=
-
1
;
sockfd
=
-
1
;
pthread_mutex_destroy
(
&
list_lock
);
pthread_mutex_destroy
(
&
list_lock
);
LOGD
(
"proc_monitor: terminating
\n
"
);
LOGD
(
"proc_monitor: terminating
\n
"
);
pthread_exit
(
NULL
);
pthread_exit
(
nullptr
);
}
}
static
int
read_ns
(
const
int
pid
,
struct
stat
*
st
)
{
static
int
read_ns
(
const
int
pid
,
struct
stat
*
st
)
{
...
@@ -63,7 +63,7 @@ static void hide_daemon(int pid) {
...
@@ -63,7 +63,7 @@ static void hide_daemon(int pid) {
LOGD
(
"hide_daemon: start unmount for pid=[%d]
\n
"
,
pid
);
LOGD
(
"hide_daemon: start unmount for pid=[%d]
\n
"
,
pid
);
char
buffer
[
PATH_MAX
];
char
buffer
[
PATH_MAX
];
auto
mounts
=
Array
<
char
*>
()
;
Array
<
CharArray
>
mounts
;
manage_selinux
();
manage_selinux
();
clean_magisk_props
();
clean_magisk_props
();
...
@@ -76,11 +76,10 @@ static void hide_daemon(int pid) {
...
@@ -76,11 +76,10 @@ static void hide_daemon(int pid) {
// Unmount dummy skeletons and /sbin links
// Unmount dummy skeletons and /sbin links
for
(
auto
&
s
:
mounts
)
{
for
(
auto
&
s
:
mounts
)
{
if
(
s
trstr
(
s
,
"tmpfs /system/"
)
||
strstr
(
s
,
"tmpfs /vendor/"
)
||
strstr
(
s
,
"tmpfs /sbin"
))
{
if
(
s
.
contains
(
"tmpfs /system/"
)
||
s
.
contains
(
"tmpfs /vendor/"
)
||
s
.
contains
(
"tmpfs /sbin"
))
{
sscanf
(
s
,
"%*s %4096s"
,
buffer
);
sscanf
(
s
,
"%*s %4096s"
,
buffer
);
lazy_unmount
(
buffer
);
lazy_unmount
(
buffer
);
}
}
free
(
s
);
}
}
mounts
.
clear
();
mounts
.
clear
();
...
@@ -90,13 +89,11 @@ static void hide_daemon(int pid) {
...
@@ -90,13 +89,11 @@ static void hide_daemon(int pid) {
// Unmount everything under /system, /vendor, and loop mounts
// Unmount everything under /system, /vendor, and loop mounts
for
(
auto
&
s
:
mounts
)
{
for
(
auto
&
s
:
mounts
)
{
if
(
s
trstr
(
s
,
"/dev/block/loop"
)
||
strstr
(
s
,
" /system/"
)
||
strstr
(
s
,
" /vendor/"
))
{
if
(
s
.
contains
(
"/dev/block/loop"
)
||
s
.
contains
(
" /system/"
)
||
s
.
contains
(
" /vendor/"
))
{
sscanf
(
s
,
"%*s %4096s"
,
buffer
);
sscanf
(
s
,
"%*s %4096s"
,
buffer
);
lazy_unmount
(
buffer
);
lazy_unmount
(
buffer
);
}
}
free
(
s
);
}
}
mounts
.
clear
();
exit:
exit:
// Send resume signal
// Send resume signal
...
@@ -159,7 +156,7 @@ void proc_monitor() {
...
@@ -159,7 +156,7 @@ void proc_monitor() {
bool
hide
=
false
;
bool
hide
=
false
;
pthread_mutex_lock
(
&
list_lock
);
pthread_mutex_lock
(
&
list_lock
);
for
(
auto
&
s
:
hide_list
)
{
for
(
auto
&
s
:
hide_list
)
{
if
(
s
trcmp
(
proc
,
s
)
==
0
)
{
if
(
s
==
proc
)
{
hide
=
true
;
hide
=
true
;
break
;
break
;
}
}
...
...
native/jni/resetprop/_resetprop.h
View file @
7c12bf7f
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
#ifndef MAGISK_PROPS_H
#ifndef MAGISK_PROPS_H
#define MAGISK_PROPS_H
#define MAGISK_PROPS_H
#include <CharArray.h>
#include "resetprop/private/system_properties.h"
#include "resetprop/private/system_properties.h"
#include "logging.h"
#include "logging.h"
...
@@ -48,7 +49,7 @@ struct read_cb_t {
...
@@ -48,7 +49,7 @@ struct read_cb_t {
extern
bool
use_pb
;
extern
bool
use_pb
;
char
*
persist_getprop
(
const
char
*
name
);
CharArray
persist_getprop
(
const
char
*
name
);
void
persist_getprop
(
read_cb_t
*
read_cb
);
void
persist_getprop
(
read_cb_t
*
read_cb
);
bool
persist_deleteprop
(
const
char
*
name
);
bool
persist_deleteprop
(
const
char
*
name
);
void
collect_props
(
const
char
*
name
,
const
char
*
value
,
void
*
v_plist
);
void
collect_props
(
const
char
*
name
,
const
char
*
value
,
void
*
v_plist
);
...
...
native/jni/resetprop/persist_properties.cpp
View file @
7c12bf7f
...
@@ -190,21 +190,21 @@ void persist_getprop(read_cb_t *read_cb) {
...
@@ -190,21 +190,21 @@ void persist_getprop(read_cb_t *read_cb) {
}
}
}
}
char
*
persist_getprop
(
const
char
*
name
)
{
CharArray
persist_getprop
(
const
char
*
name
)
{
prop_t
prop
(
name
);
prop_t
prop
(
name
);
if
(
use_pb
)
{
if
(
use_pb
)
{
read_cb_t
read_cb
(
pb_getprop_cb
,
&
prop
);
read_cb_t
read_cb
(
pb_getprop_cb
,
&
prop
);
pb_getprop
(
&
read_cb
);
pb_getprop
(
&
read_cb
);
if
(
prop
.
value
[
0
])
if
(
prop
.
value
[
0
])
return
strdup
(
prop
.
value
)
;
return
prop
.
value
;
}
else
{
}
else
{
// Try to read from file
// Try to read from file
char
value
[
PROP_VALUE_MAX
];
char
value
[
PROP_VALUE_MAX
];
file_getprop
(
name
,
value
);
file_getprop
(
name
,
value
);
if
(
value
[
0
])
if
(
value
[
0
])
return
strdup
(
value
)
;
return
value
;
}
}
return
nullptr
;
return
CharArray
()
;
}
}
bool
persist_deleteprop
(
const
char
*
name
)
{
bool
persist_deleteprop
(
const
char
*
name
)
{
...
...
native/jni/resetprop/resetprop.cpp
View file @
7c12bf7f
...
@@ -130,18 +130,18 @@ int prop_exist(const char *name) {
...
@@ -130,18 +130,18 @@ int prop_exist(const char *name) {
}
}
// Get prop by name, return string (should free manually!)
// Get prop by name, return string (should free manually!)
char
*
getprop
(
const
char
*
name
,
bool
persist
)
{
CharArray
getprop
(
const
char
*
name
,
bool
persist
)
{
if
(
!
check_legal_property_name
(
name
)
||
init_resetprop
())
if
(
!
check_legal_property_name
(
name
)
||
init_resetprop
())
return
nullptr
;
return
nullptr
;
const
prop_info
*
pi
=
__system_property_find
(
name
);
const
prop_info
*
pi
=
__system_property_find
(
name
);
if
(
pi
==
nullptr
)
{
if
(
pi
==
nullptr
)
{
if
(
persist
&&
strncmp
(
name
,
"persist."
,
8
)
==
0
)
{
if
(
persist
&&
strncmp
(
name
,
"persist."
,
8
)
==
0
)
{
char
*
value
=
persist_getprop
(
name
);
CharArray
value
=
persist_getprop
(
name
);
if
(
value
)
if
(
!
value
.
empty
()
)
return
value
;
return
value
;
}
}
LOGD
(
"resetprop: prop [%s] does not exist
\n
"
,
name
);
LOGD
(
"resetprop: prop [%s] does not exist
\n
"
,
name
);
return
nullptr
;
return
CharArray
()
;
}
else
{
}
else
{
char
value
[
PROP_VALUE_MAX
];
char
value
[
PROP_VALUE_MAX
];
read_cb_t
read_cb
;
read_cb_t
read_cb
;
...
@@ -149,7 +149,7 @@ char *getprop(const char *name, bool persist) {
...
@@ -149,7 +149,7 @@ char *getprop(const char *name, bool persist) {
read_cb
.
arg
=
value
;
read_cb
.
arg
=
value
;
read_props
(
pi
,
&
read_cb
);
read_props
(
pi
,
&
read_cb
);
LOGD
(
"resetprop: getprop [%s]: [%s]
\n
"
,
name
,
value
);
LOGD
(
"resetprop: getprop [%s]: [%s]
\n
"
,
name
,
value
);
return
strdup
(
value
)
;
return
value
;
}
}
}
}
...
@@ -254,7 +254,8 @@ int resetprop_main(int argc, char *argv[]) {
...
@@ -254,7 +254,8 @@ int resetprop_main(int argc, char *argv[]) {
log_cb
.
d
=
[](
auto
fmt
,
auto
ap
)
->
int
{
return
verbose
?
vfprintf
(
stderr
,
fmt
,
ap
)
:
0
;
};
log_cb
.
d
=
[](
auto
fmt
,
auto
ap
)
->
int
{
return
verbose
?
vfprintf
(
stderr
,
fmt
,
ap
)
:
0
;
};
bool
trigger
=
true
,
persist
=
false
;
bool
trigger
=
true
,
persist
=
false
;
char
*
argv0
=
argv
[
0
],
*
prop
;
char
*
argv0
=
argv
[
0
];
CharArray
prop
;
--
argc
;
--
argc
;
++
argv
;
++
argv
;
...
@@ -297,10 +298,9 @@ int resetprop_main(int argc, char *argv[]) {
...
@@ -297,10 +298,9 @@ int resetprop_main(int argc, char *argv[]) {
print_props
(
persist
);
print_props
(
persist
);
return
0
;
return
0
;
case
1
:
case
1
:
prop
=
getprop
(
argv
[
0
],
persist
);
prop
=
utils
::
move
(
getprop
(
argv
[
0
],
persist
));
if
(
prop
==
nullptr
)
return
1
;
if
(
!
prop
)
return
1
;
printf
(
"%s
\n
"
,
prop
);
printf
(
"%s
\n
"
,
prop
.
c_str
());
free
(
prop
);
return
0
;
return
0
;
case
2
:
case
2
:
return
setprop
(
argv
[
0
],
argv
[
1
],
trigger
);
return
setprop
(
argv
[
0
],
argv
[
1
],
trigger
);
...
...
native/jni/utils/Android.mk
View file @
7c12bf7f
...
@@ -9,6 +9,7 @@ LOCAL_SRC_FILES := \
...
@@ -9,6 +9,7 @@ LOCAL_SRC_FILES := \
selinux.cpp \
selinux.cpp \
logging.cpp \
logging.cpp \
xwrap.cpp \
xwrap.cpp \
CharArray.cpp \
vector.c
vector.c
include $(BUILD_STATIC_LIBRARY)
include $(BUILD_STATIC_LIBRARY)
native/jni/utils/CharArray.cpp
0 → 100644
View file @
7c12bf7f
#include "CharArray.h"
#include "utils.h"
CharArray
::
CharArray
()
:
_buf
(
nullptr
),
_size
(
0
){}
CharArray
::
CharArray
(
const
char
*
s
)
:
CharArray
()
{
this
->
operator
=
(
s
);
}
CharArray
::
CharArray
(
const
CharArray
&
s
)
:
CharArray
()
{
this
->
operator
=
(
s
);
}
CharArray
::
CharArray
(
size_t
i
)
{
_size
=
i
;
_buf
=
new
char
[
i
]();
/* Zero initialize */
}
CharArray
::~
CharArray
()
{
delete
[]
_buf
;
}
CharArray
::
operator
char
*
()
{
return
_buf
;
}
CharArray
::
operator
const
char
*
()
const
{
return
_buf
;
}
const
char
*
CharArray
::
c_str
()
const
{
return
_buf
;
}
size_t
CharArray
::
length
()
const
{
return
strlen
(
_buf
);
}
size_t
CharArray
::
size
()
const
{
return
_size
;
}
CharArray
&
CharArray
::
operator
=
(
const
CharArray
&
s
)
{
delete
[]
_buf
;
_size
=
s
.
_size
;
_buf
=
new
char
[
_size
];
memcpy
(
_buf
,
s
.
_buf
,
_size
);
return
*
this
;
}
CharArray
&
CharArray
::
operator
=
(
const
char
*
s
)
{
delete
[]
_buf
;
_buf
=
strdup2
(
s
,
&
_size
);
return
*
this
;
}
CharArray
&
CharArray
::
operator
=
(
CharArray
&&
s
)
{
delete
[]
_buf
;
_size
=
s
.
_size
;
_buf
=
s
.
_buf
;
s
.
_buf
=
nullptr
;
s
.
_size
=
0
;
return
*
this
;
}
bool
CharArray
::
operator
==
(
const
char
*
s
)
const
{
if
(
_buf
==
nullptr
||
s
==
nullptr
)
return
false
;
return
strcmp
(
_buf
,
s
)
==
0
;
}
bool
CharArray
::
operator
==
(
char
*
s
)
const
{
return
*
this
==
(
const
char
*
)
s
;
}
bool
CharArray
::
operator
!=
(
const
char
*
s
)
const
{
return
!
(
*
this
==
s
);
}
int
CharArray
::
compare
(
const
char
*
s
)
const
{
return
strcmp
(
_buf
,
s
);
}
int
CharArray
::
compare
(
const
char
*
s
,
size_t
len
)
const
{
return
strncmp
(
_buf
,
s
,
len
);
}
bool
CharArray
::
contains
(
const
char
*
s
)
const
{
return
strstr
(
_buf
,
s
)
!=
nullptr
;
}
bool
CharArray
::
starts_with
(
const
char
*
s
)
const
{
return
compare
(
s
,
strlen
(
s
))
==
0
;
}
bool
CharArray
::
empty
()
const
{
return
_buf
==
nullptr
||
_buf
[
0
]
==
'\0'
;
}
native/jni/utils/file.cpp
View file @
7c12bf7f
...
@@ -388,7 +388,7 @@ void write_zero(int fd, size_t size) {
...
@@ -388,7 +388,7 @@ void write_zero(int fd, size_t size) {
lseek
(
fd
,
pos
+
size
,
SEEK_SET
);
lseek
(
fd
,
pos
+
size
,
SEEK_SET
);
}
}
int
file_to_array
(
const
char
*
filename
,
Array
<
char
*
>
&
arr
)
{
int
file_to_array
(
const
char
*
filename
,
Array
<
CharArray
>
&
arr
)
{
if
(
access
(
filename
,
R_OK
)
!=
0
)
if
(
access
(
filename
,
R_OK
)
!=
0
)
return
1
;
return
1
;
char
*
line
=
nullptr
;
char
*
line
=
nullptr
;
...
@@ -404,8 +404,8 @@ int file_to_array(const char *filename, Array<char *> &arr) {
...
@@ -404,8 +404,8 @@ int file_to_array(const char *filename, Array<char *> &arr) {
if
(
line
[
read
-
1
]
==
'\n'
)
if
(
line
[
read
-
1
]
==
'\n'
)
line
[
read
-
1
]
=
'\0'
;
line
[
read
-
1
]
=
'\0'
;
arr
.
push_back
(
line
);
arr
.
push_back
(
line
);
line
=
nullptr
;
}
}
fclose
(
fp
);
fclose
(
fp
);
free
(
line
);
return
0
;
return
0
;
}
}
native/jni/utils/include/CharArray.h
0 → 100644
View file @
7c12bf7f
#pragma once
#include <string.h>
/* A wrapper around char array */
class
CharArray
{
public
:
CharArray
();
CharArray
(
const
char
*
s
);
CharArray
(
const
CharArray
&
s
);
CharArray
(
size_t
i
);
~
CharArray
();
CharArray
&
operator
=
(
const
CharArray
&
s
);
CharArray
&
operator
=
(
CharArray
&&
s
);
CharArray
&
operator
=
(
const
char
*
s
);
operator
char
*
();
operator
const
char
*
()
const
;
bool
operator
==
(
char
*
s
)
const
;
bool
operator
==
(
const
char
*
s
)
const
;
bool
operator
!=
(
const
char
*
s
)
const
;
int
compare
(
const
char
*
s
)
const
;
int
compare
(
const
char
*
s
,
size_t
len
)
const
;
bool
starts_with
(
const
char
*
s
)
const
;
bool
contains
(
const
char
*
s
)
const
;
bool
empty
()
const
;
const
char
*
c_str
()
const
;
size_t
length
()
const
;
size_t
size
()
const
;
/* These 2 ops are incompatible with implicit char* conversion */
// char &operator[](size_t i);
// const char &operator[](size_t i) const;
private
:
char
*
_buf
;
size_t
_size
;
};
native/jni/utils/include/array.h
View file @
7c12bf7f
#pragma once
#pragma once
#include <stdlib.h>
#include <stdlib.h>
#include "cpputils.h"
template
<
class
T
>
template
<
class
T
>
class
Array
{
class
Array
{
...
@@ -72,7 +73,7 @@ public:
...
@@ -72,7 +73,7 @@ public:
if
(
_capacity
)
{
if
(
_capacity
)
{
_data
=
new
T
[
_capacity
];
_data
=
new
T
[
_capacity
];
for
(
int
i
=
0
;
i
<
_size
;
++
i
)
for
(
int
i
=
0
;
i
<
_size
;
++
i
)
_data
[
i
]
=
(
T
&&
)
a
[
i
]
;
_data
[
i
]
=
utils
::
move
(
a
[
i
])
;
}
}
return
*
this
;
return
*
this
;
}
}
...
@@ -101,7 +102,7 @@ public:
...
@@ -101,7 +102,7 @@ public:
void
push_back
(
T
&&
x
)
{
void
push_back
(
T
&&
x
)
{
if
(
_size
==
_capacity
)
if
(
_size
==
_capacity
)
expand
();
expand
();
_data
[
_size
]
=
(
T
&&
)
x
;
_data
[
_size
]
=
utils
::
move
(
x
)
;
++
_size
;
++
_size
;
}
}
...
@@ -114,7 +115,7 @@ public:
...
@@ -114,7 +115,7 @@ public:
if
(
_size
==
0
||
d
<
_data
||
d
>=
_data
+
_size
)
if
(
_size
==
0
||
d
<
_data
||
d
>=
_data
+
_size
)
return
false
;
return
false
;
for
(;
d
<
_data
+
_size
-
1
;
++
d
)
for
(;
d
<
_data
+
_size
-
1
;
++
d
)
*
d
=
(
T
&&
)
*
(
d
+
1
);
*
d
=
utils
::
move
(
*
(
d
+
1
)
);
--
_size
;
--
_size
;
return
true
;
return
true
;
...
@@ -130,9 +131,16 @@ public:
...
@@ -130,9 +131,16 @@ public:
return
false
;
return
false
;
}
}
void
clear
()
{
_size
=
0
;
}
void
clear
(
bool
dealloc
=
false
)
{
_size
=
0
;
if
(
dealloc
)
{
_capacity
=
0
;
delete
[]
_data
;
_data
=
nullptr
;
}
}
void
sort
()
const
{
void
sort
()
{
qsort
(
_data
,
_size
,
sizeof
(
T
),
compare
);
qsort
(
_data
,
_size
,
sizeof
(
T
),
compare
);
}
}
...
@@ -161,7 +169,7 @@ private:
...
@@ -161,7 +169,7 @@ private:
T
*
temp
=
_data
;
T
*
temp
=
_data
;
_data
=
new
T
[
_capacity
];
_data
=
new
T
[
_capacity
];
for
(
int
i
=
0
;
i
<
_size
;
++
i
)
for
(
int
i
=
0
;
i
<
_size
;
++
i
)
_data
[
i
]
=
(
T
&&
)
temp
[
i
]
;
_data
[
i
]
=
utils
::
move
(
temp
[
i
])
;
delete
[]
temp
;
delete
[]
temp
;
}
}
};
};
...
...
native/jni/utils/include/cpputils.h
0 → 100644
View file @
7c12bf7f
#pragma once
namespace
utils
{
template
<
class
T
>
struct
remove_reference
{
typedef
T
type
;};
template
<
class
T
>
struct
remove_reference
<
T
&>
{
typedef
T
type
;};
template
<
class
T
>
struct
remove_reference
<
T
&&>
{
typedef
T
type
;};
template
<
class
T
>
constexpr
typename
remove_reference
<
T
>::
type
&&
move
(
T
&&
t
)
noexcept
{
return
static_cast
<
typename
remove_reference
<
T
>::
type
&&>
(
t
);
}
}
\ No newline at end of file
native/jni/utils/include/utils.h
View file @
7c12bf7f
...
@@ -12,9 +12,15 @@
...
@@ -12,9 +12,15 @@
#include <sys/stat.h>
#include <sys/stat.h>
#ifdef __cplusplus
#ifdef __cplusplus
// C++ only
#include "array.h"
#include "array.h"
int
file_to_array
(
const
char
*
filename
,
Array
<
char
*>
&
arr
);
#include "CharArray.h"
#include "cpputils.h"
int
file_to_array
(
const
char
*
filename
,
Array
<
CharArray
>
&
arr
);
char
*
strdup2
(
const
char
*
s
,
size_t
*
size
=
nullptr
);
extern
"C"
{
extern
"C"
{
#endif
#endif
...
...
native/jni/utils/misc.cpp
View file @
7c12bf7f
...
@@ -268,3 +268,11 @@ int exec_command(int err, int *fd, void (*cb)(void), const char *argv0, ...) {
...
@@ -268,3 +268,11 @@ int exec_command(int err, int *fd, void (*cb)(void), const char *argv0, ...) {
va_end
(
argv
);
va_end
(
argv
);
return
pid
;
return
pid
;
}
}
char
*
strdup2
(
const
char
*
s
,
size_t
*
size
)
{
size_t
l
=
strlen
(
s
)
+
1
;
char
*
buf
=
new
char
[
l
];
memcpy
(
buf
,
s
,
l
);
if
(
size
)
*
size
=
l
;
return
buf
;
}
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