/* * The approach where the system process list es enumerated looking for * the matching cr3 value in each _EPROCESS struct is not going to work * if a DKOM attack unhooks the _EPROCESS struct. * * We can access the _EPROCESS structure by reading the FS_BASE register on x86 * or the GS_BASE register on x64, which contains the _KPCR. * * FS/GS -> _KPCR._KPRCB.CurrentThread -> _ETHREAD._KTHREAD.Process = _EPROCESS * * Also see: http://www.csee.umbc.edu/~stephens/SECURITY/491M/HiddenProcesses.ppt */ static void grab_file_by_handle(filedelete* f, drakvuf_t drakvuf, vmi_instance_t vmi, drakvuf_trap_info_t* info, addr_t handle) { addr_t file = 0; addr_t filetype = 0; std::string filename = get_file_name(f, drakvuf, vmi, info, handle, &file, &filetype); if (filename.empty()) return; uint64_t fo_flags = 0; get_file_object_flags(drakvuf, info, vmi, f, handle, &fo_flags); print_filedelete_information(f, drakvuf, info, filename.c_str(), 0 /*TODO: print file size*/, fo_flags); if (f->dump_folder) { access_context_t ctx = { .translate_mechanism = VMI_TM_PROCESS_DTB, .addr = filetype, .dtb = info->regs->cr3, }; extract_file(f, drakvuf, info, vmi, file, &ctx, filename.c_str(), fo_flags); } }
int extract_iso(uniso_status_t *s, struct archive *iso, const char *dst, distro_filter_f filter, uniso_progress_t total, uniso_progress_cb cb, void *cb_data) { struct archive_entry *e; uniso_progress_t current = 0; make_dir_parents(dst); if(cb) cb(current, total, cb_data); while(archive_read_next_header(iso, &e) == ARCHIVE_OK) { char *name = unix_path(strdup2(archive_entry_pathname(e))); if(archive_entry_filetype(e) == AE_IFDIR || !filter(name)) { free(name); continue; } s->files = new_string_node_t(name, s->files); char *dest = unix_path(create_dest(dst, "/", name)); if(!extract_file(s, iso, dest)) { free(dest); return 0; } ++current; if(cb) cb(current, total, cb_data); free(dest); } return 1; }
static int set_pkgsrc(struct menudesc *menu, void *arg) { configinfo **confp = arg; distinfo dist; dist.name = "pkgsrc"; dist.set = SET_PKGSRC; dist.desc = "source for 3rd-party packages"; dist.marker_file = NULL; int status = SET_RETRY; do { status = get_pkgsrc(); if (status == SET_OK) { status = extract_file(&dist, 0); continue; } else if (status == SET_SKIP) { confp[menu->cursel]->setting = MSG_abandoned; return 0; } process_menu(MENU_yesno, deconst(MSG_retry_pkgsrc_network)); if (!yesno) { confp[menu->cursel]->setting = MSG_abandoned; return 1; } } while (status == SET_RETRY); confp[menu->cursel]->setting = MSG_DONE; return 0; }
/* If file is NULL, extract all files. */ static int extract_it(const char *file) { DBF_curs *curs; DBFile *dbf; DBSummary *dbs; if(file) g_message("Extract: %s", file); else g_message("Extracting all files."); curs = db_filename_curs_begin(); while((dbf = db_filename_curs_next(curs))) { /* I trust file more than dbf->filename not to be corrupt, so use its length. */ if(!file || strncmp(dbf->filename, file, strlen(file)) == 0) { if(file && int_option(kOption_verbose) & VERBOSE_FILES) g_message("Archiving file '%s'.", file); dbs = db_summary_fetch_last(dbf->file_id); if(dbs) extract_file(dbf, dbs); else g_warning("File is in database, but has " "no summary record: %s", dbf->filename); } cycle_main_loop(); } return 0; }
static int run_loadfile(struct subcommand *scp, int argc, char **argv) { const char *extension = ""; char *extracted_name; char *fullname; int len, ret; if ((fullname = realpath(argv[0], NULL)) == NULL) { warn("%s: realpath", scp->sc_name); return (BERI_DEBUG_USAGE_ERROR); } if (strcmp("loadsof", scp->sc_name) == 0) { if (!zflag && ((len = strlen(fullname)) < 5 || strcmp(".sof", fullname + (len - 4)) != 0)) { warnx("loadsof: file must end in .sof"); return (BERI_DEBUG_USAGE_ERROR); } else extension = ".sof"; } if (zflag) { if ((extracted_name = extract_file(fullname, extension)) == NULL) { free(fullname); warnx("%s: failed to extract %s", scp->sc_name, argv[0]); return (BERI_DEBUG_USAGE_ERROR); } free(fullname); fullname = extracted_name; } if (strcmp("loadsof", scp->sc_name) == 0) { assert (argc == 1); return(berictl_loadsof(fullname, cablep, devicep)); } /* XXX: validate argv[1] as an address */ assert(argc == 2); if (strcmp("loadbin", scp->sc_name) == 0) ret = berictl_loadbin(bdp, argv[1], fullname); else if (strcmp("loaddram", scp->sc_name) == 0) if (scp->oflags & BERI_DEBUG_CLIENT_OPEN_FLAGS_ARM_SOCKIT) ret = berictl_loaddram_sockit(bdp, argv[1], fullname); else ret = berictl_loaddram(bdp, argv[1], fullname, cablep); else errx(EXIT_FAILURE, "PROGRAMMER ERROR: %s called with unhandled command %s", __func__, scp->sc_name); free(fullname); return (ret); }
void extract(char* input_file, char* output_file) { FILE* fp_in = fopen(input_file, "rb"); FILE* fp_out = fopen(output_file, "wb"); extract_file(fp_in, fp_out); fclose(fp_in); fclose(fp_out); }
int main(int argc, char *argv[]) { if (argc!=2 && argc!=3) { std::cerr<<"To extract a file: "<<std::endl; std::cerr<<argv[0]<<" <img> <file>"<<std::endl; std::cerr<<"To extract all files: "<<std::endl; std::cerr<<argv[0]<<" <img>"<<std::endl; return EXIT_FAILURE; } bool all_files = argc==2; std::string extract; if (!all_files) extract = argv[2]; try { std::ifstream in; in.open(argv[1], std::ios::binary); APP_ASSERT_IO_SUCCESSFUL(in,"opening IMG"); Img img; img.init(in, argv[1]); if (!all_files) { unsigned long off = img.fileOffset(extract); unsigned long sz = img.fileSize(extract); extract_file(in, extract, off, sz); return EXIT_SUCCESS; } for (size_t i=0 ; i<img.size() ; i++) { unsigned long off = img.fileOffset(i); unsigned long sz = img.fileSize(i); extract_file(in, img.fileName(i), off, sz); } return EXIT_SUCCESS; } catch (const Exception &e) { CERR << e << std::endl; return EXIT_FAILURE; } }
static int extract_normal(LHAReader *reader, char *filename, LHADecoderProgressCallback callback, void *callback_data) { if (strcmp(reader->curr_file->compress_method, LHA_COMPRESS_TYPE_DIR) != 0) { return extract_file(reader, filename, callback, callback_data); } else if (reader->curr_file->symlink_target != NULL) { return extract_symlink(reader, filename); } else { return extract_directory(reader, filename); } }
int checkFile(void) { md5_state_t state; md5_byte_t md5Tag[16] = {0}; md5_byte_t md5Clc[16] = {0}; //struct MD5Context md5c; if( imageLen < 80 ) { do_upload_finnal(); return BOOL_FALSE; } if( imagePtr == NULL ) { do_upload_finnal(); return BOOL_FALSE; } memcpy(md5Tag, imagePtr+64, 16); printf("boardapi_checkCpuEndian = %s\n", boardapi_checkCpuEndian()?"little-endian":"big-endian"); //MD5Init( &md5c ); //MD5Update( &md5c, imagePtr+80, imageLen-80 ); //MD5Final( md5Clc, &md5c ); md5_init(&state); md5_append(&state, (const md5_byte_t *)(imagePtr+80), (imageLen-80)); md5_finish(&state, md5Clc); printf("MD5 SRC:\n"); dumpHex((unsigned char *)md5Tag, 16); printf("MD5 CLC:\n"); dumpHex((unsigned char *)md5Clc, 16); if( memcmp(md5Tag, md5Clc, 16) == 0 ) { if( CMM_SUCCESS != extract_file("/var/tmp/wec9720ek.tar.bz2", imagePtr+80, imageLen-80) ) { do_upload_finnal(); return BOOL_FALSE; } return BOOL_TRUE; } else { do_upload_finnal(); return BOOL_FALSE; } }
void extract(fs::path const& path, std::regex const& pattern) { std::cout << "Extracting files from " << path << "..." << std::endl; ff7::lgp::Archive ar{path.string()}; int added{}; for (auto& file : ar) { if (std::regex_match(file.first, pattern)) { extract_file(file); ++added; } } std::cout << added << " files extracted" << std::endl; }
// ================================================================== void hatch::OnImportDiz() // ================================================================== { FILE *fp; CString desc; CString fname; char buf[1000]; char path[MAX_PATH]; char fpath[MAX_PATH]; int ret=0; m_filename.GetWindowText(fname); trim_all(fname); if (fname.GetLength()<2) ERR_MSG_RET("W_NOFFFD"); make_path(path,gc.BasePath,"_TMP"); make_path(fpath,path,"file_id.diz"); _mkdir(path); if (!extract_file(fname,path)) { err_out("E_EXTFAD",fname); ret=0; goto exit; } fp=fopen(fpath,"rt"); if (fp) { while (fgets(buf,999,fp)) desc+=buf; ret=1; fclose(fp); } exit: SafeFileDelete(path,FALSE); if (!ret) ERR_MSG_RET("W_NOFIDDF"); trim_all(desc); desc.Replace("\n"," "); desc.OemToAnsi(); m_description.SetWindowText(desc); }
//======================================================================================= // DocLocator implementation //======================================================================================= DocLocator::DocLocator(const string& locator) : m_fullLocator(locator) , m_protocol(k_unknown) , m_innerProtocol(k_none) , m_fullpath("") , m_path("") , m_innerFullPath("") , m_innerFile("") , m_fValid(false) { split_locator(locator); if (is_valid()) { extract_file(); extract_path(); } }
void Launcher::UnshieldThread::extract_cab(const bfs::path& cab, const bfs::path& output_dir, bool extract_ini) { Unshield * unshield; unshield = unshield_open(cab.c_str()); int i; for (i = 0; i < unshield_file_group_count(unshield); i++) { UnshieldFileGroup* file_group = unshield_file_group_get(unshield, i); for (size_t j = file_group->first_file; j <= file_group->last_file; j++) { if (unshield_file_is_valid(unshield, j)) extract_file(unshield, output_dir, file_group->name, j); } } unshield_close(unshield); }
int main() { nd_file file; create_pack(&file); add_file(&file,"a.out"); add_file(&file,"test.txt"); write_pack(&file,"out.p"); free_pack(&file); nd_file x = {0}; read_pack(&x,"out.p"); //dump_pack(&x); extract_file(&x,"test.txt","test.xxx"); free_pack(&x); return 0; }
void CSoliDire::extract_all_files(CTreeNode * p, CFile * ifp, CString path) { extract_file(p->get_inode(), ifp, path); CString tmp = path; if (tmp.Right(1) != "\\") tmp += "\\"; if (p->get_inode().bIsDir) tmp = tmp + p->get_inode().lpszFileName + "\\"; if (p->has_lchild()) extract_all_files(p->get_lchild(), ifp, tmp); if (p->has_rchild()) { p = p->get_rchild(); extract_all_files(p, ifp, path); } }
int unpack_files( char *file_name ) { int f_out = open(file_name, O_RDONLY), count, i; if (f_out < 0) return -1; read(f_out, &count, sizeof(int)); for (i = 0; i < count; i++) if (extract_file(f_out) == -1) { close(f_out); return -1; } close(f_out); return 0; }
/* * Extract a zipfile entry: first perform some sanity checks to ensure * that it is either a directory or a regular file and that the path is * not absolute and does not try to break out of the current directory; * then call either extract_dir() or extract_file() as appropriate. * * This is complicated a bit by the various ways in which we need to * manipulate the path name. Case conversion (if requested by the -L * option) happens first, but the include / exclude patterns are applied * to the full converted path name, before the directory part of the path * is removed in accordance with the -j option. Sanity checks are * intentionally done earlier than they need to be, so the user will get a * warning about insecure paths even for files or directories which * wouldn't be extracted anyway. */ static void extract(struct archive *a, struct archive_entry *e) { char *pathname, *realpathname; mode_t filetype; char *p, *q; pathname = pathdup(archive_entry_pathname(e)); filetype = archive_entry_filetype(e); /* sanity checks */ if (pathname[0] == '/' || strncmp(pathname, "../", 3) == 0 || strstr(pathname, "/../") != NULL) { warningx("skipping insecure entry '%s'", pathname); ac(archive_read_data_skip(a)); free(pathname); return; } /* I don't think this can happen in a zipfile.. */ if (!S_ISDIR(filetype) && !S_ISREG(filetype)) { warningx("skipping non-regular entry '%s'", pathname); ac(archive_read_data_skip(a)); free(pathname); return; } /* skip directories in -j case */ if (S_ISDIR(filetype) && j_opt) { ac(archive_read_data_skip(a)); free(pathname); return; } /* apply include / exclude patterns */ if (!accept_pathname(pathname)) { ac(archive_read_data_skip(a)); free(pathname); return; } /* apply -j and -d */ if (j_opt) { for (p = q = pathname; *p; ++p) if (*p == '/') q = p + 1; realpathname = pathcat(d_arg, q); } else { realpathname = pathcat(d_arg, pathname); } /* ensure that parent directory exists */ make_parent(realpathname); if (S_ISDIR(filetype)) extract_dir(a, e, realpathname); else extract_file(a, e, &realpathname); free(realpathname); free(pathname); }
/******************************************************************************** *Function: search_chunk *Description: Analyze the given chunk by running each defined search spec on it *Return: TRUE/FALSE **********************************************************************************/ int search_chunk(f_state *s, unsigned char *buf, f_info *i, u_int64_t chunk_size, u_int64_t f_offset) { u_int64_t c_offset = 0; //u_int64_t foundat_off = 0; //u_int64_t buf_off = 0; unsigned char *foundat = buf; unsigned char *current_pos = NULL; unsigned char *header_pos = NULL; unsigned char *newbuf = NULL; unsigned char *ind_ptr = NULL; u_int64_t current_buflen = chunk_size; int tryBS[3] = { 4096, 1024, 512 }; unsigned char *extractbuf = NULL; u_int64_t file_size = 0; s_spec *needle = NULL; int j = 0; int bs = 0; int rem = 0; int x = 0; int found_ind = FALSE; off_t saveme; //char comment[32]; for (j = 0; j < s->num_builtin; j++) { needle = &search_spec[j]; foundat = buf; /*reset the buffer for the next search spec*/ #ifdef DEBUG printf(" SEARCHING FOR %s's\n", needle->suffix); #endif bs = 0; current_buflen = chunk_size; while (foundat) { needle->written = FALSE; found_ind = FALSE; memset(needle->comment, 0, COMMENT_LENGTH - 1); if (chunk_size <= (foundat - buf)) { #ifdef DEBUG printf("avoided seg fault in search_chunk()\n"); #endif foundat = NULL; break; } current_buflen = chunk_size - (foundat - buf); //if((foundat-buf)< 1 ) break; #ifdef DEBUG //foundat_off=foundat; //buf_off=buf; //printf("current buf:=%llu (foundat-buf)=%llu \n", current_buflen, (u_int64_t) (foundat_off - buf_off)); #endif if (signal_caught == SIGTERM || signal_caught == SIGINT) { user_interrupt(s, i); printf("Cleaning up.\n"); signal_caught = 0; } if (get_mode(s, mode_quick)) /*RUN QUICK SEARCH*/ { #ifdef DEBUG //printf("quick mode is on\n"); #endif /*Check if we are not on a block head, adjust if so*/ rem = (foundat - buf) % s->block_size; if (rem != 0) { foundat += (s->block_size - rem); } if (memwildcardcmp(needle->header, foundat, needle->header_len, needle->case_sen ) != 0) { /*No match, jump to the next block*/ if (current_buflen > s->block_size) { foundat += s->block_size; continue; } else /*We are out of buffer lets go to the next search spec*/ { foundat = NULL; break; } } header_pos = foundat; } else /**********RUN STANDARD SEARCH********************/ { foundat = bm_search(needle->header, needle->header_len, foundat, current_buflen, //How much to search through needle->header_bm_table, needle->case_sen, //casesensative SEARCHTYPE_FORWARD); header_pos = foundat; } if (foundat != NULL && foundat >= 0) /*We got something, run the appropriate heuristic to find the EOF*/ { current_buflen = chunk_size - (foundat - buf); if (get_mode(s, mode_ind_blk)) { #ifdef DEBUG printf("ind blk detection on\n"); #endif //dumpInd(foundat+12*1024,1024); for (x = 0; x < 3; x++) { bs = tryBS[x]; if (ind_block(foundat, current_buflen, bs)) { if (get_mode(s, mode_verbose)) { sprintf(needle->comment, " (IND BLK bs:=%d)", bs); } //dumpInd(foundat+12*bs,bs); #ifdef DEBUG printf("performing mem move\n"); #endif if(current_buflen > 13 * bs)//Make sure we have enough buffer { if (!memmove(foundat + 12 * bs, foundat + 13 * bs, current_buflen - 13 * bs)) break; found_ind = TRUE; #ifdef DEBUG printf("performing mem move complete\n"); #endif ind_ptr = foundat + 12 * bs; current_buflen -= bs; chunk_size -= bs; break; } } } } c_offset = (foundat - buf); current_pos = foundat; /*Now lets analyze the file and see if we can determine its size*/ // printf("c_offset=%llu %x %x %llx\n", c_offset,foundat,buf,c_offset); foundat = extract_file(s, c_offset, foundat, current_buflen, needle, f_offset); #ifdef DEBUG if (foundat == NULL) { printf("Foundat == NULL!!!\n"); } #endif if (get_mode(s, mode_write_all)) { if (needle->written == FALSE) { /*write every header we find*/ if (current_buflen >= needle->max_len) { file_size = needle->max_len; } else { file_size = current_buflen; } sprintf(needle->comment, " (Header dump)"); extractbuf = (unsigned char *)malloc(file_size * sizeof(char)); memcpy(extractbuf, header_pos, file_size); write_to_disk(s, needle, file_size, extractbuf, c_offset + f_offset); free(extractbuf); } } else if (!foundat) /*Should we search further?*/ { /*We couldn't determine where the file ends, now lets check to see * if we should try again */ if (current_buflen < needle->max_len) /*We need to bridge the gap*/ { #ifdef DEBUG printf(" Bridge the gap\n"); #endif saveme = ftello(i->handle); /*grow the buffer and try to extract again*/ newbuf = read_from_disk(c_offset + f_offset, i, needle->max_len); if (newbuf == NULL) break; current_pos = extract_file(s, c_offset, newbuf, needle->max_len, needle, f_offset); /*Lets put the fp back*/ fseeko(i->handle, saveme, SEEK_SET); free(newbuf); } else { foundat = header_pos; /*reset the foundat pointer to the location of the last header*/ foundat += needle->header_len + 1; /*jump past the header*/ } } } if (found_ind) { /*Put the ind blk back in, re-arrange the buffer so that the future blks names come out correct*/ #ifdef DEBUG printf("Replacing the ind block\n"); #endif /*This is slow, should we do this??????*/ if (!memmove(ind_ptr + 1 * bs, ind_ptr, current_buflen - 13 * bs)) break; memset(ind_ptr, 0, bs - 1); chunk_size += bs; memset(needle->comment, 0, COMMENT_LENGTH - 1); } } //end while } return TRUE; }
/* Open a zip-compatible archive and extract all files * into the specified directory (which is assumed to exist) */ BOOL unzip_archive(SCHEME *scheme, char *dirname, char *data, DWORD size, NOTIFYPROC notify) { int n; char pathname[MAX_PATH]; char *new_part; /* read the end of central directory record */ struct eof_cdir *pe = (struct eof_cdir *)&data[size - sizeof (struct eof_cdir)]; int arc_start = size - sizeof (struct eof_cdir) - pe->nBytesCDir - pe->ofsCDir; /* set position to start of central directory */ int pos = arc_start + pe->ofsCDir; /* make sure this is a zip file */ if (pe->tag != 0x06054b50) return FALSE; /* Loop through the central directory, reading all entries */ for (n = 0; n < pe->nTotalCDir; ++n) { int i; char *fname; char *pcomp; char *dst; struct cdir *pcdir; struct fhdr *pfhdr; pcdir = (struct cdir *)&data[pos]; pfhdr = (struct fhdr *)&data[pcdir->ofs_local_header + arc_start]; if (pcdir->tag != 0x02014b50) return FALSE; if (pfhdr->tag != 0x04034b50) return FALSE; pos += sizeof(struct cdir); fname = (char *)&data[pos]; /* This is not null terminated! */ pos += pcdir->fname_length + pcdir->extra_length + pcdir->comment_length; pcomp = &data[pcdir->ofs_local_header + sizeof(struct fhdr) + arc_start + pfhdr->fname_length + pfhdr->extra_length]; /* dirname is the Python home directory (prefix) */ strcpy(pathname, dirname); if (pathname[strlen(pathname)-1] != '\\') strcat(pathname, "\\"); new_part = &pathname[lstrlen(pathname)]; /* we must now match the first part of the pathname * in the archive to a component in the installation * scheme (PURELIB, PLATLIB, HEADERS, SCRIPTS, or DATA) * and replace this part by the one in the scheme to use */ for (i = 0; scheme[i].name; ++i) { if (0 == strnicmp(scheme[i].name, fname, strlen(scheme[i].name))) { char *rest; int len; /* length of the replaced part */ int namelen = strlen(scheme[i].name); strcat(pathname, scheme[i].prefix); rest = fname + namelen; len = pfhdr->fname_length - namelen; if ((pathname[strlen(pathname)-1] != '\\') && (pathname[strlen(pathname)-1] != '/')) strcat(pathname, "\\"); /* Now that pathname ends with a separator, * we must make sure rest does not start with * an additional one. */ if ((rest[0] == '\\') || (rest[0] == '/')) { ++rest; --len; } strncat(pathname, rest, len); goto Done; } } /* no prefix to replace found, go unchanged */ strncat(pathname, fname, pfhdr->fname_length); Done: normpath(pathname); if (pathname[strlen(pathname)-1] != '\\') { /* * The local file header (pfhdr) does not always * contain the compressed and uncompressed sizes of * the data depending on bit 3 of the flags field. So * it seems better to use the data from the central * directory (pcdir). */ dst = map_new_file(0, pathname, new_part, pcdir->uncomp_size, pcdir->last_mod_file_date, pcdir->last_mod_file_time, notify); if (dst) { if (!extract_file(dst, pcomp, pfhdr->method, pcdir->comp_size, pcdir->uncomp_size, notify)) return FALSE; } /* else ??? */ } if (notify) notify(NUM_FILES, new_part, (int)pe->nTotalCDir, (int)n+1); } return TRUE; }
int main(int argc, char **argv) { idevice_t phone = NULL; lockdownd_client_t client = NULL; uint16_t port = 0; char* crashLogFile; if(argc != 2) { print_usage(argc, argv); return -1; } crashLogFile = argv[1]; if (idevice_new(&phone, NULL) != IDEVICE_E_SUCCESS) { printf("No device found, is it plugged in?\n"); return -1; } if (lockdownd_client_new_with_handshake(phone, &client, "idevicecrashlog") != LOCKDOWN_E_SUCCESS) { fprintf(stderr, "Could not connect to lockdownd. Exiting.\n"); return -1; } if ((lockdownd_start_service(client, "com.apple.mobile.file_relay", &port) != LOCKDOWN_E_SUCCESS) || !port) { fprintf(stderr, "Could not start com.apple.mobile.file_relay!\n"); return -1; } const char *sources[] = {"CrashReporter", NULL}; idevice_connection_t dump = NULL; file_relay_client_t frc = NULL; if (file_relay_client_new(phone, port, &frc) != FILE_RELAY_E_SUCCESS) { printf("could not connect to file_relay service!\n"); return -1; } if (file_relay_request_sources(frc, sources, &dump) != FILE_RELAY_E_SUCCESS) { printf("could not get sources\n"); return -1; } if (!dump) { printf("did not get connection!\n"); return -1; } uint32_t cnt = 0; uint32_t len = 0; char buf[4096]; char* dumpTmpFile = tmpnam(NULL); FILE *f = fopen(dumpTmpFile, "w"); //receiving file while (idevice_connection_receive(dump, buf, 4096, &len) == IDEVICE_E_SUCCESS) { fwrite(buf, 1, len, f); cnt += len; len = 0; } fclose(f); extract_file(dumpTmpFile, crashLogFile); lockdownd_client_free(client); }
int unpack_update(const char* srcfile, const char* dstdir) { int fd = -1; size_t file_len = 0; struct update_header header; void *buf = MAP_FAILED; fd = open(srcfile, O_RDONLY); if (fd == -1) { fprintf(stderr, "can't open file \"%s\": %s\n", srcfile, strerror(errno)); goto unpack_fail; } file_len = lseek(fd, 0, SEEK_END); if (file_len == (size_t) -1) goto unpack_fail; if (file_len < sizeof(header)) { fprintf(stderr, "Invalid file size\n"); goto unpack_fail; } buf = mmap(NULL, file_len, PROT_READ, MAP_SHARED | MAP_FILE, fd, 0); if (buf == MAP_FAILED) { perror("Error mmap"); goto unpack_fail; } memcpy(&header, buf, sizeof(header)); if (strncmp(header.magic, RKAFP_MAGIC, sizeof(header.magic)) != 0) { fprintf(stderr, "Invalid header magic\n"); goto unpack_fail; } if (check_update(buf, header.length + 4) == -1) goto unpack_fail; printf("------- UNPACK -------\n"); if (header.num_parts) { unsigned i; char dir[PATH_MAX]; for (i = 0; i < header.num_parts; i++) { struct update_part *part = &header.parts[i]; printf("%s\t0x%08X\t0x%08X\n", part->filename, part->pos, part->size); if (strcmp(part->filename, "SELF") == 0) { printf("Skip SELF file.\n"); continue; } // parameter 多出文件头8个字节,文件尾4个字节 if (memcmp(part->name, "parameter", 9) == 0) { part->pos += 8; part->size -= 12; } snprintf(dir, sizeof(dir), "%s/%s", dstdir, part->filename); if (-1 == create_dir(dir)) continue; if (part->pos + part->size > file_len - 4) { fprintf(stderr, "Invalid part: %s\n", part->name); continue; } extract_file(buf + part->pos, part->size, dir); } } munmap(buf, file_len); close(fd); return 0; unpack_fail: if (fd) { if (buf) munmap(buf, file_len); close(fd); } return -1; }
int main() { // $ strings HotlineMiami_GL.wad | grep -Eo '^.+\.ogg' | sed 's|^Music/||' const char * const FILE_NAMES[] = { "ANewMorning.ogg", "Crush.ogg", "Crystals.ogg", "Daisuke.ogg", "DeepCover.ogg", "ElectricDreams.ogg", "Flatline.ogg", "HorseSteppin.ogg", "Hotline.ogg", "Hydrogen.ogg", "InnerAnimal.ogg", "ItsSafeNow.ogg", "Knock.ogg", "Miami2.ogg", "Musikk2.ogg", "Paris2.ogg", "Perturbator.ogg", "Release.ogg", "SilverLights.ogg", "Static.ogg", "ToTheTop.ogg", "TurfIntro.ogg", "TurfMain.ogg", }; const int fd = open(WAD_FILENAME, O_RDONLY); if (fd == -1) { fprintf(stderr, "ERROR: Could not open file \"%s\".\n", WAD_FILENAME); return EXIT_FAILURE; } struct stat props; fstat(fd, &props); if ((props.st_size != WAD_EXPECTED_SIZE_BYTES_A) && (props.st_size != WAD_EXPECTED_SIZE_BYTES_B)) { fprintf(stderr, "ERROR: Input file is neither %d nor %d bytes in size. Ideally, grab \"%s\" from \"%s\".\n", WAD_EXPECTED_SIZE_BYTES_A, WAD_EXPECTED_SIZE_BYTES_B, WAD_FILENAME, WAD_PARENT_FILENAME); return 1; } char * const content = malloc(props.st_size + 1); if (! content) { fprintf(stderr, "ERROR: Out of memory.\n"); return 1; } const ssize_t bytes_read = read(fd, content, props.st_size); content[bytes_read] = '\0'; const char * first = content; unsigned int files_found = 0; const char * current_file_start = NULL; const char * current_file_end = NULL; for (;;) { const char * haystack = first; const size_t haystack_len = bytes_read - (haystack - content); first = find_capture(first, haystack_len, CAPTURE_PATTERN, sizeof(CAPTURE_PATTERN) - 1); if (first == NULL) { break; } const uint32_t page_sequence_number = le32toh(*(uint32_t *)(first + OFFSET_PAGE_SEQUENCE_NUMBER)); if (page_sequence_number == 0) { if (files_found > 0) { extract_file(content, current_file_start, current_file_end, FILE_NAMES[files_found - 1]); } current_file_start = first; files_found++; } const uint8_t page_segment_count = *(uint8_t *)(first + OFFSET_PAGE_SEGMENT_COUNT); size_t page_segment_index = 0; uint32_t size_of_all_pages_bytes = 0; for (; page_segment_index < page_segment_count; page_segment_index++) { const uint8_t page_size_byts = *(uint8_t *)(first + OFFSET_PAGE_SEGMENTS + page_segment_index); size_of_all_pages_bytes += page_size_byts; } const uint32_t size_from_this_page_bytes = OFFSET_PAGE_SEGMENTS + page_segment_count + size_of_all_pages_bytes; current_file_end = first + size_from_this_page_bytes; first += size_from_this_page_bytes; } if(files_found) extract_file(content, current_file_start, current_file_end, FILE_NAMES[files_found - 1]); close(fd); free(content); return EXIT_SUCCESS; }
static void cmd_extract(CTar32CmdInfo &cmdinfo) { { EXTRACTINGINFOEX extractinfo; memset(&extractinfo,0,sizeof(extractinfo)); EXTRACTINGINFOEX64 exinfo64; memset(&exinfo64,0,sizeof(exinfo64)); exinfo64.dwStructSize=sizeof(exinfo64); strncpy(extractinfo.exinfo.szSourceFileName, cmdinfo.arcfile.c_str() ,FNAME_MAX32+1); exinfo64.exinfo=extractinfo.exinfo; strncpy(exinfo64.szSourceFileName, extractinfo.exinfo.szSourceFileName ,FNAME_MAX32+1); int ret = SendArcMessage(cmdinfo, ARCEXTRACT_OPEN, &extractinfo,&exinfo64); if(ret){throw CTar32Exception("Cancel button was pushed.",ERROR_USER_CANCEL);} } CTar32 tarfile; int ret; ret = tarfile.open(cmdinfo.arcfile.c_str(), "rb",-1,ARCHIVETYPE_AUTO,cmdinfo.archive_charset); if(!ret){ throw CTar32Exception("can't open archive file", ERROR_ARC_FILE_OPEN); } CTar32FileStatus stat; std::vector<char> buffer; buffer.resize(1024*1024); while(true){ bool bret = tarfile.readdir(&stat); if(!bret){break;} std::string file_internal = stat.filename; std::string file_external; { const std::list<CTar32CmdInfo::CArgs> &args = cmdinfo.argfiles; std::list<CTar32CmdInfo::CArgs>::const_iterator filei; for(filei = args.begin();filei!=args.end();filei++){ if(::is_regexp_match_dbcs(filei->file.c_str(), file_internal.c_str())){ std::string file_internal2 = file_internal; if(! cmdinfo.b_absolute_paths){ file_internal2 = escape_absolute_paths(file_internal2.c_str()); } if(!cmdinfo.b_use_directory){ file_internal2 = get_filename(file_internal2.c_str()); } file_external = make_pathname(filei->current_dir.c_str(), file_internal2.c_str()); break; } } } if(file_external.empty()){ bret = tarfile.readskip(); }else{ bool bret2 = extract_file(cmdinfo,&tarfile,file_external.c_str(),buffer); } } { EXTRACTINGINFOEX extractinfo; memset(&extractinfo,0,sizeof(extractinfo)); EXTRACTINGINFOEX64 exinfo64; memset(&exinfo64,0,sizeof(exinfo64)); exinfo64.dwStructSize=sizeof(exinfo64); int ret = SendArcMessage(cmdinfo, ARCEXTRACT_END, &extractinfo,&exinfo64); if(ret){throw CTar32Exception("Cancel button was pushed.",ERROR_USER_CANCEL);} } }
int unpack_update(const char* srcfile, const char* dstdir) { FILE *fp = NULL; struct update_header header; unsigned int crc = 0; fp = fopen(srcfile, "rb"); if (!fp) { fprintf(stderr, "can't open file \"%s\": %s\n", srcfile, strerror(errno)); goto unpack_fail; } fseek(fp, 0, SEEK_SET); if (sizeof(header) != fread(&header, 1, sizeof(header), fp)) { fprintf(stderr, "Can't read image header\n"); goto unpack_fail; } if (strncmp(header.magic, RKAFP_MAGIC, sizeof(header.magic)) != 0) { fprintf(stderr, "Invalid header magic\n"); goto unpack_fail; } fseek(fp, header.length, SEEK_SET); if (sizeof(crc) != fread(&crc, 1, sizeof(crc), fp)) { fprintf(stderr, "Can't read crc checksum\n"); goto unpack_fail; } printf("Check file..."); fflush(stdout); fseek(fp, 0, SEEK_SET); if (crc != filestream_crc(fp, header.length)) { printf("Fail\n"); goto unpack_fail; } printf("OK\n"); printf("------- UNPACK -------\n"); if (header.num_parts) { unsigned i; char dir[PATH_MAX]; for (i = 0; i < header.num_parts; i++) { struct update_part *part = &header.parts[i]; printf("%s\t0x%08X\t0x%08X\n", part->filename, part->pos, part->size); if (strcmp(part->filename, "SELF") == 0) { printf("Skip SELF file.\n"); continue; } // parameter 多出文件头8个字节,文件尾4个字节 if (memcmp(part->name, "parameter", 9) == 0) { part->pos += 8; part->size -= 12; } snprintf(dir, sizeof(dir), "%s/%s", dstdir, part->filename); if (-1 == create_dir(dir)) continue; if (part->pos + part->size > header.length) { fprintf(stderr, "Invalid part: %s\n", part->name); continue; } extract_file(fp, part->pos, part->size, dir); } } fclose(fp); return 0; unpack_fail: if (fp) { fclose(fp); } return -1; }
/* Open a zip-compatible archive and extract all files * into the specified directory (which is assumed to exist) */ BOOL unzip_archive (char *dirname, char *data, DWORD size, NOTIFYPROC notify) { int n; char pathname[MAX_PATH]; char *new_part; /* read the end of central directory record */ struct eof_cdir *pe = (struct eof_cdir *)&data[size - sizeof (struct eof_cdir)]; int arc_start = size - sizeof (struct eof_cdir) - pe->nBytesCDir - pe->ofsCDir; /* set position to start of central directory */ int pos = arc_start + pe->ofsCDir; /* make sure this is a zip file */ if (pe->tag != 0x06054b50) return FALSE; /* Loop through the central directory, reading all entries */ for (n = 0; n < pe->nTotalCDir; ++n) { char *fname; char *pcomp; char *dst; struct cdir *pcdir = (struct cdir *)&data[pos]; struct fhdr *pfhdr = (struct fhdr *)&data[pcdir->ofs_local_header + arc_start]; if (pcdir->tag != 0x02014b50) return FALSE; if (pfhdr->tag != 0x04034b50) return FALSE; pos += sizeof (struct cdir); fname = (char *)&data[pos]; /* This is not null terminated! */ pos += pcdir->fname_length + pcdir->extra_length + pcdir->comment_length; pcomp = &data[pcdir->ofs_local_header + sizeof (struct fhdr) + arc_start + pfhdr->fname_length + pfhdr->extra_length]; strcpy (pathname, dirname); strcat (pathname, "\\"); new_part = &pathname[lstrlen (pathname)]; strncat (pathname, fname, pfhdr->fname_length); fixpath (pathname); if (pathname[strlen(pathname)-1] != '\\') { /* * The local file header (pfhdr) does not always contain * the compressed and uncompressed sizes of the data * depending on bit 3 of the flags field. * So it seems better to use the data from the * central directory (pcdir). */ dst = map_new_file (0, pathname, new_part, pcdir->uncomp_size, pcdir->last_mod_file_date, pcdir->last_mod_file_time, notify); if (dst) { if (!extract_file (dst, pcomp, pfhdr->method, pcdir->comp_size, pcdir->uncomp_size, notify)) return FALSE; } /* else ??? */ } if (notify) notify (NUM_FILES, new_part, (int)pe->nTotalCDir, (int)n+1); } return TRUE; }
/* * Read a tar file and extract or list the specified files within it. * If the list is empty than all files are extracted or listed. */ static int readTarFile(int tarFd, int extractFlag, int listFlag, int tostdoutFlag, int verboseFlag, char** extractList, char** excludeList) { int status; int errorFlag=FALSE; int skipNextHeaderFlag=FALSE; TarHeader rawHeader; TarInfo header; /* Read the tar file, and iterate over it one file at a time */ while ( (status = full_read(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) { /* Try to read the header */ if ( readTarHeader(&rawHeader, &header) == FALSE ) { if ( *(header.name) == '\0' ) { goto endgame; } else { errorFlag=TRUE; error_msg("Bad tar header, skipping"); continue; } } if ( *(header.name) == '\0' ) continue; header.tarFd = tarFd; /* Skip funky extra GNU headers that precede long files */ if ( (header.type == GNULONGNAME) || (header.type == GNULONGLINK) ) { skipNextHeaderFlag=TRUE; if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE) errorFlag = TRUE; continue; } if ( skipNextHeaderFlag == TRUE ) { skipNextHeaderFlag=FALSE; error_msg(name_longer_than_foo, NAME_SIZE); if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE) errorFlag = TRUE; continue; } #if defined BB_FEATURE_TAR_EXCLUDE if (exclude_file(excludeList, header.name)) { /* There are not the droids you're looking for, move along */ /* If it is a regular file, pretend to extract it with * the extractFlag set to FALSE, so the junk in the tarball * is properly skipped over */ if ( header.type==REGTYPE || header.type==REGTYPE0 ) { if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE) errorFlag = TRUE; } continue; } #endif if (!extract_file(extractList, header.name)) { /* There are not the droids you're looking for, move along */ /* If it is a regular file, pretend to extract it with * the extractFlag set to FALSE, so the junk in the tarball * is properly skipped over */ if ( header.type==REGTYPE || header.type==REGTYPE0 ) { if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE) errorFlag = TRUE; } continue; } if (listFlag == TRUE) { /* Special treatment if the list (-t) flag is on */ if (verboseFlag == TRUE) { int len, len1; char buf[35]; struct tm *tm = localtime (&(header.mtime)); len=printf("%s ", mode_string(header.mode)); my_getpwuid(buf, header.uid); if (! *buf) len+=printf("%d", header.uid); else len+=printf("%s", buf); my_getgrgid(buf, header.gid); if (! *buf) len+=printf("/%-d ", header.gid); else len+=printf("/%-s ", buf); if (header.type==CHRTYPE || header.type==BLKTYPE) { len1=snprintf(buf, sizeof(buf), "%ld,%-ld ", header.devmajor, header.devminor); } else { len1=snprintf(buf, sizeof(buf), "%lu ", (long)header.size); } /* Jump through some hoops to make the columns match up */ for(;(len+len1)<31;len++) printf(" "); printf(buf); /* Use ISO 8610 time format */ if (tm) { printf ("%04d-%02d-%02d %02d:%02d:%02d ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); } } printf("%s", header.name); if (verboseFlag == TRUE) { if (header.type==LNKTYPE) /* If this is a link, say so */ printf(" link to %s", header.linkname); else if (header.type==SYMTYPE) printf(" -> %s", header.linkname); } printf("\n"); } /* List contents if we are supposed to do that */ if (verboseFlag == TRUE && extractFlag == TRUE) { /* Now the normal listing */ FILE *vbFd = stdout; if (tostdoutFlag == TRUE) // If the archive goes to stdout, verbose to stderr vbFd = stderr; fprintf(vbFd, "%s\n", header.name); } /* Remove files if we would overwrite them */ if (extractFlag == TRUE && tostdoutFlag == FALSE) unlink(header.name); /* If we got here, we can be certain we have a legitimate * header to work with. So work with it. */ switch ( header.type ) { case REGTYPE: case REGTYPE0: /* If the name ends in a '/' then assume it is * supposed to be a directory, and fall through */ if (!last_char_is(header.name,'/')) { if (tarExtractRegularFile(&header, extractFlag, tostdoutFlag)==FALSE) errorFlag=TRUE; break; } case DIRTYPE: if (tarExtractDirectory( &header, extractFlag, tostdoutFlag)==FALSE) errorFlag=TRUE; break; case LNKTYPE: if (tarExtractHardLink( &header, extractFlag, tostdoutFlag)==FALSE) errorFlag=TRUE; break; case SYMTYPE: if (tarExtractSymLink( &header, extractFlag, tostdoutFlag)==FALSE) errorFlag=TRUE; break; case CHRTYPE: case BLKTYPE: case FIFOTYPE: if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE) errorFlag=TRUE; break; #if 0 /* Handled earlier */ case GNULONGNAME: case GNULONGLINK: skipNextHeaderFlag=TRUE; break; #endif default: error_msg("Unknown file type '%c' in tar file", header.type); close( tarFd); return( FALSE); } } close(tarFd); if (status > 0) { /* Bummer - we read a partial header */ perror_msg("Error reading tar file"); return ( FALSE); } else if (errorFlag==TRUE) { error_msg( "Error exit delayed from previous errors"); return( FALSE); } else return( status); /* Stuff to do when we are done */ endgame: close( tarFd); if ( *(header.name) == '\0' ) { if (errorFlag==TRUE) error_msg( "Error exit delayed from previous errors"); else return( TRUE); } return( FALSE); }