Skip to content

Commit

Permalink
添加 __text 校验以及忽略一些不需要的符号
Browse files Browse the repository at this point in the history
  • Loading branch information
SilverFruity committed Aug 19, 2022
1 parent 99e6fa8 commit fa09710
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 13 deletions.
89 changes: 86 additions & 3 deletions symdl/symdl/symdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <mach-o/nlist.h>
#include <pthread/pthread.h>

typedef struct load_command load_command_t;
#ifdef __LP64__
typedef struct mach_header_64 mach_header_t;
typedef struct segment_command_64 segment_command_t;
Expand Down Expand Up @@ -48,6 +49,66 @@ static int cache_next_index = 0;
static int cache_capacity = 128;
static pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

static bool cstringPrefix(const char *str, const char *pre) {
return strncmp(pre, str, strlen(pre)) == 0;
}

static void forEachLoadCommand(const struct mach_header *header, void (^callback)(const load_command_t *cmd, bool *stop)) {
bool stop = false;
const load_command_t *startCmds = NULL;
if (header->magic == MH_MAGIC_64)
startCmds = (load_command_t *)((char *)header + sizeof(struct mach_header_64));
else if (header->magic == MH_MAGIC)
startCmds = (load_command_t *)((char *)header + sizeof(struct mach_header));
else if (header->magic == MH_CIGAM || header->magic == MH_CIGAM_64)
return; // can't process big endian mach-o
else {
return; // not a mach-o file
}
const load_command_t *const cmdsEnd = (load_command_t *)((char *)startCmds + header->sizeofcmds);
const load_command_t *cmd = startCmds;
for (uint32_t i = 0; i < header->ncmds; ++i) {
const load_command_t *nextCmd = (load_command_t *)((char *)cmd + cmd->cmdsize);
if (cmd->cmdsize < 8) {
return;
}
// FIXME: add check the cmdsize is pointer aligned (might reveal bin compat issues)
if ((nextCmd > cmdsEnd) || (nextCmd < startCmds)) {
return;
}
callback(cmd, &stop);
if (stop)
return;
cmd = nextCmd;
}
}

static void forEachSection(const struct mach_header *header, void (^callback)(const section_t *sectInfo, bool *stop)) {
__block uint32_t segIndex = 0;
forEachLoadCommand(header, ^(const load_command_t *cmd, bool *stop) {
if (cmd->cmd == LC_SEGMENT_64) {
const segment_command_t *segCmd = (segment_command_t *)cmd;
const section_t *const sectionsStart = (section_t *)((char *)segCmd + sizeof(segment_command_t));
const section_t *const sectionsEnd = &sectionsStart[segCmd->nsects];
for (const section_t *sect = sectionsStart; !(*stop) && (sect < sectionsEnd); ++sect) {
callback(sect, stop);
}
++segIndex;
}
});
}

//edit from dyld: bool MachOAnalyzer::inCodeSection
static bool inCodeSection(const struct mach_header *header, intptr_t slide, intptr_t address) {
__block bool result = false;
forEachSection(header, ^(const section_t *sectInfo, bool *stop) {
if ((sectInfo->addr + slide <= address) && (address < (sectInfo->addr + sectInfo->size + slide))) {
result = ((sectInfo->flags & S_ATTR_PURE_INSTRUCTIONS) || (sectInfo->flags & S_ATTR_SOME_INSTRUCTIONS));
*stop = true;
}
});
return result;
}


static void *func_pointer_with_name_in_image(const char *name, const struct mach_header *header, intptr_t slide){
Expand Down Expand Up @@ -83,14 +144,36 @@ static void *func_pointer_with_name_in_image(const char *name, const struct mach

uint32_t cmdsize = symtab_cmd->nsyms;
for (uint32_t i = 0; i < cmdsize; i++) {
nlist_t *nlist = &symtab[i];
if ((nlist->n_type & N_STAB) || (nlist->n_type & N_TYPE) != N_SECT || nlist->n_sect != 1) {
nlist_t *nlist = &symtab[i];

if ((nlist->n_type & N_STAB) || (nlist->n_type & N_TYPE) != N_SECT) {
continue;
}

const char *symbol_name = strtab + nlist->n_un.n_strx;
bool symbol_name_longer_than_1 = symbol_name[0] && symbol_name[1];
// <redirect>
// $ ___Z C++
// +/- objc
// __swift swift
if (!symbol_name_longer_than_1
|| symbol_name[0] == '<'
|| symbol_name[0] == '-'
|| symbol_name[0] == '+'
|| symbol_name[1] == '$'
|| cstringPrefix(symbol_name, "__Z")
|| cstringPrefix(symbol_name, "___")
|| cstringPrefix(symbol_name, "__swift")) {
continue;
}

intptr_t functionAddress = (intptr_t)(nlist->n_value + slide);
if (!inCodeSection(header, slide, functionAddress)) {
continue;
}

if (symbol_name_longer_than_1 && strcmp(&symbol_name[1], name) == 0) {
return (void *)(nlist->n_value + slide);;
return (void *)functionAddress;;
}
}

Expand Down
15 changes: 5 additions & 10 deletions symdl_example/symdl_example/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,11 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
my_load(write);
my_load(read);

symdl("fopen");
symdl("fclose");
symdl("write");
symdl("read");

symdl("fopen");
symdl("fclose");
symdl("write");
symdl("read");

assert(symdl("fopen") == fopen);
assert(symdl("fclose") == fclose);
assert(symdl("write") == write);
assert(symdl("read") == read);

// Override point for customization after application launch.
return YES;
}
Expand Down

0 comments on commit fa09710

Please sign in to comment.