【逆向筆記】OD工具使用-逆向TraceMe.exe


名詞注釋

System breakpoint:系統斷點,OllyDbg用CreateProcessA加載DEBUG_ONLY_THIS_PROCESS參數執行,程序運行之后會觸發一個INT13,在系統空間里。

Entry point of main module:主模塊的入口點,即文件的入口點。

WinMain:程序的WinMain()函數入口點

OD的設置中-選項-事件中設置

OD快捷鍵熟悉

1、F2 下斷點,
2、Alt+b 打開斷點編輯器,可編輯所有下過的斷點
3、空格鍵 可快速切換斷點狀態。
4、Ctrl+F9.當位於某個CALL中,這時想返回到調用這個CALL的地方時,可以按“Ctrl+F9”快捷鍵執行返回功能。這樣OD就會停在遇到的第一個返回命令(如RET、RETF或IRET)。
5、Alt+F9 如果跟進系統DLL提供的API函數中,此時想返回到應用程序領空里,可以按快捷鍵“Alt+F9”執行返回到用戶代碼命令。
6、Ctrl+G 跳轉到API、地址的位置

逆向之猜

逆向與開發的知識是成正比關系,只有對開發特別熟悉,逆向一個程序才能猜測到該用哪個關鍵的API才能快速定位到程序的數據處理。

通過PEID查看程序特征,根據程序語言用IDE生成特征或者熟悉開發的API函數。就可以更方便地讓我們定位到獲取edit值的函數。

【GetDlgItemText 函數】 用於獲取對話框中指定控件的標題或文本。

‘使用OD的快捷鍵【Ctrl+G】跳轉到API的位置下斷點。

F2設置斷點,當【GetDlgItemTextA】這個函數被調用OD就會中斷

【ALT+B】快捷鍵可以打開斷點窗口查看,在斷點位置按【空格鍵】可以激活與禁用斷點。

按快捷鍵【Ctrl+F9】可以回到調用函數的尾部ret處。

算法逆向

F7跟進004011E5地址內的函數,進入子程序call 00401340,特別值得注意的是00401359是跳轉到4013680的,相關匯編代碼注釋如下:

加密函數匯編注釋如下:

00401340  push ebp                                 ;  ebp入棧
00401341  mov ebp,dword ptr ss:[esp+0xC]           ;  將用戶名移動到ebp中
00401345  push esi                                 ;  esi入棧
00401346  push edi                                 ;  edi入棧
00401347  mov edi,dword ptr ss:[esp+0x18]          ;  將參數從堆棧中傳給edi(用戶名長度值) edi = 5
0040134B  mov ecx,0x3                              ;  ecx = 3
00401350  xor esi,esi                              ;  esi 清 0
00401352  xor eax,eax                              ;  eax 清0
00401354  cmp edi,ecx
00401356  jle XTraceMe.00401379                    ;  edi<ecx條件成立時跳轉,i<len
00401358  push ebx
00401359  /cmp eax,0x7                             ;  比較eax與7的值
0040135C  jle XTraceMe.00401360                    ;  當等於7,ZF=1短跳轉
0040135E  |xor eax,eax
00401360  |xor edx,edx                             ;  edx清0
00401362  |xor ebx,ebx
00401364  |mov dl,byte ptr ds:[ecx+ebp]            ;  地址低8位的一個字節,dl是存儲一個字節的寄存器,ecx = 3,  [ecx+ebp] = d
00401367  |mov bl,byte ptr ds:[eax+0x405030]       ;  00405030  0C 0A 13 09 0C 0B 0A 08
0040136D  |imul edx,ebx                            ;  edx * ebx 賦值給 edx, dl為高8位,存儲1字節數
00401370  |add esi,edx                             ;  edx+esi,把值賦予給esi ,esi = 4B0 + 3F2
00401372  |inc ecx                                 ;  遞增指令,ecx 由 3 -> 4 -> 5
00401373  |inc eax                                 ;  eax = 1,eax++
00401374  |cmp ecx,edi
00401376  \jl XTraceMe.00401359                    ;  ecx 是否大於等於5(用戶名長度), jl指令大於不等於滿足時跳轉
00401378  pop ebx
00401379  push esi                                 ; /<%ld>
0040137A  push TraceMe.00405078                    ; |Format = "%ld"
0040137F  push ebp                                 ; |s
00401380  call dword ptr ds:[<&USER32.wsprintfA>]  ; \wsprintfA
00401386  mov eax,dword ptr ss:[esp+0x1C]
0040138A  add esp,0xC
0040138D  push ebp                                 ; /String2
0040138E  push eax                                 ; |String1
0040138F  call dword ptr ds:[<&KERNEL32.lstrcmpA>] ; \lstrcmpA

程序原先輸入的用戶名:abcde、序列號:123456。在堆棧窗口看到的是d、e,也就是

   name[3]=‘d’,
   name[4]=‘e’

