forked from sim1222-mirror/wrapper
Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
ab287a2b69 | |||
|
4459548fb3 | ||
|
6ffd3585b6 | ||
|
3b3a73bb60 |
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@ -27,6 +27,9 @@ jobs:
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
|
||||
- name: Set outputs
|
||||
@ -41,3 +44,6 @@ jobs:
|
||||
path: |
|
||||
rootfs
|
||||
wrapper
|
||||
Dockerfile
|
||||
|
||||
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -89,3 +89,4 @@ rootfs/
|
||||
.vscode/
|
||||
wrapper
|
||||
rootfs/system/bin/linker64
|
||||
build/
|
58
CMakeLists.txt
Normal file
58
CMakeLists.txt
Normal file
@ -0,0 +1,58 @@
|
||||
cmake_minimum_required(VERSION 3.25)
|
||||
|
||||
project(wrapper)
|
||||
include(ExternalProject)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
set(ANDROID_NDK_PATH "$ENV{HOME}/android-ndk-r23b")
|
||||
set(TOOLCHAIN "${ANDROID_NDK_PATH}/toolchains/llvm/prebuilt/linux-x86_64")
|
||||
|
||||
set(CMAKE_C_COMPILER "${TOOLCHAIN}/bin/x86_64-linux-android22-clang")
|
||||
set(CMAKE_CXX_COMPILER "${TOOLCHAIN}/bin/x86_64-linux-android22-clang++")
|
||||
set(C_COMPILER "${TOOLCHAIN}/bin/clang")
|
||||
|
||||
set(CMAKE_C_FLAGS "-Wall -Werror -O3")
|
||||
set(CMAKE_CXX_FLAGS "-Wall -Werror -O3")
|
||||
|
||||
set(CMDLINE_SOURCE cmdline.c)
|
||||
set(HANDLE_SOURCE main.cpp)
|
||||
set(MAIN_SOURCE main.c)
|
||||
set(WRAPPER_SOURCE wrapper.c)
|
||||
|
||||
add_library(cmdline_object OBJECT ${CMDLINE_SOURCE})
|
||||
add_library(handle_object OBJECT ${HANDLE_SOURCE})
|
||||
|
||||
add_executable(main ${MAIN_SOURCE} $<TARGET_OBJECTS:cmdline_object> $<TARGET_OBJECTS:handle_object>)
|
||||
|
||||
set_target_properties(main PROPERTIES
|
||||
COMPILE_DEFINITIONS "MyRelease"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/rootfs/system/bin"
|
||||
)
|
||||
|
||||
find_library(ANDROIDAPPMUSIC_LIB androidappmusic PATHS ${CMAKE_SOURCE_DIR}/rootfs/system/lib64)
|
||||
find_library(STORESERVICESCORE_LIB storeservicescore PATHS ${CMAKE_SOURCE_DIR}/rootfs/system/lib64)
|
||||
find_library(MEDIAPLATFORM_LIB mediaplatform PATHS ${CMAKE_SOURCE_DIR}/rootfs/system/lib64)
|
||||
find_library(CXX_SHARED_LIB c++_shared PATHS ${CMAKE_SOURCE_DIR}/rootfs/system/lib64)
|
||||
|
||||
# Link libraries
|
||||
target_link_libraries(main
|
||||
${CXX_SHARED_LIB}
|
||||
${ANDROIDAPPMUSIC_LIB}
|
||||
${STORESERVICESCORE_LIB}
|
||||
${MEDIAPLATFORM_LIB}
|
||||
)
|
||||
|
||||
link_directories(${CMAKE_SOURCE_DIR}/rootfs/system/lib64)
|
||||
|
||||
ExternalProject_Add(
|
||||
wrapper
|
||||
PREFIX ${CMAKE_BINARY_DIR}
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ${C_COMPILER} -O3 -Wall -o wrapper ${WRAPPER_SOURCE}
|
||||
BUILD_IN_SOURCE 1
|
||||
INSTALL_COMMAND ""
|
||||
DEPENDS main
|
||||
)
|
26
Dockerfile
Normal file
26
Dockerfile
Normal file
@ -0,0 +1,26 @@
|
||||
FROM ubuntu:latest AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt update && \
|
||||
apt install aria2 lsb-release wget software-properties-common gnupg unzip build-essential cmake -y
|
||||
|
||||
RUN bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
|
||||
|
||||
RUN aria2c -o android-ndk-r23b-linux.zip https://dl.google.com/android/repository/android-ndk-r23b-linux.zip
|
||||
RUN unzip -q -d ~ android-ndk-r23b-linux.zip
|
||||
|
||||
COPY . /app
|
||||
|
||||
RUN mkdir /app/build && cd /app/build && cmake .. && make
|
||||
|
||||
FROM ubuntu:latest
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/rootfs/ /app/rootfs/
|
||||
COPY --from=builder /app/wrapper /app/
|
||||
ENV args ""
|
||||
|
||||
CMD ["bash", "-c", "./wrapper ${args}"]
|
||||
|
||||
EXPOSE 10020 10020
|
16
Makefile
16
Makefile
@ -1,16 +0,0 @@
|
||||
all: cmdline.o handle.o main wrapper
|
||||
|
||||
cmdline.o:
|
||||
~/android-ndk-r23b/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android22-clang -Wall -Werror -nostdlib -c -O3 -o cmdline.o cmdline.c
|
||||
|
||||
handle.o: main.cpp
|
||||
~/android-ndk-r23b/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android22-clang++ -Wall -Werror -nostdlib -c -O3 -o handle.o main.cpp
|
||||
|
||||
main: handle.o test.c cmdline.o
|
||||
~/android-ndk-r23b/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android22-clang -DMyRelease -Wall -Werror -L ./rootfs/system/lib64 -landroidappmusic -lstoreservicescore -lmediaplatform -lc++_shared -O3 -Wall -o rootfs/system/bin/main cmdline.o handle.o test.c
|
||||
|
||||
wrapper: wrapper.c
|
||||
~/android-ndk-r23b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang -O3 -Wall -o wrapper wrapper.c
|
||||
|
||||
clean:
|
||||
rm handle.o wrapper rootfs/system/bin/main cmdline.o
|
34
README.md
34
README.md
@ -3,10 +3,24 @@
|
||||
No need for an Android emulator to decrypt ALAC files. All files from anonymous.
|
||||
|
||||
### Recommended Environment
|
||||
#### x86_64 only
|
||||
#### Only support Linux x86_64 and arm64.
|
||||
For best results, it's recommended to use **Windows Subsystem for Linux (WSL)**.
|
||||
|
||||
# Special thanks
|
||||
- Anonymous, for providing the original version of this project and the legacy Frida decryption method.
|
||||
- chocomint, for providing support for arm64 arch.
|
||||
|
||||
---
|
||||
### Version 2 Docker
|
||||
Available for x86_64 and arm64. Need to download prebuilt version from releases or actions.
|
||||
|
||||
Build image: `docker build --tag wrapper .`
|
||||
|
||||
Login: `docker run -v ./rootfs/data:/app/rootfs/data -p 10020:10020 -e args="-L username:password -F -H 0.0.0.0" wrapper`
|
||||
|
||||
Run: `docker run -v ./rootfs/data:/app/rootfs/data -p 10020:10020 -e args="-H 0.0.0.0" wrapper`
|
||||
|
||||
|
||||
|
||||
### Version 2
|
||||
|
||||
@ -21,22 +35,32 @@ For best results, it's recommended to use **Windows Subsystem for Linux (WSL)**.
|
||||
-P, --proxy=STRING (default: `''`)
|
||||
-L, --login=STRING ([username]:[password])
|
||||
```
|
||||
#### Installation:
|
||||
#### Installation x86_64:
|
||||
```shell
|
||||
sudo -i
|
||||
wget "https://github.com/zhaarey/wrapper/releases/download/linux.V2/wrapper.linux.x86_64.V2.tar.gz"
|
||||
wget "https://github.com/zhaarey/wrapper/releases/download/linux.V2/wrapper.x86_64.tar.gz"
|
||||
mkdir wrapper
|
||||
tar -xzf wrapper.linux.x86_64.V2.tar.gz -C wrapper
|
||||
tar -xzf wrapper.x86_64.tar.gz -C wrapper
|
||||
cd wrapper
|
||||
./wrapper
|
||||
```
|
||||
#### Installation arm64:
|
||||
```shell
|
||||
sudo -i
|
||||
wget "https://github.com/zhaarey/wrapper/releases/download/arm64/wrapper.arm64.tar.gz"
|
||||
mkdir wrapper
|
||||
tar -xzf wrapper.arm64.tar.gz -C wrapper
|
||||
cd wrapper
|
||||
./wrapper
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
### Version 1
|
||||
#### Usage:
|
||||
`./wrapper [port] ([username] [password])`
|
||||
#### Installation:
|
||||
#### Installation only x86_64:
|
||||
```shell
|
||||
sudo -i
|
||||
wget "https://github.com/zhaarey/wrapper/releases/download/linux/wrapper.linux.x86_64.tar.gz"
|
||||
|
30
cmdline.c
30
cmdline.c
@ -1,7 +1,7 @@
|
||||
/*
|
||||
File autogenerated by gengetopt version 2.23
|
||||
generated with the following command:
|
||||
gengetopt -i wrapper.ggo
|
||||
gengetopt
|
||||
|
||||
The developers of gengetopt consider the fixed text that goes in all
|
||||
gengetopt output files to be in the public domain:
|
||||
@ -40,11 +40,13 @@ const char *gengetopt_args_info_help[] = {
|
||||
" -D, --decrypt-port=INT (default=`10020')",
|
||||
" -M, --m3u8-port=INT (default=`20020')",
|
||||
" -P, --proxy=STRING (default=`')",
|
||||
" -L, --login=STRING ",
|
||||
" -L, --login=STRING username:password",
|
||||
" -F, --code-from-file (default=off)",
|
||||
0
|
||||
};
|
||||
|
||||
typedef enum {ARG_NO
|
||||
, ARG_FLAG
|
||||
, ARG_STRING
|
||||
, ARG_INT
|
||||
} cmdline_parser_arg_type;
|
||||
@ -72,6 +74,7 @@ void clear_given (struct gengetopt_args_info *args_info)
|
||||
args_info->m3u8_port_given = 0 ;
|
||||
args_info->proxy_given = 0 ;
|
||||
args_info->login_given = 0 ;
|
||||
args_info->code_from_file_given = 0 ;
|
||||
}
|
||||
|
||||
static
|
||||
@ -88,6 +91,7 @@ void clear_args (struct gengetopt_args_info *args_info)
|
||||
args_info->proxy_orig = NULL;
|
||||
args_info->login_arg = NULL;
|
||||
args_info->login_orig = NULL;
|
||||
args_info->code_from_file_flag = 0;
|
||||
|
||||
}
|
||||
|
||||
@ -103,6 +107,7 @@ void init_args_info(struct gengetopt_args_info *args_info)
|
||||
args_info->m3u8_port_help = gengetopt_args_info_help[4] ;
|
||||
args_info->proxy_help = gengetopt_args_info_help[5] ;
|
||||
args_info->login_help = gengetopt_args_info_help[6] ;
|
||||
args_info->code_from_file_help = gengetopt_args_info_help[7] ;
|
||||
|
||||
}
|
||||
|
||||
@ -244,6 +249,8 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
|
||||
write_into_file(outfile, "proxy", args_info->proxy_orig, 0);
|
||||
if (args_info->login_given)
|
||||
write_into_file(outfile, "login", args_info->login_orig, 0);
|
||||
if (args_info->code_from_file_given)
|
||||
write_into_file(outfile, "code-from-file", 0, 0 );
|
||||
|
||||
|
||||
i = EXIT_SUCCESS;
|
||||
@ -410,6 +417,9 @@ int update_arg(void *field, char **orig_field,
|
||||
val = possible_values[found];
|
||||
|
||||
switch(arg_type) {
|
||||
case ARG_FLAG:
|
||||
*((int *)field) = !*((int *)field);
|
||||
break;
|
||||
case ARG_INT:
|
||||
if (val) *((int *)field) = strtol (val, &stop_char, 0);
|
||||
break;
|
||||
@ -440,6 +450,7 @@ int update_arg(void *field, char **orig_field,
|
||||
/* store the original value */
|
||||
switch(arg_type) {
|
||||
case ARG_NO:
|
||||
case ARG_FLAG:
|
||||
break;
|
||||
default:
|
||||
if (value && orig_field) {
|
||||
@ -507,10 +518,11 @@ cmdline_parser_internal (
|
||||
{ "m3u8-port", 1, NULL, 'M' },
|
||||
{ "proxy", 1, NULL, 'P' },
|
||||
{ "login", 1, NULL, 'L' },
|
||||
{ "code-from-file", 0, NULL, 'F' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "hVH:D:M:P:L:", long_options, &option_index);
|
||||
c = getopt_long (argc, argv, "hVH:D:M:P:L:F", long_options, &option_index);
|
||||
|
||||
if (c == -1) break; /* Exit from `while (1)' loop. */
|
||||
|
||||
@ -574,7 +586,7 @@ cmdline_parser_internal (
|
||||
goto failure;
|
||||
|
||||
break;
|
||||
case 'L': /* . */
|
||||
case 'L': /* username:password. */
|
||||
|
||||
|
||||
if (update_arg( (void *)&(args_info->login_arg),
|
||||
@ -586,6 +598,16 @@ cmdline_parser_internal (
|
||||
goto failure;
|
||||
|
||||
break;
|
||||
case 'F': /* . */
|
||||
|
||||
|
||||
if (update_arg((void *)&(args_info->code_from_file_flag), 0, &(args_info->code_from_file_given),
|
||||
&(local_args_info.code_from_file_given), optarg, 0, 0, ARG_FLAG,
|
||||
check_ambiguity, override, 1, 0, "code-from-file", 'F',
|
||||
additional_error))
|
||||
goto failure;
|
||||
|
||||
break;
|
||||
|
||||
case 0: /* Long option with no short option */
|
||||
case '?': /* Invalid option. */
|
||||
|
@ -51,9 +51,11 @@ struct gengetopt_args_info
|
||||
char * proxy_arg; /**< @brief (default=''). */
|
||||
char * proxy_orig; /**< @brief original value given at command line. */
|
||||
const char *proxy_help; /**< @brief help description. */
|
||||
char * login_arg; /**< @brief . */
|
||||
char * login_orig; /**< @brief original value given at command line. */
|
||||
const char *login_help; /**< @brief help description. */
|
||||
char * login_arg; /**< @brief username:password. */
|
||||
char * login_orig; /**< @brief username:password original value given at command line. */
|
||||
const char *login_help; /**< @brief username:password help description. */
|
||||
int code_from_file_flag; /**< @brief (default=off). */
|
||||
const char *code_from_file_help; /**< @brief help description. */
|
||||
|
||||
unsigned int help_given ; /**< @brief Whether help was given. */
|
||||
unsigned int version_given ; /**< @brief Whether version was given. */
|
||||
@ -62,6 +64,7 @@ struct gengetopt_args_info
|
||||
unsigned int m3u8_port_given ; /**< @brief Whether m3u8-port was given. */
|
||||
unsigned int proxy_given ; /**< @brief Whether proxy was given. */
|
||||
unsigned int login_given ; /**< @brief Whether login was given. */
|
||||
unsigned int code_from_file_given ; /**< @brief Whether code-from-file was given. */
|
||||
|
||||
} ;
|
||||
|
||||
|
10
compose.yaml
Normal file
10
compose.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
services:
|
||||
wrapper:
|
||||
image: sim1222/wrapper:latest
|
||||
build: .
|
||||
volumes:
|
||||
- ./rootfs/data:/app/rootfs/data
|
||||
ports:
|
||||
- 10020:10020
|
||||
environment:
|
||||
- args="-H 0.0.0.0"
|
@ -10,6 +10,7 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "import.h"
|
||||
#include "cmdline.h"
|
||||
@ -22,6 +23,11 @@ static uint8_t leaseMgr[16];
|
||||
struct gengetopt_args_info args_info;
|
||||
char *amUsername, *amPassword;
|
||||
|
||||
int file_exists(char *filename) {
|
||||
struct stat buffer;
|
||||
return (stat (filename, &buffer) == 0);
|
||||
}
|
||||
|
||||
static void dialogHandler(long j, struct shared_ptr *protoDialogPtr,
|
||||
struct shared_ptr *respHandler) {
|
||||
const char *const title = std_string_data(
|
||||
@ -79,9 +85,33 @@ static void credentialHandler(struct shared_ptr *credReqHandler,
|
||||
int passLen = strlen(amPassword);
|
||||
|
||||
if (need2FA) {
|
||||
if (args_info.code_from_file_flag) {
|
||||
fprintf(stderr, "[!] Enter your 2FA code into rootfs/data/code.txt\n");
|
||||
fprintf(stderr, "[!] Example command: echo -n 114514 > rootfs/data/2fa.txt\n");
|
||||
fprintf(stderr, "[!] Waiting for input...\n");
|
||||
int count = 0;
|
||||
while (1)
|
||||
{
|
||||
if (count >= 20) {
|
||||
fprintf(stderr, "[!] Failed to get 2FA Code in 60s. Exiting...\n");
|
||||
exit(0);
|
||||
}
|
||||
if (file_exists("/data/2fa.txt")) {
|
||||
FILE *fp = fopen("/data/2fa.txt", "r");
|
||||
fscanf(fp, "%6s", amPassword + passLen);
|
||||
remove("/data/2fa.txt");
|
||||
fprintf(stderr, "[!] Code file detected! Logging in...\n");
|
||||
break;
|
||||
} else {
|
||||
sleep(3);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("2FA code: ");
|
||||
scanf("%6s", amPassword + passLen);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *const ptr = malloc(80);
|
||||
memset(ptr + 8, 0, 16);
|
||||
@ -435,16 +465,43 @@ inline static int new_socket() {
|
||||
const char* get_m3u8_method_play(uint8_t leaseMgr[16], unsigned long adam) {
|
||||
union std_string HLS = new_std_string_short_mode("HLS");
|
||||
struct std_vector HLSParam = new_std_vector(&HLS);
|
||||
static uint8_t z0 = 1;
|
||||
struct shared_ptr *ptr_result = (struct shared_ptr *) malloc(32);
|
||||
static uint8_t z0 = 0;
|
||||
struct shared_ptr ptr_result;
|
||||
_ZN22SVPlaybackLeaseManager12requestAssetERKmRKNSt6__ndk16vectorINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS7_IS9_EEEERKb(
|
||||
ptr_result, leaseMgr, &adam, &HLSParam, &z0
|
||||
&ptr_result, leaseMgr, &adam, &HLSParam, &z0
|
||||
);
|
||||
if (_ZNK23SVPlaybackAssetResponse13hasValidAssetEv(ptr_result->obj)) {
|
||||
struct shared_ptr *playbackAsset = _ZNK23SVPlaybackAssetResponse13playbackAssetEv(ptr_result->obj);
|
||||
union std_string *m3u8 = (union std_string *) malloc(24);
|
||||
_ZNK17storeservicescore13PlaybackAsset9URLStringEv(m3u8, playbackAsset->obj);
|
||||
return std_string_data(m3u8);
|
||||
|
||||
if (ptr_result.obj == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (_ZNK23SVPlaybackAssetResponse13hasValidAssetEv(ptr_result.obj)) {
|
||||
struct shared_ptr *playbackAsset = _ZNK23SVPlaybackAssetResponse13playbackAssetEv(ptr_result.obj);
|
||||
if (playbackAsset == NULL || playbackAsset->obj == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
union std_string *m3u8 = malloc(sizeof(union std_string));
|
||||
if (m3u8 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *playbackObj = playbackAsset->obj;
|
||||
_ZNK17storeservicescore13PlaybackAsset9URLStringEv(m3u8, playbackObj);
|
||||
|
||||
if (m3u8 == NULL || std_string_data(m3u8) == NULL) {
|
||||
free(m3u8);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *m3u8_str = std_string_data(m3u8);
|
||||
if (m3u8_str) {
|
||||
char *result = strdup(m3u8_str); // Make a copy
|
||||
free(m3u8);
|
||||
return result;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
@ -469,11 +526,17 @@ void handle_m3u8(const int connfd) {
|
||||
const char *m3u8 = get_m3u8_method_play(leaseMgr, adamID);
|
||||
if (m3u8 == NULL) {
|
||||
fprintf(stderr, "[.] failed to get m3u8 of adamId: %ld\n", adamID);
|
||||
writefull(connfd, NULL, sizeof(NULL));
|
||||
writefull(connfd, "\n", sizeof("\n"));
|
||||
} else {
|
||||
fprintf(stderr, "[.] m3u8 adamId: %ld, url: %s\n", adamID, m3u8);
|
||||
strcat((char *)m3u8, "\n");
|
||||
writefull(connfd, (void *)m3u8, strlen(m3u8));
|
||||
char *with_newline = malloc(strlen(m3u8) + 2);
|
||||
if (with_newline) {
|
||||
strcpy(with_newline, m3u8);
|
||||
strcat(with_newline, "\n");
|
||||
writefull(connfd, with_newline, strlen(with_newline));
|
||||
free(with_newline);
|
||||
}
|
||||
free((void *)m3u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -544,11 +607,9 @@ int main(int argc, char *argv[]) {
|
||||
_ZN22SVPlaybackLeaseManager12requestLeaseERKb(leaseMgr, &autom);
|
||||
FHinstance = _ZN21SVFootHillSessionCtrl8instanceEv();
|
||||
|
||||
if (args_info.m3u8_port_given) {
|
||||
pthread_t m3u8_thread;
|
||||
pthread_create(&m3u8_thread, NULL, &new_socket_m3u8, NULL);
|
||||
} else {
|
||||
fprintf(stderr, "[!] The feature of getting m3u8 is defaultly disabled because it's unstable now. To enable it, please manually specify m3u8-port param.\n");
|
||||
}
|
||||
pthread_detach(m3u8_thread);
|
||||
|
||||
return new_socket();
|
||||
}
|
10
wrapper.c
10
wrapper.c
@ -1,6 +1,6 @@
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
@ -35,21 +35,19 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
chmod("/system/bin/linker64", 0755);
|
||||
chmod("/system/bin/main", 0755);
|
||||
|
||||
if (unshare(CLONE_NEWPID)) {
|
||||
perror("unshare");
|
||||
return 1;
|
||||
}
|
||||
child_proc = fork();
|
||||
if (child_proc == -1) {
|
||||
perror("fork");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (child_proc > 0) {
|
||||
close(STDOUT_FILENO);
|
||||
wait(NULL);
|
||||
wait(NULL); // Parent waits for the child process to terminate
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Child process logic
|
||||
mkdir("/data/data/com.apple.android.music/files", 0777);
|
||||
mkdir("/data/data/com.apple.android.music/files/mpl_db", 0777);
|
||||
execve("/system/bin/main", argv, envp);
|
||||
|
@ -5,4 +5,5 @@ option "host" H "" string optional default="127.0.0.1"
|
||||
option "decrypt-port" D "" int optional default="10020"
|
||||
option "m3u8-port" M "" int optional default="20020"
|
||||
option "proxy" P "" string optional default=""
|
||||
option "login" L "" string optional
|
||||
option "login" L "username:password" string optional
|
||||
option "code-from-file" F "" flag off
|
||||
|
Loading…
x
Reference in New Issue
Block a user