上次我們對主函數分析完成了,逆向入門分析實戰(一)那麼這次我們對子函數IsAlreadyRun進行分析。
C語言代碼IsAlreadyRun函數的C語言代碼如下圖所示:
下面對其彙編代碼進行分析:
rep stosd之前,同樣是入棧操作,我們無需仔細追究,重點關注call函數。
1. CreateMutexA函數
首先根據call ds:CreateMutexA
這一條指令便可得知調用了CreateMutex函數(註:CreateMutexA是在Ascii 環境下的,CreateMutexW是unicode環境下的)。
上次我們提到過,在函數調用之前,如果有參數需要傳遞,需要使用push先將參數從後往前入棧。那麼我們來看下call ds:CreateMutexA前面的三條push指令分別代表什麼意思?如果查呢?這就用到非常常用的一個文檔--msdn文檔,這個文檔是微軟寫的,介紹了Windows API函數,基本上遇到的函數都可以在這裡查到,比如CreateMutex這個函數對應的地址是:
從官網可以看到對應的函數解釋,詳細介紹了這個函數的作用,參數,返回值等:
三個參數lpMutexAttributes,bInitialOwner,lpName中第三個參數lpName的意思是互斥對象的名稱,另外兩個在此處不展開介紹了,感興趣的可以去查看msdn文檔。現在我們再回過頭來仔細看一下ida Pro給的反彙編代碼:
是不是和MSDN上的三個參數反過來就對應上了?第一條push指令對應的是lpName這個參數,所以根據ida pro右邊給出的備註,可以得知這個互斥對象的名稱是TEST。上一次也提到過,函數調用完成後,VC中,會使用eax寄存器來保存函數的返回值。在這裡也是一樣的,call ds:CreateMutexA的返回值會存入eax寄存器。
2. 跳轉分析
我們繼續分析下面的彙編代碼:
根據call __chkesp可知是調用了棧平衡錯誤檢測函數,這裡我們無需理會。之後,
mov指令將調用CreateMutexA函數的返回值eax先移動到ebp+var_4的地址上,之後又與0對比,如果兩者相等,則跳轉到 loc_40107D位置。即,如果CreateMutexA函數的返回值為0,則跳轉 loc_40107D位置。下面分兩種情況進行討論,一種是CreateMutexA函數的返回值為0,一種是不為0。2.1. CreateMutexA返回值為0
首先分析CreateMutexA函數的返回值為0的情況:
跳轉到這個位置之後,執行xor eax,eax這條指令,上次也提到過xor eax,eax直接會將eax的值設置為0,這是很常見的一種將eax置為0的方式。
執行完這條指令後,會到loc_40107F位置,根據pop出棧指令、call __chkesp、retn等指令可知,這是子函數IsAlreadyRun調用完要返回主函數。
那麼,IsAlreadyRun函數的返回值是多少呢?返回值存在eax中,由前面可知,eax在CreateMutexA函數的返回值為0情況下,eax值為0(xor eax,eax的作用),所以IsAlreadyRun函數的返回值也是0,即IsAlreadyRun返回值為false。對應的C語言代碼:
即,當hMutex = ::CreateMutex(NULL, FALSE, "TEST")執行後得到的hMutex為0時的場景,子函數IsAlreadyRun直接執行return FALSE;
2.2. CreateMutexA返回值不為0
之後,分析CreateMutexA函數的返回值不為0的情況:
此時,由於eax不為0,所以不會跳轉到loc_40107D這個位置,而是執行call ds:GetLastError執行調用GetLastError函數。後面又執行call __chkesp 調用棧平衡錯誤檢查函數,我們在這裡無需理會。之後執行cmp eax,0B7h指令,由於GetLastError函數的返回值存儲在eax中,此處其實是在看GetLastError返回值是否等於16進位的B7,對應10進位的183。
如果eax的值不等於183,那麼跳轉到loc_40107D,之後和上一種情況一樣,將eax置為0,然後返回主函數。
如果eax的值等於183,則執行mov eax,1指令,然後跳轉到loc_40107F位置,返回主函數。
那麼這個183到底代表什麼意義呢?通過查詢MSDN文檔,我們可以得知,它剛好對應常數ERROR_ALREADY_EXISTS。
對比我們寫的C語言代碼:
也就是GetLastError函數的返回值等於ERROR_ALREADY_EXISTS時,返回true;否則,返回false。到此為止,整個代碼分析完畢。感謝各位耐心的閱讀,如有不當之處,歡迎指出。
參考書籍:
《Windows黑客編程技術詳解》甘迪文著--北京:人民郵電出版社,2018年12月。
《C++反彙編與逆向分析技術揭秘》錢松林,趙海旭著--北京:機械工業出版社,2011年9月。
《惡意代碼分析實戰》 (美)Michael Sikorski / Andrew Honig 著,諸葛建偉,姜輝,張光凱譯 -- 北京:電子工業出版社,2014年4月,原書名:Practical Malware Analysis: The Hands-On Guide to Dissecting Malicious Software。
《彙編語言》王爽 著--2版,北京:清華大學出版社,2008年4月。
實驗推薦區
合天網安實驗室相關實驗推薦:逆向破解-CrackMe系列