【神器】insert_dylib 给 MacOSX APP 添加导入表注入--你懂的~~

来源:互联网 发布:基本款 外套 知乎 编辑:程序博客网 时间:2024/05/16 12:01

论坛地址:http://www.chinapyg.com/

转:http://www.dllhook.com/post/39.html

// ./insert_dylib @executable_path(表示加载bin所在目录)/inject.dylib test   #include <stdlib.h>#include <stdio.h>#include <stdbool.h>#include <stdarg.h>#include <string.h>#include <unistd.h>#include <getopt.h>#include <sys/stat.h>#include <copyfile.h>#include <mach-o/loader.h>#include <mach-o/fat.h>#define IS_64_BIT(x) ((x) == MH_MAGIC_64 || (x) == MH_CIGAM_64)#define IS_LITTLE_ENDIAN(x) ((x) == FAT_CIGAM || (x) == MH_CIGAM_64 || (x) == MH_CIGAM)#define SWAP32(x, magic) (IS_LITTLE_ENDIAN(magic)? OSSwapInt32(x): (x))__attribute__((noreturn)) void usage(void) {printf("Usage: insert_dylib [--inplace] [--weak] dylib_path binary_path [new_path]\n");exit(1);}__attribute__((format(printf, 1, 2))) bool ask(const char *format, ...) {char *question;asprintf(&question, "%s [y/n] ", format);va_list args;va_start(args, format);vprintf(question, args);va_end(args);free(question);while(true) {char *line = NULL;size_t size;getline(&line, &size, stdin);switch(line[0]) {case 'y':case 'Y':return true;break;case 'n':case 'N':return false;break;default:printf("Please enter y or n: ");}}}void remove_code_signature(FILE *f, struct mach_header *mh, size_t header_offset, size_t commands_offset) {fseek(f, commands_offset, SEEK_SET);uint32_t ncmds = SWAP32(mh->ncmds, mh->magic);for(int i = 0; i < ncmds; i++) {struct load_command lc;fread(&lc, sizeof(lc), 1, f);if(SWAP32(lc.cmd, mh->magic) == LC_CODE_SIGNATURE) {if(i == ncmds - 1 && ask("LC_CODE_SIGNATURE load command found. Remove it?")) {fseek(f, -((long)sizeof(lc)), SEEK_CUR);struct linkedit_data_command ldc;fread(&ldc, sizeof(ldc), 1, f);uint32_t cmdsize = SWAP32(ldc.cmdsize, mh->magic);uint32_t dataoff = SWAP32(ldc.dataoff, mh->magic);uint32_t datasize = SWAP32(ldc.datasize, mh->magic);fseek(f, -((long)sizeof(ldc)), SEEK_CUR);char *zero = calloc(cmdsize, 1);fwrite(zero, cmdsize, 1, f);free(zero);fseek(f, header_offset + dataoff, SEEK_SET);zero = calloc(datasize, 1);fwrite(zero, datasize, 1, f);free(zero);mh->ncmds = SWAP32(ncmds - 1, mh->magic);mh->sizeofcmds = SWAP32(SWAP32(mh->sizeofcmds, mh->magic) - ldc.cmdsize, mh->magic);return;} else {printf("LC_CODE_SIGNATURE is not the last load command, so couldn't remove.");}}fseek(f, SWAP32(lc.cmdsize, mh->magic) - sizeof(lc), SEEK_CUR);}}bool insert_dylib(FILE *f, size_t header_offset, const char *dylib_path, bool weak) {fseek(f, header_offset, SEEK_SET);struct mach_header mh;fread(&mh, sizeof(struct mach_header), 1, f);if(mh.magic != MH_MAGIC_64 && mh.magic != MH_CIGAM_64 && mh.magic != MH_MAGIC && mh.magic != MH_CIGAM) {printf("Unknown magic: 0x%x\n", mh.magic);return false;}size_t commands_offset = header_offset + (IS_64_BIT(mh.magic)? sizeof(struct mach_header_64): sizeof(struct mach_header));remove_code_signature(f, &mh, header_offset, commands_offset);size_t dylib_path_len = strlen(dylib_path);size_t dylib_path_size = (dylib_path_len & ~3) + 4;uint32_t cmdsize = (uint32_t)(sizeof(struct dylib_command) + dylib_path_size);struct dylib_command dylib_command = {.cmd = SWAP32(weak? LC_LOAD_WEAK_DYLIB: LC_LOAD_DYLIB, mh.magic),.cmdsize = SWAP32(cmdsize, mh.magic),.dylib = {.name = SWAP32(sizeof(struct dylib_command), mh.magic),.timestamp = 0,.current_version = 0,.compatibility_version = 0}};uint32_t sizeofcmds = SWAP32(mh.sizeofcmds, mh.magic);fseek(f, commands_offset + sizeofcmds, SEEK_SET);char space[cmdsize];fread(&space, cmdsize, 1, f);bool empty = true;for(int i = 0; i < cmdsize; i++) {if(space[i] != 0) {empty = false;break;}}if(!empty) {if(!ask("It doesn't seem like there is enough empty space. Continue anyway?")) {return false;}}fseek(f, -((long)cmdsize), SEEK_CUR);char *dylib_path_padded = calloc(dylib_path_size, 1);memcpy(dylib_path_padded, dylib_path, dylib_path_len);fwrite(&dylib_command, sizeof(dylib_command), 1, f);fwrite(dylib_path_padded, dylib_path_size, 1, f);free(dylib_path_padded);mh.ncmds = SWAP32(SWAP32(mh.ncmds, mh.magic) + 1, mh.magic);sizeofcmds += cmdsize;mh.sizeofcmds = SWAP32(sizeofcmds, mh.magic);fseek(f, header_offset, SEEK_SET);fwrite(&mh, sizeof(mh), 1, f);return true;}int main(int argc, const char *argv[]) {int inplace = false;int weak = false;struct option long_options[] = {{"inplace", no_argument, &inplace, true},{"weak",    no_argument, &weak,    true}};while(true) {int option_index = 0;int c = getopt_long(argc, (char *const *)argv, "", long_options, &option_index);if(c == -1) {break;}switch(c) {case 0:break;case '?':usage();break;default:abort();break;}}argv = &argv[optind - 1];argc -= optind - 1;if(argc < 3 || argc > 4) {usage();}const char *lc_name = weak? "LC_LOAD_WEAK_DYLIB": "LC_LOAD_DYLIB";const char *dylib_path = argv[1];const char *binary_path = argv[2];struct stat s;if(stat(binary_path, &s) != 0) {perror(binary_path);exit(1);}if(stat(dylib_path, &s) != 0) {if(!ask("The provided dylib path doesn't exist. Continue anyway?")) {exit(1);}}bool binary_path_was_malloced = false;if(!inplace) {char *new_binary_path;if(argc == 4) {new_binary_path = (char *)argv[3];} else {asprintf(&new_binary_path, "%s_patched", binary_path);binary_path_was_malloced = true;}if(stat(new_binary_path, &s) == 0) {if(!ask("%s already exists. Overwrite it?", new_binary_path)) {exit(1);}}if(copyfile(binary_path, new_binary_path, NULL, COPYFILE_DATA | COPYFILE_UNLINK)) {printf("Failed to create %s\n", new_binary_path);exit(1);}binary_path = new_binary_path;}FILE *f = fopen(binary_path, "r+");if(!f) {printf("Couldn't open file %s\n", argv[1]);exit(1);}bool success = true;uint32_t magic;fread(&magic, sizeof(uint32_t), 1, f);switch(magic) {case FAT_MAGIC:case FAT_CIGAM: {fseek(f, 0, SEEK_SET);struct fat_header fh;fread(&fh, sizeof(struct fat_header), 1, f);uint32_t nfat_arch = SWAP32(fh.nfat_arch, magic);printf("Binary is a fat binary with %d archs.\n", nfat_arch);struct fat_arch archs[nfat_arch];fread(&archs, sizeof(archs), 1, f);int fails = 0;for(int i = 0; i < nfat_arch; i++) {bool r = insert_dylib(f, SWAP32(archs[i].offset, magic), dylib_path, weak);if(!r) {printf("Failed to add %s to arch #%d!\n", lc_name, i + 1);fails++;}}if(fails == 0) {printf("Added %s to all archs in %s\n", lc_name, binary_path);} else if(fails == nfat_arch) {printf("Failed to add %s to any archs.\n", lc_name);success = false;} else {printf("Added %s to %d/%d archs in %s\n", lc_name, nfat_arch - fails, nfat_arch, binary_path);}break;}case MH_MAGIC_64:case MH_CIGAM_64:case MH_MAGIC:case MH_CIGAM:if(insert_dylib(f, 0, dylib_path, weak)) {printf("Added %s to %s\n", lc_name, binary_path);} else {printf("Failed to add %s!\n", lc_name);success = false;}break;default:printf("Unknown magic: 0x%x\n", magic);exit(1);}fclose(f);if(!success) {if(!inplace) {unlink(binary_path);}exit(1);}if(binary_path_was_malloced) {free((void *)binary_path);}    return 0;}

0 0
原创粉丝点击