static void act_offset (void) { char buffer[80]; char prompt[80]; fileoffset_t o; fileoffset_t new_top; int error; sprintf (prompt, "Enter start-of-file offset in bytes (now %"OFF"d): ", realoffset); if (!get_str (prompt, buffer, FALSE)) return; o = parse_num (buffer, &error); if (error) { display_beep(); strcpy (message, "Unable to parse offset value"); return; } if (o >= 0) { realoffset = o; fix_offset(); new_top = cur_pos - (scrlines-1) * width; new_top = begline(new_top); if (top_pos < new_top) top_pos = new_top; } }
static void act_width (void) { char buffer[80]; char prompt[80]; fileoffset_t w; fileoffset_t new_top; int error; sprintf (prompt, "Enter screen width in bytes (now %"OFF"d): ", width); if (!get_str (prompt, buffer, FALSE)) return; w = parse_num (buffer, &error); if (error) { display_beep(); strcpy (message, "Unable to parse width value"); return; } if (w > 0) { width = w; fix_offset(); new_top = cur_pos - (scrlines-1) * width; new_top = begline(new_top); if (top_pos < new_top) top_pos = new_top; } }
/* Calculate the offsets to the filter points, for all border regions and the interior of the array: */ int init_filter_offsets(PyArrayObject *array, bool *footprint, const npy_intp * const fshape, npy_intp* origins, const ExtendMode mode, npy_intp **offsets, npy_intp *border_flag_value, npy_intp **coordinate_offsets) { npy_intp coordinates[NPY_MAXDIMS], position[NPY_MAXDIMS]; npy_intp forigins[NPY_MAXDIMS]; const int rank = array->nd; const npy_intp* const ashape = array->dimensions; const npy_intp* const astrides = array->strides; const npy_intp sizeof_element = PyArray_ITEMSIZE(array); /* calculate how many sets of offsets must be stored: */ npy_intp offsets_size = 1; for(int ii = 0; ii < rank; ii++) offsets_size *= (ashape[ii] < fshape[ii] ? ashape[ii] : fshape[ii]); /* the size of the footprint array: */ npy_intp filter_size = 1; for(int i = 0; i < rank; ++i) filter_size *= fshape[i]; /* calculate the number of non-zero elements in the footprint: */ npy_intp footprint_size = 0; if (footprint) { for(int i = 0; i < filter_size; ++i) footprint_size += footprint[i]; } else { footprint_size = filter_size; } if (int(mode) < 0 || int(mode) > EXTEND_LAST) { PyErr_SetString(PyExc_RuntimeError, "boundary mode not supported"); return 0; } try { *offsets = 0; if (coordinate_offsets) *coordinate_offsets = 0; *offsets = new npy_intp[offsets_size * footprint_size]; if (coordinate_offsets) { *coordinate_offsets = new npy_intp[offsets_size * rank * footprint_size]; } } catch (std::bad_alloc&) { if (*offsets) delete [] offsets; PyErr_NoMemory(); return -1; } // from here on, we cannot fail anymore: for(int ii = 0; ii < rank; ii++) { forigins[ii] = fshape[ii]/2 + (origins ? *origins++ : 0); } npy_intp max_size = 0; // maximum ashape[i] npy_intp max_stride = 0; // maximum abs( astrides[i] ) for(int ii = 0; ii < rank; ii++) { const npy_intp stride = astrides[ii] < 0 ? -astrides[ii] : astrides[ii]; if (stride > max_stride) max_stride = stride; if (ashape[ii] > max_size) max_size = ashape[ii]; /* coordinates for iterating over the kernel elements: */ coordinates[ii] = 0; /* keep track of the kernel position: */ position[ii] = 0; } /* the flag to indicate that we are outside the border must have a value that is larger than any possible offset: */ *border_flag_value = max_size * max_stride + 1; /* calculate all possible offsets to elements in the filter kernel, for all regions in the array (interior and border regions): */ npy_intp* po = *offsets; npy_intp* pc = coordinate_offsets ? *coordinate_offsets : 0; /* iterate over all regions: */ for(int ll = 0; ll < offsets_size; ll++) { /* iterate over the elements in the footprint array: */ for(int kk = 0; kk < filter_size; kk++) { npy_intp offset = 0; /* only calculate an offset if the footprint is 1: */ if (!footprint || footprint[kk]) { /* find offsets along all axes: */ for(int ii = 0; ii < rank; ii++) { const npy_intp orgn = forigins[ii]; npy_intp cc = coordinates[ii] - orgn + position[ii]; cc = fix_offset(mode, cc, ashape[ii], *border_flag_value); /* calculate offset along current axis: */ if (cc == *border_flag_value) { /* just flag that we are outside the border */ offset = *border_flag_value; if (coordinate_offsets) pc[ii] = 0; break; } else { /* use an offset that is possibly mapped from outside the border: */ cc -= position[ii]; offset += astrides[ii] * cc; if (coordinate_offsets) pc[ii] = cc; } } if (offset != *border_flag_value) offset /= sizeof_element; /* store the offset */ *po++ = offset; if (coordinate_offsets) pc += rank; } /* next point in the filter: */ for(int ii = rank - 1; ii >= 0; ii--) { if (coordinates[ii] < fshape[ii] - 1) { coordinates[ii]++; break; } else { coordinates[ii] = 0; } } } /* move to the next array region: */ for(int ii = rank - 1; ii >= 0; ii--) { const int orgn = forigins[ii]; if (position[ii] == orgn) { position[ii] += ashape[ii] - fshape[ii] + 1; if (position[ii] <= orgn) position[ii] = orgn + 1; } else { position[ii]++; } if (position[ii] < ashape[ii]) { break; } else { position[ii] = 0; } } } return footprint_size; }
/* Calculate the offsets to the filter points, for all border regions and the interior of the array: */ int init_filter_offsets(PyArrayObject *array, bool *footprint, const npy_intp * const fshape, npy_intp* origins, const ExtendMode mode, std::vector<npy_intp>& offsets, std::vector<npy_intp>* coordinate_offsets) { npy_intp coordinates[NPY_MAXDIMS], position[NPY_MAXDIMS]; npy_intp forigins[NPY_MAXDIMS]; const int rank = array->nd; const npy_intp* const ashape = array->dimensions; npy_intp astrides[NPY_MAXDIMS]; for (int d = 0; d != rank; ++d) astrides[d] = array->strides[d]/PyArray_ITEMSIZE(array); /* calculate how many sets of offsets must be stored: */ npy_intp offsets_size = 1; for(int ii = 0; ii < rank; ii++) offsets_size *= (ashape[ii] < fshape[ii] ? ashape[ii] : fshape[ii]); /* the size of the footprint array: */ npy_intp filter_size = 1; for(int i = 0; i < rank; ++i) filter_size *= fshape[i]; /* calculate the number of non-zero elements in the footprint: */ npy_intp footprint_size = 0; if (footprint) { for(int i = 0; i < filter_size; ++i) footprint_size += footprint[i]; } else { footprint_size = filter_size; } if (int(mode) < 0 || int(mode) > EXTEND_LAST) { throw PythonException(PyExc_RuntimeError, "boundary mode not supported"); } offsets.resize(offsets_size * footprint_size); if (coordinate_offsets) coordinate_offsets->resize(offsets_size * footprint_size); // from here on, we cannot fail anymore: for(int ii = 0; ii < rank; ii++) { forigins[ii] = fshape[ii]/2 + (origins ? *origins++ : 0); } std::fill(coordinates, coordinates + rank, 0); std::fill(position, position + rank, 0); /* calculate all possible offsets to elements in the filter kernel, for all regions in the array (interior and border regions): */ unsigned poi = 0; npy_intp* pc = coordinate_offsets ? &(*coordinate_offsets)[0] : 0; /* iterate over all regions: */ for(int ll = 0; ll < offsets_size; ll++) { /* iterate over the elements in the footprint array: */ for(int kk = 0; kk < filter_size; kk++) { npy_intp offset = 0; /* only calculate an offset if the footprint is 1: */ if (!footprint || footprint[kk]) { /* find offsets along all axes: */ for(int ii = 0; ii < rank; ii++) { const npy_intp orgn = forigins[ii]; npy_intp cc = coordinates[ii] - orgn + position[ii]; cc = fix_offset(mode, cc, ashape[ii]); /* calculate offset along current axis: */ if (cc == border_flag_value) { /* just flag that we are outside the border */ offset = border_flag_value; if (coordinate_offsets) pc[ii] = 0; break; } else { /* use an offset that is possibly mapped from outside the border: */ cc -= position[ii]; offset += astrides[ii] * cc; if (coordinate_offsets) pc[ii] = cc; } } /* store the offset */ offsets[poi++] = offset; if (coordinate_offsets) pc += rank; } /* next point in the filter: */ for(int ii = rank - 1; ii >= 0; ii--) { if (coordinates[ii] < fshape[ii] - 1) { coordinates[ii]++; break; } else { coordinates[ii] = 0; } } } /* move to the next array region: */ for(int ii = rank - 1; ii >= 0; ii--) { const int orgn = forigins[ii]; if (position[ii] == orgn) { position[ii] += ashape[ii] - fshape[ii] + 1; if (position[ii] <= orgn) position[ii] = orgn + 1; } else { position[ii]++; } if (position[ii] < ashape[ii]) { break; } else { position[ii] = 0; } } } assert(poi <= offsets.size()); return footprint_size; }
static int fix_program(pcap_t *handle, struct sock_fprog *fcode, int is_mmapped) { size_t prog_size; register int i; register struct bpf_insn *p; struct bpf_insn *f; int len; /* * Make a copy of the filter, and modify that copy if * necessary. */ prog_size = sizeof(*handle->fcode.bf_insns) * handle->fcode.bf_len; len = handle->fcode.bf_len; f = (struct bpf_insn *)malloc(prog_size); if (f == NULL) { snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); return -1; } memcpy(f, handle->fcode.bf_insns, prog_size); fcode->len = len; fcode->filter = (struct sock_filter *) f; for (i = 0; i < len; ++i) { p = &f[i]; /* * What type of instruction is this? */ switch (BPF_CLASS(p->code)) { case BPF_RET: /* * It's a return instruction; are we capturing * in memory-mapped mode? */ if (!is_mmapped) { /* * No; is the snapshot length a constant, * rather than the contents of the * accumulator? */ if (BPF_MODE(p->code) == BPF_K) { /* * Yes - if the value to be returned, * i.e. the snapshot length, is * anything other than 0, make it * 65535, so that the packet is * truncated by "recvfrom()", * not by the filter. * * XXX - there's nothing we can * easily do if it's getting the * value from the accumulator; we'd * have to insert code to force * non-zero values to be 65535. */ if (p->k != 0) p->k = 65535; } } break; case BPF_LD: case BPF_LDX: /* * It's a load instruction; is it loading * from the packet? */ switch (BPF_MODE(p->code)) { case BPF_ABS: case BPF_IND: case BPF_MSH: /* * Yes; are we in cooked mode? */ if (handle->md.cooked) { /* * Yes, so we need to fix this * instruction. */ if (fix_offset(p) < 0) { /* * We failed to do so. * Return 0, so our caller * knows to punt to userland. */ return 0; } } break; } break; } } return 1; /* we succeeded */ }
void analyze_CPK(FILE *infile, long file_length, struct cpk_file *file, int new_file_count) { const long CpkHeader_offset = 0x0; char *toc_string_table = NULL; /* check header */ { unsigned char buf[4]; static const char CPK_signature[4] = "CPK "; /* intentionally unterminated */ get_bytes_seek(CpkHeader_offset, infile, buf, 4); CHECK_ERROR (memcmp(buf, CPK_signature, sizeof(CPK_signature)), "CPK signature not found"); } /* check CpkHeader */ { struct utf_query_result result = query_utf_nofail(infile, CpkHeader_offset+0x10, NULL); CHECK_ERROR (result.rows != 1, "wrong number of rows in CpkHeader"); } /* get TOC offset */ long toc_offset = query_utf_8byte(infile, CpkHeader_offset+0x10, 0, "TocOffset"); /* get content offset */ long content_offset = query_utf_8byte(infile, CpkHeader_offset+0x10, 0, "ContentOffset"); /* get file count from CpkHeader */ long CpkHeader_count = query_utf_4byte(infile, CpkHeader_offset+0x10, 0, "Files"); #ifdef DEBUG printf("(Debug)TocOffset: %d\n(Debug)ContentOffset: %d\n(Debug)Files(Count): %d\n",toc_offset,content_offset,CpkHeader_count); #endif /* check TOC header */ { unsigned char buf[4]; static const char TOC_signature[4] = "TOC "; /* intentionally unterminated */ get_bytes_seek(toc_offset, infile, buf, 4); CHECK_ERROR (memcmp(buf, TOC_signature, sizeof(TOC_signature)), "TOC signature not found"); } /* get TOC entry count, string table offset */ long toc_entries; long toc_string_table_offset; long toc_string_table_size; { struct utf_query_result result = query_utf_nofail(infile, toc_offset+0x10, NULL); toc_entries = result.rows; toc_string_table_offset = toc_offset + 0x10 + 8 + result.string_table_offset; toc_string_table_size = result.data_offset - result.string_table_offset; } #ifdef DEBUG printf("(Debug)TocEntries: %d\n(Debug)TocStringTableOffset: %d\n(Debug)TocStringTableSize:%d\n",toc_entries,toc_string_table_offset,toc_string_table_size); #endif /* check that counts match */ CHECK_ERROR( toc_entries != CpkHeader_count, "CpkHeader file count and TOC entry count do not match" ); /* load string table */ toc_string_table = malloc(toc_string_table_size + 1); { CHECK_ERRNO(!toc_string_table, "malloc"); memset(toc_string_table, 0, toc_string_table_size+1); get_bytes_seek(toc_string_table_offset, infile, (unsigned char *)toc_string_table, toc_string_table_size); } /* find files in cpk */ for (int i = 0; i < toc_entries; i++) { /* get file name */ const char *file_name = query_utf_string(infile, toc_offset+0x10, i, "FileName", toc_string_table); const char *dir_name=query_utf_string(infile,toc_offset+0x10,i,"DirName",toc_string_table); /* to query a file with relative path, remember to free it */ char* query_file=malloc(strlen(dir_name)+strlen(file_name)+2); strcpy(query_file,dir_name); char sep[]="/"; strcat(query_file,sep); strcat(query_file,file_name); int entry_num = contains_file_name(query_file, file, new_file_count); if (entry_num >= 0) { #ifdef DEBUG printf("(Debug)FileName length:%d\n(Debug)DirName length:%d\n",strlen(file_name),strlen(dir_name)); printf("(Debug)query file location:%s\n",query_file); #endif printf("Found %s/%s in cpk\n",dir_name, file_name); /* get file offset */ file[entry_num].orig_offset = content_offset + query_utf_8byte(infile, toc_offset+0x10, i, "FileOffset"); /* get file size */ file[entry_num].orig_size = query_utf_4byte(infile, toc_offset+0x10, i, "FileSize"); /* save index */ file[entry_num].index = i; file[entry_num].found = 1; #ifdef DEBUG printf("(Debug)EntryNum:%d\n",entry_num); #endif } /* free the query_file to avoid leak */ if(query_file) free(query_file); } sort_by_offset(file, new_file_count); FILE *outfile = fopen("out.cpk", "w+b"); printf("Starting file copy\n"); long current = 0; for (int i = 0; i < new_file_count; i++) { if (file[i].found) { /* copy from infile to start of current new file */ dump(infile, outfile, current, file[i].orig_offset-current); current = file[i].orig_offset; /* open new file and copy data */ FILE *newfile = fopen(file[i].location, "rb"); CHECK_ERRNO(!newfile, "fopen"); CHECK_ERRNO(fseek(newfile, 0 , SEEK_END) != 0, "fseek"); file[i].new_size = ftell(newfile); CHECK_ERRNO(file_length == -1, "ftell"); rewind(infile); printf("Copying %s(file name:%s)\n", file[i].location,file[i].filename); dump(newfile, outfile, 0, file[i].new_size); printf("Finished copying %s(file name:%s)\n", file[i].location,file[i].filename); fclose(newfile); /* update information */ current += file[i].orig_size; file[i].copied = 1; file[i].offset_diff = file[i].new_size -file[i].orig_size; } } /* copy remaining data */ dump(infile, outfile, current, file_length-current); printf("Finished file copy\n"); /* fix toc_offset */ toc_offset = fix_offset(outfile, CpkHeader_offset+0x10, 0, 0, "TocOffset", file, new_file_count); printf("Fixed toc offset\n"); /* fix file offsets */ for (int i = 0; i < toc_entries; i++) fix_offset(outfile, toc_offset+0x10, content_offset, i, "FileOffset", file, new_file_count); printf("Fixed file offsets\n"); /* fix file sizes */ for (int i = 0; i < new_file_count; i++) fix_file_sizes(outfile, toc_offset+0x10, file, i); printf("Finished replacing files and fixing data\n"); CHECK_ERRNO(fclose(outfile) != 0, "fclose"); if (toc_string_table) { free(toc_string_table); toc_string_table = NULL; } }