、打開軟件,查看正常運行的程序
二、打開OD,拖入要調(diào)試的程序
三、分析匯編代碼
title是"Hello world",內(nèi)存地址是0x00403000
四、數(shù)據(jù)窗口跳轉(zhuǎn)到該地址,快捷鍵ctrl+G
五、修改數(shù)據(jù)
點擊要修改的地方,按空格鍵,把保持大小的鉤去掉,輸入我們要修改的內(nèi)容,點擊確定,修改數(shù)據(jù)后會變成紅色
六、點擊運行,快捷鍵F9,讓程序跑起來,程序已被修改
七、OD窗口介紹
1、匯編代碼對應(yīng)的地址窗口
2、匯編代碼對應(yīng)的十六進制機器碼窗口
3、反匯編窗口
4、反匯編代碼對應(yīng)的注釋信息窗口
5、寄存器信息窗口
6、當(dāng)前執(zhí)行到的反匯編代碼的信息窗口
7、數(shù)據(jù)所在的內(nèi)存地址
8、數(shù)據(jù)的十六進制編碼信息
9、數(shù)據(jù)對應(yīng)的ASCII碼信息
10、棧地址
11、棧地址中存放的數(shù)據(jù)
12、對應(yīng)的說明信息
八、OD快捷鍵介紹
1、F2:斷點,在OllyDbg反匯編視圖中使用F2指定斷點地址
2、F3:加載一個可執(zhí)行程序進行調(diào)試分析
3、F4:程序執(zhí)行到光標(biāo)處
4、F5:縮小,還原當(dāng)前窗口
5、F7:單步步入,進入函數(shù)內(nèi)部,跟進CALL地址
6、F8:單步步過,越過函數(shù),不會進入函數(shù)內(nèi)部
7、F9:直接運行程序,遇到斷點處,暫停程序
8、ctrl+F2:重新運行程序到起始處,用于重新調(diào)試程序
9、ctrl+F9:執(zhí)行到函數(shù)返回處,用于跳出函數(shù)實現(xiàn)
10、ctrl+G:輸入十六進制地址,在反匯編或數(shù)據(jù)窗口中快速定位到該地址
11、alt+F9:執(zhí)行到用戶代碼處,用于快速跳出系統(tǒng)代碼
九、工具獲取
關(guān)注下方公眾號:逆向有你,回復(fù)2022c++
1、打開OD,隨便打開一個可執(zhí)行程序(我這里選擇了IE瀏覽器), 選擇EIP 及EIP以下的兩百行代碼,然后用二進制黏貼上面的shellcode。OD 會自動將shellcode代碼轉(zhuǎn)化為匯編代碼
2、hex、dec、oct使用計算器來轉(zhuǎn)換更加方便
3、hex用00000000至7FFFFFFF表示正數(shù),80000000至FFFFFFFF表示負數(shù);其中7FFFFFFF=2147483647是最大的正數(shù);FFFFFFFF等于十進制的-1;FFFFFFFE等于十進制的-2;80000000=-2147483647;
4、在od命令欄中輸入?7FFFFFFF可以查詢7FFFFFFF的值以Dec、Hex、ASCII對應(yīng)的結(jié)果,使用問號也可以查看寄存器的值,如?AX, ?EAX
5、十進制 十六進制 ASCII
48 30 0
57 39 9
97 61 a
122 7A z
65 41 A
90 5A Z
6、寄存器EAX、ECX EDX EBX ESP EBP ESI EDI EIP這些全是32位寄存器,這些寄存器中的內(nèi)容使用16進制形式顯示,它們的最小值是00000000,最大值是FFFFFFFF
7、AX是16位寄存器,用來表示EAX的后四位,AL是AX的后兩位,AH是AX的前兩位
8、6中的所有寄存器除了EIP外,都可以在OD的寄存器窗口中使用右鍵彈出的修改菜單來修改,EIP的修改方式是在匯編窗口中選擇一處地址并點擊右鍵在彈出的菜單中選擇New Origin here 這樣EIP就會被修改成對應(yīng)地址的值
9、標(biāo)志寄存器(C P A Z S T D O),他們的值只有兩個0或1
O是溢出標(biāo)志, 暫時這樣理解,當(dāng)一個指令的結(jié)果超出了他可以存取的最大值時,溢出標(biāo)志O將被設(shè)置成1
P是奇偶標(biāo)志,當(dāng)指令的結(jié)果用二進制表示時,如果其中1的個數(shù)為偶數(shù)時P標(biāo)志被設(shè)置成1,當(dāng)1的個數(shù)為奇數(shù)時P標(biāo)志被設(shè)置成0
Z零標(biāo)志,當(dāng)指令的結(jié)果是0時,Z標(biāo)志被設(shè)置成1
S符號標(biāo)志,當(dāng)指令運行結(jié)果為負數(shù)時,S標(biāo)志被設(shè)置成1
C進位標(biāo)志,
標(biāo)志被設(shè)置指將其值設(shè)置成1,被清除表示設(shè)置值為0
10、在OD的反匯編窗口選擇一條指令點擊空格或雙擊鼠標(biāo)可以打開修改當(dāng)前選中指令的修改指令窗口,在窗口中可以輸入新值,之后點擊匯編按鈕即可完成修改
11、寄存器是CPU內(nèi)部高速存儲單元,比內(nèi)存快很多
12、NOP,無操作指令,每一個NOP占用一個字節(jié),它對應(yīng)的字節(jié)碼是90,當(dāng)在OD匯編窗口中修改指令時,OD會根據(jù)原有指令的長度來判斷,如果是將長指令修改成短指令那么OD就會將原有長指令在替換成短指令時使用NOP來填充多余的字節(jié)
13、堆棧中顯示的值其實是數(shù)據(jù)窗口中倒序過來的值,如PUSH [401888], 如果數(shù)據(jù)窗口中對應(yīng)401888處保存的是CA 98 36 22,那么在執(zhí)行完P(guān)USH [401888]后在堆棧中顯示的值會是22 36 98 CA;另外 [401888]表示的是內(nèi)存單元401888存儲的值,而不加括號直接PUSH 401888則表示將數(shù)值401888壓入堆棧,PUSH [X] 與PUSH X是兩個完全不同的概念
14、PUSH X,執(zhí)行前后OD中堆棧的變化是原有內(nèi)容下移,之后最上面新增一條數(shù)據(jù),即新的棧頂;
15、POP X,執(zhí)行前后OD中堆棧的變化是原有內(nèi)容上移,之后原來最上面中的數(shù)據(jù)存儲到X中
16、LEA取地址指令,
17、XCHG交換寄存器與寄存器的值,或交換寄存器與內(nèi)存單元的值
18、INC 執(zhí)行加1, ADD有兩個操作數(shù),后面是值;DEC是減1
19、ADC帶進位的加, 如ADC EAX,3表示 EAX=EAX+3+C(進位標(biāo)志的值);SBB帶進位的減與ADC剛好相反的功能
20、MUL無符號數(shù)的乘法,只有一個操作數(shù)與EAX中的值相乘,結(jié)果保存在EDX:EAX中
21、在OD中修改一條指令時,數(shù)字的頭一位不能是字符,如mov eax, FF123989這樣寫來修改原有的指令OD會報錯,這時可以在數(shù)字前加0來解決OD的這個問題,即mov eax, 0FF123989
22、IMUL是有符號乘法,它可以使用一個或兩個、三個操作數(shù),使用一個時與MUL保存結(jié)果方式相同還是存儲在EDX:EAX中,而兩個或三個操作數(shù)時結(jié)果保存在第一個操作數(shù)中,但是這種三個操作數(shù)的乘法最終的結(jié)果可能有一部分會被丟棄,因空間不夠大
23、NEG指操作數(shù)符號即反
24、邏輯指令,有兩個操作數(shù),并將結(jié)果保存在第一個操作數(shù)里
25、AND按位與,OR按位或,XOR按位異或(即不同時取1,相同時為0),NOT按位取反
26、JZ當(dāng)標(biāo)志Z被置1就跳轉(zhuǎn),否則不跳轉(zhuǎn)
27、AX長度是word, AL長度是BYTE, EAX長度是dword,所以使用指令訪問內(nèi)存單元時要這樣, mov eax, dwrod ptr ds:[x]; mov ax, word ptr ds:[x]; mov al, byte ptr ds:[x]
28、TEST EAX, EAX用來判斷EAX的值是否為0,test指令用來將兩個操作數(shù)按位與
29、所有的跳轉(zhuǎn)指令都會指向?qū)⒁D(zhuǎn)到的地址
JMP跳轉(zhuǎn);JE,JZ結(jié)果為0則跳轉(zhuǎn);JNE,JNZ結(jié)果不為0則跳轉(zhuǎn);JS結(jié)果為負則跳轉(zhuǎn);JNS結(jié)果不為負則跳轉(zhuǎn);JP,JPE結(jié)果中1的個數(shù)為偶數(shù)則跳轉(zhuǎn);JNP,JNPE結(jié)果中1的個數(shù)為奇數(shù)則跳
JO結(jié)果溢出則跳轉(zhuǎn);JNO結(jié)果沒有溢出則跳轉(zhuǎn);JB,JNAE小于則跳轉(zhuǎn)(無符號數(shù));JNB,JAE大于等于則跳轉(zhuǎn)(無符號數(shù));JBE,JNA小于等于則跳轉(zhuǎn)(無符號數(shù));
JNBE,JA大于則跳轉(zhuǎn)(無符);JL,JNGE小于則跳轉(zhuǎn)(有符號數(shù));JNL,JGE大于等于則跳轉(zhuǎn)(有符號);JLE,JNG小于等于則跳轉(zhuǎn)(有符號數(shù));JNLE,JG大于則跳轉(zhuǎn)(有符號)
30、溢出的方法,在OD中將EAX的值設(shè)置成7FFFFFFF,之后執(zhí)行INC EAX,這樣就溢出了
31、OD允許調(diào)試人員只是查看將要執(zhí)行的CALL而不真正執(zhí)行,點擊鼠標(biāo)右鍵選擇跟隨(或Follow),現(xiàn)在看完了call中的代碼了想回到之前call的位置怎么辦?點擊減號來回到按了跟隨的那一行;
如果想從Call里跳出執(zhí)行可以點擊F8,如果想跟蹤執(zhí)行可以點擊F7
32、進入到Call代碼段后,如何判斷這個子函數(shù)的結(jié)尾呢?在代碼段中找ret/retn這就是函數(shù)結(jié)束的標(biāo)志命令
33、PUSH X ;ret 這兩條指令執(zhí)行完后會跳轉(zhuǎn)到X指定的位置,這與JMP X等效;
34、一般情況下如果在OD中改動了代碼,需要重新使用OD分析代碼(右鍵“分析/分析代碼”);有時OD的分析代碼有問題,則可以刪除分析(右鍵"分析/刪除分析")
35、在堆棧窗口中可以通過選擇某一行并點擊回車來讓匯編窗口跳轉(zhuǎn)到堆棧窗口中顯示的位置,這一方法常用用來查看函數(shù)返回
36、一般使用ECX做為循環(huán)里的計數(shù)器,LOOP也是使用ECX做為計數(shù)器的,每次減1,直到計數(shù)器為0時退出循環(huán);注,使用LOOP的效率一般要低于直接TEST X, X和JNZ組合;
類似的循環(huán)指令還有LOOPZ,LOOPE,LOOPNZ,LOOPNE,這些指令退出除了要檢查計數(shù)器外還要檢查標(biāo)志Z,前面兩個Z為1且計數(shù)器為0時退出循環(huán),后面兩個計數(shù)器為0且Z為0;
37、拷貝字符串指令,MOVS D, S可以拷貝4字節(jié),如movs dword ptr ES:[EDI], dowrd ptr DS:[ESI]
movsw可以拷貝兩個字節(jié),movsb拷貝一個字節(jié)
38、REP MOVS,結(jié)合計數(shù)器ECX,可以重復(fù)執(zhí)行movs;源指針ESI和目的指針EDI每次遞增4或者遞減4(遞增或遞減取決于方向標(biāo)志位D)
39、LODS指令從源地址ESI拷貝數(shù)到EAX中,如,lods ptr ds:[esi];另外,lods也可以結(jié)合前綴rep使用;lods對應(yīng)的兩字節(jié)和一字節(jié)版本為lodsw和lodsb
40、STOS指令將EAX的值拷貝到EDI指定的內(nèi)存單元,如stos ptr es:[edi];
41、CMPS指令比較指向esi,edi內(nèi)存單元的內(nèi)容
42、直接尋址指"不需要任何有關(guān)地址的解析或計算,地址的值是純數(shù)字", jmp 428898, call 389398, mov dword ptr [00419988],ecx
43、間接尋址指只有在執(zhí)行到這條指令時才能知道地址的值,如 jmp eax, call eax, mov eax, dword ptr [ecx], push [ebp+8]
44、OEP原始入口點,使用OD加載程序有99%的程序會默認停止在入口點,只有反調(diào)試的程序不會
45、OD在可以右鍵跳轉(zhuǎn)在表達式里輸入函數(shù)名稱或地址來查看函數(shù)的實現(xiàn),跳轉(zhuǎn)到函數(shù)的實現(xiàn)代碼段后,可以使用減號回到EIP處
46、可以在OD的命令欄中輸入?MessageBoxA來查看函數(shù)的地址
47、bp 函數(shù),指在函數(shù)的第一條指令處設(shè)置斷點,注不是函數(shù)的調(diào)用處,除非這個函數(shù)無參數(shù),否則會執(zhí)行到第一個PUSH指令處暫停
48、在OD在執(zhí)行過分析代碼后,如果感覺OD分析的有問題,可以刪除OD的代碼分析,刪除分析后大多數(shù)情況下會顯示有意義的匯編代碼
49、當(dāng)使用OD設(shè)置斷點時,OD會將對應(yīng)指令處的第一個字節(jié)替換成CC(int 3),但是OD為了不影響界面顯示效果,OD會將CC顯示成原來的字節(jié),
那么我們怎么驗證OD替換指令第一個字節(jié)為CC?
50、bpx 函數(shù)a,它用來設(shè)置所有與函數(shù)a相關(guān)調(diào)用設(shè)置斷點
51、內(nèi)存訪問斷點,顧名思義當(dāng)任何代碼訪問(讀、寫、執(zhí)行)該處的代碼都會觸發(fā)斷點;注,內(nèi)存訪問斷點不會顯示在"斷點列表中";一次只能設(shè)置一個內(nèi)存訪問斷點,不能在程序運行期間設(shè)置多個內(nèi)存訪問斷點,也就是說,設(shè)置一個內(nèi)存訪問斷點后,后面的會覆蓋前面的斷點
52、內(nèi)存訪問斷點的另一種設(shè)置方法是,為m窗口內(nèi)的模塊來設(shè)置段內(nèi)存訪問斷點,這種方式設(shè)置的斷點影響的范圍是整個模塊,如對模塊user32.dll設(shè)置了內(nèi)存訪問斷點,那么只要訪問了user32.dll內(nèi)存區(qū)域內(nèi)的任意地址都會觸發(fā)斷點
53、如果想從其他模塊的執(zhí)行返回到主程序模塊,可以點擊Alt+F9或者找到函數(shù)的返回地址后點擊F7進入
54、同一個函數(shù)如果使用bp設(shè)置斷點無效的話,可以嘗試設(shè)置內(nèi)存訪問斷點
55、硬件斷點,分為三種,硬件執(zhí)行、硬件訪問、硬件寫斷點,可以在命令欄中輸入”HE 地址“(或HE 函數(shù)名)來設(shè)置硬件執(zhí)行斷點;OD中最多可以同時設(shè)置4個硬件斷點
硬件訪問/寫入斷點是斷在觸發(fā)硬件斷點的下一條指令處。如果我們想在讀取或者寫入4020CA地址處的內(nèi)容的時候斷下來的話,我們給該地址設(shè)置1個字節(jié)的硬件訪問斷點即可
56、條件斷點
57、條件記錄,比如現(xiàn)在想要記錄MessageBoxA函數(shù)的所有返回地址、MessageBoxA調(diào)用時傳入的參數(shù),那么就可以在條件記錄中設(shè)置表達式為[esp],設(shè)置暫停為從不、設(shè)置記錄表達式為永遠、設(shè)置函數(shù)參數(shù)值為永遠即可
58、消息斷點,設(shè)置消息斷點需要在打開目標(biāo)窗口之后,在od中打開w窗口,之后可以看到當(dāng)前打開的被調(diào)試目標(biāo)的窗口上所有可以設(shè)置消息斷點的窗口
“在程序獲取我們輸入的數(shù)據(jù)時,讓程序中斷下來”,可以采用消息斷點結(jié)合主程序內(nèi)存斷點的方式快速定位到主程序中哪里代碼是用來獲取用戶輸入數(shù)據(jù)的
59、硬編碼序列號指由固定的字符和數(shù)字構(gòu)成的固定不變的字符串
60、OD中查看地址中存儲的值,可以在反匯編窗口下面的數(shù)據(jù)窗口中跳轉(zhuǎn)到對應(yīng)的地址查看;找到關(guān)鍵API(MessageBoxA, GetDlgItemTextA, GetWindowTextA, lstrcmpA)下斷點
61、MOVSX指令將指定字節(jié)保存到EDX中,如果該字節(jié)是正數(shù),高位補零,如果該字節(jié)為負數(shù)高位補1
62、硬編碼注冊碼的破解技巧總結(jié)
1)利用輸入的錯誤注冊碼找到與正確注冊比較的關(guān)鍵代碼
(1)方法一、通過MessageBox來定位,如果比較后程序給用戶的提示是使用MessageBox來告知用戶注冊碼輸入錯誤的,那么可以根據(jù)MessageBox的返回地址找到關(guān)鍵代碼
(2)方法二、如果程序中使用的是自定義的提示框來提示用戶注冊碼輸入的結(jié)果,此時要怎么確認關(guān)鍵代碼?
答案是,找到關(guān)鍵時機,什么樣的關(guān)鍵時機呢?我們知道注冊碼的校驗流程是從用戶的輸入開始,終止于告知用戶輸入注冊碼正確與否的提示框,
那么比較注冊碼的關(guān)鍵代碼必定出現(xiàn)在用戶輸入注冊碼之后、提示框出現(xiàn)之前,所以,我們可以以鍵盤轉(zhuǎn)換函數(shù)GetWindowText或TranslateMessage為切入點,
在他上面設(shè)置斷點,等待用戶輸入完成后得到輸入的錯誤注冊碼在內(nèi)存中保存的地址A,之后在A上設(shè)置內(nèi)存訪問斷點,之后F9運行程序等待程序訪問地址A,從而找到關(guān)鍵代碼
注,如果程序入口不在401000(程序可能加殼了),那么在od加載程序時不要讓od分析,等待程序運行起來后,在od的m窗口中找到401000代碼區(qū)域并設(shè)置內(nèi)存訪問斷點,
之后等待程序在主模塊中中斷下來,這樣再來查找程序主模塊中的函數(shù)列表、字符串。
在程序剛剛加載的時候不能這么做,因為那個時候我們查看當(dāng)前模塊使用的API的話是查看的殼所在模塊使用的API函數(shù)
方法二中,如果使用的是函數(shù)TranslateMessage來確認錯誤注冊碼在內(nèi)存中的位置從而找到關(guān)鍵代碼的話,
需要在函數(shù)TranslateMessage設(shè)置斷點時設(shè)置條件MSG=WM_LBUTTONDOWN,這樣當(dāng)在程序中輸入錯誤的注冊碼后,通過點擊鼠標(biāo)左鍵來觸發(fā)設(shè)置在TranslateMessage函數(shù)的斷點,
此時的注冊碼已經(jīng)輸入完,所以內(nèi)存中已經(jīng)保存了你剛剛輸入的錯誤注冊碼,此后就可以在od的m窗口中通過查詢輸入的錯誤注冊碼找到對應(yīng)的地址
63.F2設(shè)置一般斷點,shift+F2設(shè)置條件斷點,shift+F4設(shè)置記錄斷點
原文地址:https://www.slvit.com/zdlDetail?id=68