main linux.V2
zhaarey 2 weeks ago
parent 976118d948
commit 1077660bcc
  1. 14
      .github/workflows/c-cpp.yml
  2. 91
      .gitignore
  3. 15
      Makefile
  4. 41
      README.md
  5. 617
      cmdline.c
  6. 193
      cmdline.h
  7. 1
      rootfs/data/data/com.apple.android.music/.gitkeep
  8. 1
      rootfs/dev/.gitkeep
  9. 65
      test.c
  10. 4
      wrapper.c
  11. 8
      wrapper.ggo

@ -23,19 +23,21 @@ jobs:
- name: Set up Android NDK r23b
run: |
aria2c -o android-ndk-r23b-linux.zip https://dl.google.com/android/repository/android-ndk-r23b-linux.zip
unzip -q android-ndk-r23b-linux.zip
unzip -q -d ~ android-ndk-r23b-linux.zip
- name: Build
run: |
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
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 handle.o test.c
clang -O3 -Wall -o wrapper wrapper.c
make
- name: Set outputs
id: vars
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: Wrapper.x86_64
name: Wrapper.x86_64.${{ steps.vars.outputs.sha_short }}
include-hidden-files: true
path: |
rootfs
handle.o
wrapper

91
.gitignore vendored

@ -0,0 +1,91 @@
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
rootfs/
.vscode/
wrapper
rootfs/system/bin/linker64

@ -1,13 +1,16 @@
all: handle.o main wrapper
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/standalone/bin/clang++ -Wall -Werror -nostdlib -c -O3 -o 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
~/android-ndk-r23b/standalone/bin/clang -DMyRelease -Wall -Werror -L ./rootfs/system/lib64 -landroidappmusic -lstoreservicescore -lmediaplatform -lc++_shared -O3 -Wall -o rootfs/system/bin/main handle.o test.c
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
clang -O3 -Wall -o 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
rm handle.o wrapper rootfs/system/bin/main cmdline.o