根據00401367 地址處判斷,密碼數組索引第3位之后的值逐位取出與固定地址的值比對。然后在0040137A 會輸出密鑰的值2201。

仔細逆推一遍:

   edx =  64 * 0C = 4B0

   edx =  65 * 0A = 3F2

   4B0 + 3F2  =  8A2 
   
8A2對應的十進制為2210

逆向結論:

abcde轉換為十六進制從索引值第3位開始逐位取值,64:d、65:e ,然后與00405030 0C 0A 13 09 0C 0B 0A 08對應的值進行相乘然后累加。得出的8A2轉換成十進制2210就是密碼的值。

把加密函數取出來就成了算號注冊機,下面是加密函數反匯編轉換來的C代碼:

#include "stdafx.h"
#include <string.h>



//char name[65] = "abcdexxxx";
char name[65];
char table[8] = { 0xC ,0xA ,0x13 ,0x09 ,0x0C ,0x0B ,0x0A ,0x08 };
int main()
{
	printf(" 輸入key:\n ");
	scanf_s("%s",name,65);


	//會用到一個固定地址的值
	//會用到姓名里的后兩位
	//eax = i
	int user_len = strlen(name);
	int key_code= 0; //esi
	


	int count_ecx = 3;  //esi
	int eax = 0;      //eax
    for (; count_ecx<user_len;)
	{
		if (eax>7)
			eax = 0;

		int ebx = 0;
		int edx = 0;

		edx = name[count_ecx];
		ebx = table[eax];
		ebx = edx * ebx;

		key_code += ebx;
		count_ecx++;
		eax++;

	}
	printf("key_code: %d", key_code);
    return 0;
}

暴力破解

在定位到GetDlgItemText這個API處,F8單步步過向下跟隨到有test判斷的地方,注意觀察數據堆棧區的位置。

匯編指令注釋如下:

0040119C  mov esi,dword ptr ss:[esp+0x100]         ;  Case 3F5 of switch 0040115E
004011A3  mov edi,dword ptr ds:[<&USER32.GetDlgIte>;  user32.GetDlgItemTextA
004011A9  push ebx
004011AA  lea eax,dword ptr ss:[esp+0x4C]
004011AE  push 0x51                                ; /Count = 51 (81.)
004011B0  push eax                                 ; |Buffer
004011B1  push 0x6E                                ; |ControlID = 6E (110.)
004011B3  push esi                                 ; |hWnd
004011B4  call edi                                 ; \GetDlgItemTextA
004011B6  lea ecx,dword ptr ss:[esp+0x9C]
004011BD  push 0x65                                ; /最大字符數
004011BF  push ecx                                 ; |文本緩沖區指針
004011C0  push 0x3E8                               ; |控件標識
004011C5  push esi                                 ; |對話框句柄
004011C6  mov ebx,eax                              ; |將用戶名的長度轉到ebx中
004011C8  call edi                                 ; \GetDlgItemTextA
004011CA  mov al,byte ptr ss:[esp+0x4C]            ;  將用戶名的第一個字節給al
004011CE  test al,al                               ;  檢查有沒有輸入用戶名
004011D0  je XTraceMe.00401248                     ;  如果沒有輸入用戶名跳走,告知輸入的字符太少,zf=0跳轉
004011D2  cmp ebx,0x5
004011D5  jl XTraceMe.00401248                     ;  如果用戶名不大於5那么就跳轉到錯誤提示處
004011D7  lea edx,dword ptr ss:[esp+0x4C]          ;  用戶名地址放到edx中
004011DB  push ebx                                 ;  用戶名長度
004011DC  lea eax,dword ptr ss:[esp+0xA0]          ;  密碼地址放到eax
004011E3  push edx                                 ;  用戶名地址入棧
004011E4  push eax                                 ;  密碼地址入棧
004011E5  call TraceMe.00401340                    ;  調用函數,相當於a("123456",abcde,5)
004011EA  mov edi,dword ptr ds:[<&USER32.GetDlgIte>;  user32.GetDlgItem
004011F0  add esp,0xC                              ;  平衡堆棧
004011F3  test eax,eax                             ;  函數返回值都是在eax里面的,eax=0注冊失敗,eax=1注冊成功
004011F5  nop                                      ;  zf標志位為0,滿足條件時跳轉

第一個test指令首先對比用戶名是否大於5,不大於5就跳轉到彈出錯誤提示的地方。否則繼續執行。F8單步步過進入【GetDlgItemTextA】后面的調用查看相關的代碼。004011E5地址處call調用一個函數,並且在之前push了三個參數。

第二處test指令下面那條je跳轉指令用nop填充掉。

然后右鍵【復制到可執行文件】-【所有修改】

選擇全部復制

選擇【保存文件】,暴力破解就完成了

成功后輸入任何密碼都提示成功彈框,截圖如下:

樣本引用

《加密與解密》這本書里的附帶小程序TraceMe.exe。

http://pan.baidu.com/s/1miRZZg0 bdq1


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM