static void close_input(pesign_context *ctx) { pe_end(ctx->inpe); ctx->inpe = NULL; close(ctx->infd); ctx->infd = -1; }
static void close_output(pesign_context *ctx) { Pe_Cmd cmd = ctx->outfd == STDOUT_FILENO ? PE_C_RDWR : PE_C_RDWR_MMAP; finalize_signatures(ctx); pe_update(ctx->outpe, cmd); pe_end(ctx->outpe); ctx->outpe = NULL; close(ctx->outfd); ctx->outfd = -1; }
static int dw_iter_by_addr(struct ps_prochandle *P, const char *object_name, int which, int mask, proc_sym_f *func, void *cd) { int fd = 0, ret = -1, i, index = 0; Pe_object *pe; proc_mod_t *mod = findmodulebyname(P, object_name); fd = _open(mod->fullname, _O_RDONLY|_O_BINARY, 0); if (fd == -1 ) return -1; if ((pe = pe_init(fd)) != NULL) { IMAGE_SYMBOL *Sym = pe_getsymarr(pe, &index); char name[MAX_SYM_NAME]; if (Sym == NULL) goto end; ret = 0; for (i = 0; i < index; i++) { GElf_Sym symp; char *n = NULL; if (ISFCN(Sym[i].Type) == 0) continue; symp.st_name = 0; symp.st_other = 0; symp.st_info = GELF_ST_INFO((STB_GLOBAL), (STT_FUNC)); symp.st_shndx = 1; symp.st_value = Sym[i].Value+mod->imgbase+pe_getsecva(pe, Sym[i].SectionNumber); /* If size is zero libdtrace will reject the probe.Allow creation of entry probe */ symp.st_size = 1; if (pe_getsymname(pe, &Sym[i], name, MAX_SYM_NAME) == NULL) continue; if (pe_getarch(pe) == PE_ARCH_I386) func(cd, &symp, &name[1]); else func(cd, &symp, name); } } end: if (pe != NULL) pe_end(pe); if (fd != -1) close(fd); return ret; }
static int is64bitmodule(PVOID base, char *s) { int fd = _open(s, _O_RDONLY|_O_BINARY, 0); Pe_object *pe; if (fd != -1 && (pe = pe_init(fd)) != NULL) { int type = pe_getarch(pe); pe_end(pe); close(fd); if ( type == PE_ARCH_AMD64) return 1; else return 0; } }
static int dw_lookup_by_name(struct ps_prochandle *P, const char *oname, const char *sname, GElf_Sym *symp) { IMAGE_SYMBOL Sym; int ret = -1, fd; Pe_object *pe; proc_mod_t *mod; mod = findmodulebyname(P, oname); if (mod == NULL) return -1; fd = _open(mod->fullname, _O_RDONLY|_O_BINARY, 0); if (fd != -1 && (pe = pe_init(fd)) != NULL) { char s[MAX_SYM_NAME]; if (pe_getarch(pe) == PE_ARCH_I386) { s[0] = '_'; strcpy(&s[1], sname); } else { strcpy(s, sname); } if (pe_getsymbyname(pe, s, &Sym) != NULL) { symp->st_name = 0; symp->st_other = 0; if (ISFCN(Sym.Type)) { symp->st_info = GELF_ST_INFO((STB_GLOBAL), (STT_FUNC)); symp->st_shndx = 1; } else { symp->st_info = GELF_ST_INFO((STB_GLOBAL), (STT_NOTYPE)); symp->st_shndx = SHN_UNDEF; } symp->st_value = Sym.Value + mod->imgbase + pe_getsecva(pe, Sym.SectionNumber); /* If size is zero libdtrace will reject the function. Allow creation of entry probe */ symp->st_size = 1; ret = 0; } } if (pe != NULL) pe_end(pe); if (fd != -1) close(fd); return ret; }
void pesigcheck_context_fini(pesigcheck_context *ctx) { if (!ctx) return; cms_context_fini(ctx->cms_ctx); xfree(ctx->infile); if (ctx->inpe) { pe_end(ctx->inpe); ctx->inpe = NULL; } if (!(ctx->flags & pesigcheck_C_ALLOCATED)) pesigcheck_context_init(ctx); while (ctx->db) { dblist *db = ctx->db; if (db->type == DB_CERT) free(db->data); munmap(db->map, db->size); close(db->fd); ctx->db = db->next; free(db); } while (ctx->dbx) { dblist *db = ctx->dbx; if (db->type == DB_CERT) free(db->data); munmap(db->map, db->size); close(db->fd); ctx->dbx = db->next; free(db); } while (ctx->hashes) { hashlist *hashes = ctx->hashes; free(hashes->data); ctx->hashes = hashes->next; free(hashes); } }
static int dw_lookup_by_addr(struct ps_prochandle *P, uintptr_t addr, char *buf, size_t size, GElf_Sym *symp) { proc_mod_t *mod = NULL; int fd, ret = -1, index, i; Pe_object *pe; mod = findmodulebyaddr(P, addr); if (mod == NULL) return -1; fd = _open(mod->fullname, _O_RDONLY|_O_BINARY, 0); if (fd == -1 ) return -1; if ((pe = pe_init(fd)) != NULL) { IMAGE_SYMBOL *Sym = pe_getsymarr(pe, &index); char name[MAX_SYM_NAME]; int secno, addr1, mark = -1, prev = 0, va; if (Sym == NULL) goto end; if ((secno = pe_getsecnofromaddr(pe, addr - mod->imgbase))== 0) goto end; va = pe_getsecva(pe, secno); addr1 = addr - (mod->imgbase + va); if (addr1 <= 0) goto end; for (i = 0; i < index; i++) { if (ISFCN(Sym[i].Type) == 0 || Sym[i].SectionNumber != secno) continue; if (addr1 == Sym[i].Value) { mark = i; break; } else if (addr1 > Sym[i].Value) { if (prev < Sym[i].Value) { prev = Sym[i].Value; mark = i; } } } if (mark >= 0) { symp->st_name = 0; symp->st_other = 0; symp->st_info = GELF_ST_INFO((STB_GLOBAL), (STT_FUNC)); symp->st_shndx = 1; symp->st_value = Sym[mark].Value + mod->imgbase + pe_getsecva(pe, Sym[mark].SectionNumber); /* If size is zero libdtrace will reject the function. Allow creation of entry probe */ symp->st_size = 1; if (pe_getsymname(pe, &Sym[mark], name, MAX_SYM_NAME) == NULL) goto end; if (pe_getarch(pe) == PE_ARCH_I386) { strncpy(buf, &name[1], size); } else { strncpy(buf, name, size); } ret = 0; } } end: if (pe != NULL) pe_end(pe); if (fd != -1) close(fd); return ret; }
void pesign_context_fini(pesign_context *ctx) { if (!ctx) return; if (ctx->cms_ctx) { cms_context_fini(ctx->cms_ctx); ctx->cms_ctx = NULL; } if (ctx->outpe) { pe_end(ctx->outpe); ctx->outpe = NULL; } if (ctx->inpe) { pe_end(ctx->inpe); ctx->inpe = NULL; } xfree(ctx->outfile); xfree(ctx->infile); xfree(ctx->rawsig); xfree(ctx->insattrs); xfree(ctx->outsattrs); xfree(ctx->insig); xfree(ctx->outsig); xfree(ctx->outkey); xfree(ctx->outcert); if (ctx->rawsigfd >= 0) { close(ctx->rawsigfd); ctx->rawsigfd = -1; } if (ctx->insattrsfd >= 0) { close(ctx->insattrsfd); ctx->insattrsfd = -1; } if (ctx->outsattrsfd >= 0) { close(ctx->outsattrsfd); ctx->outsattrsfd = -1; } if (ctx->insigfd >= 0) { close(ctx->insigfd); ctx->insigfd = -1; } if (ctx->outsigfd >= 0) { close(ctx->outsigfd); ctx->outsigfd = -1; } if (ctx->outkeyfd >= 0) { close(ctx->outkeyfd); ctx->outkeyfd = -1; } if (ctx->outcertfd >= 0) { close(ctx->outcertfd); ctx->outcertfd = -1; } if (ctx->cinfo) { SEC_PKCS7DestroyContentInfo(ctx->cinfo); ctx->cinfo = NULL; } if (ctx->outfd >= 0) { close(ctx->outfd); ctx->outfd = -1; } if (ctx->infd >= 0) { close(ctx->infd); ctx->infd = -1; } ctx->signum = -1; if (!(ctx->flags & PESIGN_C_ALLOCATED)) pesign_context_init(ctx); }
int pe_end(Pe *pe) { Pe *parent = NULL; if (pe == NULL) { /* This is allowed and is a no-op. */ return 0; } if (pe->ref_count != 0 && --pe->ref_count != 0) { int result = pe->ref_count; return result; } parent = pe->parent; switch (pe->kind) { case PE_K_NONE: case PE_K_MZ: break; case PE_K_PE_OBJ: case PE_K_PE_EXE: case PE_K_PE_ROM: case PE_K_PE64_OBJ: case PE_K_PE64_EXE: { Pe_ScnList *list = &pe->state.pe.scns; do { size_t cnt = list->max; while (cnt-- > 0) { Pe_Scn *scn = &list->data[cnt]; if ((scn->shdr_flags & PE_F_MALLOCED)) xfree(scn->shdr); if (scn->data_base != scn->rawdata_base) xfree(scn->data_base); if (pe->map_address == NULL) xfree(scn->rawdata_base); } Pe_ScnList *oldp = list; list = list->next; assert(list == NULL || oldp->cnt == oldp->max); if (oldp != &pe->state.pe.scns) xfree(oldp); } while (list); } break; case PE_K_NUM: default: break; } if (pe->map_address != NULL && parent == NULL) { if (pe->flags & PE_F_MALLOCED) xfree(pe->map_address); else if (pe->flags & PE_F_MMAPPED) xmunmap(pe->map_address, pe->maximum_size); } xfree(pe); return (parent != NULL && parent->ref_count ? pe_end(parent) : 0); }