反汇编程序导致程序crash的解决思路
曾經發現win7下程序基地址不停地變動,又發現下移代碼會導致程序crash,一度懷疑win7系統或者vs編譯器是不是做了什么校驗機制,專門針對數據逆向者,限制反匯編修改代碼,打斷了我學習外掛編寫的信心和腳步,后來在一騙博客中解決了基地址不停地變動的問題,現在一塊兒看看這個下移代碼導致程序crash的問題,首先寫個測試工程,VS2008,Debug版,就有一對話框,點擊按鈕相應代碼如下:
void CttDlg::OnBnClickedOk() { // TODO: 在此添加控件通知處理程序代碼 __asm mov eax,eax if (mint==1) { AfxMessageBox(_T("1111")); } else { AfxMessageBox(_T("2222")); } }內嵌匯編是方便反匯編定位時用的,比較方便
看看這個成員按鈕響應函數的反匯編:
00412D0C CC int3 00412D0D CC int3 00412D0E CC int3 00412D0F CC int3 00412D10 > 55 push ebp 00412D11 8BEC mov ebp,esp 00412D13 81EC CC000000 sub esp,0xCC 00412D19 53 push ebx 00412D1A 56 push esi 00412D1B 57 push edi 00412D1C 51 push ecx 00412D1D 8DBD 34FFFFFF lea edi,dword ptr ss:[ebp-0xCC] 00412D23 B9 33000000 mov ecx,0x33 00412D28 B8 CCCCCCCC mov eax,0xCCCCCCCC 00412D2D F3:AB rep stos dword ptr es:[edi] 00412D2F 59 pop ecx 00412D30 894D F8 mov dword ptr ss:[ebp-0x8],ecx 00412D33 8BC0 mov eax,eax 00412D35 8B45 F8 mov eax,dword ptr ss:[ebp-0x8] 00412D38 8378 78 01 cmp dword ptr ds:[eax+0x78],0x1 00412D3C 75 10 jnz short tt.00412D4E 00412D3E 6A 00 push 0x0 00412D40 6A 00 push 0x0 00412D42 68 F0CE4100 push tt.0041CEF0 ; UNICODE "1111" 00412D47 E8 5FE7FFFF call tt.004114AB 00412D4C EB 0E jmp short tt.00412D5C 00412D4E 6A 00 push 0x0 00412D50 6A 00 push 0x0 00412D52 68 E4CE4100 push tt.0041CEE4 ; UNICODE "2222" 00412D57 E8 4FE7FFFF call tt.004114AB 00412D5C 5F pop edi 00412D5D 5E pop esi 00412D5E 5B pop ebx 00412D5F 81C4 CC000000 add esp,0xCC 00412D65 3BEC cmp ebp,esp 00412D67 E8 16E8FFFF call tt.00411582 00412D6C 8BE5 mov esp,ebp 00412D6E 5D pop ebp 00412D6F C3 retn 00412D70 CC int3 00412D71 CC int3 00412D72 CC int3 00412D73 CC int3測試1:把最后retn指令后面的幾個int3改為NOP指令,保存文件,雙擊執行看看程序是否運行正常
???????結果:正常運行
???????猜想:VS應該沒有做反匯編方面的限制,否則程序應該crash
測試2:把下面幾個指令下移(空出來的位置用NOP填充)
00412D6C 8BE5 mov esp,ebp 00412D6E 5D pop ebp 00412D6F C3 retn???????結果:正常運行
???????猜想:vs和win7應該沒有做限制吧,最少限制沒有那么絕,但是自己反匯編修改代碼的時候經常會導致程序crash又是什么原因呢,難道是堆棧平衡,應該不是吧,只是下移代碼,又沒有缺少什么指令,繼續看測試3
測試3:把00412d3c地址后的指令下移(具體操作:選中下移代碼->二進制復制->選中下移目標區域->二進制填充->二進制粘貼)得到的代碼:
00412D0E CC int3 00412D0F CC int3 00412D10 > 55 push ebp 00412D11 8BEC mov ebp,esp 00412D13 81EC CC000000 sub esp,0xCC 00412D19 53 push ebx 00412D1A 56 push esi 00412D1B 57 push edi 00412D1C 51 push ecx 00412D1D 8DBD 34FFFFFF lea edi,dword ptr ss:[ebp-0xCC] 00412D23 B9 33000000 mov ecx,0x33 00412D28 B8 CCCCCCCC mov eax,0xCCCCCCCC 00412D2D F3:AB rep stos dword ptr es:[edi] 00412D2F 59 pop ecx 00412D30 894D F8 mov dword ptr ss:[ebp-0x8],ecx 00412D33 8BC0 mov eax,eax 00412D35 8B45 F8 mov eax,dword ptr ss:[ebp-0x8] 00412D38 8378 78 01 cmp dword ptr ds:[eax+0x78],0x1 00412D3C 90 nop 00412D3D 75 10 jnz short tt2.00412D4F 00412D3F 6A 00 push 0x0 00412D41 6A 00 push 0x0 00412D43 68 F0CE4100 push tt2.0041CEF0 ; UNICODE "1111" 00412D48 E8 5FE7FFFF call tt2.004114AC 00412D4D EB 0E jmp short tt2.00412D5D 00412D4F 6A 00 push 0x0 00412D51 6A 00 push 0x0 00412D53 68 E4CE4100 push tt2.0041CEE4 ; UNICODE "2222" 00412D58 E8 4FE7FFFF call tt2.004114AC 00412D5D 5F pop edi 00412D5E 5E pop esi 00412D5F 5B pop ebx 00412D60 81C4 CC000000 add esp,0xCC 00412D66 3BEC cmp ebp,esp 00412D68 E8 16E8FFFF call tt2.00411583 00412D6D 8BE5 mov esp,ebp 00412D6F 5D pop ebp 00412D70 C3 retn 00412D71 90 nop 00412D72 90 nop 00412D73 90 nop 00412D74 90 nop 00412D75 90 nop 00412D76 90 nop 00412D77 90 nop 00412D78 90 nop 00412D79 CC int3結果:程序crash
猜想:妹的,小弟瞬間崩潰,為什么這個就會崩潰呢?
解決:一步一步調試發現程序崩潰在一個call函數上邊,仔細觀察發現call函數的地址變了,代碼下移之后call函數地址也隨之加一,這不胡扯嗎?Call函數實際調用的是afxmessagebox函數,這是API,地址應該是不會變的,下移部分代碼,里面的call的地址會發生變化,這個還真沒注意到,以前知道跳轉指令的地址可能會發生變化,因為有的跳轉的是絕對地址,有的跳轉的是相對偏移,所以移動跳轉指令的時候一定要注意移動之后的代碼跳轉的位置是否和移動之前的一致,這個call應該是call的絕對地址啊,怎么會有改變呢?暫時不知道,不過先改過來再說,把兩個call地址都改回原來的之后程序正常運行。
?
總結
以上是生活随笔為你收集整理的反汇编程序导致程序crash的解决思路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 玩转Google开源C++单元测试框架G
- 下一篇: OD快捷键例子