예제 #1
0
파일: drmgr.c 프로젝트: unbaiat/robocheck
/* XXX: exporting this so drwrap can use it but I might prefer to have
 * this in drutil or the upcoming drsys
 */
DR_EXPORT
int
drmgr_decode_sysnum_from_wrapper(app_pc entry)
{
    void *drcontext = dr_get_current_drcontext();
    int num = -1;
    byte *pc = entry;
    uint opc;
    instr_t instr;
    instr_init(drcontext, &instr);
    do {
        instr_reset(drcontext, &instr);
        pc = decode(drcontext, pc, &instr);
        if (!instr_valid(&instr))
            break; /* unknown system call sequence */
        opc = instr_get_opcode(&instr);
        /* sanity check: wrapper should be short */
        if (pc - entry > 20)
            break; /* unknown system call sequence */
        if (opc == OP_mov_imm && opnd_is_reg(instr_get_dst(&instr, 0)) &&
            opnd_get_reg(instr_get_dst(&instr, 0)) == DR_REG_EAX &&
            opnd_is_immed_int(instr_get_src(&instr, 0))) {
            num = (int) opnd_get_immed_int(instr_get_src(&instr, 0));
            break; /* success */
        }
        /* stop at call to vsyscall (wow64) or at int itself */
    } while (opc != OP_call_ind && opc != OP_int &&
             opc != OP_sysenter && opc != OP_syscall);
    instr_free(drcontext, &instr);
    return num;
}
예제 #2
0
void memory_write(void *pc, void *prev_pc)
{
  void		*drcontext = dr_get_current_drcontext();
  instr_t	*instr = instr_create(drcontext);
  dr_mcontext_t mctx;
  opnd_t	dst;
  ctx_t		ctx;
  
  pc = dr_app_pc_for_decoding(pc);

  mctx.flags = DR_MC_CONTROL|DR_MC_INTEGER;
  mctx.size = sizeof(mctx);
  dr_get_mcontext(drcontext, &mctx);

  instr_init(drcontext, instr);
  if (!decode(drcontext, pc, instr))
    {
      dr_printf("Decode of instruction at %p failed\n", pc);
      return;
    }

  ctx.addr = prev_pc;
  ctx.dr_addr = prev_pc;

  for (int i = 0; i < instr_num_dsts(instr); i++)
    {
      dst = instr_get_dst(instr, i);
      check_opnd(dst, pc, 0, drcontext, &mctx, &ctx);
    }

  instr_destroy(drcontext, instr);
}
예제 #3
0
파일: replace.c 프로젝트: unbaiat/robocheck
static app_pc
get_function_entry(app_pc C_var)
{
    void *drcontext = dr_get_current_drcontext();
    byte *pc;
    instr_t inst;
    instr_init(drcontext, &inst);
    pc = decode(drcontext, C_var, &inst);
    ASSERT(pc != NULL, "invalid instr at function entry");
    if (instr_get_opcode(&inst) == OP_jmp) {
        /* skip jmp in ILT */
        ASSERT(opnd_is_pc(instr_get_target(&inst)), "decoded jmp should have pc tgt");
        pc = opnd_get_pc(instr_get_target(&inst));
    } else
        pc = C_var;
    instr_free(drcontext, &inst);
    return pc;
}
예제 #4
0
파일: ir.c 프로젝트: Arunpreet/dynamorio
static void
test_strict_invalid(void *dc)
{
    instr_t instr;
    byte *pc;
    const byte buf[] = { 0xf2, 0x0f, 0xd8, 0xe9 }; /* psubusb w/ invalid prefix */

    instr_init(dc, &instr);

    /* The instr should be valid by default and invalid if decode_strict */
    pc = decode(dc, (byte *)buf, &instr);
    ASSERT(pc != NULL);

    disassemble_set_syntax(DR_DISASM_STRICT_INVALID);
    instr_reset(dc, &instr);
    pc = decode(dc, (byte *)buf, &instr);
    ASSERT(pc == NULL);

    instr_free(dc, &instr);
}
예제 #5
0
void Shade::disassemble_code(void *code, void *target, size_t size)
{
    instr_t instr;

    byte *pos = (byte *)code;
    byte *stop = (byte *)code + size;

    while(pos < stop)
    {
        instr_init(0, &instr);

        byte *next = decode_from_copy(0, pos, (byte *)target + (pos - (byte *)code), &instr);

        print_instr(pos - (byte *)code + (byte *)target, &instr);

        pos = next;

        instr_free(0, &instr);
    }

}
예제 #6
0
int main(int argc, char *argv[])
{
	FILE *fp,*opfp,*testf;
	int test,n,c,ln,i,m,m1,m2,b,flag=0,flag1=1,len,last,first,dig,id,errorflag=0,flen=0;
	long int madd=0000000,mm=1048575;
	label lbl[10];
	char ch,*nem[4],*str,*token,*token1,*token2,*token3,*s=" ",state,c1;

	str = (char *)malloc(sizeof(char)*50);
	token1 = (char *)malloc(sizeof(char)*10);
	token2 = (char *)malloc(sizeof(char)*20);
	token3 = (char *)malloc(sizeof(char)*20);
	//printf("file name %s\n", argv[1]);
	fp = fopen(argv[1],"r"); // opens input file which contains assembly code
	testf = fopen(argv[1],"r");
	opfp = fopen("stable.txt","w");

	if( fp == NULL )
	{
		perror("Error while opening the file.\n");
		exit(EXIT_FAILURE);
	}

	for(m1=0;m1<10;m1++)
	{
		lbl[m1].labels = (char *)malloc(sizeof(char)*10);
	}
	
	register_init();
	instr_init();

	for (c1 = getc(testf); c1 != EOF; c1 = getc(testf)){
        if (c1 == '\n') // Increment count if this character is newline
            flen++;
	}
	fclose(testf);
	//printf("--%d--",flen);
	while( fgets(str,50,fp)!=NULL) //line reading
	{
	
		state='X';
		if(flen==l){
			strcat(str,"\0");
		}
		if((str!="")&&((flen!=l)))
			str[strlen(str)-1]='\0';
		if(strcmp(str,"")==0)
			strcpy(str,"BLANK LINE");
		
		if(l==0)
		{
			if(strlen(str)!=5)
			{
				printf("error in line : %d",l+1);
				errorflag=1;
			}
			strncpy(token1,str,5);//printf( "==%s",token1 );
			if(strcmp(token1,(ins[0].nemo))!=0)
			{
				printf("error in line : %d",l+1);
				errorflag=1;
			}
		}
		
		if(l>0)
		{
			//printf( "%00000007ld\t\t%s\n",madd,str );
			madd+=32;
			state='X';
			token = strtok(str,s); // instruction name
			
			len=strlen(token);
			last=token[len-1];
			if(last==58)
			{
				token[strlen(token)-1]='\0';//printf("--%s\n",token);
				strcpy(lbl[lb].labels,token);
				lbl[lb].mad=(madd-32);
				lb++;	
				token = strtok(NULL,s);
			}

			while( token != NULL )
			{
				
				for(b=1;b<=4;b++)  // data transfer (MOV)
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='T';
						break;
					}
				}
	
				for(b=5;b<=8;b++)  // direct address
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='I';
						break;
					}
				}
				
				for(b=9;b<=15;b++) // arithmatic instruction and AND
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='A';
						id=b;
						break;
					}
				}

				for(b=16;b<=18;b++) // OR types
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						id=b;
						state='O';
						break;
					}
				}

				for(b=19;b<=20;b++)  // NOT
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='N';
						break;
					}
				}
				
				for(b=21;b<=26;b++)  // type INS r1
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='R';
						break;
					}
				}

				if(strcmp(token,(ins[27].nemo))==0) // compare CMP
				{
					state='P';
				}
				for(b=28;b<=36;b++)  // branching instruction
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='B';
						break;
					}
				}
				
				
				for(b=37;b<=40;b++) // machine control instruction
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='C';
					}
				}
		

				
				switch(state)
				{
					case 'A':
						flag1=0;
						token = strtok(NULL,s); // 1st token
						if(token!=NULL){
							for(m=0;m<64;m++)
							{
								if((strcmp(token,regs[m].regi)==0))
								{
									regs[m].used=0;
									token = strtok(NULL,s); // 2nd token
									if(token!=NULL){
										if((token[0]==91)&&(id!=13)&&(token[strlen(token)-1]==93))
										{
											flag1=1;
											token++;
											token[strlen(token)-1]='\0';
											token2 = strtok(NULL,s);
											if(token2 != NULL){
												state='X';
												break;
											}
										}
										
										for(m1=0;m1<64;m1++)
										{
											if((strcmp(token,regs[m1].regi)==0))
											{
												regs[m1].used=0;
												if(flag1==1)
													state='F';
												token = strtok(NULL,s);// 3rd token
												if((token==NULL)&&(id==13))
													state='X';
												if((token!=NULL)){
													for(m2=0;m2<64;m2++){
														if((strcmp(token,regs[m2].regi)==0)){
															regs[m2].used=0;
															state='F';
															break;
														}
														else{
															flag=0;
															state='X';
														}
													}
													token = strtok(NULL,s);
													if(token!=NULL){state='X';break;}
												}
												break;
											}
										}
									}break;
								}
							}
						}
						break;
					case 'T':
						
						token = strtok(NULL,s); // 1st token
						if(token!=NULL){
							if(token[0]==91)
							{
								if(token[strlen(token)-1]!=93)
								{
									state='X';
								}
								token++;
								token[strlen(token)-1]='\0';
							}
							for(m=0;m<64;m++)
							{
								if((strcmp(token,regs[m].regi)==0))
								{
									regs[m].used=0;
									token = strtok(NULL,s); // 2nd token
									if(token!=NULL){
										if(token[0]==91)
										{
											if(token[strlen(token)-1]!=93)
											{
												state='X';
											}
											token++;
											token[strlen(token)-1]='\0';
										}
										if(token[0]==35)
										{
											if(strlen(token)!=1)
												strcpy(lbl[lb++].labels,token);
											else{
												state='X';
												break;
											}
										}
										for(m1=0;m1<64;m1++)
										{
											
											if((strcmp(token,regs[m1].regi)==0)||(token[0]==35))
											{
												if((m1<64)&&(token[0]!=35))
												{
													regs[m1].used=0;
												}
												state='F';
												break;
											}
										}
										token = strtok(NULL,s);
										if(token!=NULL){state='X';break;}
										
									}break;
								}
							}
						}	
						break;
					case 'O':
						flag=0;
						token = strtok(NULL,s); // 1st token
						if(token!=NULL){
							for(m=0;m<64;m++)
							{
								if((strcmp(token,regs[m].regi)==0))
								{
									regs[m].used=0;
									token = strtok(NULL,s); // 2nd token
									if(token!=NULL){
										if(token[0]==91&&(token[strlen(token)-1]==93))
										{
											token++;
											token[strlen(token)-1]='\0';
											flag=2;
											token1 = strtok(NULL,s);
											if(token1 != NULL){state='X';break;}
										}
										for(m1=0;m1<64;m1++)
										{
											if((strcmp(token,regs[m1].regi)==0))
											{
												regs[m1].used=0;
												token = strtok(NULL,s);// 3rd token
												if(token!=NULL){
													for(m2=0;m2<64;m2++){
														if((strcmp(token,regs[m2].regi)==0)){
															regs[m2].used=0;
															state='F';
															break;
														}
														else{
															flag=0;
															state='X';
														}
													}
													token = strtok(NULL,s);
													if(token!=NULL){state='X';break;}
												}
												else
													state='X';
												if(flag!=0){
													state='F';
												}break;
											}
											else
											{
												if((checkHex(token)==1)){
													state='F';
													token1 = strtok(NULL,s);
													if(token1 != NULL){state='X';break;}
												}
											}
										}
									}break;
								}
							}
						}
						break;
					case 'B':
						
						token = strtok(NULL,s); // 1st token-------
						if(token!=NULL){
							state='F';
						}
						token = strtok(NULL,s);
						if(token!=NULL){state='X';}
							
						break;

					case 'P':
						token = strtok(NULL,s); // 1st token
						if(token!=NULL){
							for(m=0;m<64;m++)
							{
								if((strcmp(token,regs[m].regi)==0))
								{	
										regs[m].used=0;
										token = strtok(NULL,s); //2nd token
										if(token!=NULL){
											for(m1=0;m1<64;m1++)
											{
												if((strcmp(token,regs[m1].regi)==0))
												{
													regs[m1].used=0;
													state='F';
												}	
											}
										}
				
										break;
								}
							}
						}
						
					token = strtok(NULL,s);
					if(token!=NULL){state='X';}
					break;

					case 'I':
						
						token = strtok(NULL,s); // 1st token
						if(token!=NULL){
							for(m=0;m<64;m++)
							{
								if((strcmp(token,regs[m].regi)==0))
								{	
										regs[m].used=0;
										break;
								}
							}
						}
						token = strtok(NULL,s); // 2nd token
						if(token!=NULL){
							if(checkHex(token)==1){
								state='F';
							}
						}
						token = strtok(NULL,s);
						if(token!=NULL){state='X';}
							
						break;
					case 'R':
						
						token = strtok(NULL,s); // 1st token
						if(token!=NULL){
							for(m=0;m<64;m++)
							{
								if((strcmp(token,regs[m].regi)==0))
								{	
										regs[m].used=0;
										state='F';
										break;
								}
							}
						}
						token = strtok(NULL,s);
						if(token!=NULL){state='X';}
						break;

					case 'N':
						token = strtok(NULL,s); // 1st token
						if(token!=NULL){
							if(token[0]==91)
								{
									token++;
									token[strlen(token)-1]='\0';
								}
							for(m=0;m<64;m++)
							{
								if((strcmp(token,regs[m].regi)==0))
								{	
										regs[m].used=0;
										state='F';
										break;
								}
							}
						}
						token = strtok(NULL,s);
						if(token!=NULL){state='X';}
						break;

					case 'C':
						state='F';
						token = strtok(NULL,s);
						if(token!=NULL)
							state='X';
							
						break;
					default:
						state='X';	
				}	
				token = strtok(NULL,s);
				if(state!='F')
				{
					printf("\nerror in line : %d",l+1);
					errorflag=1;
				}
				break;
			}
		}
		l++;
	}



	for(m1=0;m1<lb;m1++)
	{
		if(lbl[m1].labels[0]==35)
		{
			lbl[m1].mad=madd;
			madd+=32;
		}
	}

	for(m1=0;m1<lb;m1++)
	{
			//printf("Labels :: %s \t address :: %ld\n",lbl[m1].labels,lbl[m1].mad);
			fprintf(opfp,"%s\t%ld\n",lbl[m1].labels,lbl[m1].mad);
	}

	fclose(fp);
	fclose(opfp);
	strcpy(token3,"pass2.exe ");
	strcat(token3,argv[1]);
	if(errorflag==0)
		system(token3);
	exit(0);
	}
