?? 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 + -