160個CrackMe之108 mfc程式 尋找按鈕事件,程式碼還原(下)
極安御信發表於2022-03-10
·分析該CrackMe按鈕事件
這個check就是個按鈕,現在用visual studio提供的工具看看這個按鈕id
·選擇自己的Spy++(不會用的話百度查一下)
找到check按鈕id是1
·那該程式的檢查按鈕事件就為
AFX_MSGMAP_ENTRY 按鈕;按鈕。nMessage = WM_COMMAND ; 按鈕。nCode = BN_CLICKED ; 按鈕。nID = 1 ; 按鈕。nLastID = 1 ; 按鈕。nSig = AfxSigCmd_v ; 按鈕。pfn =未知; 等價替換後 btn.nMessage=0x0111; btn.nCode=0; btn.nID=1; btn.nLastID=1; btn.nSig=AfxSigCmd_v; btn.pfn=CMFCApplication3Dlg::未知; btn的記憶體呈現形式為 nMessage,nCode,nID,nLastID,nSig,pfn 可以不用管nSig,pfn的值,只用搜尋前四項就夠了,等價替換為 0x0111, 0, 1,1,nSig,pfn 等價替換為 11 01 00 00, 00 00 00 00, 01 00 00 00, 01 00 00 00 ,nSig,pfn 等價替換為 11 01 00 00 00 00 00 00 01 00 00 00 01 00 00 00
找到按鈕事件地址 795E7980
·地址795E7980的彙編程式碼看著有點怪異的是因為這裡是虛擬函式呼叫(vcall) 執行到795E798D jmp eax f7跟進去後來到真正的按鈕事件地址
·現在來講講vcall,寫了個小例子
#include <Windows.h> #include <stdio.h> class myclass { public: virtual void func1() { } virtual void func2() { } }; int main ( ) { printf ( "MYACLS::myvirfunc1()地址=%p\n" , & myclass :: func1 ) ; //列印的是vcall函式 printf ( "MYACLS::myvirfunc2()地址=%p\n" , & myclass :: func2 ) ; myclass * pmyobj = new myclass ( ) ; 返回 1 ; }
·執行的結果
#### 而myvirfunc1 myvirfunc2函式真正的地址為
現在00FB1084與00FB1088程式碼組合
是不是和地址795E7980程式碼很相似
·vcall 的作用
調整這個指標到真正的虛擬函式中
·現在看看程式碼還原
ida開啟該程式跳轉00401512
text:00401518 mov [ebp+var_20], ecx .text:0040151B mov ax, word_40315C .text:00401521 mov word ptr [ebp+String], ax .text:00401525 xor ecx, ecx .text:00401527 mov [ebp+var_A], ecx .text:0040152A mov [ebp+var_6], ecx .text:0040152D mov edx, dword_403020 .text:00401533 mov dword ptr [ebp+String2], edx .text:00401536 mov eax, dword_403024 .text:0040153B mov [ebp+var_18], eax .text:0040153E mov cx, word_403028 .text:00401545 mov [ebp+var_14], cx var_20看前後使用是 用來this指標的不用管 var_A和var_6都被初始化為0,上下文都沒有使用,說明是陣列 String 只初始化了2個位元組,加上var_A和var_6,String是10個位元組 String2 和var_18,var_14地址相連,var_18,var_14上下文都沒有使用,說明是陣列 var_14只初始化了2個位元組,加上String2和var_18,String2是10個位元組 dword_403020 值為4472423C,dword_403024值為426F532D,word_403028值為003E換成asci碼為 <BrD-SoB> 程式碼為 CHAR String[10]={0};//因為彙編程式碼中都陣列中的值被初始化為0了,所以寫成String[10]={0} CHAR String2[10]="<BrD-SoB>"; .text:00401549 push 0Ah ; int .text:0040154B lea edx, [ebp+String] .text:0040154E push edx ; char * .text:0040154F push 3E8h ; int .text:00401554 mov ecx, [ebp+var_20] ; this .text:00401557 call ?GetDlgItemTextA@CWnd@@QBEHHPADH@Z ; CWnd::GetDlgItemTex .text:0040155C lea eax, [ebp+String] .text:0040155F push eax ; lpString .text:00401560 call ds:lstrlenA .text:00401566 mov [ebp+var_10], eax .text:00401569 cmp [ebp+var_10], 1 .text:0040156D jnb short loc_401585 push的是10,呼叫的函式是intGetDlgItemText(intnID**,LPTSTRlpStr,intnMaxCount),說明陣列 大就是10, var_10=lstrlenA函式的返回值, 後比較的後的跳轉指令是jnb 說明var_10是無符號的 程式碼為 GetDlgItemTextA(1000, String, 10); unsigned int var_10; var_10 = lstrlenA(String); if ( var_10<1)
.text:0040156F push 40h ; '@' ; unsigned int .text:00401571 push offset aCrackme ; "CrackMe" .text:00401576 push offset aEnterRegistrat ; "Enter Registration Number" .text:0040157B mov ecx, [ebp+var_20] ; this .text:0040157E call ?MessageBoxA@CWnd@@QAEHPBD0I@Z ; CWnd::MessageBoxA(char .text:00401583 jmp short loc_4015C1 .text:00401585 ; --------------------------------------------------------------------------- .text:00401585 .text:00401585 loc_401585: ; CODE XREF: sub_401512+5Bj .text:00401585 lea ecx, [ebp+String2] .text:00401588 push ecx ; lpString2 .text:00401589 lea edx, [ebp+String] .text:0040158C push edx ; lpString1 .text:0040158D call ds:lstrcmpA .text:00401593 test eax, eax .text:00401595 jnz short loc_4015AD .text:00401597 push 40h ; '@' ; unsigned int .text:00401599 push offset aCrackme_0 ; "CrackMe" .text:0040159E push offset aCorrectWayToGo ; "Correct way to go!!" .text:004015A3 mov ecx, [ebp+var_20] ; this .text:004015A6 call ?MessageBoxA@CWnd@@QAEHPBD0I@Z ; CWnd::MessageBoxA(char .text:004015AB jmp short loc_4015C1 .text:004015AD ; --------------------------------------------------------------------------- .text:004015AD .text:004015AD loc_4015AD: ; CODE XREF: sub_401512+83j .text:004015AD push 40h ; '@' ; unsigned int .text:004015AF push offset aCrackme_1 ; "CrackMe" .text:004015B4 push offset aIncorrectTryAg ; "Incorrect try again!!" .text:004015B9 mov ecx, [ebp+var_20] ; this .text:004015BC call ?MessageBoxA@CWnd@@QAEHPBD0I@Z ; CWnd::MessageBoxA(char .text:004015C1 .text:004015C1 loc_4015C1: ; CODE XREF: sub_401512+71j .text:004015C1 ; sub_401512+99j .text:004015C1 mov esp, ebp .text:004015C3 pop ebp .text:004015C4 retn .text:004015C4 sub_401512 endp 彙編結構來看感覺是 if, elseif, else結構程式碼為 MessageBoxA("Enter Registration Number", "CrackMe", 0x40u); else if ( lstrcmpA(String, String2) ) MessageBoxA("Incorrect try again!!", "CrackMe", 0x40u); else MessageBoxA("Correct way to go!!", "CrackMe", 0x40u); CHAR String2[10]="<BrD-SoB>"; unsigned int var_10; CHAR String[10]={0};//因為彙編程式碼中都陣列中的值被初始化為0了,所以寫成String[10]={0} GetDlgItemTextA(1000, String, 10); var_10 = lstrlenA(String); if ( var_10<1) MessageBoxA("Enter Registration Number", "CrackMe", 0x40u); else if ( lstrcmpA(String, String2) ) MessageBoxA("Incorrect try again!!", "CrackMe", 0x40u); else MessageBoxA("Correct way to go!!", "CrackMe", 0x40u);
·因為該程式是vc6寫的,我自己也用vc6寫了一份,因為該crackme引用的dll是 MFC42.DLL 明說不是Debug編譯的,Debug編譯的是用的MFC42D.DLL,所以
選擇用Release編譯,第二因為該crackme是用ebp尋找的區域性變數,說明沒有開 o2最佳化編譯,我個人就選擇的無最佳化編譯,最後生成的二進位制和原版還有略有差異
·最後輸入秘鑰 實現破解
·完成自己程式碼還原的mfc程式以打包到附件了
相關文章
- 160個CrackMe之108 mfc程式 尋找按鈕事件,程式碼還原(上)2022-03-10C程式事件
- 160個crackme(6)2018-12-02
- 160個CrackMe(4)2018-12-02
- MFC 捕獲按鈕 按下和抬起 (轉)2019-01-18
- 小程式按鈕2019-04-10
- 微信小程式避免按鈕重複觸發事件2019-04-04微信小程式事件
- 各種語言按鈕事件特徵碼2024-05-20事件特徵
- Qt 模擬滑鼠事件-在兩個按鈕之間切換2018-10-12QT事件
- 尋找寫程式碼感覺(十四)之 新增功能的開發2022-02-04
- 尋找寫程式碼感覺(五)之Mybatis官方程式碼生成器的使用2021-10-11MyBatis
- VsCode顯示左邊摺疊程式碼+-按鈕2018-09-07VSCode
- 移動端模擬hover:按鈕點選變色之後還原2019-02-16
- 一個程式猿的2023總結:《尋找》2023-12-11
- 尋找寫程式碼感覺(十五)之 刪除功能的開發2022-02-04
- 尋找寫程式碼感覺(十三)之 編輯功能的開發2022-02-03
- 尋找寫程式碼感覺(三)之使用 Spring Boot 編寫介面2021-08-28Spring Boot
- 原來微信聊天按下這個按鈕,1分鐘能打300字,誰還會說你打字慢2019-12-17
- 尋找寫程式碼感覺(十六)之 整合Validation做引數校驗2022-02-05
- 尋找寫程式碼感覺(一)之使用 Spring Boot 快速搭建專案2021-08-17Spring Boot
- 尋找寫程式碼感覺(二)之 Spring Boot 專案屬性配置2021-08-19Spring Boot
- QT經驗(一)——按鈕長按事件分析2021-08-04QT事件
- CatFly【彙編程式碼還原】2023-12-22
- 使用grep命令,玩轉程式碼審計尋找Sink2021-11-11
- SAP:SALV重新整理按鈕事件2024-06-13事件
- DuiLib逆向分析の按鈕事件定位2021-12-10UI事件
- 大局事件風暴:尋找差距2024-03-18事件
- 程式設計題:尋找木頭2021-10-30程式設計
- Blazor入門100天 : 自做一個支援長按事件的按鈕元件2023-12-20Blazor事件元件
- 精讀《用160行js程式碼實現一個React》2018-05-27JSReact
- 開源用於尋找系外行星的程式碼2018-04-05
- MFC下CSocket程式設計詳解(轉)2018-07-12程式設計
- HTC Vive Cosmos開發——手柄按鈕事件2020-10-07事件
- 小程式沒有返回按鈕怎麼辦?2018-04-03
- 尋找寫程式碼感覺(十九)之 分類表格顯示優化 之 樹形表格展示2022-02-19優化
- 找論文程式碼2018-04-28
- 建立工程,編寫一個介面有兩個按鈕的程式,通過定時器控制這兩個按鈕上的文字變化。2021-01-01定時器
- 尋找寫程式碼感覺(七)之封裝請求引數和返回引數2021-10-13封裝
- 點選一個按鈕使其樣式發生變化,再點選另一個按鈕發生同樣變化,但上一個按鈕樣式復原2020-11-01