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; }
//-------------------------------------------------------------------------- local void *read_chunk(FILE *fp,chunk_entry_t *ce,long i) { size_t idx = size_t(i); void *chunk = qnewarray(char,size_t(ce[idx].size)); if ( chunk == NULL ) nomem("chunk size %d",size_t(ce[idx].size)); qfseek(fp,ce[idx].file_offset,SEEK_SET); if ( qfread(fp,chunk,size_t(ce[idx].size)) != ce[idx].size ) fatal("Chunk read error: %s",strerror(errno)); return chunk; }
//-------------------------------------------------------------------------- PyObject *read(int size) { do { char *buf = (char *) malloc(size + 5); if ( buf == NULL ) break; PYW_GIL_CHECK_LOCKED_SCOPE(); int r; Py_BEGIN_ALLOW_THREADS; r = qfread(fp, buf, size); Py_END_ALLOW_THREADS; if ( r <= 0 ) { free(buf); break; } PyObject *ret = PyString_FromStringAndSize(buf, r); free(buf); return ret; } while ( false ); Py_RETURN_NONE; }
//-------------------------------------------------------------------------- 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; }