⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcwiz2.cpp

📁 Decompilation Dos Program is a technique that allows you to recover lost source code. It is also nee
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			  CompOperators[inst.Instr - JA]);
		  //if (i) sprintf(EndOf(LineBuffer),"(unsigned)");
		  CompareVar.EndAddress = inst.Data11;
		  GetLabel(inst.Data11,tmp);
		  sprintf(EndOf(LineBuffer),"(%s))",(char *)CompareVar.Operand2);
		  Byte far *p=Inst+InstLen;
		  // If we are just checking the registers modified in this
		  // part of the code, don't decode ternary operators etc.
		  if (!RegUsed && !RegModified)
		  // else, Check for ternary operator code here.
		    p = CheckForTernaryOperCode(Inst+InstLen,LineBuffer+2);
		  if(p!=Inst+InstLen)
		  {
		    ctr += p-Inst;
		    Inst = p;
		    // Just to fool the incrementing code at the end of the proc.
		    InstLen=0;
		  }
		  else
		  {
		    sprintf(EndOf(LineBuffer)," goto %s;",(char *)tmp);
		    CheckAndOutput(LineBuffer,How,sList);
		  }
		  ((char *)CompareVar.Operand1)[0]=0;	// reset.
		  break;
      case SHL : case SHR :
		  if (inst.Operand2==IMMEDIATE)
		    tmp1 += inst.Data21;
		  else if (inst.Operand2==REG_DIRECT)
		    tmp1 += GetReg(inst.Data21);
		  else assert(0);
      case INC : case DEC :
		  switch(inst.Operand1)
		  {
		    case REG_DIRECT :
			// If the register used is not a register variable...
			if (!RegisterVariable(inst.Data11))
			{
			  char *t;
			  switch(inst.Instr)
			  {
			    case INC : t="+1"; break;
			    case DEC : t="-1"; break;
			    case SHL : t="<<"; break;
			    case SHR : t=">>"; break;
			  }
			  Regs[inst.Data11] = toString("(") + \
				GetReg(inst.Data11) + t + tmp1 + ")";
			  SetRegModified(inst.Data11);
			  SetRegUsed(inst.Data11);
			  break;
			}
			// If it is a register variable, or other operands,...
		    default :
			tmp=GetOperand1(inst);
			char *t;
			switch(inst.Instr)
			{
			  case INC : t="++"; break;
			  case DEC : t="--"; break;
			  case SHL : t="<<="; break;
			  case SHR : t=">>="; break;
			}
			sprintf(LineBuffer,"%s%s%s;",(char *)tmp,\
				t,(char *)tmp1);
			CheckAndOutput(LineBuffer,How,sList);
			break;
		  }
		  break;
      case ADC  : case SBB :
		  // only the high words of the long-int are involved in
		  // ADC & SBB. Hence subtract 2 from the variable to get
		  // the actual address of the long int.
		  int whichOper;
		  whichOper=(inst.Operand1!=REG_DIRECT)?1:2;
		  if (whichOper==1) inst.GetVariable(v1,1);
		  else inst.GetVariable(v1,2);

		  DelVar(v1-2); DelVar(v1);
		  AddVar(v1-2,VAR_LONG,4);
		  if (inst.Instr==ADC) inst.Instr=ADD;
		  else inst.Instr=SUB;
		  goto ComForMovingData;
      // We get an 'LES' instruction while using 'far' pointers.
      // eg.  LES BX,[1000] means we are loading es:bx with far-pointer
      // located at 1000.  Here, I just ignore the 'es' part of the
      // instruction, and load BX with [1000].
      case LES  : inst.Instr=MOV;
      case MOV  : case ADD : case SUB :
      case AND  : case OR  : case XOR :
		  // Check if the destination operand is a part of a long-int.
		  //  Execute the instruction only if it is the HIWORD of the
		  //  long-int.
		ComForMovingData:
		  int Use2ndData=0;
		  int HiWordPrefix=0;
		  whichOper=(inst.Operand1!=REG_DIRECT)?1:2;

		  if (whichOper==1) inst.GetVariable(v1,1);
		  else inst.GetVariable(v1,2);

		  if (IsLongInt(v1))
		  {
		    // If it is not the 1st word of the long-int, ignore
		    //  the instruction.
		    if (!IsFirstWordOfLongInt(v1))
		    {
		      if (inst.Operand2==IMMEDIATE)
		      {
			PrevImmValueStored=1;
			PrevImmediateValue=inst.Data21;
		      }
		      if (whichOper==2)
		      {
			inst.SetVariable(v1-2,2);
			HiWordPrefix=1;
		      }
		      else break;
		    }
		    if (inst.Operand2==IMMEDIATE)
		    {
		      // This instruction operates on the 1st word using
		      //  an immediate value. Grab the 2nd word of the
		      //  immediate value - which could be the previous or
		      //  next instruction.
		      // If it has not been obtained from previous
		      //  instruction it must be in the next instruction.
		      if (!PrevImmValueStored)
		      {
			Inst+=InstLen;
			d.TraceInst(Inst,InstLen);
			if (d.CurInst.Instr==ADC) d.CurInst.Instr=ADD;
			if (d.CurInst.Instr==SBB) d.CurInst.Instr=SUB;
			if(d.CurInst.Instr!=inst.Instr ||
			   d.CurInst.Operand2!=IMMEDIATE)
			{
			  sprintf(errorStr,"Error understanding long int code at %X",InstAddr);
			  ErrorList.Add(errorStr);
			  break;
			}
			PrevImmediateValue=d.CurInst.Data21;
		      }
		      inst.Data22=inst.Data21;
		      inst.Data21=PrevImmediateValue;
		      PrevImmValueStored=0;
		      Use2ndData=1;
		    }
		  }
		  switch(inst.Operand1)
		  {
		    case REG_INDIRECT :
		    case INDEXED_BYTE :
		    case INDEXED_WORD :
			tmp=GetOperand1(inst);
			goto PrintVariableAssignment;
		    case MEMORY :
			tmp=GetOperand1(inst);
		      PrintVariableAssignment:
			tmp1=tmp;
			sprintf(LineBuffer,"%s %s= ",(char *)tmp,\
				ArithOperators[inst.Instr - MOV]);
			switch(inst.Operand2)
			{
			  case IMMEDIATE :
				s_LineBuffer += (Word)inst.Data21;
				if (Use2ndData)		// See above.
				  s_LineBuffer += (Word)inst.Data22;
				break;
			  case REG_DIRECT :
				CheckAndSetRegUsed(inst.Operand2,inst.Data21);
				tmp=GetOperand2(inst);
				strcat(LineBuffer,(char *)tmp);
				// Is it a long-int?
				if (strncmp((char *)tmp,"HIWORD",6)==0)
				  Use2ndData=1;	// Used in the checking below.
				// If it is like MOV addr,REG then do a false
				//  assignment MOV REG,addr so that any
				//  following instructions of the format
				//  MOV addr,REG are translated properly.
				if (!RegisterVariable(inst.Data21))
				{
				  tmp=GetOperand1(inst);
				  Regs[inst.Data21] = tmp;
				}
				break;
			  default :
				tmp = GetOperand2(inst);
				strcat(LineBuffer,(char *)tmp);
				break;
			}
			sprintf(EndOf(LineBuffer),";");
			CheckAndOutput(LineBuffer,How,sList);
			// check for long-ints and register them
			if (Use2ndData)
			{
			  inst.GetVariable(v1,1);
			  if (!IsLongInt(v1))
			  {
			    DelVar(v1-2); DelVar(v1);
			    AddVar(v1-2,VAR_LONG,4);
			  }
			}
			break;
		    case REG_DIRECT :
			tmp=GetOperand2(inst);
			tmp1=tmp;
			if (HiWordPrefix) tmp=toString("HIWORD(")+tmp+")";
			SetRegModified(inst.Data11);
			CheckAndSetRegUsed(inst.Operand2,inst.Data21);
			// Is it ADD SP,Imm?
			if ((inst.Instr == ADD) && \
			    (inst.Operand2 == IMMEDIATE) && \
			    (inst.Data11 == Register(1,4)))
			{
			  int dec = (int)inst.Data21 / sizeof(Word);
			  for(i=0;i<dec;i++,StackTop--)
			    Stack[StackTop-1] = "";
			  assert(StackTop>=0);		// Stack Underflow?
			  break;
			}
			if (inst.Instr == MOV)
			  Regs[inst.Data11] = tmp;
			else
			{
			  tmp = toString("(") + tmp + ")";
			  Regs[inst.Data11] = GetReg(inst.Data11) +  \
			    " " + ArithOperators[inst.Instr - MOV] \
			    + " " + tmp;
			}
			// Check if it is a register variable
			// If so,  print it out the same way a memory
			//  variable is assigned.
			if (RegisterVariable(inst.Data11))
			{
			  tmp=GetRegVarName(inst.Data11);
			  goto PrintVariableAssignment;
			}
			SetRegModified(inst.Data11);
			break;
		  }
		  break;
      case PUSH : i = StackTop; assert(StackTop<NUM_STACK_LINES);
		  CheckAndSetRegUsed(inst.Operand1,inst.Data11);
		  tmp=GetOperand1(inst);
		  Stack[i] += tmp;
		  UseAsFnParms[i]=1;
		  // Check for PUSHs involving part of long-ints.
		  inst.GetVariable(v1,1);
		  if (IsLongInt(v1))
		    UseAsFnParms[i]=IsFirstWordOfLongInt(v1);

		  // If it is a comma-expression, close the braces.
		  if (!IsEqualClosingParentheses(Stack[i])) Stack[i] += ")";
		  // Clear the current stack string to blank.
		  StackTop++;
		  Stack[StackTop] = "";
		  TracingFunctionCall=1;
		  break;
      case POP  : if (StackTop<=0)
		  {
		    sprintf(errorStr,"Procedure Stack Underflow at %X",InstAddr);
		    ErrorList.Add(errorStr);
		    break;
		  }
		  StackTop--;
		  switch(inst.Operand1)
		  {
		    case MEMORY :
		    case INDEXED_BYTE :
		    case INDEXED_WORD :
		      tmp = GetOperand1(inst);
		      sprintf(EndOf(LineBuffer),"%s = %s;",(char *)tmp,\
			      (char *)Stack[StackTop]);
		      CheckAndOutput(LineBuffer,How,sList);
		      break;
		    case REG_DIRECT :
		      Regs[inst.Data11] = Stack[StackTop];
		      SetRegModified(inst.Data11);
		      break;
		  }
		  Stack[StackTop] = "";
		  TracingFunctionCall=0;
		  break;
      case CALL : TracingFunctionCall=0;
		  if (IsInternalLongIntProc(inst))
		    break;
		  inst.GetVariable(v1,1);
		  vName=GlobalVars.GetName(v1,VAR_LIB_FUNCTION);
		  if (!vName) vName=GlobalVars.GetName(v1,VAR_USER_FUNCTION);
		  if (vName) tmp=vName;
		  else
		  {
		    if (inst.operSize1) tmp = String((Word)inst.Data12);
		    else tmp="";
		    tmp += String(inst.Data11);
		  }
		  sprintf(EndOf(LineBuffer),"%s(",(char *)tmp);
		  // For some library procedures, no parameters are passed
		  //  by stack, hence ignore the stack in such cases.  This
		  //  is checked by finding if the previous instruction
		  //  was a PUSH - if not, just ignore the stack.
		  if (previnst.Instr==PUSH && StackTop)
		  {
		    for(i=StackTop-1;i>=0;i--) if (UseAsFnParms[i]) break;
		    if (i>=0)
		    {
		      sprintf(EndOf(LineBuffer),"%s",(char *)Stack[i]);
		      i--;
		      for(;i>=0;i--)
			if (UseAsFnParms[i])
			  sprintf(EndOf(LineBuffer),",%s",(char *)Stack[i]);
		    }
		  }
		  // Append the address of the instruction 'CALL Proc' to
		  //  the pending line buffer, so that this address tag can
		  //  be used to locate this statement in case it has to be
		  //  deleted from the pending lines array.
		  // Don't terminate LineBuffer with a ';' because pending
		  //  lines should not be terminated now, only while printing.
		  sprintf(EndOf(LineBuffer),")");
		  tmp = toString(";") + String((int)InstAddr) + ";";
		  Regs[REG_AL] = tmp + LineBuffer;
		  Regs[REG_AX] = tmp + LineBuffer;
		  Regs[REG_DX] = tmp + toString("HIWORD(") + LineBuffer + ")";
		  SetRegModified2(REG_AL);
		  SetRegModified2(REG_AX);
		  SetRegModified2(REG_DX);
		  String tmp1 = tmp + LineBuffer;
		  strcpy(LineBuffer,(char *)tmp1);
		  CheckAndAddPending(LineBuffer);

		  // Some functions give a RET/RETF xxxx while returning
		  //  so that there is no need to do a stack unwind by the
		  //  caller.  Check for such conditions, and unwind the
		  //  stack by a suitable amount.
		  Word seg,off;
		  if (inst.operSize1==1) { seg=inst.Data11; off=inst.Data12; }
		  else { seg=FP_SEG(Inst); off=inst.Data11; }
		  Byte far *ProcBegin = (Byte far *)MK_FP(seg,off);
		  Byte far *ProcEnd = ProcBegin+GetProcSize(ProcBegin);
		  Disasm d;
		  d.TraceInst(ProcEnd,i);
		  int dec = (int)d.CurInst.Data11 / sizeof(Word);
		  for(i=0;i<dec;i++,StackTop--)
		    Stack[StackTop-1] = "";
		  assert(StackTop>=0);		// Stack Underflow?
		  break;
      case LOOP : break;
      default   : sprintf(errorStr,"Unknown Instruction at address %X",InstAddr);
		  ErrorList.Add(errorStr);
		  break;
    }
    Inst += InstLen;
    ctr += InstLen;
    previnst=inst;
  }
  CheckAndOutput(NULL,How,sList);
  InstAddr = FP_OFF(Inst);
  if (GetLabel(InstAddr,tmp))
  {
    tmp += ":";
    CheckAndOutput(tmp,How,sList);
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -