📄 square.idc
字号:
else if(opcode == "ldi" && GetOpnd(addr,1) == REG ) //ldil 0x55,%r
{
D_MSG(DEBUG_FLAG,addr,"ldi",REG);
return VALUE+getValue(addr,0);
}
else if(opcode == "ldo" && GetOpnd(addr,1) == REG) //ldo 0x456(%r),%r / ldo -0xc0 +var_23(%sp),%r
{
D_MSG(DEBUG_FLAG,addr,"ldo",REG);
if(GetOpType(addr,0) !=4) //非相对寻址,出错
F_ERR(addr,VALUE);
tmpStr = GetOpnd(addr,0);
REG = getRegister(tmpStr);
if(REG == "")
F_ERR(addr,VALUE);
if(REG == "%dp")
return VALUE + REGDP;
if(REG == "%r0")
return VALUE + getValue(addr,0);
if(REG == "%sp")
F_STA(addr,VALUE);
if(REG == "%r28")
F_RET(addr,VALUE);
VALUE = VALUE + getValue(addr,0);
}
else if(opcode == "or" && GetOpnd(addr,2) == REG) //目前只能处理or的几种特殊情形
{
auto type1,type2;
auto str1,str2;
D_MSG(DEBUG_FLAG,addr,"or",REG);
type1=GetOpType(addr,0);
type2=GetOpType(addr,1);
str1 = GetOpnd(addr,0);
str2 = GetOpnd(addr,1);
if( (type1==5 || type1==7) && (type2==5 || type2==7) ) //or 0x45,0x23 ,%r
{
VALUE = VALUE + (getValue(addr,0) | getValue(addr,1));
}
else if(type1 == 1 && (str2=="0" || str2=="%r0") ) // or %r,0,%r / or %r,%r0,%r
{
if(str1 == "%dp")
return VALUE + REGDP;
if(str1 == "%r0")
return VALUE ;
if(str1 == "%sp")
F_STA(addr,VALUE);
if(str1 == "%r28")
F_RET(addr,VALUE);
REG = str1; //如果引用的是其他积存器则继续回溯
}
else
F_ERR(addr,VALUE); //其他情形出错
}
else if(opcode == "ldw" && GetOpnd(addr,1) == REG) //ldw %r15(%r23),%r3 / ldw 4(%r1),%r2 / ldw -0x44+var_8(%sp,%r3)
{
D_MSG(DEBUG_FLAG,addr,"ldw",REG);
type = GetOpType(addr,0);
if(type != 4 ) //目前只能处理基址寻址
F_ERR(addr,VALUE);
tmpReg = getRegister(GetOpnd(addr,0));
if(tmpReg == "")
F_ERR(addr,VALUE);
tmp = getValue(addr,0);
if(tmpReg == "%dp") //ldw -0x4882(%dp),%r26
{
if(tmp == "ERR")
F_ERR(addr,VALUE);
tmpAddr = tmp + REGDP;
return VALUE + Dword(tmpAddr);
}
if(tmpReg != "%sp" && tmp != "ERR" )//如果不是栈内变量试图在前10条指令内找到 ldil 0x77,%dp,%r,如果没有找到则出错
{
//addil -0x800, %dp, %r1
// . . . .
//ldw -0x150(%sr0,%r1), %r21 # ._write
//ldw -0x14C(%sr0,%r1), %r19 # dword_40024E74
//该处理方式不是非常严谨,基本基于常见如上形势,出现,如果没有找到就将整个作为REG,试图找到对应的stw
auto n ;
n=0;
tmpAddr = addr;
while(tmpAddr > FUNC_BEGIN && tmpAddr < FUNC_END && n < 30 && CLICK <PREVENT_UN_LOCK_CLICK )
{
tmpAddr =tmpAddr-4;//=RfirstB(tmpAddr);
n++;
CLICK++; //防止死循环
if(GetMnem(tmpAddr) == "addil" && GetOpnd(tmpAddr,1) == "%dp" && GetOpnd(tmpAddr,2) == tmpReg)
{
tmpValue = getValue(tmpAddr,0);
if(tmpValue == "ERR")
F_ERR(tmpAddr,VALUE);
return VALUE + Dword( tmp + tmpValue+REGDP );
}
else if(GetMnem(tmpAddr)=="ldil" || GetMnem(tmpAddr)=="ldi" && GetOpnd(tmpAddr,1) == tmpReg)
{
tmpValue =getValue(tmpAddr,0);
if(tmpValue == "ERR")
F_ERR(tmpAddr,VALUE);
return VALUE + Dword( tmp + tmpValue);
}
else if(GetMnem(tmpAddr) == "copy" && GetOpnd(tmpAddr,1) == tmpReg)
{
tmpReg = GetOpnd(tmpAddr,0);
if(GetOpType(tmpAddr,0) == 1)
{
if(tmpReg == "%r0")
return VALUE + Dword(tmp);
if(tmpReg == "%dp")
return VALUE + Dword(tmp + REGDP);
if(tmpReg == "%sp")
break;
}
else
{
return VALUE + Dword(tmp + getValue(tmpAddr,0));
}
}
}// END while (指定范围内寻找能迅速处理的指令)
}
//将整个字符串 -0x140+var_48(%sr0,%sp) 作为寻找对象,该目标只能由stw处理。
REG = GetOpnd(addr,0); //继续回溯
}
else if(opcode == "stw" && GetOpnd(addr,1) == REG) //stw %r,sw / stw 0x88,sw
{
D_MSG(DEBUG_FLAG,addr,"stw",REG);
type = GetOpType(addr,0);
if(type == 1) //寄存器
{
tmpReg = GetOpnd(addr,0);
if(tmpReg == "%dp")
return VALUE + REGDP;
if(tmpReg == "%r0")
return VALUE;
if(tmpReg == "%sp")
F_STA(addr,VALUE);
if(tmpReg == "%r28")
F_RET(addr,VALUE);
REG = tmpReg; //继续回溯
}
else if(type == 5 || type == 7)
return VALUE + getValue(addr,0);
else
F_ERR(addr,VALUE);
}
else if(GetOpnd(addr,1)==REG) //未实现相应处理的指令
{
if( opcode=="ldb" || opcode=="ldh" || opcode=="addib" || opcode=="movib")
F_IMP(addr,VALUE);
}
else if(GetOpnd(addr,2)==REG)
{
if(opcode=="sub"||opcode=="and"||opcode=="add"||opcode=="subi")
F_IMP(addr,VALUE);
else if(opcode=="shrd"||opcode=="xor"||opcode=="uxor")
F_IMP(addr,VALUE);
}
else if(GetOpnd(addr,3)==REG)
{
if(opcode=="depw" || opcode=="shladd" || opcode=="extrw")
F_IMP(addr,VALUE);
}
} //END while(addr > FUNC_BEGIN)
//现在已经找离开了函数区域
if( CLICK == PREVENT_UN_LOCK_CLICK )
{
if(DEBUG_FLAG >=3)
Message("ERROR: getDataResEx() 出现死循环 : 0x%x 0x%x!\n",_addr,addr);
if(DEBUG_FLAG == 10) //如果调试等级为10则退出程序,退回到IDA
{
//没有找到合适的功能函数 :(
}
F_ERR(3,0);
}
if(REG=="%r26")
F_ARG(REG,VALUE);
if(REG=="%r25")
F_ARG(REG,VALUE);
if(REG=="%r24")
F_ARG(REG,VALUE);
if(REG=="%r23")
F_ARG(REG,VALUE);
//仍然没有判断出来,出错
F_NOF(REG,VALUE);
}
/**
函数: long getDataRes(long,string,long)
说明: 取得数据来源 ,该函数是对getDataResEx()的包装。
**/
static getDataRes(_addr,_reg,_debugFlag)
{
auto tmp,tmpValue;
tmpValue = getDataResEx(_addr,"%r26",_debugFlag);
tmp = substr(tmpValue,0,3);
if( !isDRValue(tmpValue) )
{
if(_debugFlag >=1)
Message("Get DataResource Failed : %s\n",tmpValue);
return "ERR";
}
return tmpValue;
}
/**
函数:string getDRFunName(string _drString)
说明:返回"RET xxxx xxxx"中第一个xxxx指定处的回溯路径上小段范围内的最近的一个函数调用名称。出错返回""。
**/
static getDRFunName(_drString)
{
auto type,addr,opcode,opnd1,opnd0,tmp;
auto n,MAX_NUMBER,FUNC_BEGIN,FUNC_END;
MAX_NUMBER = 40; //在回溯路径上40个指令内寻找函数调用
type=getDRType(_drString) ;
if(type!= "RET" )
return "";
tmp = getDRStr1(_drString);
addr = xtol(tmp);
if(addr == 0)
return "";
if( GetFunctionName(addr) == "")
return "";
if( SegName(addr) != "$CODE$")
return "";
FUNC_BEGIN = getFuncBeginEA(addr);
FUNC_END = FindFuncEnd(FUNC_BEGIN);
if(FUNC_BEGIN == BADADDR || FUNC_END == BADADDR || FUNC_END <= FUNC_BEGIN)
return "";
addr=RfirstB(addr);
n = 0;
while(addr > FUNC_BEGIN && addr < FUNC_END && n < MAX_NUMBER)
{
addr=RfirstB(addr);
n++;
opcode = GetMnem(addr);
opnd0 = GetOpnd(addr,0);
opnd1 = GetOpnd(addr,1);
if(opcode == "call" )
return opnd0;
if(opcode == "b" && opnd1 == "%r31")
return opnd0;
}
return "";
}
/**
函数:string getDRStrFunName(string _drString)
说明:返回"STA xxxx xxxx"中第一个xxxx指定处的回溯路径上小段范围内的字符串操作函数调用名称。出错返回""。
**/
static getDRStrFunName(_drString)
{
auto reg,flag,type,addr,opcode,opnd1,opnd0,tmp;
auto n,MAX_NUMBER,FUNC_BEGIN,FUNC_END;
MAX_NUMBER = 400; //在回溯路径上指定范围内寻找函数调用
type=getDRType(_drString) ;
if(type!= "STA" )
return "";
tmp = getDRStr1(_drString);
addr = xtol(tmp);
if(addr == 0)
return "";
if( GetFunctionName(addr) == "")
return "";
if( SegName(addr) != "$CODE$")
return "";
if(GetMnem(addr) != "ldo")
return "";
flag=GetFlags(addr);
if(! isStkvar0(flag) )
return "";
reg=GetOpnd(addr,0);
FUNC_BEGIN = getFuncBeginEA(addr);
FUNC_END = FindFuncEnd(FUNC_BEGIN);
if(FUNC_BEGIN == BADADDR || FUNC_END == BADADDR || FUNC_END <= FUNC_BEGIN)
return "";
addr=RfirstB(addr);
n = 0;
while(addr > FUNC_BEGIN && addr < FUNC_END && n < MAX_NUMBER)
{
addr=RfirstB(addr);
n++;
opcode = GetMnem(addr);
opnd0 = GetOpnd(addr,0);
opnd1 = GetOpnd(addr,1);
if(opcode == "ldo" && opnd0 == reg && opnd1 == "%r26") //目前仅处理给%r26赋值紧跟在call之后的情况
{
addr=RfirstB(addr);
n++;
opcode = GetMnem(addr);
opnd0 = GetOpnd(addr,0);
opnd1 = GetOpnd(addr,1);
if(opcode == "call" || (opcode == "b" && opnd1 == "%r31") )
{
if(opnd0=="strcpy"||opnd0=="strncpy"||opnd0=="strcat"||opnd0=="strncat")
return opnd0;
if(opnd0=="memcpy"||opnd0=="sprintf"||opnd0=="snprintf")
return opnd0;
}
}//end opcode == "ldo" . . .
}
return "";
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -