/* rewind to beginning */ void faad_rewindbits(bitfile *ld) { uint32_t tmp; ld->bytes_left = ld->buffer_size; if (ld->bytes_left >= 4) { tmp = getdword((uint32_t*)&ld->start[0]); ld->bytes_left -= 4; } else { tmp = getdword_n((uint32_t*)&ld->start[0], ld->bytes_left); ld->bytes_left = 0; } ld->bufa = tmp; if (ld->bytes_left >= 4) { tmp = getdword((uint32_t*)&ld->start[1]); ld->bytes_left -= 4; } else { tmp = getdword_n((uint32_t*)&ld->start[1], ld->bytes_left); ld->bytes_left = 0; } ld->bufb = tmp; ld->bits_left = 32; ld->tail = &ld->start[2]; }
/* reversed bit reading routines, used for RVLC and HCR */ void faad_initbits_rev(bitfile *ld, void *buffer, uint32_t bits_in_buffer) { uint32_t tmp; int32_t index; ld->buffer_size = bit2byte(bits_in_buffer); index = (bits_in_buffer+31)/32 - 1; ld->start = (uint32_t*)buffer + index - 2; tmp = getdword((uint32_t*)buffer + index); ld->bufa = tmp; tmp = getdword((uint32_t*)buffer + index - 1); ld->bufb = tmp; ld->tail = (uint32_t*)buffer + index; ld->bits_left = bits_in_buffer % 32; if (ld->bits_left == 0) ld->bits_left = 32; ld->bytes_left = ld->buffer_size; ld->error = 0; }
/* initialize buffer, call once before first getbits or showbits */ void faad_initbits(bitfile *ld, const void *_buffer, const uint32_t buffer_size) { uint32_t tmp; if (ld == NULL) return; // useless //memset(ld, 0, sizeof(bitfile)); if (buffer_size == 0 || _buffer == NULL) { ld->error = 1; return; } ld->buffer = _buffer; ld->buffer_size = buffer_size; ld->bytes_left = buffer_size; if (ld->bytes_left >= 4) { tmp = getdword((uint32_t*)ld->buffer); ld->bytes_left -= 4; } else { tmp = getdword_n((uint32_t*)ld->buffer, ld->bytes_left); ld->bytes_left = 0; } ld->bufa = tmp; if (ld->bytes_left >= 4) { tmp = getdword((uint32_t*)ld->buffer + 1); ld->bytes_left -= 4; } else { tmp = getdword_n((uint32_t*)ld->buffer + 1, ld->bytes_left); ld->bytes_left = 0; } ld->bufb = tmp; ld->start = (uint32_t*)ld->buffer; ld->tail = ((uint32_t*)ld->buffer + 2); ld->bits_left = 32; ld->error = 0; }
void process(FILE *f,long namepos,unsigned long datapos) { byte name[1040]; byte namelen; static int count=0; FILE *out; int i; unsigned long len; if(namepos==-1) sprintf(name,"%s%d.data",thename,count++); else { myseek(f,namepos); namelen=getbyte(f); if((int)fread(name,1,namelen,f)!=(int)namelen) err("Error reading resource name\n"); name[namelen]=0; for(i=0;i<namelen;i++) { if(name[i]>126 || name[i]<32 || name[i]=='\\' || name[i]=='?' || name[i]==':' || name[i]=='/' || name[i]=='%' || name[i]=='<' || name[i]=='>' || name[i]=='*' || name[i]=='"') name[i]='_'; } strcat(name,".data"); } out=myfopen(name,"wb"); printf("Extracting: %s\n",name); myseek(f,datapos); len=getdword(f); while(len--) fputc(myfgetc(f),out); fclose(out); }
/* reset to a certain point */ void faad_resetbits(bitfile *ld, int bits) { uint32_t tmp; int words = bits >> 5; int remainder = bits & 0x1F; ld->bytes_left = ld->buffer_size - words*4; if (ld->bytes_left >= 4) { tmp = getdword(&ld->start[words]); ld->bytes_left -= 4; } else { tmp = getdword_n(&ld->start[words], ld->bytes_left); ld->bytes_left = 0; } ld->bufa = tmp; if (ld->bytes_left >= 4) { tmp = getdword(&ld->start[words+1]); ld->bytes_left -= 4; } else { tmp = getdword_n(&ld->start[words+1], ld->bytes_left); ld->bytes_left = 0; } ld->bufb = tmp; ld->bits_left = 32 - remainder; ld->tail = &ld->start[words+2]; /* recheck for reading too many bytes */ ld->error = 0; // if (ld->bytes_left == 0) // ld->no_more_reading = 1; // if (ld->bytes_left < 0) // ld->error = 1; }
/* initialize buffer, call once before first getbits or showbits */ void faad_initbits(bitfile *ld, const void *_buffer, const uint32_t buffer_size) { uint32_t tmp; if (ld == NULL) return; memset(ld, 0, sizeof(bitfile)); if (buffer_size == 0 || _buffer == NULL) { ld->error = 1; ld->no_more_reading = 1; return; } ld->buffer = faad_malloc((buffer_size+12)*sizeof(uint8_t)); memset(ld->buffer, 0, (buffer_size+12)*sizeof(uint8_t)); memcpy(ld->buffer, _buffer, buffer_size*sizeof(uint8_t)); ld->buffer_size = buffer_size; tmp = getdword((uint32_t*)ld->buffer); ld->bufa = tmp; tmp = getdword((uint32_t*)ld->buffer + 1); ld->bufb = tmp; ld->start = (uint32_t*)ld->buffer; ld->tail = ((uint32_t*)ld->buffer + 2); ld->bits_left = 32; ld->bytes_used = 0; ld->no_more_reading = 0; ld->error = 0; }
void faad_flushbits_ex(bitfile *ld, uint32_t bits) { uint32_t tmp; ld->bufa = ld->bufb; if (ld->no_more_reading == 0) { tmp = getdword(ld->tail); ld->tail++; } else { tmp = 0; } ld->bufb = tmp; ld->bits_left += (32 - bits); ld->bytes_used += 4; if (ld->bytes_used == ld->buffer_size) ld->no_more_reading = 1; if (ld->bytes_used > ld->buffer_size) ld->error = 1; }
void faad_flushbits_ex(bitfile *ld, uint32_t bits) { uint32_t tmp; ld->bufa = ld->bufb; if (ld->bytes_left >= 4) { tmp = getdword(ld->tail); ld->bytes_left -= 4; } else { tmp = getdword_n(ld->tail, ld->bytes_left); ld->bytes_left = 0; } ld->bufb = tmp; ld->tail++; ld->bits_left += (32 - bits); //ld->bytes_left -= 4; // if (ld->bytes_left == 0) // ld->no_more_reading = 1; // if (ld->bytes_left < 0) // ld->error = 1; }
/* * Handle a GP fault that occurred while in VM86 mode. Things that are easy * to handle here are done here (much more efficient than trapping to 32-bit * handler code and then having it restart VM86 mode). */ void vm86_gpfault(struct proc *p, int type) { struct trapframe *tf = p->p_md.md_regs; union sigval sv; /* * we want to fetch some stuff from the current user virtual * address space for checking. remember that the frame's * segment selectors are real-mode style selectors. */ u_long cs, ip, ss, sp; u_char tmpbyte; int trace; cs = CS(tf) << 4; ip = IP(tf); ss = SS(tf) << 4; sp = SP(tf); trace = tf->tf_eflags & PSL_T; /* * For most of these, we must set all the registers before calling * macros/functions which might do a vm86_return. */ tmpbyte = getbyte(cs, ip); IP(tf) = ip; switch (tmpbyte) { case CLI: /* simulate handling of IF */ clr_vif(p); break; case STI: /* simulate handling of IF. * XXX the i386 enables interrupts one instruction later. * code here is wrong, but much simpler than doing it Right. */ set_vif(p); break; case INTxx: /* try fast intxx, or return to 32bit mode to handle it. */ tmpbyte = getbyte(cs, ip); IP(tf) = ip; fast_intxx(p, tmpbyte); break; case INTO: if (tf->tf_eflags & PSL_V) fast_intxx(p, 4); break; case PUSHF: putword(ss, sp, get_vflags_short(p)); SP(tf) = sp; break; case IRET: IP(tf) = getword(ss, sp); CS(tf) = getword(ss, sp); case POPF: set_vflags_short(p, getword(ss, sp)); SP(tf) = sp; break; case OPSIZ: tmpbyte = getbyte(cs, ip); IP(tf) = ip; switch (tmpbyte) { case PUSHF: putdword(ss, sp, get_vflags(p) & ~PSL_VM); SP(tf) = sp; break; case IRET: IP(tf) = getdword(ss, sp); CS(tf) = getdword(ss, sp); case POPF: set_vflags(p, getdword(ss, sp) | PSL_VM); SP(tf) = sp; break; default: IP(tf) -= 2; goto bad; } break; case LOCK: default: IP(tf) -= 1; goto bad; } if (trace && tf->tf_eflags & PSL_VM) { sv.sival_int = 0; trapsignal(p, SIGTRAP, T_TRCTRAP, TRAP_TRACE, sv); } return; bad: vm86_return(p, VM86_UNKNOWN); return; }
/* getaloc - get an action from the action table */ int getaloc(int n) { if (n < 1 || n > acount) nerror("action number out of range: %d",n); return (getdword(atable+n+n)); }
/* getcword - get a code word */ int getcword(int n) { return (getdword(cbase+n)); }
/* getword - get a word from the data array */ int getword(int n) { return (getdword(base+n)); }
/* getwloc - get a word from the word table */ int getwloc(int n) { if (n < 1 || n > wcount) nerror("word number out of range: %d",n); return (getdword(wtable+n+n)); }
/* getvalue - get the value of a variable from the variable table */ int getvalue(int n) { if (n < 1 || n > vcount) nerror("variable number out of range: %d",n); return (getdword(vtable+n+n)); }
main(int argc, char **argv) { int i; char name[1024]; char rsrc[5]="NFNT"; char s[5]; char *p; unsigned short n; int rsrconly=0; FILE *in,*out; unsigned long dforklen,rforklen,pos; if(argc!=2 && argc!=3) err("getmacfont filename [RSRC]\n" " This extracts all the bitmapped font (NFNT) resources\n" " from the specified MacBinary encoded file.\n" " You can also use it to extract any other type of resource\n" " by supplying the resource type on the commandline,\n" " for instance: getmacfont input.bin FOND.\n" " Each resource found gets saved into a separate file with\n" " filename ending in .data.\n"); strcpy(name,argv[1]); if(strlen(argv[1])>5 && !strcmp(argv[1]+strlen(argv[1])-5,".rsrc")) rsrconly=1; if(argc==3) { if(strlen(argv[2])!=4) err("Resource name should be four characters.\n"); strcpy(rsrc,argv[2]); } in=myfopen(name,"rb"); strcpy(thename,name); if((p=strrchr(thename,'.'))!=NULL) *p=0; if(!rsrconly) { myseek(in,83); dforklen=getdword(in); rforklen=getdword(in); printf("Data fork length = %lu\n" "Resource fork length = %lu\n", dforklen,rforklen); myseek(in,rforkpos=128+dforklen); } else { rforkpos=0; } rdatapos=rforkpos+getdword(in); rmappos=rforkpos+getdword(in); rdatalen=getdword(in); rmaplen=getdword(in); myseek(in,rmappos+16+4+2+2); /* printf("%lx\n",rmappos); */ rtypepos=rmappos+getword(in); /* printf("%lx\n",rtypepos); */ rnamepos=rmappos+getword(in); /* printf("%lx\n",rnamepos); */ myseek(in,rtypepos); numtypes=getword(in)+1; for(i=0;i<numtypes;i++) { read4bytes(in,s); if(!strcmp(rsrc,s)) break; getword(in); getword(in); } if(i==numtypes) err("Cannot find resources of type %s.\n",rsrc); myresnum=1+getword(in); myreflistpos=rtypepos+getword(in); myseek(in,myreflistpos); for(i=0;i<(int)myresnum;i++) { getword(in); /* Resource ID */ mynamepos=rnamepos+(n=getword(in)); getbyte(in); /* Resource attributes */ mydatapos=rdatapos+get3bytes(in); getdword(in); pos=ftell(in); process(in,n==65535?-1:mynamepos,mydatapos); myseek(in,pos); } fclose(in); return 0; }
int prefix_0f(void *handle_void, struct dis_instructions_s *dis_instructions, uint8_t *base_address, uint64_t offset, uint64_t size, uint8_t rex) { int half; uint8_t reg = 0; int tmp; int result = 0; uint8_t byte; //int8_t rel8 = 0; int32_t rel32 = 0; int64_t rel64 = 0; struct instruction_s *instruction; byte = base_address[offset + dis_instructions->bytes_used++]; debug_print(DEBUG_INPUT_DIS, 1, "Prefix_0f Byte = 0x%x\n", byte); switch (byte) { case 0x00: /* GRP 6 Exxx */ case 0x01: /* Group 7 Ev */ case 0x02: /* LAR Gv,Ev */ case 0x03: /* LSL Gv,Ev */ case 0x06: /* CLTS */ break; case 0x1F: /* NOP */ byte = base_address[offset + dis_instructions->bytes_used++]; switch (byte) { case 0x84: dis_instructions->bytes_used++; case 0x80: dis_instructions->bytes_used += 2; case 0x44: dis_instructions->bytes_used++; case 0x40: dis_instructions->bytes_used++; case 0x00: result = 1; break; default: break; } break; case 0x20: /* MOV Rd.CRx */ break; case 0x21: /* MOV Rd,DRx */ break; case 0x22: /* MOV CRx,Rd */ break; case 0x23: /* MOV DRx,Rd */ break; /* CMOVcc */ case 0x40: /* CMOVO */ case 0x41: /* CMOVNO */ case 0x42: /* CMOVB */ case 0x43: /* CMOVNB */ case 0x44: /* CMOVZ */ case 0x45: /* CMOVNZ */ case 0x46: /* CMOVBE */ case 0x47: /* CMOVNBE */ case 0x48: /* CMOVS */ case 0x49: /* CMOVNS */ case 0x4a: /* CMOVP */ case 0x4b: /* CMOVNP */ case 0x4c: /* CMOVL */ case 0x4d: /* CMOVNL */ case 0x4e: /* CMOVLE */ case 0x4f: /* CMOVNLE */ /* FIXME: Add the MOV bit */ instruction = &dis_instructions->instruction[dis_instructions->instruction_number]; instruction->opcode = IF; instruction->flags = 0; instruction->dstA.store = STORE_DIRECT; instruction->dstA.indirect = IND_DIRECT; instruction->dstA.indirect_size = 64; /* Means get from rest of instruction */ //relative = getbyte(base_address, offset + dis_instructions->bytes_used); /* extends byte to int64_t */ rel64 = 0; /* Skip to next instruction */ instruction->dstA.index = rel64; instruction->dstA.relocated = 0; instruction->dstA.value_size = 32; instruction->srcA.store = STORE_DIRECT; instruction->srcA.indirect = IND_DIRECT; instruction->srcA.indirect_size = 64; instruction->srcA.index = ((byte & 0xf) ^ 0x01) + 1; /* CONDITION to skip mov instruction */ instruction->srcA.relocated = 0; instruction->srcA.value_size = 32; debug_print(DEBUG_INPUT_DIS, 1, "JCD7: Before: %d\n", dis_instructions->instruction_number); dis_instructions->instruction_number++; result = dis_Gx_Ex(handle_void, MOV, rex, dis_instructions, base_address, offset, ®, size); debug_print(DEBUG_INPUT_DIS, 1, "JCD7: After: %d\n", dis_instructions->instruction_number); break; /* JMP */ case 0x80: /* JO */ case 0x81: /* JNO */ case 0x82: /* JB */ case 0x83: /* JNB */ case 0x84: /* JZ */ case 0x85: /* JNZ */ case 0x86: /* JBE */ case 0x87: /* JNBE */ case 0x88: /* JS */ case 0x89: /* JNS */ case 0x8a: /* JP */ case 0x8b: /* JNP */ case 0x8c: /* JL */ case 0x8d: /* JNL */ case 0x8e: /* JLE */ case 0x8f: /* JNLE */ instruction = &dis_instructions->instruction[dis_instructions->instruction_number]; instruction->opcode = IF; instruction->flags = 0; instruction->dstA.store = STORE_DIRECT; instruction->dstA.indirect = IND_DIRECT; instruction->dstA.indirect_size = 64; /* Means get from rest of instruction */ rel32 = getdword(base_address, offset + dis_instructions->bytes_used); rel64 = rel32; dis_instructions->bytes_used += 4; /* extends byte to int64_t */ instruction->dstA.index = rel64; instruction->dstA.relocated = 0; instruction->dstA.value_size = 32; instruction->srcA.store = STORE_DIRECT; instruction->srcA.indirect = IND_DIRECT; instruction->srcA.indirect_size = 64; instruction->srcA.index = (byte & 0xf) + 1; /* CONDITION */ instruction->srcA.relocated = 0; instruction->srcA.value_size = 32; dis_instructions->instruction_number++; result = 1; break; /* SET */ case 0x90: /* SETO */ case 0x91: /* SETNO */ case 0x92: /* SETB */ case 0x93: /* SETNB */ case 0x94: /* SETZ */ case 0x95: /* SETNZ */ case 0x96: /* SETBE */ case 0x97: /* SETNBE */ case 0x98: /* SETS */ case 0x99: /* SETNS */ case 0x9a: /* SETP */ case 0x9b: /* SETNP */ case 0x9c: /* SETL */ case 0x9d: /* SETNL */ case 0x9e: /* SETLE */ case 0x9f: /* SETNLE */ instruction = &dis_instructions->instruction[dis_instructions->instruction_number]; instruction->opcode = IF; instruction->flags = 0; instruction->dstA.store = STORE_DIRECT; instruction->dstA.indirect = IND_DIRECT; instruction->dstA.indirect_size = 64; /* Means get from rest of instruction */ //relative = getbyte(base_address, offset + dis_instructions->bytes_used); /* extends byte to int64_t */ rel64 = 0; /* Skip to next instruction */ instruction->dstA.index = rel64; instruction->dstA.relocated = 0; instruction->dstA.value_size = 32; instruction->srcA.store = STORE_DIRECT; instruction->srcA.indirect = IND_DIRECT; instruction->srcA.indirect_size = 64; instruction->srcA.index = ((byte & 0xf) ^ 0x01) + 1; /* CONDITION to skip mov instruction */ instruction->srcA.relocated = 0; instruction->srcA.value_size = 32; dis_instructions->instruction_number++; tmp = rmb(handle_void, dis_instructions, base_address, offset, size, rex, ®, &half); instruction = &dis_instructions->instruction[dis_instructions->instruction_number]; instruction->opcode = MOV; instruction->flags = 0; instruction->srcA.store = STORE_DIRECT; instruction->srcA.indirect = IND_DIRECT; instruction->srcA.indirect_size = 64; instruction->srcA.index = 1; instruction->srcA.relocated = 0; instruction->srcA.value_size = 8; instruction->dstA.store = STORE_REG; instruction->dstA.indirect = IND_DIRECT; instruction->dstA.indirect_size = 64; instruction->dstA.index = REG_TMP1; instruction->dstA.relocated = 0; instruction->dstA.value_size = size; dis_instructions->instruction_number++; result = 1; break; case 0xa0: /* PUSH FS */ case 0xa1: /* POP FS */ case 0xa2: /* CPUID */ case 0xa3: /* BT Ev,Gv */ case 0xa4: /* SHLD Ev,Gv,Ib */ case 0xa5: /* SHLD Ev,Gv,CL */ case 0xa8: /* PUSH GS */ case 0xa9: /* POP GS */ case 0xab: /* BTS Ev,Gv */ case 0xac: /* SHRD Ev,Gv,Ib */ break; case 0xad: /* SHRD Ev,Gv,CL */ break; case 0xaf: /* IMUL Gv,Ev */ break; case 0xb2: /* LSS Ev */ case 0xb3: /* BTR Ev,Gv */ case 0xb4: /* LFS Ev */ case 0xb5: /* LGS Ev */ case 0xb6: /* MOVZX Gv,Eb */ tmp = rmb(handle_void, dis_instructions, base_address, offset, size, rex, ®, &half); instruction = &dis_instructions->instruction[dis_instructions->instruction_number]; instruction->opcode = MOV; instruction->flags = 0; instruction->dstA.store = STORE_REG; instruction->dstA.indirect = 0; instruction->dstA.indirect_size = 64; instruction->dstA.index = reg_table[reg].offset; instruction->dstA.value_size = size; if (!half) { instruction->srcA.store = STORE_REG; instruction->srcA.indirect = 1; instruction->srcA.indirect_size = 64; instruction->srcA.index = REG_TMP1; } instruction->srcA.relocated = 0; instruction->srcA.value_size = 8; dis_instructions->instruction_number++; result = 1; break; case 0xb7: /* MOVZX Gv,Ev */ tmp = rmb(handle_void, dis_instructions, base_address, offset, size, rex, ®, &half); instruction = &dis_instructions->instruction[dis_instructions->instruction_number]; instruction->opcode = MOV; instruction->flags = 0; instruction->dstA.store = STORE_REG; instruction->dstA.indirect = 0; instruction->dstA.indirect_size = 64; instruction->dstA.index = reg_table[reg].offset; instruction->dstA.value_size = size; if (!half) { instruction->srcA.store = STORE_REG; instruction->srcA.indirect = 1; instruction->srcA.indirect_size = 64; instruction->srcA.index = REG_TMP1; } instruction->srcA.relocated = 0; instruction->srcA.value_size = 16; dis_instructions->instruction_number++; result = 1; break; case 0xbf: /* MOVSX Gv,Ev */ case 0xba: /* GRP8 Ev,Ib */ case 0xbb: /* BTC Ev,Gv */ case 0xbc: /* BSF Gv,Ev */ case 0xbd: /* BSR Gv,Ev */ case 0xbe: /* MOVSX Gv,Eb */ case 0xc8: /* BSWAP EAX */ case 0xc9: /* BSWAP ECX */ case 0xca: /* BSWAP EDX */ case 0xcb: /* BSWAP EBX */ case 0xcc: /* BSWAP ESP */ case 0xcd: /* BSWAP EBP */ case 0xce: /* BSWAP ESI */ case 0xcf: /* BSWAP EDI */ break; default: break; }; return result; }
/* getoloc - get an object from the object table */ int getoloc(int n) { if (n < 1 || n > ocount) nerror("object number out of range: %d",n); return (getdword(otable+n+n)); }