@ -1,12 +1,41 @@
# wrapper
All files from anonymous, No need for an Android emulator to decrypt alac
## Wrapper
No need for an Android emulator to decrypt ALAC files. This solution works on all files from Anonymous.
### 安装
推荐Windows Subsystem for Linux (WSL)使用
usage: `./wrapper [port] ([username] [password])`
get-m3u8为port+10000
### Recommended Environment
For best results, it's recommended to use **Windows Subsystem for Linux (WSL)**.
---
### Version 2
#### Usage:
```shell
./wrapper [OPTION]...
-h, --help Print help and exit
-V, --version Print version and exit
-H, --host=STRING (default: `127.0.0.1`)
-D, --decrypt-port=INT (default: `10020`)
-M, --m3u8-port=INT (default: `20020`)
-P, --proxy=STRING (default: `''`)
-L, --login=STRING ([username]:[password])
```
#### Installation:
```shell
sudo -i
wget "https://github.com/zhaarey/wrapper/releases/download/linux/wrapper.linux.x86_64.V2.tar.gz"
mkdir wrapper
tar -xzf wrapper.linux.x86_64.V2.tar.gz -C wrapper
cd wrapper
./wrapper
```
---
### Version 1
#### Usage:
`./wrapper [port] ([username] [password])`
#### Installation:
```shell
sudo -i
wget "https://github.com/zhaarey/wrapper/releases/download/linux/wrapper.linux.x86_64.tar.gz"

@ -0,0 +1,617 @@
/*
File autogenerated by gengetopt version 2.23
generated with the following command:
gengetopt -i wrapper.ggo
The developers of gengetopt consider the fixed text that goes in all
gengetopt output files to be in the public domain:
we make no copyright claims on it.
*/
/* If we use autoconf. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef FIX_UNUSED
#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */
#endif
#include <getopt.h>
#include "cmdline.h"
const char *gengetopt_args_info_purpose = "";
const char *gengetopt_args_info_usage = "Usage: wrapper [OPTION]...";
const char *gengetopt_args_info_versiontext = "";
const char *gengetopt_args_info_description = "";
const char *gengetopt_args_info_help[] = {
" -h, --help Print help and exit",
" -V, --version Print version and exit",
" -H, --host=STRING (default=`127.0.0.1')",
" -D, --decrypt-port=INT (default=`10020')",
" -M, --m3u8-port=INT (default=`20020')",
" -P, --proxy=STRING (default=`')",
" -L, --login=STRING ",
0
};
typedef enum {ARG_NO
, ARG_STRING
, ARG_INT
} cmdline_parser_arg_type;
static
void clear_given (struct gengetopt_args_info *args_info);
static
void clear_args (struct gengetopt_args_info *args_info);
static int
cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info,
struct cmdline_parser_params *params, const char *additional_error);
static char *
gengetopt_strdup (const char *s);
static
void clear_given (struct gengetopt_args_info *args_info)
{
args_info->help_given = 0 ;
args_info->version_given = 0 ;
args_info->host_given = 0 ;
args_info->decrypt_port_given = 0 ;
args_info->m3u8_port_given = 0 ;
args_info->proxy_given = 0 ;
args_info->login_given = 0 ;
}
static
void clear_args (struct gengetopt_args_info *args_info)
{
FIX_UNUSED (args_info);
args_info->host_arg = gengetopt_strdup ("127.0.0.1");
args_info->host_orig = NULL;
args_info->decrypt_port_arg = 10020;
args_info->decrypt_port_orig = NULL;
args_info->m3u8_port_arg = 20020;
args_info->m3u8_port_orig = NULL;
args_info->proxy_arg = gengetopt_strdup ("");
args_info->proxy_orig = NULL;
args_info->login_arg = NULL;
args_info->login_orig = NULL;
}
static
void init_args_info(struct gengetopt_args_info *args_info)
{
args_info->help_help = gengetopt_args_info_help[0] ;
args_info->version_help = gengetopt_args_info_help[1] ;
args_info->host_help = gengetopt_args_info_help[2] ;
args_info->decrypt_port_help = gengetopt_args_info_help[3] ;
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] ;
}
void
cmdline_parser_print_version (void)
{
printf ("%s %s\n",
(strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE),
CMDLINE_PARSER_VERSION);
if (strlen(gengetopt_args_info_versiontext) > 0)
printf("\n%s\n", gengetopt_args_info_versiontext);
}
static void print_help_common(void)
{
size_t len_purpose = strlen(gengetopt_args_info_purpose);
size_t len_usage = strlen(gengetopt_args_info_usage);
if (len_usage > 0) {
printf("%s\n", gengetopt_args_info_usage);
}
if (len_purpose > 0) {
printf("%s\n", gengetopt_args_info_purpose);
}
if (len_usage || len_purpose) {
printf("\n");
}
if (strlen(gengetopt_args_info_description) > 0) {
printf("%s\n\n", gengetopt_args_info_description);
}
}
void
cmdline_parser_print_help (void)
{
int i = 0;
print_help_common();
while (gengetopt_args_info_help[i])
printf("%s\n", gengetopt_args_info_help[i++]);
}
void
cmdline_parser_init (struct gengetopt_args_info *args_info)
{
clear_given (args_info);
clear_args (args_info);
init_args_info (args_info);
}
void
cmdline_parser_params_init(struct cmdline_parser_params *params)
{
if (params)
{
params->override = 0;
params->initialize = 1;
params->check_required = 1;
params->check_ambiguity = 0;
params->print_errors = 1;
}
}
struct cmdline_parser_params *
cmdline_parser_params_create(void)
{
struct cmdline_parser_params *params =
(struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params));
cmdline_parser_params_init(params);
return params;
}
static void
free_string_field (char **s)
{
if (*s)
{
free (*s);
*s = 0;
}
}
static void
cmdline_parser_release (struct gengetopt_args_info *args_info)
{
free_string_field (&(args_info->host_arg));
free_string_field (&(args_info->host_orig));
free_string_field (&(args_info->decrypt_port_orig));
free_string_field (&(args_info->m3u8_port_orig));
free_string_field (&(args_info->proxy_arg));
free_string_field (&(args_info->proxy_orig));
free_string_field (&(args_info->login_arg));
free_string_field (&(args_info->login_orig));
clear_given (args_info);
}
static void
write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])
{
FIX_UNUSED (values);
if (arg) {
fprintf(outfile, "%s=\"%s\"\n", opt, arg);
} else {
fprintf(outfile, "%s\n", opt);
}
}
int
cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
{
int i = 0;
if (!outfile)
{
fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE);
return EXIT_FAILURE;
}
if (args_info->help_given)
write_into_file(outfile, "help", 0, 0 );
if (args_info->version_given)
write_into_file(outfile, "version", 0, 0 );
if (args_info->host_given)
write_into_file(outfile, "host", args_info->host_orig, 0);
if (args_info->decrypt_port_given)
write_into_file(outfile, "decrypt-port", args_info->decrypt_port_orig, 0);
if (args_info->m3u8_port_given)
write_into_file(outfile, "m3u8-port", args_info->m3u8_port_orig, 0);
if (args_info->proxy_given)
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);
i = EXIT_SUCCESS;
return i;
}
int
cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info)
{
FILE *outfile;
int i = 0;
outfile = fopen(filename, "w");
if (!outfile)
{
fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename);
return EXIT_FAILURE;
}
i = cmdline_parser_dump(outfile, args_info);
fclose (outfile);
return i;
}
void
cmdline_parser_free (struct gengetopt_args_info *args_info)
{
cmdline_parser_release (args_info);
}
/** @brief replacement of strdup, which is not standard */
char *
gengetopt_strdup (const char *s)
{
char *result = 0;
if (!s)
return result;
result = (char*)malloc(strlen(s) + 1);
if (result == (char*)0)
return (char*)0;
strcpy(result, s);
return result;
}
int
cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info)
{
return cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
}
int
cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info,
struct cmdline_parser_params *params)
{
int result;
result = cmdline_parser_internal (argc, argv, args_info, params, 0);
if (result == EXIT_FAILURE)
{
cmdline_parser_free (args_info);
exit (EXIT_FAILURE);
}
return result;
}
int
cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required)
{
int result;
struct cmdline_parser_params params;
params.override = override;
params.initialize = initialize;
params.check_required = check_required;
params.check_ambiguity = 0;
params.print_errors = 1;
result = cmdline_parser_internal (argc, argv, args_info, &params, 0);
if (result == EXIT_FAILURE)
{
cmdline_parser_free (args_info);
exit (EXIT_FAILURE);
}
return result;
}
int
cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name)
{
FIX_UNUSED (args_info);
FIX_UNUSED (prog_name);
return EXIT_SUCCESS;
}
static char *package_name = 0;
/**
* @brief updates an option
* @param field the generic pointer to the field to update
* @param orig_field the pointer to the orig field
* @param field_given the pointer to the number of occurrence of this option
* @param prev_given the pointer to the number of occurrence already seen
* @param value the argument for this option (if null no arg was specified)
* @param possible_values the possible values for this option (if specified)
* @param default_value the default value (in case the option only accepts fixed values)
* @param arg_type the type of this option
* @param check_ambiguity @see cmdline_parser_params.check_ambiguity
* @param override @see cmdline_parser_params.override
* @param no_free whether to free a possible previous value
* @param multiple_option whether this is a multiple option
* @param long_opt the corresponding long option
* @param short_opt the corresponding short option (or '-' if none)
* @param additional_error possible further error specification
*/
static
int update_arg(void *field, char **orig_field,
unsigned int *field_given, unsigned int *prev_given,
char *value, const char *possible_values[],
const char *default_value,
cmdline_parser_arg_type arg_type,
int check_ambiguity, int override,
int no_free, int multiple_option,
const char *long_opt, char short_opt,
const char *additional_error)
{
char *stop_char = 0;
const char *val = value;
int found;
char **string_field;
FIX_UNUSED (field);
stop_char = 0;
found = 0;
if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
{
if (short_opt != '-')
fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n",
package_name, long_opt, short_opt,
(additional_error ? additional_error : ""));
else
fprintf (stderr, "%s: `--%s' option given more than once%s\n",
package_name, long_opt,
(additional_error ? additional_error : ""));
return 1; /* failure */
}
FIX_UNUSED (default_value);
if (field_given && *field_given && ! override)
return 0;
if (prev_given)
(*prev_given)++;
if (field_given)
(*field_given)++;
if (possible_values)
val = possible_values[found];
switch(arg_type) {
case ARG_INT:
if (val) *((int *)field) = strtol (val, &stop_char, 0);
break;
case ARG_STRING:
if (val) {
string_field = (char **)field;
if (!no_free && *string_field)
free (*string_field); /* free previous string */
*string_field = gengetopt_strdup (val);
}
break;
default:
break;
};
/* check numeric conversion */
switch(arg_type) {
case ARG_INT:
if (val && !(stop_char && *stop_char == '\0')) {
fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
return 1; /* failure */
}
break;
default:
;
};
/* store the original value */
switch(arg_type) {
case ARG_NO:
break;
default:
if (value && orig_field) {
if (no_free) {
*orig_field = value;
} else {
if (*orig_field)
free (*orig_field); /* free previous string */
*orig_field = gengetopt_strdup (value);
}
}
};
return 0; /* OK */
}
int
cmdline_parser_internal (
int argc, char **argv, struct gengetopt_args_info *args_info,
struct cmdline_parser_params *params, const char *additional_error)
{
int c; /* Character of the parsed option. */
int error_occurred = 0;
struct gengetopt_args_info local_args_info;
int override;
int initialize;
int check_required;
int check_ambiguity;
package_name = argv[0];
/* TODO: Why is this here? It is not used anywhere. */
override = params->override;
FIX_UNUSED(override);
initialize = params->initialize;
check_required = params->check_required;
/* TODO: Why is this here? It is not used anywhere. */
check_ambiguity = params->check_ambiguity;
FIX_UNUSED(check_ambiguity);
if (initialize)
cmdline_parser_init (args_info);
cmdline_parser_init (&local_args_info);
optarg = 0;
optind = 0;
opterr = params->print_errors;
optopt = '?';
while (1)
{
int option_index = 0;
static struct option long_options[] = {
{ "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'V' },
{ "host", 1, NULL, 'H' },
{ "decrypt-port", 1, NULL, 'D' },
{ "m3u8-port", 1, NULL, 'M' },
{ "proxy", 1, NULL, 'P' },
{ "login", 1, NULL, 'L' },
{ 0, 0, 0, 0 }
};
c = getopt_long (argc, argv, "hVH:D:M:P:L:", long_options, &option_index);
if (c == -1) break; /* Exit from `while (1)' loop. */
switch (c)
{
case 'h': /* Print help and exit. */
cmdline_parser_print_help ();
cmdline_parser_free (&local_args_info);
exit (EXIT_SUCCESS);
case 'V': /* Print version and exit. */
cmdline_parser_print_version ();
cmdline_parser_free (&local_args_info);
exit (EXIT_SUCCESS);
case 'H': /* . */
if (update_arg( (void *)&(args_info->host_arg),
&(args_info->host_orig), &(args_info->host_given),
&(local_args_info.host_given), optarg, 0, "127.0.0.1", ARG_STRING,
check_ambiguity, override, 0, 0,
"host", 'H',
additional_error))
goto failure;
break;
case 'D': /* . */
if (update_arg( (void *)&(args_info->decrypt_port_arg),
&(args_info->decrypt_port_orig), &(args_info->decrypt_port_given),
&(local_args_info.decrypt_port_given), optarg, 0, "10020", ARG_INT,
check_ambiguity, override, 0, 0,
"decrypt-port", 'D',
additional_error))
goto failure;
break;
case 'M': /* . */
if (update_arg( (void *)&(args_info->m3u8_port_arg),
&(args_info->m3u8_port_orig), &(args_info->m3u8_port_given),
&(local_args_info.m3u8_port_given), optarg, 0, "20020", ARG_INT,
check_ambiguity, override, 0, 0,
"m3u8-port", 'M',
additional_error))
goto failure;
break;
case 'P': /* . */
if (update_arg( (void *)&(args_info->proxy_arg),
&(args_info->proxy_orig), &(args_info->proxy_given),
&(local_args_info.proxy_given), optarg, 0, "", ARG_STRING,
check_ambiguity, override, 0, 0,
"proxy", 'P',
additional_error))
goto failure;
break;
case 'L': /* . */
if (update_arg( (void *)&(args_info->login_arg),
&(args_info->login_orig), &(args_info->login_given),
&(local_args_info.login_given), optarg, 0, 0, ARG_STRING,
check_ambiguity, override, 0, 0,
"login", 'L',
additional_error))
goto failure;
break;
case 0: /* Long option with no short option */
case '?': /* Invalid option. */
/* `getopt_long' already printed an error message. */
goto failure;
default: /* bug: option not considered. */
fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
abort ();
} /* switch */
} /* while */
FIX_UNUSED(check_required);
cmdline_parser_release (&local_args_info);
if ( error_occurred )
return (EXIT_FAILURE);
return 0;
failure:
cmdline_parser_release (&local_args_info);
return (EXIT_FAILURE);
}
/* vim: set ft=c noet ts=8 sts=8 sw=8 tw=80 nojs spell : */

@ -0,0 +1,193 @@
/** @file cmdline.h
* @brief The header file for the command line option parser
* generated by GNU Gengetopt version 2.23
* http://www.gnu.org/software/gengetopt.
* DO NOT modify this file, since it can be overwritten
* @author GNU Gengetopt */
#ifndef CMDLINE_H
#define CMDLINE_H
/* If we use autoconf. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> /* for FILE */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifndef CMDLINE_PARSER_PACKAGE
/** @brief the program name (used for printing errors) */
#define CMDLINE_PARSER_PACKAGE "wrapper"
#endif
#ifndef CMDLINE_PARSER_PACKAGE_NAME
/** @brief the complete program name (used for help and version) */
#define CMDLINE_PARSER_PACKAGE_NAME "wrapper"
#endif
#ifndef CMDLINE_PARSER_VERSION
/** @brief the program version */
#define CMDLINE_PARSER_VERSION "1.2.0"
#endif
/** @brief Where the command line options are stored */
struct gengetopt_args_info
{
const char *help_help; /**< @brief Print help and exit help description. */
const char *version_help; /**< @brief Print version and exit help description. */
char * host_arg; /**< @brief (default='127.0.0.1'). */
char * host_orig; /**< @brief original value given at command line. */
const char *host_help; /**< @brief help description. */
int decrypt_port_arg; /**< @brief (default='10020'). */
char * decrypt_port_orig; /**< @brief original value given at command line. */
const char *decrypt_port_help; /**< @brief help description. */
int m3u8_port_arg; /**< @brief (default='20020'). */
char * m3u8_port_orig; /**< @brief original value given at command line. */
const char *m3u8_port_help; /**< @brief help description. */
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. */
unsigned int help_given ; /**< @brief Whether help was given. */
unsigned int version_given ; /**< @brief Whether version was given. */
unsigned int host_given ; /**< @brief Whether host was given. */
unsigned int decrypt_port_given ; /**< @brief Whether decrypt-port was given. */
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. */
} ;
/** @brief The additional parameters to pass to parser functions */
struct cmdline_parser_params
{
int override; /**< @brief whether to override possibly already present options (default 0) */
int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */
int check_required; /**< @brief whether to check that all required options were provided (default 1) */
int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */
int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */
} ;
/** @brief the purpose string of the program */
extern const char *gengetopt_args_info_purpose;
/** @brief the usage string of the program */
extern const char *gengetopt_args_info_usage;
/** @brief the description string of the program */
extern const char *gengetopt_args_info_description;
/** @brief all the lines making the help output */
extern const char *gengetopt_args_info_help[];
/**
* The command line parser
* @param argc the number of command line options
* @param argv the command line options
* @param args_info the structure where option information will be stored
* @return 0 if everything went fine, NON 0 if an error took place
*/
int cmdline_parser (int argc, char **argv,
struct gengetopt_args_info *args_info);
/**
* The command line parser (version with additional parameters - deprecated)
* @param argc the number of command line options
* @param argv the command line options
* @param args_info the structure where option information will be stored
* @param override whether to override possibly already present options
* @param initialize whether to initialize the option structure my_args_info
* @param check_required whether to check that all required options were provided
* @return 0 if everything went fine, NON 0 if an error took place
* @deprecated use cmdline_parser_ext() instead
*/
int cmdline_parser2 (int argc, char **argv,
struct gengetopt_args_info *args_info,
int override, int initialize, int check_required);
/**
* The command line parser (version with additional parameters)
* @param argc the number of command line options
* @param argv the command line options
* @param args_info the structure where option information will be stored
* @param params additional parameters for the parser
* @return 0 if everything went fine, NON 0 if an error took place
*/
int cmdline_parser_ext (int argc, char **argv,
struct gengetopt_args_info *args_info,
struct cmdline_parser_params *params);
/**
* Save the contents of the option struct into an already open FILE stream.
* @param outfile the stream where to dump options
* @param args_info the option struct to dump
* @return 0 if everything went fine, NON 0 if an error took place
*/
int cmdline_parser_dump(FILE *outfile,
struct gengetopt_args_info *args_info);
/**
* Save the contents of the option struct into a (text) file.
* This file can be read by the config file parser (if generated by gengetopt)
* @param filename the file where to save
* @param args_info the option struct to save
* @return 0 if everything went fine, NON 0 if an error took place
*/
int cmdline_parser_file_save(const char *filename,
struct gengetopt_args_info *args_info);
/**
* Print the help
*/
void cmdline_parser_print_help(void);
/**
* Print the version
*/
void cmdline_parser_print_version(void);
/**
* Initializes all the fields a cmdline_parser_params structure
* to their default values
* @param params the structure to initialize
*/
void cmdline_parser_params_init(struct cmdline_parser_params *params);
/**
* Allocates dynamically a cmdline_parser_params structure and initializes
* all its fields to their default values
* @return the created and initialized cmdline_parser_params structure
*/
struct cmdline_parser_params *cmdline_parser_params_create(void);
/**
* Initializes the passed gengetopt_args_info structure's fields
* (also set default values for options that have a default)
* @param args_info the structure to initialize
*/
void cmdline_parser_init (struct gengetopt_args_info *args_info);
/**
* Deallocates the string fields of the gengetopt_args_info structure
* (but does not deallocate the structure itself)
* @param args_info the structure to deallocate
*/
void cmdline_parser_free (struct gengetopt_args_info *args_info);
/**
* Checks that all the required options were specified
* @param args_info the structure to check
* @param prog_name the name of the program that will be used to print
* possible errors
* @return
*/
int cmdline_parser_required (struct gengetopt_args_info *args_info,
const char *prog_name);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CMDLINE_H */

@ -7,19 +7,20 @@
#include <unistd.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include "import.h"
#include "cmdline.h"
#ifndef MyRelease
#include "subhook/subhook.c"
#endif
static struct shared_ptr apInf;
static size_t passLen;
static char *amUsername, *amPassword;
static uint16_t port;
static uint8_t leaseMgr[16];
struct gengetopt_args_info args_info;
char *amUsername, *amPassword;
static void dialogHandler(long j, struct shared_ptr *protoDialogPtr,
struct shared_ptr *respHandler) {
@ -75,6 +76,8 @@ static void credentialHandler(struct shared_ptr *credReqHandler,
credReqHandler->obj)),
need2FA ? "true" : "false");
int passLen = strlen(amPassword);
if (need2FA) {
printf("2FA code: ");
scanf("%6s", amPassword + passLen);
@ -113,7 +116,13 @@ static inline void init() {
// raise(SIGSTOP);
fprintf(stderr, "[+] starting...\n");
setenv("ANDROID_DNS_MODE", "local", 1);
static const char *resolvers[2] = {"1.1.1.1", "223.5.5.5"};
if (args_info.proxy_given) {
fprintf(stderr, "[+] Using proxy %s", args_info.proxy_arg);
setenv("http_proxy", args_info.proxy_arg, 1);
setenv("https_proxy", args_info.proxy_arg, 1);
}
static const char *resolvers[2] = {"1.1.1.1", "1.0.0.1"};
_resolv_set_nameservers_for_net(0, resolvers, 2, ".");
#ifndef MyRelease
subhook_install(subhook_new(
@ -364,8 +373,6 @@ void handle(const int connfd) {
}
extern uint8_t handle_cpp(int);
static char *selfPath;
static char *portStr;
inline static int new_socket() {
const int fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
@ -377,8 +384,8 @@ inline static int new_socket() {
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
static struct sockaddr_in serv_addr = {.sin_family = AF_INET};
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(port);
inet_pton(AF_INET, args_info.host_arg, &serv_addr.sin_addr);
serv_addr.sin_port = htons(args_info.decrypt_port_arg);
if (bind(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) {
perror("bind");
return EXIT_FAILURE;
@ -389,8 +396,8 @@ inline static int new_socket() {
return EXIT_FAILURE;
}
fprintf(stderr, "[!] listening 0.0.0.0:%d\n", port);
close(STDOUT_FILENO);
fprintf(stderr, "[!] listening %s:%d\n", args_info.host_arg, args_info.decrypt_port_arg);
// close(STDOUT_FILENO);
static struct sockaddr_in peer_addr;
static socklen_t peer_addr_size = sizeof(peer_addr);
@ -477,12 +484,11 @@ static inline void *new_socket_m3u8(void *args) {
perror("socket");
}
const int optval = 1;
const int m3u8_port = port + 10000;
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
static struct sockaddr_in serv_addr = {.sin_family = AF_INET};
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(m3u8_port);
inet_pton(AF_INET, args_info.host_arg, &serv_addr.sin_addr);
serv_addr.sin_port = htons(args_info.m3u8_port_arg);
if (bind(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) {
perror("bind");
}
@ -491,8 +497,8 @@ static inline void *new_socket_m3u8(void *args) {
perror("listen");
}
fprintf(stderr, "[!] listening m3u8 request on 0.0.0.0:%d\n", m3u8_port);
close(STDOUT_FILENO);
fprintf(stderr, "[!] listening m3u8 request on %s:%d\n", args_info.host_arg, args_info.m3u8_port_arg);
// close(STDOUT_FILENO);
static struct sockaddr_in peer_addr;
static socklen_t peer_addr_size = sizeof(peer_addr);
@ -506,6 +512,7 @@ static inline void *new_socket_m3u8(void *args) {
errno == ENETUNREACH)
continue;
perror("accept4");
}
handle_m3u8(connfd);
@ -517,23 +524,15 @@ static inline void *new_socket_m3u8(void *args) {
}
int main(int argc, char *argv[]) {
selfPath = argv[0];
if (argc != 2) {
if (argc != 4) {
fprintf(stderr, "usage: %s [port] ([username] [password])\n",
argv[0]);
return EXIT_FAILURE;
}
amUsername = argv[2];
passLen = strlen(argv[3]);
amPassword = malloc(passLen + 7);
strcpy(amPassword, argv[3]);
}
port = atoi(portStr = argv[1]);
cmdline_parser(argc, argv, &args_info);
init();
const struct shared_ptr ctx = init_ctx();
if (argc == 4 && !login(ctx)) {
if (args_info.login_given) {
amUsername = strtok(args_info.login_arg, ":");
amPassword = strtok(NULL, ":");
}
if (args_info.login_given && !login(ctx)) {
fprintf(stderr, "[!] login failed\n");
return EXIT_FAILURE;
}
@ -545,7 +544,11 @@ int main(int argc, char *argv[]) {
_ZN22SVPlaybackLeaseManager12requestLeaseERKb(leaseMgr, &autom);
FHinstance = _ZN21SVFootHillSessionCtrl8instanceEv();
pthread_t m3u8_thread;
pthread_create(&m3u8_thread, NULL, &new_socket_m3u8, NULL);
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");
}
return new_socket();
}

@ -23,10 +23,6 @@ int main(int argc, char *argv[], char *envp[]) {
return 1;
}
if (argc > 2) {
system("rm -r ./rootfs/data/data/com.apple.android.music/files/");
}
if (chdir("./rootfs") != 0) {
perror("chdir");
return 1;

@ -0,0 +1,8 @@
package "wrapper"
version "1.2.0"
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
Loading…
Cancel
Save