예제 #7
0
std::string
raw2trace_t::append_bb_entries(uint tidx, offline_entry_t *in_entry, OUT bool *handled)
{
    uint instr_count = in_entry->pc.instr_count;
    instr_t instr;
    trace_entry_t buf_start[MAX_COMBINED_ENTRIES];
    app_pc start_pc = modvec[in_entry->pc.modidx].map_base + in_entry->pc.modoffs;
    app_pc pc, decode_pc = start_pc;
    if ((in_entry->pc.modidx == 0 && in_entry->pc.modoffs == 0) ||
        modvec[in_entry->pc.modidx].map_base == NULL) {
        // FIXME i#2062: add support for code not in a module (vsyscall, JIT, etc.).
        // Once that support is in we can remove the bool return value and handle
        // the memrefs up here.
        VPRINT(3, "Skipping ifetch for %u instrs not in a module\n", instr_count);
        *handled = false;
        return "";
    } else {
        VPRINT(3, "Appending %u instrs in bb " PFX " in mod %u +" PIFX " = %s\n",
               instr_count, (ptr_uint_t)start_pc, (uint)in_entry->pc.modidx,
               (ptr_uint_t)in_entry->pc.modoffs, modvec[in_entry->pc.modidx].path);
    }
    bool skip_icache = false;
    if (instr_count == 0) {
        // L0 filtering adds a PC entry with a count of 0 prior to each memref.
        skip_icache = true;
        instr_count = 1;
        // We set a flag to avoid peeking forward on instr entries.
        if (!instrs_are_separate)
            instrs_are_separate = true;
    }
    CHECK(!instrs_are_separate || instr_count == 1, "cannot mix 0-count and >1-count");
    instr_init(dcontext, &instr);
    for (uint i = 0; i < instr_count; ++i) {
        trace_entry_t *buf = buf_start;
        app_pc orig_pc = decode_pc - modvec[in_entry->pc.modidx].map_base +
            modvec[in_entry->pc.modidx].orig_base;
        bool skip_instr = false;
        instr_reset(dcontext, &instr);
        // We assume the default ISA mode and currently require the 32-bit
        // postprocessor for 32-bit applications.
        pc = decode(dcontext, decode_pc, &instr);
        if (pc == NULL || !instr_valid(&instr)) {
            WARN("Encountered invalid/undecodable instr @ %s+" PFX,
                 modvec[in_entry->pc.modidx].path, (ptr_uint_t)in_entry->pc.modoffs);
            break;
        }
        CHECK(!instr_is_cti(&instr) || i == instr_count - 1, "invalid cti");
        if (instr_is_rep_string(&instr)) {
            // We want it to look like the original rep string instead of the
            // drutil-expanded loop.
            if (!prev_instr_was_rep_string)
                prev_instr_was_rep_string = true;
            else
                skip_instr = true;
        } else
            prev_instr_was_rep_string = false;
        // FIXME i#1729: make bundles via lazy accum until hit memref/end.
        if (!skip_instr) {
            DO_VERBOSE(3, {
                instr_set_translation(&instr, orig_pc);
                dr_print_instr(dcontext, STDOUT, &instr, "");
            });
예제 #8
0
/* returns whether found a syscall
 * - found_eax: whether the caller has seen "mov imm => %eax"
 * - found_edx: whether the caller has seen "mov $0x7ffe0300 => %edx",
 *              xref the comment in process_syscall_instr.
 */
static bool
process_syscall_call(void *dcontext, byte *next_pc, instr_t *call,
                     bool found_eax, bool found_edx)
{
    int num_instr;
    byte *pc;
    instr_t instr;
    bool found_syscall = false;

    assert(instr_get_opcode(call) == OP_call && opnd_is_pc(instr_get_target(call)));
    pc = opnd_get_pc(instr_get_target(call));
    if (pc > next_pc + MAX_SYSENTER_CALLEE_OFFSET ||
        pc <= next_pc /* assuming the call won't go backward */)
        return false;
    /* handle win8 x86 which has sysenter callee adjacent-"inlined"
     *     ntdll!NtYieldExecution:
     *     77d7422c b801000000  mov     eax,1
     *     77d74231 e801000000  call    ntdll!NtYieldExecution+0xb (77d74237)
     *     77d74236 c3          ret
     *     77d74237 8bd4        mov     edx,esp
     *     77d74239 0f34        sysenter
     *     77d7423b c3          ret
     *
     * or DrMem-i#1366-c#2
     *     USER32!NtUserCreateWindowStation:
     *     75caea7a b841110000  mov     eax,0x1141
     *     75caea7f e838000000  call    user32!...+0xd (75caeabc)
     *     75caea84 c22000      ret     0x20
     *     ...
     *     USER32!GetWindowStationName:
     *     75caea8c 8bff        mov     edi,edi
     *     75caea8e 55          push    ebp
     *     ...
     *     75caeabc 8bd4        mov     edx,esp
     *     75caeabe 0f34        sysenter
     *     75caeac0 c3          ret
     */
    /* We expect the win8 x86 sysenter adjacent "inlined" callee to be as simple as
     *     75caeabc 8bd4        mov     edx,esp
     *     75caeabe 0f34        sysenter
     *     75caeac0 c3          ret
     */
    instr_init(dcontext, &instr);
    num_instr = 0;
    do {
        instr_reset(dcontext, &instr);
        pc = decode(dcontext, pc, &instr);
        if (verbose)
            dr_print_instr(dcontext, STDOUT, &instr, "");
        if (pc == NULL || !instr_valid(&instr))
            break;
        if (instr_is_syscall(&instr) || instr_is_call_indirect(&instr)) {
            found_syscall = process_syscall_instr(dcontext, &instr, found_eax, found_edx);
            break;
        } else if (instr_is_cti(&instr)) {
            break;
        }
        num_instr++;
    } while (num_instr <= MAX_INSTRS_SYSENTER_CALLEE);
    instr_free(dcontext, &instr);
    return found_syscall;
}
예제 #9
0
static void
module_load_event(void *drcontext, const module_data_t *mod, bool loaded)
{
    if (strstr(dr_module_preferred_name(mod),
               "client.drwrap-test.appdll.") != NULL) {
        bool ok;
        instr_t inst;
        app_pc init_pc, pc, next_pc;

        load_count++;
        if (load_count == 2) {
            /* test no-frills */
            drwrap_set_global_flags(DRWRAP_NO_FRILLS);
        }

        addr_replace = (app_pc) dr_get_proc_address(mod->handle, "replaceme");
        CHECK(addr_replace != NULL, "cannot find lib export");
        ok = drwrap_replace(addr_replace, (app_pc) replacewith, false);
        CHECK(ok, "replace failed");

        addr_replace2 = (app_pc) dr_get_proc_address(mod->handle, "replaceme2");
        CHECK(addr_replace2 != NULL, "cannot find lib export");
        ok = drwrap_replace_native(addr_replace2, (app_pc) replacewith2, true/*at entry*/,
                                   0, (void *)(ptr_int_t)DRWRAP_NATIVE_PARAM, false);
        CHECK(ok, "replace_native failed");

        init_pc = (app_pc) dr_get_proc_address(mod->handle, "replace_callsite");
        CHECK(init_pc != NULL, "cannot find lib export");
        /* Find callsite: we assume we'll linearly hit a ret.  We take final call
         * to skip any PIC call.
         */
        instr_init(drcontext, &inst);
        pc = init_pc;
        do {
            instr_reset(drcontext, &inst);
            next_pc = decode(drcontext, pc, &inst);
            if (!instr_valid(&inst))
                break;
            /* if initial jmp, follow it to handle ILT-indirection */
            if (pc == init_pc && instr_is_ubr(&inst))
                next_pc = opnd_get_pc(instr_get_target(&inst));
            else if (instr_is_call(&inst))
                addr_replace_callsite = pc;
            pc = next_pc;
        } while (instr_valid(&inst) && !instr_is_return(&inst));
        CHECK(addr_replace_callsite != NULL, "cannot find lib export");
        ok = drwrap_replace_native(addr_replace_callsite, (app_pc) replace_callsite,
                                   false/*!at entry*/, 0,
                                   (void *)(ptr_int_t)DRWRAP_NATIVE_PARAM, false);
        CHECK(ok, "replace_native failed");
        instr_free(drcontext, &inst);

        wrap_addr(&addr_level0, "level0", mod, true, true);
        wrap_addr(&addr_level1, "level1", mod, true, true);
        wrap_addr(&addr_level2, "level2", mod, true, true);
        wrap_addr(&addr_tailcall, "makes_tailcall", mod, true, true);
        wrap_addr(&addr_skipme, "skipme", mod, true, true);
        wrap_addr(&addr_repeat, "repeatme", mod, true, true);
        wrap_addr(&addr_preonly, "preonly", mod, true, false);
        wrap_addr(&addr_postonly, "postonly", mod, false, true);
        wrap_addr(&addr_runlots, "runlots", mod, false, true);

        /* test longjmp */
        wrap_unwindtest_addr(&addr_long0, "long0", mod);
        wrap_unwindtest_addr(&addr_long1, "long1", mod);
        wrap_unwindtest_addr(&addr_long2, "long2", mod);
        wrap_unwindtest_addr(&addr_long3, "long3", mod);
        wrap_unwindtest_addr(&addr_longdone, "longdone", mod);
        drmgr_set_tls_field(drcontext, tls_idx, (void *)(ptr_uint_t)0);
#ifdef WINDOWS
        /* test SEH */
        /* we can't do this test for no-frills b/c only one wrap per addr */
        if (load_count == 1) {
            ok = drwrap_wrap_ex(addr_long0, wrap_unwindtest_seh_pre,
                                wrap_unwindtest_seh_post,
                                NULL, DRWRAP_UNWIND_ON_EXCEPTION);
            CHECK(ok, "wrap failed");
            ok = drwrap_wrap_ex(addr_long1, wrap_unwindtest_seh_pre,
                                wrap_unwindtest_seh_post,
                                NULL, DRWRAP_UNWIND_ON_EXCEPTION);
            CHECK(ok, "wrap failed");
            ok = drwrap_wrap_ex(addr_long2, wrap_unwindtest_seh_pre,
                                wrap_unwindtest_seh_post,
                                NULL, DRWRAP_UNWIND_ON_EXCEPTION);
            CHECK(ok, "wrap failed");
            ok = drwrap_wrap_ex(addr_long3, wrap_unwindtest_seh_pre,
                                wrap_unwindtest_seh_post,
                                NULL, DRWRAP_UNWIND_ON_EXCEPTION);
            CHECK(ok, "wrap failed");
            ok = drwrap_wrap_ex(addr_longdone, wrap_unwindtest_seh_pre,
                                wrap_unwindtest_seh_post,
                                NULL, DRWRAP_UNWIND_ON_EXCEPTION);
            CHECK(ok, "wrap failed");
        }
#endif
        /* test leaner wrapping */
        if (load_count == 2)
            drwrap_set_global_flags(DRWRAP_NO_FRILLS | DRWRAP_FAST_CLEANCALLS);
        wrap_addr(&addr_skip_flags, "skip_flags", mod, true, false);
    }
}
예제 #10
0
int main(int argc, char *argv[])
{
	FILE *fp,*opfp,*omc,*mc,*testf;
	int test,n,c,ln,i,m,m1,m2,b,flag=0,len,last,digit=0,var,id=0,f,flen=0;
	long int madd=0;
	char ch,*nem[4],*str,*token,*s=" ",state,*str1,*s1="\t",*token1,*temp,*token2,c1;//*labels[10]

	str = (char *)malloc(sizeof(char)*50);
	str1 = (char *)malloc(sizeof(char)*50);
	token1 = (char *)malloc(sizeof(char)*50);
	token2 = (char *)malloc(sizeof(char)*50);
	register_init();
	instr_init();
	opfp = fopen("stable.txt","r"); 
	if(opfp == NULL) 
	{
		perror("Error while opening the file.\n");
		exit(EXIT_FAILURE);
	}

	//printf("file name %s\n", argv[1]);
	fp = fopen(argv[1],"r"); // opens file
	testf = fopen(argv[1],"r");
	omc = fopen("mcode.txt","w"); 
	mc= fopen("onlymcode.txt","w"); 

	if(fp == NULL)
	{
		perror("Error while opening the file.\n");
		exit(EXIT_FAILURE);
	}
	

	label lbl[10];

	for(m1=0;m1<10;m1++)
	{
		lbl[m1].labels = (char *)malloc(sizeof(char)*10);
	}

	for(m1=0;m1<10;m1++)
	{
		lbl[m1].mad = (char *)malloc(sizeof(char)*10);
	}
	
	while( fgets(str1,50,opfp)!=NULL) 
		{
			token=strtok(str1,s1);
			while(token!=NULL)
			{
				strcpy(lbl[lb].labels,token);
				token=strtok(NULL,s1);
				strcpy(lbl[lb].mad,token);
				token=strtok(NULL,s1);
			}++lb;	
		}

	/*for(m1=0;m1<lb;m1++)
	{
		printf("Labels :: %s \t address :: %s\n",lbl[m1].labels,lbl[m1].mad);
	}
	*/
	for (c1 = getc(testf); c1 != EOF; c1 = getc(testf)){
        if (c1 == '\n') // Increment count if this character is newline
            flen++;
	}
	fclose(testf);
	while( fgets(str,50,fp)!=NULL) //line reading
	{
	
		state='X';
		if(flen==l){
			strcat(str,"\0");
		}
		if((str!="")&&((flen!=l)))
			str[strlen(str)-1]='\0';
		
		
		if(l>0)
		{
			//printf( "\n%00000007ld\t%s",madd,str );
			fprintf(omc,"\n%00000007ld\t%s",madd,str );
			madd+=32;
			state='X';
			token = strtok(str,s); // instruction name
			
			len=strlen(token);
			last=token[len-1];
			if(last==58)
			{
				token = strtok(NULL,s);
			}

			while( token != NULL )
   			{

				for(b=1;b<=4;b++) // MOV
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='M';
						id=b;
						break;
					}
				}
				
				for(b=5;b<=8;b++)  // direct address
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='I';
						//printf("\nMCODE : %s ",ins[b].mcode);
						fprintf(omc,"\nMCODE : %s ",ins[b].mcode);
						fprintf(mc,"\n%s",ins[b].mcode);
						break;
					}
				}
				
				for(b=9;b<=10;b++)  // ADD
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='A';
						id=b;
						break;
					}
				}
				
				for(b=11;b<=13;b++)  // MUL 
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='A';
						id=b;
						break;
					}
				}
				
				for(b=14;b<=15;b++)  // AND
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='A';
						id=b;
						break;
					}
				}

				for(b=16;b<=18;b++)  // OR
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='O';
						break;
					}
				}

				for(b=19;b<=20;b++)  // NOT
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='N';
						id=b;
						break;
					}
				}

				for(b=21;b<=26;b++)  // type INS r1
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						//printf("\nMCODE : %s ",ins[b].mcode);
						fprintf(omc,"\nMCODE : %s ",ins[b].mcode);
						fprintf(mc,"\n%s",ins[b].mcode);
						state='R';
						break;
					}
				}

				if(strcmp(token,(ins[27].nemo))==0) // compare CMP
				{
					id=28;
					state='M';
				}
				for(b=28;b<=36;b++)  // branching instruction JMP
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='B';
						//printf("\nMCODE : %s ",ins[b].mcode);
						fprintf(omc,"\nMCODE : %s ",ins[b].mcode);
						fprintf(mc,"\n%s",ins[b].mcode);
						break;
					}
				}

				for(b=37;b<=40;b++) // machine control instruction
				{
					if(strcmp(token,(ins[b].nemo))==0)
					{
						state='C';
						//printf("\nMCODE : %s  ",ins[b].mcode);
						fprintf(omc,"\nMCODE : %s\n",ins[b].mcode);
						fprintf(mc,"\n%s",ins[b].mcode);
					}
				}	
				
				switch(state)
				{
	
					case 'M':
						token = strtok(NULL,s); // 1st token-------
						if(token!=NULL){
							if(token[0]==91)
							{
								token++;
								token[strlen(token)-1]='\0';
								f=4;
							}
							for(m=0;m<64;m++)
							{
								if((strcmp(token,regs[m].regi)==0))
								{	
									strcpy(token1,regs[m].address);
									strcpy(token2,regs[m].address);
									strcat(token1," ");
									token = strtok(NULL,s); // 2nd token-------
									if(token!=NULL){
										if(token[0]==91)
										{
											token++;
											token[strlen(token)-1]='\0';
											for(m1=0;m1<64;m1++)
											{
												if((strcmp(token,regs[m1].regi)==0))
												{
													strcat(token1,regs[m1].address);
													strcat(token2,regs[m1].address);
													//printf("\nMCODE : %s %s",ins[3].mcode,token1);
													fprintf(omc,"\nMCODE : %s %s\n",ins[3].mcode,token1);
													fprintf(mc,"\n%s%s",ins[3].mcode,token2);
													break;
												}
											}
											token="xx";
										}
										for(m1=0;m1<64;m1++)
										{
											if((strcmp(token,regs[m1].regi)==0))
											{
												if(f!=4)
												{
													strcat(token1,regs[m1].address);
													strcat(token2,regs[m1].address);
													//printf("\nMCODE : %s %s",ins[id].mcode,token1);
													fprintf(omc,"\nMCODE : %s %s\n",ins[id].mcode,token1);
													fprintf(mc,"\n%s%s",ins[id].mcode,token2);
													state='F';
												}
												if(f==4)
												{
													strcat(token1,regs[m1].address);
													strcat(token2,regs[m1].address);
													//printf("\nMCODE : %s %s",ins[4].mcode,token1);
													fprintf(omc,"\nMCODE : %s %s\n",ins[4].mcode,token1);
													fprintf(mc,"\n%s%s",ins[4].mcode,token2);
													f=0;
													state='F';
												}
												break;
											}
											else
											{
												if(token[0]==35)
												{
													for(var=0;var<lb;var++)
													{
														if(strcmp(lbl[var].labels,token)==0)
														{
															lbl[var].mad[strlen(lbl[var].mad)-1]='\0';
															strcat(token1,appendLeft(toBin(atoi(lbl[var].mad))));
															strcat(token2,appendLeft(toBin(atoi(lbl[var].mad))));
															//printf("\nMCODE : %s %s",ins[++id].mcode,token1);
															fprintf(omc,"\nMCODE : %s %s\n",ins[id].mcode,token1);
															fprintf(mc,"\n%s%s",ins[id].mcode,token2);
															token++;
															break;
														}
													}
												}
											}
											
										}
										token = strtok(NULL,s);
										if(token!=NULL){state='X';break;}
										
									}break;
								}
							}
						}	
						
						break;
					case 'I':
						
							token = strtok(NULL,s); // 1st token-------
							if(token!=NULL){
								for(m=0;m<64;m++)
								{
									if((strcmp(token,regs[m].regi)==0))
									{	
										//printf("%s ",regs[m].address);
										fprintf(omc,"%s ",regs[m].address);
										fprintf(mc,"%s",regs[m].address);
										break;
									}
								}
							}
							token = strtok(NULL,s); // 2nd token-------
							//printf("%s",hextoBin(token));
							fprintf(omc,"%s\n",hextoBin(token));
							fprintf(mc,"%s",hextoBin(token));
						break;
					case 'A':
							token = strtok(NULL,s);//1st token
							for(m=0;m<64;m++)
							{
								if((strcmp(token,regs[m].regi)==0))
								{
									strcpy(token1,regs[m].address);
									strcpy(token2,regs[m].address);
									strcat(token1," ");
									token = strtok(NULL,s);//2nd token
									if(token[0]==91)
									{
										token++;
										token[strlen(token)-1]='\0';
										id++;
										f=6;
									}
									for(m1=0;m1<64;m1++)
									{
										if((strcmp(token,regs[m1].regi)==0))
										{
											strcat(token1,regs[m1].address);
											strcat(token2,regs[m1].address);
											if(f==6){
												//printf("\nMCODE : %s %s",ins[id].mcode,token1);
												fprintf(omc,"\nMCODE : %s %s\n",ins[id].mcode,token1);
												fprintf(mc,"\n%s%s",ins[id].mcode,token2);
												f=0;
												break;
											}
											token = strtok(NULL,s);//3rd token
											for(m2=0;m2<64;m2++)
											{
												if((strcmp(token,regs[m2].regi)==0))
												{
													strcat(token1," ");
													strcat(token1,regs[m2].address);
													strcat(token2,regs[m2].address);
													//printf("\nMCODE : %s %s",ins[id].mcode,token1);
													fprintf(omc,"\nMCODE : %s %s\n",ins[id].mcode,token1);
													fprintf(mc,"\n%s%s",ins[id].mcode,token2);
													break;
												}
											}
											break;
										}
									}
									break;
								}
							}
						break;
					case 'O':
							token = strtok(NULL,s);//1st token
							for(m=0;m<64;m++)
							{
								if((strcmp(token,regs[m].regi)==0))
								{
									strcpy(token1,regs[m].address);
									strcpy(token2,regs[m].address);
									strcat(token1," ");
									token = strtok(NULL,s);//2nd token
									if(token[0]==91)
									{
										token++;
										token[strlen(token)-1]='\0';
										id++;
										id++;
										f=6;
									}
									if(checkHex(token)==1)	
									{
										id++;
										//printf("\nMCODE : %s %s %s",ins[id].mcode,token1,hextoBin(token));
										fprintf(omc,"\nMCODE : %s %s %s\n",ins[id].mcode,token1,hextoBin(token));
										fprintf(mc,"\n%s%s%s",ins[id].mcode,token2,hextoBin(token));
										break;
									}
									for(m1=0;m1<64;m1++)
									{
										if((strcmp(token,regs[m1].regi)==0))
										{
											strcat(token1,regs[m1].address);
											strcat(token2,regs[m1].address);
											strcat(token1," ");
											if(f==6){
												//printf("\nMCODE : %s %s",ins[id].mcode,token1);
												fprintf(omc,"\nMCODE : %s %s\n",ins[id].mcode,token1);
												fprintf(mc,"\n%s%s",ins[id].mcode,token2);
												f=0;
												break;
											}
											token = strtok(NULL,s);//3rd token
											for(m2=0;m2<64;m2++)
											{
												if((strcmp(token,regs[m2].regi)==0))
												{
													//puts(token);
													strcat(token1,regs[m2].address);//puts(token1);
													strcat(token2,regs[m2].address);
													//printf("\nMCODE : %s %s",ins[id].mcode,token1);
													fprintf(omc,"\nMCODE : %s %s\n",ins[id].mcode,token1);
													fprintf(mc,"\n%s%s",ins[id].mcode,token2);
													break;
												}
											}
											break;
										}
									}
									break;
								}
							}
						break;
					case 'N':
							token = strtok(NULL,s); // 1st token-------
							if(token!=NULL){
								if(token[0]==91)
								{
									token++;
									token[strlen(token)-1]='\0';
									id++;
								}
								for(m=0;m<64;m++)
								{
									if((strcmp(token,regs[m].regi)==0))
									{	
										//printf("\nMCODE : %s %s",ins[id].mcode,regs[m].address);
										fprintf(omc,"\nMCODE : %s %s\n",ins[id].mcode,regs[m].address);
										fprintf(mc,"\n%s%s",ins[id].mcode,regs[m].address);
										break;
									}
								}
							}
						break;
					case 'R':
							token = strtok(NULL,s); // 1st token-------
							if(token!=NULL){
								for(m=0;m<64;m++)
								{
									if((strcmp(token,regs[m].regi)==0))
									{	
										//printf("%s",regs[m].address);
										fprintf(omc,"%s\n",regs[m].address);
										fprintf(mc,"%s",regs[m].address);
										break;
									}
								}
							}
						break;
					case 'B':
						token = strtok(NULL,s); // 1st token-------
						if(token!=NULL){
							for(m1=0;m1<lb;m1++)
							{
								if(strcmp(lbl[m1].labels,token)==0)
								{
									lbl[m1].mad[strlen(lbl[m1].mad)-1]='\0';
									//printf("%s",appendLeft(toBin(atoi(lbl[m1].mad))));
									fprintf(omc,"%s\n",appendLeft(toBin(atoi(lbl[m1].mad))));
									fprintf(mc,"%s",appendLeft(toBin(atoi(lbl[m1].mad))));
									break;
								}
									if(m1==lb-1)
									{
										printf("\nError in code!!No lebel found in jump instruction at line %d !! Exit from program !!",l+1);
										exit(0);
									}
							}
							if(lb==0)
							{
								printf("\nError in code!!No lebel found in jump instruction at line %d !! Exit from program !!",l+1);
								exit(0);
							}
						}
						break;

					default:
						state='X';	
				}	
				token = strtok(NULL,s);
				break;
			}
		}
		l++;
	}
	printf("compilation successful :D ");
	fclose(fp);
	fclose(opfp);
	fclose(mc);
	append();
	return 0;
}
예제 #11
0
/* Here we attempt to combine a loop involving ldex (load exclusive) and
 * stex (store exclusive) into an OP_ldstex macro-instruction. The algorithm
 * is roughly this:
 *
 * Decode up to (2 * N) instructions while:
 * - none of them are indirect branches or system calls
 * - none of them is a direct branch out of these (2 * N) instructions
 * - none of them is OP_xx (to be safe)
 * - there is, or might yet be, both ldex and stex in the first N
 * - none of them is a non-branch PC-relative instruction: ADR, ADRP,
 *   PC-relative PRFM, literal load (this last condition could be removed
 *   if we mangled such instructions as we encountered them)
 *
 * To save time, give up if the first instruction is neither ldex nor stex
 * and there is no branch to it.
 * Take a sub-block containing both ldex and stex from the first N instructions.
 * Expand this sub-block to a minimal single-entry single-exit block.
 * Give up if the sub-block grows beyond N instructions.
 * Finally, give up if the sub-block does not contain the first instruction.
 * Also give up if the sub-block uses all of X0-X5 and the stolen register
 * because we would be unable to mangle such a block.
 *
 * XXX: This function uses a lot of CPU time. It could be made faster in
 * several ways, for example by caching decoded instructions or using a
 * custom decoder to recognise the particular instructions that we care
 * about here.
 */
