void hotpatch_destroy(hotpatch_t *hp) { if (hp) { size_t idx; if (hp->attached) hotpatch_detach(hp); if (hp->exe_symbols) { for (idx = 0; idx < hp->exe_symbols_num; ++idx) { free(hp->exe_symbols[idx].name); hp->exe_symbols[idx].name = NULL; } free(hp->exe_symbols); } hp->exe_symbols = NULL; hp->exe_symbols_num = 0; if (hp->exe_interp.name) { free(hp->exe_interp.name); hp->exe_interp.name = NULL; } for (idx = 0; idx < HOTPATCH_LIB_MAX; ++idx) { if (hp->libs[idx].pathname) free(hp->libs[idx].pathname); hp->libs[idx].pathname = NULL; } memset(hp->libs, 0, sizeof(hp->libs)); if (hp->ld_maps) { ld_free_maps(hp->ld_maps, hp->ld_maps_num); hp->ld_maps = NULL; hp->ld_maps_num = 0; } free(hp); hp = NULL; } }
int main(int argc, char **argv) { struct hp_options opts = { 0 }; hotpatch_t *hp = NULL; int rc = 0; /* parse all arguments first */ if ((rc = parse_arguments(argc, argv, &opts)) != 0) { return rc; } print_options(&opts); /* break from execution whenever a step fails */ do { uintptr_t ptr = 0; hp = hotpatch_create(opts.pid, opts.verbose); if (!hp) { fprintf(stderr, "[%s:%d] Unable to create hotpatch for PID %d\n", __func__, __LINE__, opts.pid); rc = -1; break; } if (opts.dryrun) break; if (opts.dll) { uintptr_t dlres = 0; uintptr_t symres = 0; rc = hotpatch_inject_library(hp, opts.dll, opts.symbol, NULL, 0, &dlres, &symres); if (rc >=0) { printf("Dll was injected at %p\n", (void *)dlres); printf("Invocation of %s() returned %p\n", (opts.symbol ? opts.symbol : "_init"), (void *)symres); } } else { /* handles the stripped apps as well */ if (opts.is__start) { ptr = hotpatch_get_entry_point(hp); } else { ptr = hotpatch_read_symbol(hp, opts.symbol, NULL, NULL); } if (!ptr) { printf("Symbol %s not found. Cannot proceed\n", opts.symbol); break; } printf("Setting execution pointer to %s at 0x"LX"\n", opts.symbol, ptr); rc = hotpatch_attach(hp); if (rc < 0) { printf("Failed to attach to process. Cannot proceed\n"); break; } rc = hotpatch_exec_symbol(hp, ptr, opts.verbose); if (rc < 0) { printf("Failed to execute the symbol in 0x"LX"\n", ptr); rc = hotpatch_detach(hp); break; } rc = hotpatch_detach(hp); } } while (0); hotpatch_destroy(hp); hp = NULL; if (opts.symbol) free(opts.symbol); opts.symbol = NULL; if (opts.dll) free(opts.dll); opts.dll = NULL; return rc; }