問:用IDA靜態分析,函數結尾出現 endp ; sp-analysis failed 用F5調不出偽代碼,不知道是什么原因,請問有什么解決辦法沒有?
答:endp ; sp-analysis failed.
一般是程序代碼有一些干擾代碼,讓IDA的反匯編分析出現錯誤。比如用push + n條指令 + retn來實際跳轉,而IDA會以為retn是函數要結束,結果它分析后發現調用棧不平衡,因此就提示sp analysis failed.
我還遇到過一種情況,是因為編譯器優化,結果IDA無法正確識別一個函數體的結尾部分,換句話說,它找不
到C中的“大括號”應該位於哪里。例如以下代碼:
int one_function( int a,int b);
int another_function( int a, int b)
{
if ( a == 0 || b == 0 )
return -1;
return one_function(a,b);
}
其中return one_function(a,b)這條語句,在某些新的編譯器,可能會編譯成這樣的指令序列:
mov esp, ebp
pop ebp
jmp one_funcion
而IDA是通過retn指令來識別函數的結束的,因為它不知道這里的意思,會把它當成一個函數內部 的跳轉,最后就會出現sp analysis failed了。
問:有沒有什么辦法可以讓IDA正確分析,因為函數非常長,需要偽代碼來減少分析時間?
答:用alt-k調整sp來解決。
問:如何用ALT+K 調整SP 要輸入什么值呢?
答:並沒有一個固定值,針對每一條指令執行完后,看看棧是否正常,如果不對,則通過ALT + K來修改.重點檢查虛函數的調用, 如call [esi + n] , 這里不一定非得是esi,以及跳轉前后的棧是否一致.另外還需要通過ALT + P 來確認下變量起始地址,清除個數與保存個數是否正常.
1)用Option->General->Disassembly, 將選項Stack pointer打勾;
2)仔細觀察每條call sub_xxxxxx前后的堆棧指針是否平衡;
3)有時還要看被調用的sub_xxxxxx內部的堆棧情況,主要是看入棧的參數與ret xx是否匹配;
4)注意觀察jmp指令前后的堆棧是否有變化;
5)有時用Edit->Functions->Edit function...,然后點擊OK,(按D再按C鍵)刷一下函數定義。
以上是轉載。小結下:SP是堆棧指針,上面的問題就是堆棧不平衡,其實問題解決的主要思路就是修正SP,其實勾選Stack pointer選項后每行匯編代碼和指令地址之間會多一列數字,這些數值就是SP實際的偏移值。call sub_xxx前面如果顯示-0x07H,則將光標停在緊接着這個call后面的一行指令之前(即剛返回的地方),按Alt+K設置新的SP值為-0x07H,再按D按C刷新下函數定義就可以了。