Skip to content

Commit

Permalink
Merge pull request #261 from Princess-of-Sleeping/master
Browse files Browse the repository at this point in the history
Added stub privilege checker part 2
  • Loading branch information
Princess-of-Sleeping authored Dec 25, 2023
2 parents fb328e2 + e48dcb6 commit 6b9236f
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 2 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ usage: vita-elf-create [-v|vv|vvv] [-n] [-e config.yml] input.elf output.velf
-v,-vv,-vvv: logging verbosity (more v is more verbose)
-n : allow empty imports
-e yml : optional config options
-g yml : generate an export config from ELF symbols
-m list : specify the list of module entrypoints
-l op name : long name option name
input.elf : input ARM ET_EXEC type ELF
output.velf: output ET_SCE_RELEXEC type ELF
```
Expand Down
18 changes: 17 additions & 1 deletion src/vita-elf-create/elf-create-argp.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ int parse_arguments(int argc, char *argv[], elf_create_args *arguments)
arguments->log_level = 0;
arguments->check_stub_count = 1;
arguments->is_test_stripping = 0;
arguments->is_bypass_stub_privilege_check = 0;

while ((c = getopt(argc, argv, "vne:sg:m:")) != -1)
while ((c = getopt(argc, argv, "vne:sg:m:l:")) != -1)
{
switch (c)
{
Expand All @@ -39,6 +40,21 @@ int parse_arguments(int argc, char *argv[], elf_create_args *arguments)
break;
case 'm':
entrypoint_list = optarg;
break;
case 'l': // long name option

if (strlen(optarg) == 0) {
fprintf(stderr, "long name option lemgth is 0\n");
return -1;
}

if (strcmp(optarg, "skip_stub_privilege_check") == 0) {
arguments->is_bypass_stub_privilege_check = 1;
} else {
fprintf(stderr, "unknown long name option (%s)\n", optarg);
return -1;
}

break;
case '?':
fprintf(stderr, "unknown option -%c\n", optopt);
Expand Down
1 change: 1 addition & 0 deletions src/vita-elf-create/elf-create-argp.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ typedef struct elf_create_args
int check_stub_count;
int is_test_stripping;
char *entrypoint_funcs[3]; // module_start, module_stop, module_exit
int is_bypass_stub_privilege_check;
} elf_create_args;


Expand Down
48 changes: 47 additions & 1 deletion src/vita-elf-create/vita-elf-create.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "utils/fail-utils.h"
#include "elf-create-argp.h"
#include "utils/yamlemitter.h"
#include "../vita-libs-gen-2/defs.h"

// logging level
int g_log = 0;
Expand Down Expand Up @@ -470,13 +471,14 @@ static void write_exports(vita_export_t *exports, const char *export_path)

static int usage(int argc, char *argv[])
{
fprintf(stderr, "usage: %s [-v|vv|vvv] [-s] [-n] [[-e | -g] config.yml] [-m start,stop,exit] input.elf output.velf\n"
fprintf(stderr, "usage: %s [-v|vv|vvv] [-s] [-n] [[-e | -g] config.yml] [-l <long_name_option>] [-m start,stop,exit] input.elf output.velf\n"
"\t-v,-vv,-vvv: logging verbosity (more v is more verbose)\n"
"\t-s : strip the output ELF\n"
"\t-n : allow empty imports\n"
"\t-e yml : optional config options\n"
"\t-g yml : generate an export config from ELF symbols\n"
"\t-m list : specify the list of module entrypoints\n"
"\t-l op name : long name option name\n"
"\tinput.elf : input ARM ET_EXEC type ELF\n"
"\toutput.velf: output ET_SCE_RELEXEC type ELF\n", argc > 0 ? argv[0] : "vita-elf-create");
return 0;
Expand Down Expand Up @@ -534,6 +536,50 @@ int main(int argc, char *argv[])
TRACEF(VERBOSE, "export config loaded from default\n");
}

if (args.is_bypass_stub_privilege_check == 0) {
int prev_privilege = ~0;

for (int i=0;i<ve->num_fstubs;i++) {

// printf("%s 0x%08X 0x%08X\n", ve->fstubs[i].library->name, ve->fstubs[i].library->flags, ve->fstubs[i].target_nid);

int flags = ve->fstubs[i].library->flags & 0xFFFF; // mask for flags. upper16 is library version.

if ((flags & ~(VITA_STUB_GEN_2_FLAG_WEAK | VITA_STUB_GEN_2_FLAG_IS_KERNEL)) != 0) {
printf("library have unknown flag (0x%04X)\n", flags & ~(VITA_STUB_GEN_2_FLAG_WEAK | VITA_STUB_GEN_2_FLAG_IS_KERNEL));
}

if (prev_privilege != ~0 && prev_privilege != (flags & VITA_STUB_GEN_2_FLAG_IS_KERNEL)) {
printf("Importing stubs with different privileges.\n");
printf("\tIf needed for exploit, add flag \"-l skip_stub_privilege_check\" and try again.\n");
printf("\tIf not, check the stub you are importing to make sure there are no mistake regarding privileges.\n");
return EXIT_FAILURE;
}

prev_privilege = flags & VITA_STUB_GEN_2_FLAG_IS_KERNEL;
}

for (int i=0;i<ve->num_vstubs;i++) {

// printf("%s 0x%08X 0x%08X\n", ve->fstubs[i].library->name, ve->fstubs[i].library->flags, ve->fstubs[i].target_nid);

int flags = ve->vstubs[i].library->flags & 0xFFFF; // mask for flags. upper16 is library version.

if ((flags & ~(VITA_STUB_GEN_2_FLAG_WEAK | VITA_STUB_GEN_2_FLAG_IS_KERNEL)) != 0) {
printf("library have unknown flag (0x%04X)\n", flags & ~(VITA_STUB_GEN_2_FLAG_WEAK | VITA_STUB_GEN_2_FLAG_IS_KERNEL));
}

if (prev_privilege != ~0 && prev_privilege != (flags & VITA_STUB_GEN_2_FLAG_IS_KERNEL)) {
printf("Importing stubs with different privileges.\n");
printf("\tIf needed for exploit, add flag \"-l skip_stub_privilege_check\" and try again.\n");
printf("\tIf not, check the stub you are importing to make sure there are no mistake regarding privileges.\n");
return EXIT_FAILURE;
}

prev_privilege = flags & VITA_STUB_GEN_2_FLAG_IS_KERNEL;
}
}

if (ve->fstubs_va.count) {
TRACEF(VERBOSE, "Function stubs in sections \n");
print_stubs(ve->fstubs, ve->num_fstubs);
Expand Down

0 comments on commit 6b9236f

Please sign in to comment.