示例#1
0
文件: VSM.c 项目: mikoim/funstuff
void DumpIseg(int first, int last)               /* Display Iseg */
{
  printf("\nContents of Instruction Segment\n");
  for (; first<=last; first++)
    PrintIns(first),  printf("\n");
  printf("\n");
}
示例#2
0
文件: VSM.c 项目: mikoim/funstuff
void SetI(OP OpCode, int F, int Addr)            /* write instruction*/
{
    Iseg[Pctr].Op = OpCode;                      /* opcode */
    Iseg[Pctr].Reg = F;                          /* register flag */
    Iseg[Pctr].Addr = Addr;                      /* address */
    if (DebugSW) {
      PrintIns(Pctr); printf("\n"); }
    if (++Pctr > MaxPC) MaxPC = Pctr;            /* Too long program... */
}
示例#3
0
VOID Ins( INS ins, VOID *v )
{
    if (KnobDetach > 0 && scount > KnobDetach)
        return;

    if (KnobLog)
    {
        void *addr = Addrint2VoidStar(INS_Address(ins));
        string disasm = INS_Disassemble(ins);
        PrintIns(addr, disasm.c_str());
    }

    scount++;

    // call and return need also stack manipulation (see emu_stack.cpp)
    // conditional jumps need handling the condition (not supported yet)
    if (INS_IsCall(ins) || INS_IsRet(ins) || INS_Category(ins) == XED_CATEGORY_COND_BR)
        return;

    if (INS_IsIndirectBranchOrCall(ins))
    {
        INS_InsertCall(ins, IPOINT_BEFORE,
            AFUNPTR(EmuIndJmp),
            IARG_BRANCH_TARGET_ADDR,
            IARG_RETURN_REGS, scratchReg, IARG_END);

        INS_InsertIndirectJump(ins, IPOINT_AFTER, scratchReg);

        INS_Delete(ins);
    }
    else if (INS_IsDirectBranchOrCall(ins))
    {
        ADDRINT tgt = INS_DirectBranchOrCallTargetAddress(ins);

        INS_InsertDirectJump(ins, IPOINT_AFTER, tgt);

        INS_Delete(ins);
    }
}
示例#4
0
文件: VSM.c 项目: mikoim/funstuff
int StartVSM(int StartAddr, int TraceSW)         /* Start VSM */
{
  int addr, op;

  Pctr = StartAddr;                              /* Set Pctr */
  SP = Freg = 0;                                 /* Set register flag */
  while (1) {
    if (SP >= STACK_SIZE || SP < 0) {            /* check the range of stack pointer */
      fprintf(stderr, "Illegal Stack pointer %d\n", SP);
      return -1; }
    op   = Iseg[Pctr].Op;                        /* fetch instruction */
    addr = Iseg[Pctr].Addr;                      /* calculate effective address */
    if (Iseg[Pctr++].Reg & FP)                   /* FP register modification */
      addr += Freg;                              /* add FP */
    InsCount++;                                  /* Increment the number of instructions */
    if (SP > MaxSD) MaxSD = SP;                  /* check the max SP value */
    if (TraceSW) {                               /* if trace flag is on, make trace */
      PrintIns(Pctr-1);
      printf("%15d %5d %12d\n", addr, SP, Stack[SP]); }
    switch (op) {                                /* execute each instruction */
      case NOP:                                              continue;
      case ASSGN:  addr = Stack[--SP];
                   Dseg[addr] = Stack[SP] = Stack[SP+1];     continue;
      case ADD:    BINOP(+);                                 continue;
      case SUB:    BINOP(-);                                 continue;
      case MUL:    BINOP(*);                                 continue;
      case DIV:    if (Stack[SP] == 0) {
                     yyerror("Zero divider detected"); return -2; }
                   BINOP(/);                                 continue;
      case MOD:    if (Stack[SP] == 0) {
                     yyerror("Zero divider detected"); return -2; }
                   BINOP(%);                                 continue;
      case CSIGN:  Stack[SP] = -Stack[SP];                   continue;
      case AND:    BINOP(&&);                                continue;
      case OR:     BINOP(||);                                continue;
      case NOT:    Stack[SP] = !Stack[SP];                   continue;
      case COMP:   Stack[SP-1] = Stack[SP-1] > Stack[SP] ? 1 :
                                 Stack[SP-1] < Stack[SP] ? -1 : 0;
                   SP--;                                     continue;
      case COPY:   ++SP; Stack[SP] = Stack[SP-1];            continue;
      case PUSH:   Stack[++SP] = Dseg[addr];                 continue;
      case PUSHI:  Stack[++SP] = addr;                       continue;
      case REMOVE: --SP;                                     continue;
      case POP:    Dseg[addr] = Stack[SP--];                 continue;
      case INC:    Stack[SP] = ++Stack[SP];                  continue;
      case DEC:    Stack[SP] = --Stack[SP];                  continue;
      case SETFR:  Freg = addr;                              continue;
      case INCFR : if ((Freg += addr) >= DSEG_SIZE) {
                     printf("Freg overflow at loc. %d\n", Pctr-1);
                     return -3; }                            continue;
      case DECFR : Freg -= addr;
                   if (Freg < MinFR) MinFR = Freg;           continue;
      case JUMP:   Pctr = addr;           continue;
      case BLT:    if (Stack[SP--] <  0) Pctr = addr;        continue; 
      case BLE:    if (Stack[SP--] <= 0) Pctr = addr;        continue; 
      case BEQ:    if (Stack[SP--] == 0) Pctr = addr;        continue; 
      case BNE:    if (Stack[SP--] != 0) Pctr = addr;        continue; 
      case BGE:    if (Stack[SP--] >= 0) Pctr = addr;        continue; 
      case BGT:    if (Stack[SP--] >  0) Pctr = addr;        continue; 
      case CALL:   Stack[++SP] = Pctr; Pctr = addr; CallC++; continue;
      case RET:    Pctr = Stack[SP--];                       continue;
      case HALT:                                             return 0;
      case INPUT:  scanf("%d", &Dseg[Stack[SP--]]);          continue;
      case OUTPUT: printf("%15d\n", Stack[SP--]);            continue;
      default:
        printf("Illegal Op. code at location %d\n", Pctr);   return -4;
      }
  }
}
示例#5
0
VOID Ins( INS ins, VOID *v )
{
    if (KnobDetach > 0 && scount > KnobDetach)
        return;

    if (KnobLog)
    {
        void *addr = Addrint2VoidStar(INS_Address(ins));
        string disasm = INS_Disassemble(ins);
        PrintIns(addr, disasm.c_str());
    }

    scount++;

    if (INS_Opcode(ins) == XED_ICLASS_PUSH)
    {
        if (INS_OperandIsImmediate(ins, 0))
        {
            ADDRINT value = INS_OperandImmediate(ins, 0);
            INS_InsertCall(ins, IPOINT_BEFORE,
                AFUNPTR(EmuPushValue),
                IARG_REG_VALUE, REG_STACK_PTR,
                IARG_ADDRINT, value,
                IARG_RETURN_REGS, REG_STACK_PTR, IARG_END);

            INS_Delete(ins);
        }
        else if(INS_OperandIsReg(ins, 0))
        {
            REG reg = INS_OperandReg(ins, 0);
            INS_InsertCall(ins, IPOINT_BEFORE,
                AFUNPTR(EmuPushValue),
                IARG_REG_VALUE, REG_STACK_PTR,
                IARG_REG_VALUE, reg,
                IARG_RETURN_REGS, REG_STACK_PTR, IARG_END);

            INS_Delete(ins);
        }
        else if(INS_OperandIsMemory(ins, 0))
        {
            INS_InsertCall(ins, IPOINT_BEFORE,
                AFUNPTR(EmuPushMem),
                IARG_REG_VALUE, REG_STACK_PTR,
                IARG_MEMORYREAD_EA,
                IARG_RETURN_REGS, REG_STACK_PTR, IARG_END);

            INS_Delete(ins);
        }
        else
        {
            fprintf(stderr, "EmuPush: unsupported operand type (%p:'%s')\n", 
                Addrint2VoidStar(INS_Address(ins)), INS_Disassemble(ins).c_str());
        }
    } 
    else if (INS_Opcode(ins) == XED_ICLASS_POP)
    {
        if(INS_OperandIsReg(ins, 0))
        {
            INS_InsertCall(ins, IPOINT_BEFORE,
                AFUNPTR(EmuPopReg),
                IARG_REG_VALUE, REG_STACK_PTR,
                IARG_REG_REFERENCE, INS_OperandReg(ins, 0),
                IARG_RETURN_REGS, REG_STACK_PTR, IARG_END);

            INS_Delete(ins);
        }
        else if(INS_OperandIsMemory(ins, 0))
        {
            INS_InsertCall(ins, IPOINT_BEFORE,
                AFUNPTR(EmuPopMem),
                IARG_REG_VALUE, REG_STACK_PTR,
                IARG_MEMORYWRITE_EA,
                IARG_RETURN_REGS, REG_STACK_PTR, IARG_END);

            INS_Delete(ins);
        }
        else
        {
            fprintf(stderr, "EmuPop: unsupported operand type (%p:'%s')\n", 
                Addrint2VoidStar(INS_Address(ins)), INS_Disassemble(ins).c_str());
        }
    }
    else if (INS_Opcode(ins) == XED_ICLASS_LEAVE)
    {
        INS_InsertCall(ins, IPOINT_BEFORE,
            AFUNPTR(EmuLeave),
            IARG_REG_VALUE, REG_STACK_PTR,
            IARG_REG_REFERENCE, REG_GBP,
            IARG_RETURN_REGS, REG_STACK_PTR, IARG_END);

        INS_Delete(ins);
    }
    else if (INS_IsCall(ins))
    {
        INS_InsertCall(ins, IPOINT_BEFORE,
            AFUNPTR(EmuCall),
            IARG_ADDRINT, INS_NextAddress(ins),
            IARG_BRANCH_TARGET_ADDR,
            IARG_REG_REFERENCE, REG_STACK_PTR,
            IARG_RETURN_REGS, scratchReg, IARG_END);

        INS_InsertIndirectJump(ins, IPOINT_AFTER, scratchReg);

        INS_Delete(ins);
    }
    else if (INS_IsRet(ins))
    {
        UINT64 imm = 0;
        if (INS_OperandCount(ins) > 0 && INS_OperandIsImmediate(ins, 0))
        {
            imm = INS_OperandImmediate(ins, 0);
        }

        INS_InsertCall(ins, IPOINT_BEFORE,
            AFUNPTR(EmuRet),
            IARG_CALL_ORDER, CALL_ORDER_FIRST,
            IARG_REG_REFERENCE, REG_STACK_PTR,
            IARG_ADDRINT, (ADDRINT)imm,
            IARG_RETURN_REGS, scratchReg, IARG_END);

        INS_InsertIndirectJump(ins, IPOINT_AFTER, scratchReg);

        INS_Delete(ins);
    }
    else if (INS_IsIndirectBranchOrCall(ins))
    {
        // This is not a call (it was checked before) so this is indirect jump
        INS_InsertCall(ins, IPOINT_BEFORE,
            AFUNPTR(EmuIndJmp),
            IARG_BRANCH_TARGET_ADDR,
            IARG_RETURN_REGS, scratchReg, IARG_END);

        INS_InsertIndirectJump(ins, IPOINT_AFTER, scratchReg);

        INS_Delete(ins);
    }
}