/** \fn ~TsIndexer */ TsIndexer::~TsIndexer() { if(index) qfclose(index); if(pkt) delete pkt; if(ui) delete ui; ui=NULL; }
//--------------------------------------------------------------------------- void extract_resource(const char *fname) { if ( !initPtrs(fname) ) return; store(NULL, 0); // zero-resource header bool wrerr = false; bool res = extractDirectory(0, 0); if ( !res ) { msg("Can't extract resource (possible it is invalid)\n"); } else { qflush(fr); if ( ferror(fr) || feof(fr) ) wrerr = true; } if ( qfclose(fr) ) wrerr = true; if ( res && wrerr ) msg("Error writing resource file\n"); if ( !res || wrerr ) unlink(fname); else msg("Resources have been extracted and stored in '%s'\n", fname); }
/********************************************** ** Usage : qCatFile(filename); ** Return: Success number of characters, Fail -1. ** Do : Stream out file. **********************************************/ int qCatFile(char *format, ...) { FILE *fp; char filename[1024]; int status; va_list arglist; int c, counter; va_start(arglist, format); status = vsprintf(filename, format, arglist); if ((strlen(filename) + 1 > sizeof(filename)) || (status == EOF)) qError("qCatFile(): File name is too long or invalid."); va_end(arglist); #ifdef _WIN32 setmode(fileno(stdin), _O_BINARY); setmode(fileno(stdout), _O_BINARY); #endif if ((fp = qfopen(filename, "rb")) == NULL) return -1; for (counter = 0; (c = fgetc(fp)) != EOF; counter++) { putc(c, stdout); } qfclose(fp); return counter; }
int close_log_file(void) { if (g_log_file != NULL) { time_t start_time = time(NULL); char logtime_string[32]; /* write date */ if (start_time != (time_t)-1) { char *c = ctime(&start_time); if (c != NULL) { strlcpy(logtime_string, c, sizeof(logtime_string)); logtime_string[strlen(logtime_string)-1] = '\0'; // string from ctime includes return } } qfprintf(g_log_file, "---[ End @ %s ]---\n", logtime_string); qfprintf(g_log_file, "---[ Target: %s ]---\n\n", command_line_file); qfclose(g_log_file); } return 0; }
bool getFileMd5(unsigned char *md5, int len) { if (len < MD5_LEN) { return false; } #if IDA_SDK_VERSION >= 500 retrieve_input_file_md5(md5); #else #define RIDX_MD5 1302 //MD5 of the input file if (RootNode.supval(RIDX_MD5, md5, MD5_LEN) != MD5_LEN) { char buf[512]; get_input_file_path(buf, sizeof(buf)); FILE *f = qfopen(buf, "rb"); if (f) { MD5Context ctx; MD5Init(&ctx); int len; while ((len = qfread(f, buf, sizeof(buf))) > 0) { MD5Update(&ctx, (unsigned char*)buf, len); } MD5Final(md5, &ctx); RootNode.supset(RIDX_MD5, md5, MD5_LEN); qfclose(f); } else { //failed to open input file return false; } } #endif return true; }
/********************************************** ** Usage : qSaveStr(string pointer, string size, filename, mode) ** Return: Success number bytes stored, File open fail -1. ** Do : Store string to file. **********************************************/ int qSaveStr(char *sp, int spsize, char *filename, char *mode) { FILE *fp; int i; if ((fp = qfopen(filename, mode)) == NULL) return -1; for (i = 0; i < spsize; i++) fputc(*sp++, fp); qfclose(fp); return i; }
//-------------------------------------------------------------------------- void close() { if ( fp == NULL ) return; if ( own ) { Py_BEGIN_ALLOW_THREADS; qfclose(fp); Py_END_ALLOW_THREADS; } fp = NULL; own = true; }
//-------------------------------------------------------------------------- static void load_symbols(const char *file) { free_syms(); if ( file == NULL ) return; char cfgpath[QMAXPATH]; const char *rfile = getsysfile(cfgpath, sizeof(cfgpath), file, CFG_SUBDIR); if ( rfile == NULL ) { NOFILE: // warning("Can't open %s, symbol definitions are not loaded", file); return; } FILE *fp = fopenRT(rfile); if ( fp == NULL ) goto NOFILE; int ln = 0; char line[MAXSTR]; while ( qfgets(line, sizeof(line), fp) ) { ln++; line[strlen(line)-1] = '\0'; trim(line); if ( line[0] == ';' || line[0] == ' ' || line[0] == '\0' ) continue; char word[MAXSTR]; int addr; if ( sscanf(line, "%s %i", word, &addr) != 2 ) { warning("%s: syntax error at line %d", file, ln); break; } int i; for ( i=0; i < numsyms; i++) { if ( syms[i].address == addr && strcmp(syms[i].name, word) != 0 ) { warning("%s: duplicate address %#x at line %d", file, addr, ln); break; } } if ( i != numsyms ) break; syms = qrealloc_array<sym_t>(syms, numsyms + 1); if ( syms == NULL ) nomem("h8/500 symbols"); syms[numsyms].address = addr; syms[numsyms].name = qstrdup(word); numsyms++; } qfclose(fp); }
/*--------------------------------------------------------------------*/ uint32_t quantstat[32]; /* 0-31 ; 0 and 1 are unused */ void print_quant_stat (const char *n) { char *str = (char *) ADM_alloc (strlen (n) + 4); unsigned int i = 2, sum = 0, total = 0; FILE *fd; ADM_assert (str); strcpy (str, n); strcat (str, ".qs"); if ((fd = qfopen (str, "wb"))) { for (; i < 32; i++) { qfprintf (fd, "Quant % 2u: % 7u times\n", i, quantstat[i]); sum += i * quantstat[i]; total += quantstat[i]; } qfprintf (fd, "\nQuant over all: %2.2f\n", (float) sum / (float) total); qfclose (fd); } ADM_dealloc (str); }
//-------------------------------------------------------------------------- bool groupman_t::emit( const char *filename, const char *additional_sections) { FILE *fp = qfopen(filename, "w"); if (fp == NULL) return false; qfprintf(fp, "--%s\n", STR_PATHINFO); emit_sgl(fp, &path_sgl); qfprintf(fp, "--%s\n", STR_SIMILARINFO); emit_sgl(fp, &similar_sgl); // Emit additional sections if (additional_sections != NULL) qfprintf(fp, "%s\n", additional_sections); qfclose(fp); return true; }
/* * function to extract non-fat binaries, 32 and 64bits */ uint8_t extract_macho(ea_t address, char *outputFilename) { uint32 magicValue = get_long(address); struct mach_header *mach_header = NULL; struct mach_header_64 *mach_header64 = NULL; uint8_t arch = 0; if (magicValue == MH_MAGIC || magicValue == MH_CIGAM) { #if DEBUG msg("[DEBUG] Target is 32bits!\n"); #endif mach_header = (struct mach_header *)qalloc(sizeof(struct mach_header)); // retrieve mach_header contents if(!get_many_bytes(address, mach_header, sizeof(struct mach_header))) { msg("[ERROR] Read bytes failed!\n"); return 1; } } else if (magicValue == MH_MAGIC_64 || magicValue == MH_CIGAM_64) { #if DEBUG msg("[DEBUG] Target is 64bits!\n"); #endif mach_header64 = (struct mach_header_64 *)qalloc(sizeof(struct mach_header_64)); if(!get_many_bytes(address, mach_header64, sizeof(struct mach_header_64))) { msg("[ERROR] Read bytes failed!\n"); return 1; } arch = 1; } else { msg("[ERROR] Unknown target!\n"); return 1; } // open output file FILE *outputFile = qfopen(outputFilename, "wb+"); if (outputFile == NULL) { msg("[ERROR] Could not open %s file!\n", outputFilename); return 1; } /* * we need to write 3 distinct blocks of data: * 1) the mach_header * 2) the load commands * 3) the code and data from the LC_SEGMENT/LC_SEGMENT_64 commands */ // write the mach_header to the file if (arch) qfwrite(outputFile, mach_header64, sizeof(struct mach_header_64)); else qfwrite(outputFile, mach_header, sizeof(struct mach_header)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM) { mach_header->ncmds = ntohl(mach_header->ncmds); mach_header->sizeofcmds = ntohl(mach_header->sizeofcmds); } else if (magicValue == MH_CIGAM_64) { mach_header64->ncmds = ntohl(mach_header64->ncmds); mach_header64->sizeofcmds = ntohl(mach_header64->sizeofcmds); } // read the load commands uint32_t ncmds = arch ? mach_header64->ncmds : mach_header->ncmds; uint32_t sizeofcmds = arch ? mach_header64->sizeofcmds : mach_header->sizeofcmds; uint32_t headerSize = arch ? sizeof(struct mach_header_64) : sizeof(struct mach_header); uint8_t *loadcmdsBuffer = NULL; loadcmdsBuffer = (uint8_t*)qalloc(sizeofcmds); get_many_bytes(address + headerSize, loadcmdsBuffer, sizeofcmds); // write all the load commands block to the output file // only LC_SEGMENT commands contain further data qfwrite(outputFile, loadcmdsBuffer, sizeofcmds); // and now process the load commands so we can retrieve code and data struct load_command loadCommand; ea_t cmdsBaseAddress = address + headerSize; ea_t codeOffset = 0; // read segments so we can write the code and data // only the segment commands have useful information for (uint32_t i = 0; i < ncmds; i++) { get_many_bytes(cmdsBaseAddress, &loadCommand, sizeof(struct load_command)); struct segment_command segmentCommand; struct segment_command_64 segmentCommand64; // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM || magicValue == MH_CIGAM_64) { loadCommand.cmd = ntohl(loadCommand.cmd); loadCommand.cmdsize = ntohl(loadCommand.cmdsize); } // 32bits targets // FIXME: do we also need to dump the relocs info here ? if (loadCommand.cmd == LC_SEGMENT) { get_many_bytes(cmdsBaseAddress, &segmentCommand, sizeof(struct segment_command)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM) { segmentCommand.nsects = ntohl(segmentCommand.nsects); segmentCommand.fileoff = ntohl(segmentCommand.fileoff); segmentCommand.filesize = ntohl(segmentCommand.filesize); } // the file offset info in LC_SEGMENT is zero at __TEXT so we need to get it from the sections // the size is ok to be used if (strncmp(segmentCommand.segname, "__TEXT", 16) == 0) { ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command); struct section sectionCommand; // iterate thru all sections to find the first code offset // FIXME: we need to find the lowest one since the section info can be reordered for (uint32_t x = 0; x < segmentCommand.nsects; x++) { get_many_bytes(sectionAddress, §ionCommand, sizeof(struct section)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM) sectionCommand.offset = ntohl(sectionCommand.offset); if (strncmp(sectionCommand.sectname, "__text", 16) == 0) { codeOffset = sectionCommand.offset; break; } sectionAddress += sizeof(struct section); } } // for all other segments the fileoffset info in the LC_SEGMENT is valid so we can use it else { codeOffset = segmentCommand.fileoff; } // read and write the data uint8_t *buf = (uint8_t*)qalloc(segmentCommand.filesize); get_many_bytes(address + codeOffset, buf, segmentCommand.filesize); // always set the offset qfseek(outputFile, codeOffset, SEEK_SET); qfwrite(outputFile, buf, segmentCommand.filesize); qfree(buf); } // 64bits targets else if (loadCommand.cmd == LC_SEGMENT_64) { get_many_bytes(cmdsBaseAddress, &segmentCommand64, sizeof(struct segment_command_64)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM_64) { segmentCommand64.nsects = ntohl(segmentCommand64.nsects); segmentCommand64.fileoff = bswap64(segmentCommand64.fileoff); segmentCommand64.filesize = bswap64(segmentCommand64.filesize); } if(strncmp(segmentCommand64.segname, "__TEXT", 16) == 0) { ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command_64); struct section_64 sectionCommand64; for (uint32_t x = 0; x < segmentCommand64.nsects; x++) { get_many_bytes(sectionAddress, §ionCommand64, sizeof(struct section_64)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM_64) sectionCommand64.offset = ntohl(sectionCommand64.offset); if (strncmp(sectionCommand64.sectname, "__text", 16) == 0) { codeOffset = sectionCommand64.offset; break; } sectionAddress += sizeof(struct section_64); } } else { codeOffset = segmentCommand64.fileoff; } // read and write the data uint8_t *buf = (uint8_t*)qalloc(segmentCommand64.filesize); get_many_bytes(address + codeOffset, buf, segmentCommand64.filesize); qfseek(outputFile, codeOffset, SEEK_SET); qfwrite(outputFile, buf, segmentCommand64.filesize); qfree(buf); } cmdsBaseAddress += loadCommand.cmdsize; } // all done, close file and free remaining buffers! qfclose(outputFile); qfree(mach_header); qfree(mach_header64); qfree(loadcmdsBuffer); return 0; }
/*______________________________________________ Save the project as a script ______________________________________________*/ uint8_t ADM_Composer::saveAsScript (const char *name, const char *outputname) { const char *truefalse[]={"false","true"}; printf("\n **Saving script project **\n"); char * tmp; if (!_nb_segment) return 1; FILE * fd; if( !(fd = qfopen (name, "wt")) ){ fprintf(stderr,"\ncan't open script file \"%s\" for writing: %u (%s)\n", name, errno, strerror(errno)); return 0; } // Save source and segment //______________________________________________ qfprintf( fd,"//AD <- Needed to identify"); qfprintf (fd, "//\n"); qfprintf (fd, "//--automatically built--\n"); qfprintf (fd, "//--Project: %s\n\n",name); qfprintf (fd, "var app = new Avidemux();\n"); qfprintf (fd,"\n//** Video **\n"); qfprintf (fd,"// %02ld videos source \n", _nb_video); char *nm; uint32_t vop=!!(video_body->getSpecificMpeg4Info()&ADM_VOP_ON); for (uint32_t i = 0; i < _nb_video; i++) { nm=cleanupPath(_videos[i]._aviheader->getMyName() ); if(vop) { qfprintf(fd,"app.forceUnpack();\n"); } if(!i) { qfprintf (fd, "app.load(\"%s\");\n", nm); } else { qfprintf (fd, "app.append(\"%s\");\n", nm); } ADM_dealloc(nm); } qfprintf (fd,"//%02ld segments\n", _nb_segment); qfprintf (fd,"app.clearSegments();\n"); for (uint32_t i = 0; i < _nb_segment; i++) { uint32_t src,start,nb; src=_segments[i]._reference; start=_segments[i]._start_frame; nb=_segments[i]._nb_frames; qfprintf (fd, "app.addSegment(%lu,%lu,%lu);\n",src,start,nb); } // Markers // qfprintf(fd,"app.markerA=%d;\n",frameStart); qfprintf(fd,"app.markerB=%d;\n",frameEnd); // Reordering : Warning works only for video with one source video if(video_body->isReordered(0) && !vop) { qfprintf(fd,"app.rebuildIndex();\n"); } // postproc //___________________________ uint32_t pptype, ppstrength,ppswap; video_body->getPostProc( &pptype, &ppstrength, &ppswap); qfprintf(fd,"\n//** Postproc **\n"); qfprintf(fd,"app.video.setPostProc(%d,%d,%d);\n",pptype,ppstrength,ppswap); // fps if( avifileinfo ){ aviInfo info; video_body->getVideoInfo(&info); qfprintf(fd,"\napp.video.setFps1000(%u);\n",info.fps1000); } // Filter //___________________________ qfprintf(fd,"\n//** Filters **\n"); filterSaveScriptJS(fd); // Video codec //___________________________ uint8_t *extraData ; uint32_t extraDataSize; char *pth; qfprintf(fd,"\n//** Video Codec conf **\n"); videoCodecGetConf(&extraDataSize,&extraData); pth= cleanupPath(name ); qfprintf(fd,"app.video.codec(\"%s\",\"%s\",\"",videoCodecGetName(),videoCodecGetMode()); ADM_dealloc(pth); // Now deal with extra data qfprintf(fd,"%d ",extraDataSize); if(extraDataSize) { for(int i=0;i<extraDataSize;i++) { qfprintf(fd,"%02x ",extraData[i]); } } qfprintf(fd,"\");\n"); // Audio Source //______________________________________________ // Audio //______________________________________________ uint32_t delay,bitrate; qfprintf(fd,"\n//** Audio **\n"); qfprintf(fd,"app.audio.reset();\n"); // External audio ? char *audioName; AudioSource source; source=getCurrentAudioSource(&audioName); if(!audioName) audioName=""; if(source!=AudioAvi) { char *nm=cleanupPath(audioName); qfprintf(fd,"app.audio.load(\"%s\",\"%s\");\n", audioSourceFromEnum(source),nm); ADM_dealloc(nm); } else { // Maybe not the 1st track int source; source=video_body->getCurrentAudioStreamNumber(0); if(source) qfprintf(fd,"app.audio.setTrack(%d);\n", source); } getAudioExtraConf(&bitrate,&extraDataSize,&extraData); qfprintf(fd,"app.audio.codec(\"%s\",%d,%d,\"", audioCodecGetName(),bitrate,extraDataSize); for(int i=0;i<extraDataSize;i++) { qfprintf(fd,"%02x ",extraData[i]); } qfprintf(fd,"\");\n"); //qfprintf(fd,"app.audio.process=%s;\n",truefalse[audioProcessMode()]); qfprintf(fd,"app.audio.normalizeMode=%d;\n",audioGetNormalizeMode()); qfprintf(fd,"app.audio.normalizeValue=%d;\n",audioGetNormalizeValue()); qfprintf(fd,"app.audio.delay=%d;\n",audioGetDelay()); qfprintf(fd,"app.audio.mixer(\"%s\");\n",getCurrentMixerString()); // VBR ? if(currentaudiostream) { uint32_t encoding=currentaudiostream->getInfo()->encoding; if(currentaudiostream->isVBR() && (encoding==WAV_MP3 || encoding==WAV_MP2)) { qfprintf(fd,"app.audio.scanVBR();\n"); } } // Change fps ? switch(audioGetFpsConv()) { case FILMCONV_NONE: ;break; case FILMCONV_PAL2FILM: qfprintf(fd,"app.audio.pal2film=true;\n");break; case FILMCONV_FILM2PAL: qfprintf(fd,"app.audio.film2pal=true;\n");break; default:ADM_assert(0); } // Resampling switch(audioGetResampling()) { case RESAMPLING_NONE: ;break; case RESAMPLING_CUSTOM: qfprintf(fd,"app.audio.resample=%u;\n",audioGetResample());break; default:ADM_assert(0); } if (audioGetDrc()) qfprintf(fd,"app.audio.drc=true;\n"); // Mixer // container qfprintf(fd,"app.setContainer(\"%s\");\n",getCurrentContainerAsString()); if(outputname) { char *o=cleanupPath(outputname); qfprintf(fd,"setSuccess(app.save(\"%s\"));\n",o); ADM_dealloc(o); } else { qfprintf(fd,"setSuccess(%d);\n",1); } qfprintf(fd,"//app.Exit();\n"); qfprintf(fd,"\n//End of script\n"); // All done qfclose (fd); return 1; }
void IDAP_run(int arg) { FILE *f, *f2; char *filename = construct_output_filename(".import_allocs.txt"); f = qfopen(filename, "wb"); char *filename2 = construct_output_filename(".import_allocs_wrappers.txt"); f2 = qfopen(filename2, "wb"); //r0 allocators funcMalloc.push_back(TFuncMalloc(" ExAllocatePoolWithQuota", 2)); funcMalloc.push_back(TFuncMalloc(" __imp__ExAllocatePoolWithQuota@8", 2));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc(" ExAllocatePoolWithQuotaTag", 2)); funcMalloc.push_back(TFuncMalloc(" __imp__ExAllocatePoolWithQuotaTag@12", 2));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc("ExAllocatePoolWithTag", 2)); funcMalloc.push_back(TFuncMalloc("__imp__ExAllocatePoolWithTag@12", 2));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc("ExAllocatePoolWithTagPriority", 2)); funcMalloc.push_back(TFuncMalloc("__imp__ExAllocatePoolWithTagPriority@16", 2));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc("IoAllocateMdl", 2)); funcMalloc.push_back(TFuncMalloc("__imp__IoAllocateMdl@20", 2));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc("RtlAllocateHeap", 3)); funcMalloc.push_back(TFuncMalloc("__imp__RtlAllocateHeap", 3));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc("EngAllocMem", 2)); funcMalloc.push_back(TFuncMalloc("__imp__EngAllocMem", 2));//win32k.sys funcMalloc.push_back(TFuncMalloc("__imp__EngAllocMem@12", 2));//win32k.sys //type pointer to size!!! //funcMalloc.push_back(TFuncMalloc("ZwAllocateVirtualMemory", 4)); //funcMalloc.push_back(TFuncMalloc("__imp__ZwAllocateVirtualMemory@24", 4));//ntoskrnl.exe //funcMalloc.push_back(TFuncMalloc("NtAllocateVirtualMemory", 4)); //funcMalloc.push_back(TFuncMalloc("__imp__NtAllocateVirtualMemory@24", 4));//ntoskrnl.exe //funcMalloc.push_back(TFuncMalloc("RtlReAllocateHeap", 4)); //funcMalloc.push_back(TFuncMalloc("HeapAlloc", 3)); //r3 allocators funcMalloc.push_back(TFuncMalloc("GlobalAlloc", 2));//kernel32.dll funcMalloc.push_back(TFuncMalloc("HeapAlloc", 3));//kernel32.dll funcMalloc.push_back(TFuncMalloc("__imp__HeapAlloc@12", 3));//kernel32.dll funcMalloc.push_back(TFuncMalloc("__imp__HeapReAlloc@16", 4));//kernel32.dll funcMalloc.push_back(TFuncMalloc("HeapReAlloc", 4));//kernel32.dll funcMalloc.push_back(TFuncMalloc("__imp__LocalAlloc@8", 2));//kernel32.dll funcMalloc.push_back(TFuncMalloc("LocalAlloc", 2));//kernel32.dll funcMalloc.push_back(TFuncMalloc("__imp__LocalReAlloc@12", 3));//kernel32.dll funcMalloc.push_back(TFuncMalloc("LocalReAlloc", 3));//kernel32.dll funcMalloc.push_back(TFuncMalloc("VirtualAlloc", 2)); funcMalloc.push_back(TFuncMalloc("__imp__VirtualAlloc@16", 2));//kernel32.dll funcMalloc.push_back(TFuncMalloc("__imp__MpHeapAlloc", 3));//msdart.dll export funcMalloc.push_back(TFuncMalloc("__imp__MpHeapReAlloc", 3));//msdart.dll export funcMalloc.push_back(TFuncMalloc("__imp__GdipAlloc@4", 1));//gdiplus.dll export //funcMalloc.push_back(TFuncMalloc("GpMalloc", 1));//gdiplus.dll funcMalloc.push_back(TFuncMalloc("__imp__malloc", 1));//msvcrt.dll funcMalloc.push_back(TFuncMalloc("_malloc", 1));//msvcrt.dll, the same as __imp__malloc funcMalloc.push_back(TFuncMalloc("__imp__realloc", 2));//msvcrt.dll funcMalloc.push_back(TFuncMalloc("_realloc", 2));//msvcrt.dll //funcMalloc.push_back(TFuncMalloc("_alloca", 1)); //funcMalloc.push_back(TFuncMalloc("_malloca", 1)); uint i = 0, j = funcMalloc.size(); msg("standart funcMalloc.size() = %d\n", funcMalloc.size()); for(; i< funcMalloc.size(); i++){ find_alloc_calls_ex(f, funcMalloc[i]); pretty_printing_ex(f, funcMalloc[i]); if(Malloc_calls.size() > 0 ) Malloc_calls.clear(); qfprintf(f,"\n\n"); qflush( f ); } qfclose( f ); j = funcMalloc_wrappers.size(); msg("standart funcMalloc_wrappers.size() = %d\n", j); //TODO: add level property i = 0; while( i < j){ find_alloc_calls_warreps_ex(f2, funcMalloc_wrappers[i]); msg("[%d].funcMalloc.size() = %d\n", i, funcMalloc_wrappers.size()); msg("[%d].Malloc_calls.size() = %d\n", i, Malloc_calls.size()); pretty_printing_ex(f2, funcMalloc_wrappers[i]); if(Malloc_calls.size() > 0 ) Malloc_calls.clear(); j = funcMalloc_wrappers.size(); i++; qflush( f2 ); } qfclose( f2 ); return ; }
void idaapi run(int arg) { char buf[MAXSTR]; char cmt[MAXSTR]; char *valid_cmt = NULL; char ext[0x20]; FILE *f = NULL; short checkboxes = OPTION_NAMES | OPTION_COMMENTS; sval_t bank = 1; // default bool first = true; bool hasName = false; flags_t flags; ea_t ea = 0x0; if( AskUsingForm_c( madnes_options, &checkboxes, &bank ) != 1 || checkboxes == 0 ) return; // prepare filename for namelist (.nl) file get_input_file_path( buf, sizeof( buf ) ); qsnprintf( ext, sizeof( ext ),".%X.nl",--bank ); qstrncat( buf, ext, sizeof( buf )-strlen( buf ) ); // (always) create file f = qfopen( buf, "w" ); if( f == NULL ) { warning( "%s could not be created!", buf ); return; } msg( "Writing to file %s..", buf ); while( ea <= 0xFFFF ) { hasName = false; // get flags if( isCode( getFlags( ea ) ) ) flags = getFlags( ea ); else flags = getFlags( get_item_head( ea ) ); // if user either chose to export names or anynames if( ( ( checkboxes & OPTION_NAMES ) && has_name( flags ) ) || ( ( checkboxes & OPTION_ANYNAME ) && has_any_name( flags ) ) ) { // if current item is code or if current item is head of item if( isCode( flags ) || ea==get_item_head( ea ) ) { // get name get_name( ea, ea, buf, sizeof( buf ) ); // write to file qfprintf( f, "$%04X#%s#", ea, buf ); } else // if not code or not head of item (must be an array) { // get name of item start get_name( get_item_head( ea ), get_item_head( ea ), buf, sizeof( buf ) ); // calc displacement, write to file (example: "password+$04") qfprintf( f, "$%04X#%s+$%X#", ea, buf, ea-get_item_head( ea ) ); } hasName = true; } // if user chose to export cross references if( checkboxes & OPTION_XREFS ) { xrefblk_t xb; first = true; // cycle through all xrefs except ordinary flow xrefs for ( bool ok=xb.first_to( ea, XREF_FAR/*XREF_ALL*/); ok; ok=xb.next_to() ) { if( first ) // if first xref { if( !hasName ) // if this location hasn't a name yet, add symbol stub { qfprintf( f, "$%04X##", ea ); hasName = true; } qfprintf( f, "XREFS:\n\\"); // append XREFS first = false; } qfprintf( f, " $%04X\n\\", xb.from ); } } // if user chose to export comments if( checkboxes & OPTION_COMMENTS ) { if( has_cmt( flags ) ) // if current item has comment { // get comment // workaround for get_any_indeted_cmt() // -> unresolved external symbol "char * __stdcall get_any_indented_cmt(unsigned long,unsigned char *)" (?get_any_indented_cmt@@YGPADKPAE@Z) if( get_cmt( ea, false, cmt, sizeof( cmt ) ) == -1 ) get_cmt( ea, true, cmt, sizeof( cmt ) ); // validate comment (replace invalid chars, add room for additional chars) valid_cmt = validate_comment( cmt ); if( valid_cmt != NULL ) { if( !hasName ) { qfprintf( f, "$%04X##", ea ); // add symbol stub if no name yet hasName = true; } qfprintf( f, "%s", valid_cmt ); // write comment to file qfree( valid_cmt ); } } } if( hasName) qfprintf( f, "\n" ); ea++; // get name of each byte } qfclose( f ); msg( "done.\n" ); }
/** \fn runH264 \brief Index H264 stream */ bool TsIndexer::runH264(const char *file,ADM_TS_TRACK *videoTrac) { bool seq_found=false; bool firstSps=true; TSVideo video; indexerData data; dmxPacketInfo tmpInfo; TS_PESpacket SEI_nal(0); bool result=false; bool bAppend=false; beginConsuming=0; listOfUnits.clear(); printf("Starting H264 indexer\n"); if(!videoTrac) return false; if(videoTrac[0].trackType!=ADM_TS_H264) { printf("[Ts Indexer] Only H264 video supported\n"); return false; } video.pid=videoTrac[0].trackPid; memset(&data,0,sizeof(data)); data.picStructure=pictureFrame; string indexName=string(file); indexName=indexName+string(".idx2"); index=qfopen(indexName,(const char*)"wt"); if(!index) { printf("[PsIndex] Cannot create %s\n",indexName.c_str()); return false; } pkt=new tsPacketLinearTracker(videoTrac->trackPid, audioTracks); FP_TYPE append=FP_DONT_APPEND; if(true==ADM_probeSequencedFile(file)) { if(true==GUI_Question("There are several files with sequential file names. Should they be all loaded ?")) bAppend=true; } if(bAppend==true) append=FP_APPEND; writeSystem(file,bAppend); pkt->open(file,append); data.pkt=pkt; fullSize=pkt->getSize(); gui=createProcessing("Indexing",pkt->getSize()); int lastRefIdc=0; bool keepRunning=true; //****************** // 1 search SPS //****************** while(keepRunning) { int startCode=pkt->findStartCode(); if(startCode&0x80) continue; // Marker missing startCode&=0x1f; if(startCode!=NAL_SPS) continue; // Got SPS! uint32_t xA,xR; // Get info pkt->getInfo(&tmpInfo); // Read just enough... { SEI_nal.empty(); uint32_t code=0xffff+0xffff0000; while(((code&0xffffff)!=1) && pkt->stillOk()) { uint8_t r=pkt->readi8(); code=(code<<8)+r; SEI_nal.pushByte(r); } if(!pkt->stillOk()) break;; pkt->seek(tmpInfo.startAt,tmpInfo.offset-5); if (extractSPSInfo(SEI_nal.payload, SEI_nal.payloadSize-4,&spsInfo)) { ADM_info("[TsIndexer] Found video %"PRIu32"x%"PRIu32", fps=%"PRIu32"\n",video.w,video.h,video.fps); ADM_info("[TsIndexer] SPS says %"PRIu32"x%"PRIu32"\n",spsInfo.width,spsInfo.height); seq_found=1; video.w=spsInfo.width; video.h=spsInfo.height; video.fps=spsInfo.fps1000; xA=spsInfo.darNum; xR=spsInfo.darDen; writeVideo(&video,ADM_TS_H264); writeAudio(); qfprintf(index,"[Data]"); // Rewind break; }; } } if(!seq_found) goto the_end; decodingImage=false; //****************** // 2 Index //****************** bool fourBytes; while(keepRunning) { fourBytes=false; int startCode=pkt->findStartCode2(fourBytes); resume: if(!pkt->stillOk()) break; int startCodeLength=4; if(fourBytes==true) startCodeLength++; // 1:0 2:Nal ref idc 5:Nal Type if(startCode&0x80) { printf("[Ts] Nal Marker missing:%x\n",startCode); continue; // Marker missing } int fullStartCode=startCode; int ref=(startCode>>5)&3; startCode&=0x1f; // Ignore nal ref IDR aprintf("[%02x] Nal :0x%x,ref=%d,lastRef=%d at : %d \n",fullStartCode,startCode,ref,lastRefIdc,pkt->getConsumed()-beginConsuming); // Ignore multiple chunk of the same pic if((startCode==NAL_NON_IDR || startCode==NAL_IDR)&&decodingImage ) { aprintf("Still capturing, ignore\n"); continue; } switch(startCode) { case NAL_AU_DELIMITER: { aprintf("AU DELIMITER\n"); decodingImage = false; } break; case NAL_SEI: { // Load the whole NAL SEI_nal.empty(); uint32_t code=0xffff+0xffff0000; while(((0xffffff&code)!=1) && pkt->stillOk()) { uint8_t r=pkt->readi8(); code=(code<<8)+r; SEI_nal.pushByte(r); } if(!pkt->stillOk()) goto resume; aprintf("[SEI] Nal size :%d\n",SEI_nal.payloadSize); if(SEI_nal.payloadSize>=7) decodeSEI(SEI_nal.payloadSize-4, SEI_nal.payload,&(thisUnit.recoveryCount),&(thisUnit.imageStructure)); else printf("[SEI] Too short size+4=%d\n",*(SEI_nal.payload)); startCode=pkt->readi8(); decodingImage=false; pkt->getInfo(&thisUnit.packetInfo); thisUnit.consumedSoFar=pkt->getConsumed(); if(!addUnit(data,unitTypeSei,thisUnit,startCodeLength+SEI_nal.payloadSize+1)) keepRunning=false; fourBytes=true; goto resume; } break; case NAL_SPS: decodingImage=false; pkt->getInfo(&thisUnit.packetInfo); if(firstSps) { pkt->setConsumed(startCodeLength); // reset consume counter firstSps=false; } thisUnit.consumedSoFar=pkt->getConsumed(); if(!addUnit(data,unitTypeSps,thisUnit,startCodeLength)) keepRunning=false; break; case NAL_IDR: case NAL_NON_IDR: { #define NON_IDR_PRE_READ 8 aprintf("Pic start last ref:%d cur ref:%d nb=%d\n",lastRefIdc,ref,data.nbPics); lastRefIdc=ref; uint8_t bufr[NON_IDR_PRE_READ+4]; uint8_t header[NON_IDR_PRE_READ+4]; pkt->read(NON_IDR_PRE_READ,bufr); // unescape... ADM_unescapeH264(NON_IDR_PRE_READ,bufr,header); // getBits bits(NON_IDR_PRE_READ,header); int first_mb_in_slice,slice_type; first_mb_in_slice= bits.getUEG(); slice_type= bits.getUEG31(); if(slice_type>9) { printf("[TsIndexer] Bad slice type\n"); } if(slice_type>4) slice_type-=5; switch(slice_type) { case 0 : thisUnit.imageType=2;break; // P case 1 : thisUnit.imageType=3;break; // B case 2 : thisUnit.imageType=1;break; // I default : thisUnit.imageType=2;break; // SP/SI } if(startCode==NAL_IDR) thisUnit.imageType=4; // IDR aprintf("[>>>>>>>>] Pic Type %"PRIu32" Recovery %"PRIu32"\n",thisUnit.imageType,recoveryCount); if(thisUnit.imageType==1 && !thisUnit.recoveryCount) thisUnit.imageType=4; //I + Recovery=0 = IDR! data.nbPics++; decodingImage=true; pkt->getInfo(&thisUnit.packetInfo); thisUnit.consumedSoFar=pkt->getConsumed(); if(!addUnit(data,unitTypePic,thisUnit,startCodeLength+NON_IDR_PRE_READ)) keepRunning=false; // reset to default thisUnit.imageStructure=pictureFrame; thisUnit.recoveryCount=0xff; pkt->invalidatePtsDts(); } break; default: break; } } // End while result=true; the_end: printf("\n"); qfprintf(index,"\n[End]\n"); qfclose(index); index=NULL; audioTracks=NULL; delete pkt; pkt=NULL; return result; }
/* * function to extract fat archives */ uint8_t extract_fat(ea_t address, char *outputFilename) { #if DEBUG msg("[DEBUG] Trying to extract a fat binary target!\n"); #endif struct fat_header fatHeader; if(!get_many_bytes(address, &fatHeader, sizeof(struct fat_header))) { msg("[ERROR] Read bytes failed!\n"); return 1; } if(validate_fat(fatHeader, address)) return 1; // for fat binaries things are much easier to dump // since the fat_arch struct contains total size of the binary :-) // open output file FILE *outputFile = qfopen(outputFilename, "wb+"); if (outputFile == NULL) { msg("[ERROR] Could not open %s file!\n", outputFilename); return 1; } // write fat_header qfwrite(outputFile, &fatHeader, sizeof(struct fat_header)); // read fat_arch ea_t fatArchAddress = address + sizeof(struct fat_header); uint32_t fatArchSize = sizeof(struct fat_arch)*ntohl(fatHeader.nfat_arch); // write all fat_arch structs void *fatArchBuf = qalloc(fatArchSize); if(!get_many_bytes(fatArchAddress, fatArchBuf, fatArchSize)) { msg("[ERROR] Read bytes failed!\n"); return 1; } qfwrite(outputFile, fatArchBuf, fatArchSize); qfree(fatArchBuf); // write the mach-o binaries inside the fat archive for (uint32_t i = 0; i < ntohl(fatHeader.nfat_arch) ; i++) { struct fat_arch tempFatArch; // read the fat_arch struct if(!get_many_bytes(fatArchAddress, &tempFatArch, sizeof(struct fat_arch))) { msg("[ERROR] Read bytes failed!\n"); return 1; } // read and write the mach-o binary pointed by each fat_arch struct void *tempBuf = qalloc(ntohl(tempFatArch.size)); if(!get_many_bytes(address+ntohl(tempFatArch.offset), tempBuf, ntohl(tempFatArch.size))) { msg("[ERROR] Read bytes failed!\n"); return 1; } qfseek(outputFile, ntohl(tempFatArch.offset), SEEK_SET); qfwrite(outputFile, tempBuf, ntohl(tempFatArch.size)); qfree(tempBuf); // advance to next fat_arch struct fatArchAddress += sizeof(struct fat_arch); } // all done qfclose(outputFile); return 0; }
/** \fn dmx_indexer \brief Create index file @param mpeg Name of the file to index @param file Name of the index file to create @param preferedAudio Default audio track @param nbTracks # of tracks, including video @param tracks track descriptor @return 1 on success, 0 on failure The incoming file can be mpeg PS/TS/ES or ASF. The payload can be mostly mpeg2, with some work done to support later mpeg4/H264 in TS mostly */ uint8_t dmx_indexer(const char *mpeg,const char *file,uint32_t preferedAudio,uint8_t autosync,uint32_t nbTracks,MPEG_TRACK *tracks) { DIA_progressIndexing *work; dmx_demuxer *demuxer; char *realname=PathCanonize(mpeg); FILE *out; DMX_TYPE mpegType; uint8_t mpegTypeChar; uint32_t multi=0; dmx_payloadType payloadType=DMX_PAYLOAD_MPEG2; mpegType=dmxIdentify(realname); if(mpegType==DMX_MPG_UNKNOWN) { delete [] realname; return 0; } switch(mpegType) { case DMX_MPG_MSDVR: { dmx_demuxerMSDVR *dmx; dmx=new dmx_demuxerMSDVR(nbTracks,tracks,0); demuxer=dmx; mpegTypeChar='M'; break; } case DMX_MPG_TS: case DMX_MPG_TS2: { dmx_demuxerTS *dmx; dmx=new dmx_demuxerTS(nbTracks,tracks,0,mpegType); demuxer=dmx; switch(mpegType) { case DMX_MPG_TS :mpegTypeChar='T';break; case DMX_MPG_TS2 :mpegTypeChar='S';break; default: ADM_assert(0); } switch(tracks[0].streamType) { case ADM_STREAM_H264: payloadType=DMX_PAYLOAD_H264;break; case ADM_STREAM_MPEG4: payloadType=DMX_PAYLOAD_MPEG4;break; case ADM_STREAM_MPEG_VIDEO: payloadType=DMX_PAYLOAD_MPEG2;break; default: ADM_assert(0); } break; } case DMX_MPG_ES: demuxer=new dmx_demuxerES; mpegTypeChar='E'; break; case DMX_MPG_H264_ES: payloadType=DMX_PAYLOAD_H264; demuxer=new dmx_demuxerES; mpegTypeChar='E'; break; case DMX_MPG_PS: { dmx_demuxerPS *dmx; fileParser *fp; FP_TYPE type=FP_PROBE; fp=new fileParser; fp->open(realname,&type); delete fp; if(type==FP_APPEND) { if(GUI_Question(QT_TR_NOOP("There is several mpeg file, append them ?"))) multi=1; } dmx=new dmx_demuxerPS(nbTracks,tracks,multi); demuxer=dmx; mpegTypeChar='P'; } break; default : ADM_assert(0); } demuxer->open(realname); out=qfopen(file,"wt"); if(!out) { printf("\n Error : cannot open index !"); delete demuxer; delete [] realname; return 0; } qfprintf(out,"ADMY0003\n"); qfprintf(out,"Type : %c\n",mpegTypeChar); // ES for now qfprintf(out,"File : %s\n",realname); qfprintf(out,"Append : %d\n",multi); qfprintf(out,"Image : %c\n",'P'); // Progressive qfprintf(out,"Picture : %04lu x %04lu %05lu fps\n",0,0,0); // width... qfprintf(out,"Payload : %c%c%c%c\n",'M','P','E','G'); // width... qfprintf(out,"Nb Gop : %08lu \n",0); // width... qfprintf(out,"Nb Images: %010lu \n",0); // width... qfprintf(out,"Nb Audio : %02lu\n",nbTracks-1); qfprintf(out,"Main aud : %02lu\n",preferedAudio); qfprintf(out,"Streams : "); for(int s=0;s<nbTracks;s++) { if(!s){ qfprintf(out,"V%04x:%04x ",tracks[0].pid,tracks[0].pes); }else{ qfprintf(out,"A%04x:%04x ",tracks[s].pid,tracks[s].pes); } } qfprintf(out,"\n"); qfprintf(out,"# NGop NImg nbImg type:abs:rel:size ...\n"); uint8_t grabbing=0,seq_found=0; uint32_t total_frame=0,val; uint32_t originalPriority = getpriority(PRIO_PROCESS, 0); uint32_t priorityLevel; prefs->get(PRIORITY_INDEXING,&priorityLevel); setpriority(PRIO_PROCESS, 0, ADM_getNiceValue(priorityLevel)); work=new DIA_progressIndexing(mpeg); printf("*********Indexing started (%d audio tracks)***********\n",nbTracks); dmx_runData run; memset(&run,0,sizeof(dmx_runData)); run.totalFileSize=demuxer->getSize(); run.demuxer=demuxer; run.work=work; run.nbTrack=nbTracks; run.fd=out; dmx_videoIndexer *idxer=NULL; switch(payloadType) { case DMX_PAYLOAD_MPEG2: { idxer=new dmx_videoIndexerMpeg2(&run); break; } case DMX_PAYLOAD_MPEG4:ADM_assert(0); case DMX_PAYLOAD_H264: idxer=new dmx_videoIndexerH264(&run); break; default: ADM_assert(0); } idxer->run(); idxer->cleanup(); delete idxer; idxer=NULL; printf("*********Indexing Ended (%d audio tracks)***********\n",nbTracks); switch(run.imageAR) { case 1: qfprintf(out,"# Video Aspect Ratio : %s\n", "1:1" );break; case 2: qfprintf(out,"# Video Aspect Ratio : %s\n", "4:3" );break; case 3: qfprintf(out,"# Video Aspect Ratio : %s\n", "16:9" );break; default: printf("imageAR=%u\n",run.imageAR); GUI_Error_HIG(QT_TR_NOOP("Can't determine aspect ratio"),NULL); } /* Now update......... */ fseeko(out,0,SEEK_SET); // Update if needed uint32_t compfps,delta=computeTimeDifference(&(run.firstStamp),&(run.lastStamp)); delta=delta/1000; // in second if(delta) { compfps= (1000*run.nbImage)/delta; // 3 Million images should be enough, no overflow } else { compfps=run.imageFPS; } // Detect film (i.e. NTSC with computed fps close to 24) if(run.imageFPS==29970 || run.imageFPS==30000) { if(compfps>23800 && compfps < 24200) run.imageFPS=23976; } // Detect interlaced vs progressive // If field encoded, the average fps is about twice as theoritical fps char type='P'; float err; err=run.imageFPS*2; err-=compfps; err*=100; err/=run.imageFPS*2; if(err<0) err=-err; printf("%lu :%lu / %lu , %f\n",run.imageFPS,run.imageFPS*2,compfps,err); if(err<10) { type='I'; printf("Seems to be field encoded\n"); } else { printf("Seems to be frame encoded\n"); } // Now dump the delta PTS // *****************Update header************* qfprintf(out,"ADMY0003\n"); qfprintf(out,"Type : %c\n",mpegTypeChar); // ES for now qfprintf(out,"File : %s\n",realname); qfprintf(out,"Append : %d\n",multi); qfprintf(out,"Image : %c\n",type); // Progressive qfprintf(out,"Picture : %04lu x %04lu %05lu fps\n",run.imageW,run.imageH,run.imageFPS); // width... switch(payloadType) { case DMX_PAYLOAD_MPEG2: qfprintf(out,"Payload : MPEG\n"); // MPEG,MP_4,H264 break; case DMX_PAYLOAD_MPEG4: qfprintf(out,"Payload : MP_4\n"); // MPEG,MP_4,H264 break; case DMX_PAYLOAD_H264: qfprintf(out,"Payload : H264\n"); // MPEG,MP_4,H264 break; default: ADM_assert(0); } qfprintf(out,"Nb Gop : %08lu \n",run.nbGop); // width... qfprintf(out,"Nb Images: %010lu \n",run.nbImage); // width... qfclose(out); delete work; printf("*********Indexing stopped***********\n"); printf("Found :%lu gop\n",run.nbGop); printf("Found :%lu image\n",run.nbImage); printf("Average fps :%lu /1000 fps\n",compfps); delete demuxer; delete [] realname; setpriority(PRIO_PROCESS, 0, originalPriority); return 1; }
//-------------------------------------------------------------------------- int main(int argc,char *argv[]) { int i; fprintf(stderr,"ARM Library unpacker. Copyright 1997 by Ilfak Guilfanov. Version 1.00\n"); if ( argc < 2 ) fatal("Usage: unlib libfile"); strcpy(infile,argv[1]); FILE *fp = qfopen(infile,"rb"); if ( fp == NULL ) fatal("Can't open library %s",infile); chunk_header_t hd; if ( qfread(fp, &hd, sizeof(hd)) != sizeof(hd) || (hd.ChunkFileId != AOF_MAGIC && hd.ChunkFileId != AOF_MAGIC_B) ) fatal("Bad library format"); if ( hd.ChunkFileId == AOF_MAGIC_B ) { // BIG ENDIAN mf = 1; hd.max_chunks = swap(hd.max_chunks); hd.num_chunks = swap(hd.num_chunks); } chunk_entry_t *ce = qnewarray(chunk_entry_t,size_t(hd.max_chunks)); if ( ce == NULL ) nomem("chunk entries (%d)",size_t(hd.max_chunks)); qfread(fp, ce, sizeof(chunk_entry_t)*size_t(hd.max_chunks)); if ( mf ) for ( i=0; i < hd.max_chunks; i++ ) swap_chunk_entry(ce+i); int vrsn = -1; int diry = -1; int data = 0; for ( i=0; i < hd.max_chunks; i++ ) { if ( ce[i].file_offset == 0 ) continue; if ( strncmp(ce[i].chunkId,LIB_DIRY,sizeof(ce[i].chunkId)) == 0 ) diry = i; if ( strncmp(ce[i].chunkId,LIB_VRSN,sizeof(ce[i].chunkId)) == 0 ) vrsn = i; if ( strncmp(ce[i].chunkId,LIB_DATA,sizeof(ce[i].chunkId)) == 0 ) data++; } if ( diry == -1 ) fatal("Can't find library directory!"); if ( data == 0 ) fatal("No modules in the library!"); if ( vrsn == -1 ) fatal("Can't determine library version!"); ulong *version = (ulong *)read_chunk(fp,ce,vrsn); if ( mf ) *version = swap(*version); if ( *version != 1 ) fatal("Wrong library version (%ld)",*version); qfree(version); ulong *dir = (ulong *)read_chunk(fp,ce,diry); ulong *end = dir + size_t(ce[diry].size/4); while ( dir < end ) { ulong idx = *dir++; /* ulong elen = */ *dir++; ulong dlen = *dir++; if ( mf ) { idx = swap(idx); dlen = swap(dlen); } if ( idx != 0 ) { printf("%ld. %s\n",idx,dir); strncpy(modname,(char *)dir,sizeof(modname)); modname[sizeof(modname)-1] = '\0'; void *core = read_chunk(fp,ce,idx); outfp = qfopen(modname,"wb"); if ( outfp == NULL ) { warning("Can't open output file %s",modname); } else { qfwrite(outfp,core,size_t(ce[size_t(idx)].size)); qfclose(outfp); } qfree(core); } dir += size_t(dlen/4); } qfree(dir); qfclose(fp); return 0; }
uint8_t extract_mhobject(ea_t address, char *outputFilename) { uint32 magicValue = get_long(address); struct mach_header *mach_header = NULL; struct mach_header_64 *mach_header64 = NULL; uint8_t arch = 0; if (magicValue == MH_MAGIC) { #if DEBUG msg("[DEBUG] Target is 32bits!\n"); #endif mach_header = (struct mach_header *)qalloc(sizeof(struct mach_header)); // retrieve mach_header contents if(!get_many_bytes(address, mach_header, sizeof(struct mach_header))) { msg("[ERROR] Read bytes failed!\n"); return 1; } } else if (magicValue == MH_MAGIC_64) { #if DEBUG msg("[DEBUG] Target is 64bits!\n"); #endif mach_header64 = (struct mach_header_64 *)qalloc(sizeof(struct mach_header_64)); if(!get_many_bytes(address, mach_header64, sizeof(struct mach_header_64))) { msg("[ERROR] Read bytes failed!\n"); return 1; } arch = 1; } // open output file FILE *outputFile = qfopen(outputFilename, "wb+"); if (outputFile == NULL) { msg("[ERROR] Could not open %s file!\n", outputFilename); return 1; } /* * we need to write 3 distinct blocks of data: * 1) the mach_header * 2) the load commands * 3) the code and data from the LC_SEGMENT/LC_SEGMENT_64 commands */ // write the mach_header to the file if (arch) qfwrite(outputFile, mach_header64, sizeof(struct mach_header_64)); else qfwrite(outputFile, mach_header, sizeof(struct mach_header)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM) { mach_header->ncmds = ntohl(mach_header->ncmds); mach_header->sizeofcmds = ntohl(mach_header->sizeofcmds); } else if (magicValue == MH_CIGAM_64) { mach_header64->ncmds = ntohl(mach_header64->ncmds); mach_header64->sizeofcmds = ntohl(mach_header64->sizeofcmds); } // read the load commands uint32_t ncmds = arch ? mach_header64->ncmds : mach_header->ncmds; uint32_t sizeofcmds = arch ? mach_header64->sizeofcmds : mach_header->sizeofcmds; uint32_t headerSize = arch ? sizeof(struct mach_header_64) : sizeof(struct mach_header); uint8_t *loadcmdsBuffer = NULL; loadcmdsBuffer = (uint8_t*)qalloc(sizeofcmds); get_many_bytes(address + headerSize, loadcmdsBuffer, sizeofcmds); // write all the load commands block to the output file // only LC_SEGMENT commands contain further data qfwrite(outputFile, loadcmdsBuffer, sizeofcmds); // and now process the load commands so we can retrieve code and data struct load_command loadCommand; ea_t cmdsBaseAddress = address + headerSize; // read segments so we can write the code and data // only the segment commands have useful information for (uint32_t i = 0; i < ncmds; i++) { get_many_bytes(cmdsBaseAddress, &loadCommand, sizeof(struct load_command)); struct segment_command segmentCommand; struct segment_command_64 segmentCommand64; // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM || magicValue == MH_CIGAM_64) { loadCommand.cmd = ntohl(loadCommand.cmd); loadCommand.cmdsize = ntohl(loadCommand.cmdsize); } // 32bits targets if (loadCommand.cmd == LC_SEGMENT) { get_many_bytes(cmdsBaseAddress, &segmentCommand, sizeof(struct segment_command)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM) { segmentCommand.nsects = ntohl(segmentCommand.nsects); segmentCommand.fileoff = ntohl(segmentCommand.fileoff); segmentCommand.filesize = ntohl(segmentCommand.filesize); } ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command); struct section sectionCommand; // iterate thru all sections to find the first code offset // FIXME: we need to find the lowest one since the section info can be reordered for (uint32_t x = 0; x < segmentCommand.nsects; x++) { get_many_bytes(sectionAddress, §ionCommand, sizeof(struct section)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM) { sectionCommand.offset = ntohl(sectionCommand.offset); sectionCommand.nreloc = ntohl(sectionCommand.nreloc); sectionCommand.reloff = ntohl(sectionCommand.reloff); } if (sectionCommand.nreloc > 0) { uint32_t size = sectionCommand.nreloc*sizeof(struct relocation_info); uint8_t *relocBuf = (uint8_t*)qalloc(size); get_many_bytes(address + sectionCommand.reloff, relocBuf, size); qfseek(outputFile, sectionCommand.reloff, SEEK_SET); qfwrite(outputFile, relocBuf, size); qfree(relocBuf); } sectionAddress += sizeof(struct section); } // read and write the data uint8_t *buf = (uint8_t*)qalloc(segmentCommand.filesize); get_many_bytes(address + segmentCommand.fileoff, buf, segmentCommand.filesize); // always set the offset qfseek(outputFile, segmentCommand.fileoff, SEEK_SET); qfwrite(outputFile, buf, segmentCommand.filesize); qfree(buf); } // we need this to dump missing relocations else if (loadCommand.cmd == LC_SYMTAB) { struct symtab_command symtabCommand; get_many_bytes(cmdsBaseAddress, &symtabCommand, sizeof(struct symtab_command)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM || magicValue == MH_CIGAM_64) { symtabCommand.nsyms = ntohl(symtabCommand.nsyms); symtabCommand.symoff = ntohl(symtabCommand.symoff); symtabCommand.stroff = ntohl(symtabCommand.stroff); symtabCommand.strsize = ntohl(symtabCommand.strsize); } if (symtabCommand.symoff > 0) { void *buf = qalloc(symtabCommand.nsyms*sizeof(struct nlist)); get_many_bytes(address + symtabCommand.symoff, buf, symtabCommand.nsyms*sizeof(struct nlist)); qfseek(outputFile, symtabCommand.symoff, SEEK_SET); qfwrite(outputFile, buf, symtabCommand.nsyms*sizeof(struct nlist)); qfree(buf); } if (symtabCommand.stroff > 0) { void *buf = qalloc(symtabCommand.strsize); get_many_bytes(address + symtabCommand.stroff, buf, symtabCommand.strsize); qfseek(outputFile, symtabCommand.stroff, SEEK_SET); qfwrite(outputFile, buf, symtabCommand.strsize); qfree(buf); } } // 64bits targets // FIXME: will this work ? needs to be tested :-) else if (loadCommand.cmd == LC_SEGMENT_64) { get_many_bytes(cmdsBaseAddress, &segmentCommand64, sizeof(struct segment_command_64)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM_64) { segmentCommand64.nsects = ntohl(segmentCommand64.nsects); segmentCommand64.fileoff = bswap64(segmentCommand64.fileoff); segmentCommand64.filesize = bswap64(segmentCommand64.filesize); } ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command_64); struct section_64 sectionCommand64; for (uint32_t x = 0; x < segmentCommand64.nsects; x++) { get_many_bytes(sectionAddress, §ionCommand64, sizeof(struct section_64)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM_64) { sectionCommand64.offset = ntohl(sectionCommand64.offset); sectionCommand64.nreloc = ntohl(sectionCommand64.nreloc); sectionCommand64.reloff = ntohl(sectionCommand64.reloff); } if (sectionCommand64.nreloc > 0) { uint32_t size = sectionCommand64.nreloc*sizeof(struct relocation_info); uint8_t *relocBuf = (uint8_t*)qalloc(size); get_many_bytes(address + sectionCommand64.reloff, relocBuf, size); qfseek(outputFile, sectionCommand64.reloff, SEEK_SET); qfwrite(outputFile, relocBuf, size); qfree(relocBuf); } sectionAddress += sizeof(struct section_64); } // read and write the data uint8_t *buf = (uint8_t*)qalloc(segmentCommand64.filesize); get_many_bytes(address + segmentCommand64.fileoff, buf, segmentCommand64.filesize); qfseek(outputFile, segmentCommand64.fileoff, SEEK_SET); qfwrite(outputFile, buf, segmentCommand64.filesize); qfree(buf); } cmdsBaseAddress += loadCommand.cmdsize; } // all done, close file and free remaining buffers! qfclose(outputFile); qfree(mach_header); qfree(mach_header64); qfree(loadcmdsBuffer); return 0; }
/* Save as with the external mpeg2enc */ uint8_t mpegWritter::save_regular (const char *name, ADM_MPEGTYPE mpegtype, int qz, int bitrate, int matrix, uint8_t interlaced, uint8_t bff, // WLA uint8_t widescreen) { uint32_t size; AVDMGenericVideoStream *incoming; FILE *fd = NULL; uint64_t total_size = 0; uint32_t len, flags; uint32_t outquant; uint32_t audiolen = 0; DIA_encoding *encoding; uint32_t sample_target = 0; double sample_time; ADMBitstream bitstream; incoming = getLastVideoFilter (frameStart, frameEnd - frameStart); _total = incoming->getInfo ()->nb_frames; _fps1000 = incoming->getInfo ()->fps1000; if (!_total) { GUI_Error_HIG (_("No frames to encode"), _("Please check markers. Is \"A>\" == \">B\"?")); return 0; } printf ("Br:%d, qz:%d\n", bitrate, qz); if (!_audio) { if (!(fd = qfopen (name, "wb"))) return 0; } else { ADM_assert (_muxer); sample_time = _total; sample_time *= 1000; sample_time /= _fps1000; // target_time in second sample_time *= _audio->getInfo ()->frequency; sample_target = (uint32_t) floor (sample_time); } _w = incoming->getInfo ()->width; _h = incoming->getInfo ()->height; _page = _w * _h; _page += _page >> 1; // if(!init(name,ADM_VCD,interlaced,widescreen)) return 0; if (!init (name, ADM_VCD, interlaced, bff, widescreen)) return 0; //WLA printf ("\n mpeg2enc init done \n"); //_buffer =new uint8_t[_w*_h*2]; aImage = new ADMImage (_w, _h); _buffer_out = new uint8_t[_w * _h * 2]; ADM_assert (aImage); ADM_assert (_buffer_out); encoding = new DIA_encoding (_fps1000); encoding->setPhasis ("Encoding."); encoding->setFrame (0, _total); // printf("Br:%d, qz:%d\n",bitrate,qz); switch (mpegtype) { case ADM_VCD: { encoding->setCodec ("VCD."); Mpeg2encVCD *dec; dec = new Mpeg2encVCD (_w, _h); // dec->init(1,0,_fps1000,interlaced,widescreen); dec->init (1, 0, _fps1000, interlaced, bff, widescreen, 0); // WLA _codec = dec; } break; case ADM_SVCD: Mpeg2encSVCD * dec; dec = new Mpeg2encSVCD (_w, _h); dec->setMatrix (matrix); // dec->init(qz,bitrate,_fps1000,interlaced,widescreen); dec->init (qz, bitrate, _fps1000, interlaced, bff, widescreen, 0); // WLA _codec = dec; encoding->setCodec ("SVCD."); break; case ADM_DVD: { Mpeg2encDVD *dec; dec = new Mpeg2encDVD (_w, _h); dec->setMatrix (matrix); // dec->init(qz,bitrate,_fps1000,interlaced,widescreen); dec->init (qz, bitrate, _fps1000, interlaced, bff, widescreen, 0); // WLA _codec = dec; encoding->setCodec ("DVD."); } break; default: ADM_assert (0); } printf ("\n--encoding started--\n"); if (_muxer) { if (audioProcessMode ()) encoding-> setAudioCodec (getStrFromAudioCodec (_audio->getInfo ()->encoding)); else encoding->setAudioCodec ("Copy"); switch (_outputAs) { case MUXER_TS: encoding->setContainer ("Mpeg TS"); break; case MUXER_VCD: encoding->setContainer ("Mpeg VCD"); break; case MUXER_SVCD: encoding->setContainer ("Mpeg SVCD"); break; case MUXER_DVD: encoding->setContainer ("Mpeg DVD"); break; default: ADM_assert (0); } } else encoding->setContainer ("Mpeg ES"); bitstream.data = _buffer_out; for (uint32_t i = 0; i < _total; i++) { if (!incoming->getFrameNumberNoAlloc (i, &size, aImage, &flags)) { delete encoding; GUI_Error_HIG (_("Encoding error"), NULL); if (fd) qfclose (fd); end (); return 0; } bitstream.cleanup (i); bitstream.in_quantizer=0; _codec->encode (aImage, &bitstream); //_buffer_out , &len,&flags,&outquant); total_size += bitstream.len; encoding->feedFrame (bitstream.len); encoding->setQuant (bitstream.out_quantizer); encoding->setFrame (i, _total); // Null frame are only possible // when in prefill state for mpeg-X if (!len) continue; if (_muxer) { #warning FIXME #warning FIXME #warning FIXME #warning FIXME _muxer->writeVideoPacket (&bitstream); PACK_AUDIO; } else { qfwrite (_buffer_out, bitstream.len, 1, fd); fflush (fd); } aprintf (" outquant %02d size :%d flags %x\n", outquant, len, flags); if (!encoding->isAlive ()) { delete encoding; end (); if (fd) qfclose (fd); return 0; } } encoding->setPhasis ("Finishing"); bitstream.data = _buffer_out; for (uint32_t i = 0; i < MPEG_PREFILL; i++) { bitstream.cleanup (i); _codec->encode (aImage, &bitstream); //_buffer_out , &len,&flags); total_size += bitstream.len; encoding->feedFrame (bitstream.len); if (!_muxer) qfwrite (_buffer_out, bitstream.len, 1, fd); else { _muxer->writeVideoPacket (&bitstream); PACK_AUDIO; } // printf("\n pipe opened %ld\n",i); encoding->setFrame (i, _total); } delete encoding; if (!_muxer) qfclose (fd); else { _muxer->close (); delete _muxer; _muxer = NULL; deleteAudioFilter (_audio); _audio = NULL; } end (); return 1; }
/** \fn runVC1 \brief Index VC1 stream */ bool TsIndexer::runVC1(const char *file,ADM_TS_TRACK *videoTrac) { uint32_t temporal_ref,val; uint8_t buffer[50*1024]; bool seq_found=false; TSVideo video; indexerData data; dmxPacketInfo info; beginConsuming=0; listOfUnits.clear(); if(!videoTrac) return false; if(videoTrac[0].trackType!=ADM_TS_VC1) { printf("[Ts Indexer] Only VC1 video supported\n"); return false; } video.pid=videoTrac[0].trackPid; memset(&data,0,sizeof(data)); data.picStructure=pictureFrame; string indexName=string(file); indexName=indexName+string(".idx2"); index=qfopen(indexName,"wt"); if(!index) { printf("[PsIndex] Cannot create %s\n",indexName.c_str()); return false; } writeSystem(file,false); pkt=new tsPacketLinearTracker(videoTrac->trackPid, audioTracks); FP_TYPE append=FP_APPEND; pkt->open(file,append); data.pkt=pkt; fullSize=pkt->getSize(); int startCode; decodingImage=false; #define likely(x) x #define unlikely(x) x while(1) { startCode=pkt->findStartCode(); if(!pkt->stillOk()) break; switch(startCode) { case 0x0f: // sequence start if(seq_found) { pkt->getInfo(&thisUnit.packetInfo); thisUnit.consumedSoFar=pkt->getConsumed(); addUnit(data,unitTypeSps,thisUnit,4); decodingImage=false; break; } // Verify it is high/advanced profile { int seqSize=0; tsGetBits bits(pkt); if(!bits.peekBits(1)) continue; // simple/main profile if(!decodeVC1Seq(bits,video)) continue; seqSize=bits.getConsumed(); video.extraDataLength=seqSize+4+1; memcpy(video.extraData+4,bits.data,seqSize); // Add info so that ffmpeg is happy video.extraData[0]=0; video.extraData[1]=0; video.extraData[2]=1; video.extraData[3]=0xf; video.extraData[seqSize+4+0]=0; seq_found=1; // Hi Profile printf("[VC1] Found seq start with %d x %d video\n",(int)video.w,(int)video.h); printf("[VC1] FPS : %d\n",(int)video.fps); printf("[VC1] sequence header is %d bytes\n",(int)seqSize); writeVideo(&video,ADM_TS_VC1); writeAudio(); qfprintf(index,"[Data]"); pkt->getInfo(&thisUnit.packetInfo); thisUnit.consumedSoFar=pkt->getConsumed(); addUnit(data,unitTypeSps,thisUnit,seqSize+4); decodingImage=false; continue; } break; case 0x0D: // Picture start { int type; uint8_t buffer[4]; uint32_t fType,sType; if(!seq_found) { continue; printf("[TsIndexer]No sequence start yet, skipping..\n"); } pkt->getInfo(&thisUnit.packetInfo); thisUnit.consumedSoFar=pkt->getConsumed(); tsGetBits bits(pkt); if(!decodeVC1Pic(bits,fType,sType)) continue; thisUnit.imageType=fType; updatePicStructure(video,sType); addUnit(data,unitTypePic,thisUnit,4); decodingImage=true; data.nbPics++; } break; default: break; } } printf("\n"); // Mark(&data,&info,2); qfprintf(index,"\n[End]\n"); qfprintf(index,"\n# Found %"PRIu32" images \n",data.nbPics); // Size qfprintf(index,"# Found %"PRIu32" frame pictures\n",video.frameCount); // Size qfprintf(index,"# Found %"PRIu32" field pictures\n",video.fieldCount); // Size qfclose(index); index=NULL; audioTracks=NULL; delete pkt; pkt=NULL; return 1; }
//**************************************************************** uint8_t mpegWritter::dopass2 (const char *name, char *statname, uint32_t final_size, uint32_t bitrate, ADM_MPEGTYPE mpegtype, int matrix, uint8_t interlaced, uint8_t bff, // WLA uint8_t widescreen) { int intra, q; uint32_t size; AVDMGenericVideoStream *incoming; FILE *fd = NULL; uint64_t total_size = 0; uint32_t len, flags, type, outquant, audiolen; uint32_t sample_target = 0; double sample_time; ADMBitstream bitstream; memset (quantstat, 0, 32); incoming = getLastVideoFilter (frameStart, frameEnd - frameStart); if (!_audio) { if (!(fd = qfopen (name, "wb"))) return 0; } // if(!init(name,mpegtype,interlaced,widescreen)) if (!init (name, mpegtype, interlaced, bff, widescreen)) // WLA { printf ("Mpeg2 init failed\n"); return 0; } printf ("\n mpeg2enc init done \n"); ADM_assert (aImage); ADM_assert (_buffer_out); encoding->reset (); encoding->setFrame (0, _total); /*-------------------- Pass 1 over, go to pass 2 --------------------------------*/ ADM_assert (_ratecontrol->startPass2 (final_size, _total)); encoding->setPhasis ("2nd Pass"); q = 2; //mpegvbr.maxAllowedBitrate=(bitrate*1000)>>3;//(bitrate*1000)>>3; //mpegvbr.maxAllowedBitrate=(9000*1000)>>3; // enable stuff in xvid //-> switch (mpegtype) { case ADM_SVCD: Mpeg2encSVCD * dec; dec = new Mpeg2encSVCD (_w, _h); dec->setMatrix (matrix); // dec->init(q,bitrate,_fps1000,interlaced,widescreen); dec->init (q, bitrate, _fps1000, interlaced, bff, widescreen, 0); // WLA _codec = dec; encoding->setCodec ("SVCD"); printf ("Svcd max bitrate : %d\n", bitrate); break; case ADM_DVD: { Mpeg2encDVD *dec; dec = new Mpeg2encDVD (_w, _h); dec->setMatrix (matrix); // dec->init(q,bitrate,_fps1000,interlaced,widescreen); dec->init (q, bitrate, _fps1000, interlaced, bff, widescreen, 0); // WLA _codec = dec; printf ("DVD max bitrate : %d\n", bitrate); encoding->setCodec ("DVD"); } break; default: ADM_assert (0); break; } encoding->setPhasis ("2nd Pass"); if (_muxer) { encoding-> setAudioCodec (getStrFromAudioCodec (_audio->getInfo ()->encoding)); sample_time = _total; sample_time *= 1000; sample_time /= _fps1000; // target_time in second sample_time *= _audio->getInfo ()->frequency; sample_target = (uint32_t) floor (sample_time); } bitstream.data = _buffer_out; for (uint32_t i = 0; i < _total; i++) { if (!incoming->getFrameNumberNoAlloc (i, &size, aImage, &flags)) { GUI_Error_HIG (_("Encoding error"), NULL); if (!_audio) qfclose (fd); end (); return 0; } encoding->setFrame (i, _total); if (i < MPEG_PREFILL) { _codec->encode (aImage, &bitstream); //_buffer_out , &len,&flags,&outquant); quantstat[bitstream.out_quantizer]++; continue; } // Set // ADM_rframe ftype, ztype; uint32_t qz; ADM_assert (_ratecontrol->getQz (&qz, &ztype)); q = qz; //_codec->setQuantize(q); bitstream.in_quantizer = q; _codec->encode (aImage, &bitstream); //_buffer_out , &len,&flags,&outquant); quantstat[bitstream.out_quantizer]++; encoding->setQuant (bitstream.out_quantizer); switch (bitstream.flags) { case AVI_KEY_FRAME: ftype = RF_I; break; case AVI_B_FRAME: ftype = RF_B; break; default: ftype = RF_P; break; } if (ftype != ztype) { printf ("**Frame type does not match %d %d\n", ztype, ftype); } //aprintf("inquant : %02d outquant %02d Intra %d size :%d flags %x\n", // q,outquant,intra,len,flags); ADM_assert (_ratecontrol-> logPass2 (bitstream.out_quantizer, ftype, bitstream.len)); total_size += bitstream.len; encoding->feedFrame (bitstream.len); if (!_muxer) { qfwrite (_buffer_out, bitstream.len, 1, fd); fflush (fd); } else { // write video _muxer->writeVideoPacket (&bitstream); PACK_AUDIO; } if (!encoding->isAlive ()) { print_quant_stat (name); end (); qfclose (fd); return 0; } } //-- // flush queue for (uint32_t i = 0; i < MPEG_PREFILL; i++) { ADM_rframe ftype; uint32_t qz; ADM_assert (_ratecontrol->getQz (&qz, &ftype)); q = qz; //_codec->setQuantize(q); bitstream.in_quantizer = q; _codec->encode (aImage, &bitstream); //_buffer_out , &len,&flags,&outquant); quantstat[bitstream.out_quantizer]++; encoding->setQuant (bitstream.out_quantizer); switch (bitstream.flags) { case AVI_KEY_FRAME: ftype = RF_I; break; case AVI_B_FRAME: ftype = RF_B; break; default: ftype = RF_P; break; } //aprintf("inquant : %02d outquant %02d Intra %d size :%d flags %x\n", // q,outquant,intra,len,flags); ADM_assert (_ratecontrol-> logPass2 (bitstream.out_quantizer, ftype, bitstream.len)); total_size += bitstream.len; if (!_muxer) { qfwrite (_buffer_out, bitstream.len, 1, fd); fflush (fd); } else { // write video _muxer->writeVideoPacket (&bitstream); PACK_AUDIO; } // printf("\n pipe opened %ld\n",i); encoding->feedFrame (bitstream.len); // Set encoding->setQuant (bitstream.out_quantizer); encoding->setFrame (i, MPEG_PREFILL); } //-- if (!_muxer) qfclose (fd); else { _muxer->close (); delete _muxer; _muxer = NULL; } print_quant_stat (name); end (); return 1; }