예제 #1
0
DWORD Detour_c::SetupDetour(void)
{
	BYTE* CurrOpcode = (BYTE*)dwOldAddress;
	OpcodeLen = oplen(CurrOpcode);
	CurrOpcode += OpcodeLen;
	while(OpcodeLen < 5)
	{
		int Len = oplen(CurrOpcode);
		if(!Len)
			return 0;

		OpcodeLen += Len;
		CurrOpcode += Len;
	}

	if(VirtualProtect((PVOID)dwOldAddress, OpcodeLen, PAGE_EXECUTE_READWRITE, &dwTempProtect[0]) == FALSE)
		return 0;

	RtlCopyMemory((PVOID)PatchBackup, (PVOID)dwOldAddress, OpcodeLen);

	*(BYTE*) (dwOldAddress + 0) = 0xE9;
	*(DWORD*)(dwOldAddress + 1) = dwMyAddress - dwOldAddress - 5;

	for(int i=5; i < OpcodeLen; i++)
		*(BYTE*) (dwOldAddress + i) = 0x90;		// NOP;

	if(VirtualProtect((PVOID)dwOldAddress, OpcodeLen, dwTempProtect[0], &dwTempProtect[1]) == FALSE)
		return 0;

	dwNewAddress = (DWORD)VirtualAlloc(NULL, OpcodeLen + 6, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	if(dwNewAddress == NULL)
		return 0;

	RtlCopyMemory((PVOID)dwNewAddress, (PVOID)PatchBackup, OpcodeLen);
	*(BYTE*) (dwNewAddress + OpcodeLen + 0) = 0xE9;
	*(DWORD*)(dwNewAddress + OpcodeLen + 1) = (dwOldAddress +  OpcodeLen) - (dwNewAddress + OpcodeLen + 5);

	return dwNewAddress;
}
예제 #2
0
파일: syntax.c 프로젝트: ezrec/vasm
static void stab_entry(char *name,int type,int othr,int desc,char *s)
{
  section *stabs;

  if (!(stabs = find_section(stabname,stabattr))) {
    section *str;
    dblock *db;

    stabs = new_section(stabname,stabattr,4);
    if (!(str = find_section(stabstrname,stabstrattr))) {
      str = new_section(stabstrname,stabstrattr,1);
    }
    else {
      if (str->pc != 0)
        ierror(0);
    }
    /* first byte of .stabstr is 0 */
    add_atom(str,new_space_atom(number_expr(1),1,0)); 
    /* compilation unit header has to be patched by output module */
    new_stabstr(getfilename());
    db = new_dblock();
    db->size = 12;
    db->data = mymalloc(12);
    add_atom(stabs,new_data_atom(db,1));
  }

  add_const_datadef(stabs,name?new_stabstr(name):0,32,1);
  add_const_datadef(stabs,type,8,1);
  add_const_datadef(stabs,othr,8,1);
  add_const_datadef(stabs,desc,16,1);
  if (s) {
    operand *op = new_operand();
    int len = oplen(skip_operand(s),s);

    if (parse_operand(s,len,op,DATA_OPERAND(32))) {
      atom *a = new_datadef_atom(32,op);

      a->align = 1;
      add_atom(stabs,a);
    }
    else
      syntax_error(8);
  }
  else
    add_atom(stabs,new_space_atom(number_expr(4),1,0));  /* no value */
}
예제 #3
0
int CDetour::GetDetourLenAuto ( BYTE * &orig, int iMinLen )
{
	int		tmpLen = 0;
	BYTE	*pCurOp = orig;

	while ( tmpLen < iMinLen )
	{
		int i = oplen( pCurOp );

		if ( i == 0 || i == -1 )
			return false;

		tmpLen += i;
		pCurOp += i;
	}

	return tmpLen;
}
예제 #4
0
파일: syntax.c 프로젝트: ezrec/vasm
void parse(void)
{
  char *s,*line,*ext[MAX_QUALIFIERS?MAX_QUALIFIERS:1],*op[MAX_OPERANDS];
  char *labname,*start;
  int inst_len,ext_len[MAX_QUALIFIERS?MAX_QUALIFIERS:1],op_len[MAX_OPERANDS];
  int ext_cnt,op_cnt;
  instruction *ip;

  while (line=read_next_line()){
    if (clev >= MAXCONDLEV)
      syntax_error(16,clev);  /* nesting depth exceeded */

    if (!cond[clev]) {
      /* skip source until ELSE or ENDIF */
      int idx;

      s = line;
      idx = check_directive(&s);
      if (idx >= 0) {
        if (!strncmp(directives[idx].name,"if",2)) {
          ifnesting++;
        }
        else if (ifnesting==0 && !strncmp(directives[idx].name,"else",4)) {
          cond[clev] = 1;
        }
        else if (directives[idx].func == handle_endif) {
          if (ifnesting == 0) {
            if (clev > 0)
              clev--;
            else
              syntax_error(14);  /* endif without if */
          }
          else
            ifnesting--;
        }
      }
      continue;
    }

    s=skip(line);

    if(handle_directive(s))
      continue;

    /* skip spaces */
    s=skip(s);
    if(!*s||*s==commentchar)
      continue;

    /* check for label */
    start=s;
    if(labname=get_local_label(&s)){   /* local label? */
      if(*s!=':'){
        s=start;
        myfree(labname);
        labname=NULL;
      }
    }
    else if(ISIDSTART(*s)){            /* or global label? */
      s++;
      while(ISIDCHAR(*s)) s++;
      if(*s!=':')
        s=start;
      else
        labname=cnvstr(start,s-start);
    }
    if(labname){
      /* we have found a valid global or local label */
      add_atom(0,new_label_atom(new_labsym(0,labname)));
      s=skip(s+1);
      myfree(labname);
    }

    if(!*s||*s==commentchar)
      continue;

    s=skip(parse_cpu_special(s));
    if(*s==0||*s==commentchar)
      continue;

    if(handle_directive(s))
      continue;

    /* read mnemonic name */
    start=s;
    ext_cnt=0;
    if(!ISIDSTART(*s)){
      syntax_error(10);
      continue;
    }
#if MAX_QUALIFIERS==0
    while(*s&&!isspace((unsigned char)*s))
      s++;
    inst_len=s-start;
#else
    s=parse_instruction(s,&inst_len,ext,ext_len,&ext_cnt);
#endif
    s=skip(s);

    if(execute_macro(start,inst_len,ext,ext_len,ext_cnt,s,clev))
      continue;

    /* read operands, terminated by comma (unless in parentheses)  */
    op_cnt=0;
    while(*s&&*s!=commentchar&&op_cnt<MAX_OPERANDS){
      op[op_cnt]=s;
      s=skip_operand(s);
      op_len[op_cnt]=oplen(s,op[op_cnt]);
#if !ALLOW_EMPTY_OPS
      if(op_len[op_cnt]<=0)
        syntax_error(5);
      else
#endif
        op_cnt++;
      s=skip(s);
      if(*s!=','){
        break;
      }else{
        s=skip(s+1);
      }
    }      
    s=skip(s);
    if(*s!=0&&*s!=commentchar) syntax_error(6);
    ip=new_inst(start,inst_len,op_cnt,op,op_len);
#if MAX_QUALIFIERS>0
    if(ip){
      int i;
      for(i=0;i<ext_cnt;i++)
        ip->qualifiers[i]=cnvstr(ext[i],ext_len[i]);
      for(;i<MAX_QUALIFIERS;i++)
        ip->qualifiers[i]=0;
    }
#endif
    if(ip){
      add_atom(0,new_inst_atom(ip));
    }else
      ;
  }

  if (clev > 0)
    syntax_error(15);  /* if without endif */
}
예제 #5
0
파일: syntax.c 프로젝트: kusma/vasm
void parse(void)
{
  char *s,*line,*inst;
  char *ext[MAX_QUALIFIERS?MAX_QUALIFIERS:1];
  char *op[MAX_OPERANDS];
  int ext_len[MAX_QUALIFIERS?MAX_QUALIFIERS:1];
  int op_len[MAX_OPERANDS];
  int ext_cnt,op_cnt,inst_len;
  instruction *ip;

  while (line = read_next_line()) {

    if (!cond_state()) {
      /* skip source until ELSE or ENDIF */
      int idx = -1;

      s = skip(line);
      if (labname = parse_labeldef(&s,1)) {
        if (*s == ':')
          s++;  /* skip double-colon */
        myfree(labname);
        s = skip(s);
      }
      else {
        if (inst = skip_identifier(s)) {
          inst = skip(inst);
          idx = check_directive(&inst);
        }
      }
      if (idx < 0)
        idx = check_directive(&s);
      if (idx >= 0) {
        if (directives[idx].func == handle_if)
          cond_skipif();
        else if (directives[idx].func == handle_else)
          cond_else();
        else if (directives[idx].func == handle_endif)
          cond_endif();
      }
      continue;
    }

    s = skip(line);
again:
    if (*s=='\0' || *line=='*' || *s==commentchar)
      continue;

    if (labname = parse_labeldef(&s,1)) {
      /* we have found a valid global or local label */
      symbol *sym = new_labsym(0,labname);

      if (*s == ':') {
        /* double colon automatically declares label as exported */
        sym->flags |= EXPORT;
        s++;
      }
      add_atom(0,new_label_atom(sym));
      myfree(labname);
      s = skip(s);
    }
    else {
      /* there can still be a sym. in the 1st fld and an assignm. directive */
      inst = s;
      labname = parse_symbol(&s);
      if (labname == NULL) {
        syntax_error(10);  /* identifier expected */
        continue;
      }
      s = skip(s);

      /* Now we have labname pointing to the first field in the line
         and s pointing to the second. Find out where the directive is. */
      if (!ISEOL(s)) {
#ifdef PARSE_CPU_LABEL
        if (PARSE_CPU_LABEL(labname,&s)) {
          myfree(labname);
          continue;
        }
#endif
        if (handle_directive(s)) {
          myfree(labname);
          continue;
        }
      }

      /* directive or mnemonic must be in the first field */
      myfree(labname);
      s = inst;
    }

    if (!strnicmp(s,".iif",4) || !(strnicmp(s,"iif",3))) {
      /* immediate conditional assembly: parse line after ',' when true */
      s = skip(*s=='.'?s+4:s+3);
      if (do_cond(&s)) {
        s = skip(s);
        if (*s == ',') {
          s = skip(s+1);
          goto again;
        }
        else
          syntax_error(0);  /* malformed immediate-if */
      }
      continue;
    }

    /* check for directives */
    s = parse_cpu_special(s);
    if (ISEOL(s))
      continue;

    if (handle_directive(s))
      continue;

    /* read mnemonic name */
    inst = s;
    ext_cnt = 0;
    if (!ISIDSTART(*s)) {
      syntax_error(10);  /* identifier expected */
      continue;
    }
#if MAX_QUALIFIERS==0
    while (*s && !isspace((unsigned char)*s))
      s++;
    inst_len = s - inst;
#else
    s = parse_instruction(s,&inst_len,ext,ext_len,&ext_cnt);
#endif
    if (!isspace((unsigned char)*s) && *s!='\0')
      syntax_error(2);  /* no space before operands */
    s = skip(s);

    if (execute_macro(inst,inst_len,ext,ext_len,ext_cnt,s))
      continue;

    /* read operands, terminated by comma or blank (unless in parentheses) */
    op_cnt = 0;
    while (!ISEOL(s) && op_cnt<MAX_OPERANDS) {
      op[op_cnt] = s;
      s = skip_operand(s);
      op_len[op_cnt] = oplen(s,op[op_cnt]);
#if !ALLOW_EMPTY_OPS
      if (op_len[op_cnt] <= 0)
        syntax_error(5);  /* missing operand */
      else
#endif
        op_cnt++;
      s = skip(s);
      if (*s != ',')
        break;
      else
        s = skip(s+1);
    }
    eol(s);

    ip = new_inst(inst,inst_len,op_cnt,op,op_len);

#if MAX_QUALIFIERS>0
    if (ip) {
      int i;

      for (i=0; i<ext_cnt; i++)
        ip->qualifiers[i] = cnvstr(ext[i],ext_len[i]);
      for(; i<MAX_QUALIFIERS; i++)
        ip->qualifiers[i] = NULL;
    }
#endif

    if (ip)
      add_atom(0,new_inst_atom(ip));
  }

  cond_check();  /* check for open conditional blocks */
}
예제 #6
0
파일: cpu.c 프로젝트: kusma/vasm
/* Convert an instruction into a DATA atom including relocations,
   if necessary. */
dblock *eval_instruction(instruction *p,section *sec,taddr pc)
{
  dblock *db=new_dblock();
  int c,sz,enc,cc,ww,m=0;
  unsigned long code,code2,code3;
  rlist *relocs=0;

  if(p->qualifiers[0]){
    int i;
    for(i=0;i<15;i++){
      if(!strcmp(p->qualifiers[0],ccs[i])){
	cc=i;
	break;
      }
    }
    if(i>15) ierror(0);
  }else
    cc=14;

  c=translate(p,sec,pc);
  enc=mnemonics[c].ext.encoding;

  db->size=sz=oplen(enc);
  db->data=mymalloc(db->size);

  code=mnemonics[c].ext.code;

  switch(enc){
  case EN_ARITHR16:
    if(cc!=14) cpu_error(3);
    code=0x40000000|(code<<24);
    code|=(p->op[0]->reg<<16)|(p->op[1]->reg<<20);
    break;
  case EN_ARITHI16:
    if(cc!=14) cpu_error(3);
    code=0x60000000|((code>>1)<<25);
    code|=(p->op[0]->reg<<16)|(absval(p->op[1]->offset,sec,pc,5,0)<<20);
    break;
  case EN_FIX16:
    if(cc!=14) cpu_error(3);
    break;
  case EN_IBRANCH16:
    if(cc!=14) cpu_error(3);
    code|=(p->op[0]->reg<<16);
    break;
  case EN_RBRANCH16:
    code=0x18000000;
    code|=cc<<23;
    code|=((reloffset(p->op[0]->offset,sec,pc,&relocs,0,7,0xfe)>>1)&127)<<16;
    break;
  case EN_MREG16:
    if(cc!=14) cpu_error(3);
    code|=(p->op[0]->dreg<<21)|(p->op[0]->reg<<16);
    break;
  case EN_RBRANCH32:
    if(code==0x90000000)
      code|=cc<<24;
    else
      code|=((reloffset(p->op[0]->offset,sec,pc,&relocs,8,4,0xF000000)>>24)&0xf)<<24;
    code|=((reloffset(p->op[0]->offset,sec,pc,&relocs,16,16,0x1fffe)>>1)&0x7fffff);
    code|=((reloffset(p->op[0]->offset,sec,pc,&relocs,0,7,0xfe0000)>>17)&0x7f)<<16;
    break;
  case EN_FUNARY32:
    code=0xC0000040|(code<<21);
    code|=p->op[0]->reg<<16;
    code|=p->op[1]->reg<<11;
    code|=cc<<7;
    break;
  case EN_ARITHR32:
    code=0xC0000000|(code<<21);
    code|=p->op[0]->reg<<16;
    if(p->op[2]){
      code|=p->op[1]->reg<<11;
      code|=p->op[2]->reg;
    }else{
      code|=p->op[0]->reg<<11;
      code|=p->op[1]->reg;
    }      
    code|=cc<<7;
    break;
  case EN_ARITHI32:
    code=0xC0000040|(code<<21);
    code|=p->op[0]->reg<<16;
    if(p->op[2]){
      code|=p->op[1]->reg<<11;
      code|=absval(p->op[2]->offset,sec,pc,6,1);
    }else{
      code|=p->op[0]->reg<<11;
      code|=absval(p->op[1]->offset,sec,pc,6,1);
    }
    code|=cc<<7;
    break;
  case EN_ADDCMPB64:
    // Large offset: invert CC, place a long branch after
    // so we really generate the following:
    //   addcmpb<~cc> d, a, b, skip
    //   b <destination>
    // skip:
    //   <rest of code>
    m=1;
    if(cc&1) cc--; else cc++;
  case EN_ADDCMPB32:
    code=0x80000000|(code<<14);
    code|=cc<<24;
    code|=p->op[0]->reg<<16;
    if(code&0x4000){
      code|=absval(p->op[1]->offset,sec,pc,4,1)<<20;
    }else{
      code|=p->op[1]->reg<<20;
    }
    if(code&0x8000){
      code|=absval(p->op[2]->offset,sec,pc,6,0)<<8;
      if(m)
	code|=4;
      else
	code|=((reloffset(p->op[3]->offset,sec,pc,&relocs,16,9,0x1ff)>>1)&0xff);
    }else{