byte *
decode_ldstex(dcontext_t *dcontext, byte *pc_, byte *orig_pc_, instr_t *instr_ldstex)
{
# define N (MAX_INSTR_LENGTH / AARCH64_INSTR_SIZE)
    instr_t ibuf[2 * N];
    uint *pc = (uint *)pc_;
    uint *orig_pc = (uint *)orig_pc_;
    bool seen_ldex = false;
    bool seen_stex = false;
    bool seen_branch_to_start = false;
    bool failed = false;
    int ldstex_beg = -1;
    int ldstex_end = -1;
    int i, len;

    /* Decode up to 2 * N instructions. */
    for (i = 0; i < N; i++) {
        instr_t *instr = &ibuf[i];
        instr_init(dcontext, instr);
        decode_from_copy(dcontext, (byte *)(pc + i), (byte *)(orig_pc + i), instr);
        if (instr_is_mbr_arch(instr) || instr_is_syscall(instr) ||
            instr_get_opcode(instr) == OP_xx || instr_is_nonbranch_pcrel(instr))
            break;
        if (instr_is_ubr_arch(instr) || instr_is_cbr_arch(instr)) {
            ptr_uint_t target = (ptr_uint_t)instr_get_branch_target_pc(instr);
            if (target < (ptr_uint_t)pc || target > (ptr_uint_t)(pc + 2 * N))
                break;
            if (target == (ptr_uint_t)pc)
                seen_branch_to_start = true;
        }
        if (instr_is_exclusive_load(instr))
            seen_ldex = true;
        if (instr_is_exclusive_store(instr))
            seen_stex = true;
        if (i + 1 >= N && !(seen_ldex && seen_stex))
            break;
        if (ldstex_beg == -1 && (seen_ldex || seen_stex))
            ldstex_beg = i;
        if (ldstex_end == -1 && (seen_ldex && seen_stex))
            ldstex_end = i + 1;
    }
    if (i < N) {
        instr_reset(dcontext, &ibuf[i]);
        len = i;
    } else
        len = N;

    /* Quick check for hopeless situations. */
    if (len == 0 || !(seen_ldex && seen_stex) ||
        !(seen_branch_to_start || (instr_is_exclusive_load(&ibuf[0]) ||
                                   instr_is_exclusive_store(&ibuf[0])))) {
        for (i = 0; i < len; i++)
            instr_reset(dcontext, &ibuf[i]);
        return NULL;
    }

    /* There are several ways we could choose a sub-block containing both ldex
     * and stex from the first N instructions. Investigate further, perhaps.
     * We have already set ldstex_beg and ldstex_end.
     */
    ASSERT(ldstex_beg != -1 && ldstex_end != -1 && ldstex_beg < ldstex_end);

    /* Expand ldstex sub-block until it is a single-entry single-exit block. */
    for (;;) {
        int new_beg = ldstex_beg;
        int new_end = ldstex_end;
        for (i = ldstex_beg; i < ldstex_end; i++) {
            instr_t *instr = &ibuf[i];
            if (instr_is_ubr_arch(instr) || instr_is_cbr_arch(instr)) {
                int target = (uint *)instr_get_branch_target_pc(instr) - pc;
                if (target > len) {
                    failed = true;
                    break;
                }
                if (target < new_beg)
                    new_beg = target;
                if (target > new_end)
                    new_end = target;
            }
        }
        if (new_beg == ldstex_beg && new_end == ldstex_end)
            break;
        ldstex_beg = new_beg;
        ldstex_end = new_end;
    }

    if (ldstex_beg != 0)
        failed = true;

    if (!failed) {
        /* Check whether the sub-block uses the stolen register and all of X0-X5.
         * If it does, it would be impossible to mangle it so it is better not to
         * create an OP_ldstex.
         */
        reg_id_t regs[] = { dr_reg_stolen,
                            DR_REG_X0, DR_REG_X1, DR_REG_X2,
                            DR_REG_X3, DR_REG_X4, DR_REG_X5 };
        int r;
        for (r = 0; r < sizeof(regs) / sizeof(*regs); r++) {
            for (i = ldstex_beg; i < ldstex_end; i++) {
                if (instr_uses_reg(&ibuf[i], regs[r]))
                    break;
            }
            if (i >= ldstex_end)
                break;
        }
        if (r >= sizeof(regs) / sizeof(*regs))
            failed = true;
    }

    if (!failed) {
        instr_create_ldstex(dcontext, ldstex_end - ldstex_beg,
                            pc + ldstex_beg, &ibuf[ldstex_beg], instr_ldstex);
    }

    for (i = 0; i < len; i++)
        instr_reset(dcontext, &ibuf[i]);
    return failed ? NULL : (byte *)(pc + ldstex_end);
}