OD汇编指令集(不断更新)
一、快捷鍵
F7 執(zhí)行一行代碼,遇到 CALL 等子程序時(shí)會(huì)進(jìn)入其中,進(jìn)入后首先會(huì)停留在子程序的第一條指令上。
F8 執(zhí)行一行代碼,遇到 CALL 等子程序不進(jìn)入其代碼。
F2 在顯著行設(shè)置斷點(diǎn),再次按 F2 刪除斷點(diǎn)。
F9 F9運(yùn)行調(diào)試程序,直到遇到斷點(diǎn)停止運(yùn)行,Debug->Run。
F12 臨時(shí)暫停程序,Debug-> Pause。
二、寄存器
ESP 指向堆棧最頂端的地址。
EIP 指向當(dāng)前將要執(zhí)行的指令的地址。
EAX ECX EDX EBX ESP EBP ESI EDI EIP——32位寄存器
EAX=0x12345678 AX=0x5678——16位寄存器 AH=0x56,AL=0x78
O/歐 溢出標(biāo)志
A 輔助進(jìn)位標(biāo)志/不關(guān)心
P 奇偶標(biāo)志,指令的結(jié)果用二進(jìn)制表示,該二進(jìn)制數(shù)中1的總個(gè)數(shù)為偶數(shù)時(shí),P標(biāo)志被設(shè)置。
Z 零標(biāo)志,當(dāng)運(yùn)算產(chǎn)生的結(jié)果為 0 時(shí)被設(shè)置。
S 符號(hào)標(biāo)志,這個(gè)標(biāo)志在運(yùn)算結(jié)果為負(fù)時(shí)設(shè)置為 1。
C 進(jìn)位/借位標(biāo)志,(無(wú)符號(hào)運(yùn)算的結(jié)果)在超過(guò)最大數(shù)值時(shí)設(shè)置為 1 ,可能是寄存器的值。
T,D 標(biāo)志和其它
三、匯編指令
指令
1.? 寄存器或數(shù)值——查看寄存器內(nèi)容,顯示數(shù)值的十進(jìn)制以及ASCII碼
NOP指令
2.替換指令:右鍵->Assemble 或 Space
3.在數(shù)據(jù)窗口查看指定內(nèi)存數(shù)據(jù):右鍵->“Go to”->“Expression”->輸入地址
4.撤銷修改的指令:選擇被替換的幾行->右鍵->“Undo Selection”
PUSH指令
5.push 401008
push [401008];內(nèi)存的倒序存儲(chǔ) = push DWORD PTR DS:[401008]
不明確規(guī)定,OD認(rèn)為都是4個(gè)字節(jié)內(nèi)存,DWORD
POP指令
6.POP EAX——從棧頂中取出第一個(gè)值存放到EAX中,隨后的一個(gè)值隨即變成棧頂。
PUSHAD指令
7.PUSHAD指令把所有通用寄存器的內(nèi)容按一定順序壓入到堆棧中
=push eax, push ecx, push edx, push ebx, push esp, push ebp, push esi, push edi
POPAD指令
8.POPAD指令與PUSHAD正好相反,它從堆棧中取值,并將它們放到相應(yīng)的寄存器中
=pop edi, pop esi, pop esp, pop ebx, pop edx, pop ecx, pop eax
MOV指令
9.該指令將第二個(gè)操作數(shù)賦值給第一個(gè)操作數(shù),例如:
MOV EAX, EBX;EBX值賦值給EAX。
mov [405000],eax——報(bào)錯(cuò),不能直接寫入內(nèi)存
MOVSX(帶符號(hào)擴(kuò)展的傳送指令)
10.第二個(gè)操作數(shù)可能一個(gè)寄存器也可能是內(nèi)存單元,第一個(gè)操作數(shù)的位數(shù)比第二個(gè)操作數(shù)多,第二個(gè)操作數(shù)的符號(hào)位填充第一個(gè)操作數(shù)剩余部分
eax=00401008,bx=e000
movsx eax,bx
eax=ffffe000,bx=e000
16位范圍,0000-7fff 正數(shù) 8000-ffff 負(fù)數(shù)
MOVZX(帶0擴(kuò)展的傳送指令)
11.MOVZX類似于前面的語(yǔ)句,但是這種情況下,剩余的部分不根據(jù)第二個(gè)操作數(shù)的正負(fù)來(lái)進(jìn)行填充。我們這里不提供范例,因?yàn)楹蜕厦媸窍嗨频?剩余的部分總是被填充為0。
LEA(取地址指令)
12.第一個(gè)操作數(shù)是一個(gè)通用寄存器,并且第二個(gè)操作數(shù)是一個(gè)內(nèi)存單元。
lea eax,dword ptr ds:[ecx+38]
ecx=12ffb0
實(shí)質(zhì)是 eax=ecx+38
eax=12ffe8
XCHG(交換 寄存器/內(nèi)存單元 和 寄存器)
13.該指令交換兩個(gè)操作數(shù)的值;也可以使用這個(gè)指令來(lái)交換寄存器和內(nèi)存單元的值
XGHG EAX,ECX
四、數(shù)學(xué)指令
INC 和 DEC指令
14.INC EAX ; 使EAX+1
DEC EAX ; 使EAX-1
INC DWORD PTR DS:[405000]
INC WORD PTR DS:[405000]
ADD指令
ADD指令有兩個(gè)操作數(shù),相加后的結(jié)果存放到第一個(gè)操作數(shù)中。ADD EAX,1等價(jià)于INC EAX。
ADC指令(帶進(jìn)位的加法)
15.兩個(gè)操作數(shù)的和加上進(jìn)位標(biāo)志的值,結(jié)果存放到第一個(gè)操作數(shù)中。
SUB指令
16.這個(gè)指令與ADD剛好相反-它將第一個(gè)操作數(shù)減去第二個(gè)操作數(shù)的值存放到第一個(gè)操作數(shù)中。
SBB指令
17.該指令跟ADC正好相反,它計(jì)算兩個(gè)操作數(shù)的差值,并且還要減去進(jìn)位標(biāo)志,結(jié)果存放到第一個(gè)操作數(shù)中。
MUL(無(wú)符號(hào)數(shù)的乘法)
18.有兩種乘法,第一個(gè)種是MUL,這種是無(wú)符號(hào)數(shù)乘法,只有一個(gè)操作數(shù),另一個(gè)操作數(shù)是EAX,結(jié)果存放到EDX:EAX中
MUL ECX ; EDX:EAX=EAX*ECX
IMUL(有符號(hào)數(shù)的乘法)
19.IMUL指令用法類似于MUL。操作數(shù)可以有1個(gè) 2個(gè) 或 3個(gè)
IMUL ECX; 該指令將有有符號(hào)數(shù)ECX乘以EAX,結(jié)果存放到EDX:EAX中。
IMUL EDX, DWORD PTR [EBP-18]; EDX x [EBP-18] -> EDX
IMUL EBP, DWORD PTR [ESI+74],FF800002; [ESI+74] x FF800002 -> EBP
DIV/IDIV指令
20.這兩個(gè)指令反別與MUL和IMUL相反。
DIV只有一個(gè)操作數(shù),該操作數(shù)必須是無(wú)符號(hào)數(shù),結(jié)果存放到EDX:EAX中。
IDIV指令經(jīng)常被使用。
如果是一個(gè)操作數(shù)的話,那么它和DIV類似,只不過(guò)操作數(shù)是有符號(hào)的,結(jié)果依然保存在EDX:EAX中。
兩個(gè)操作數(shù)的情況,第一個(gè)操作數(shù)除以第二個(gè)操作數(shù),結(jié)果存放到第一個(gè)操作數(shù)中。
三個(gè)操作數(shù)的情況,第二個(gè)操作數(shù)除以第三個(gè)操作數(shù),結(jié)果存放到第一個(gè)操作數(shù)中。
1- div除法指令
(1) 除數(shù): 有8位和16位兩種,在一個(gè)寄存器或內(nèi)存單元中.
(2) 被除數(shù): 默認(rèn)放在AX和DX或AX中
除數(shù)為8位, 被除數(shù)為16位, 默認(rèn)在AX中存放.
除數(shù)為16位, 被除數(shù)為32位, 在DX或AX中存放. AX存放低16位,DX存放高16位.
(3) 結(jié)果
除數(shù)為8位, 則AL存儲(chǔ)除法操作的商, AH存放余數(shù)
除數(shù)為16為, 則AX存儲(chǔ)除法操作的商, DX存放余數(shù)
XADD指令(交換并相加)
21.這個(gè)指令其實(shí)就是XCHG和ADD兩個(gè)簡(jiǎn)單指令的組合,相加的結(jié)果放到第1個(gè)操作數(shù)中。
NEG指令
22.取補(bǔ)指令,負(fù)數(shù)的補(bǔ)碼是取反再加1,正數(shù)的補(bǔ)碼是它本身;
邏輯指令
邏輯指令有兩個(gè)操作數(shù),兩操作數(shù)按位運(yùn)算,并將結(jié)果存放到第一個(gè)操作數(shù)中。
AND OR XOR(同為零,異為一) NOT(按位取反)
ebx=38 neg ffffffc8
neg != not
五、比較和條件跳轉(zhuǎn)指令
CMP指令(判斷2個(gè)操作數(shù)是否相等)
23.該指令是比較兩個(gè)操作數(shù),實(shí)際上,它相當(dāng)于SUB指令,但是相減的結(jié)構(gòu)并不保存到第一個(gè)操作數(shù)中。
只是根據(jù)相減的結(jié)果來(lái)改變零標(biāo)志位的,當(dāng)兩個(gè)操作數(shù)相等的時(shí)候,零標(biāo)志位 Z 置1。
符號(hào)標(biāo)志位 S 是比較第一個(gè)操作數(shù)是否大于第二個(gè)操作數(shù)。
CMP EAX,ECX; 若EAX > ECX,則Z=0,S=0
若EAX < ECX,則Z=0,S=1
CMP AX,WORD PTR DS:[405000]
CMP AL,BYTE PTR DS:[405000]
TEST(邏輯比較)
24.該指令在一定程序上和CMP指令時(shí)類似的,兩個(gè)數(shù)值進(jìn)行與操作,結(jié)果不保存,但是會(huì)改變相應(yīng)標(biāo)志位(比如說(shuō),SF,ZF,PF標(biāo)志位),程序可以根據(jù)結(jié)果來(lái)決定是否跳轉(zhuǎn)到相應(yīng)的分支。
TEST EAX,EAX; 用這個(gè)指令,可以確定EAX是否等于0。
邏輯指令
JMP - 跳轉(zhuǎn)
JE, JE - 結(jié)果為零則跳轉(zhuǎn) Z=1
JNE, JNZ - 結(jié)果不為零則跳轉(zhuǎn)
JS - 結(jié)果為負(fù)則跳轉(zhuǎn) S=1
JNS - 結(jié)果不為負(fù)則跳轉(zhuǎn)
JP, JPE - 結(jié)果中1的個(gè)數(shù)為偶數(shù)則跳轉(zhuǎn) P=1
JNP, JNPE – 結(jié)果為1的個(gè)數(shù)為奇數(shù)則跳轉(zhuǎn)
JO - 結(jié)果溢出了則跳轉(zhuǎn) O=1
JNO – 結(jié)果沒(méi)有溢出則跳轉(zhuǎn)
JB, JNAE – 小于則跳轉(zhuǎn)(無(wú)符號(hào)數(shù)) 進(jìn)位/借位標(biāo)志位 C=1
JNB, JAE – 大于等于則跳轉(zhuǎn)(無(wú)符號(hào)數(shù)) C=0
JBE, JNA – 小于等于則跳轉(zhuǎn)(無(wú)符號(hào)數(shù)) C=1 或 Z=1
JNBE, JA – 大于則跳轉(zhuǎn)(無(wú)符號(hào)數(shù)) C=0 且 Z=0
JL, JNGE – 小于則跳轉(zhuǎn)(有符號(hào)數(shù)) S = 1
JNL, JGE – 大于等于則跳轉(zhuǎn)(有符號(hào)數(shù))
JLE, JNG – 小于等于則跳轉(zhuǎn)(有符號(hào)數(shù)) Z=1 或者 S!=OF
JNLE, JG – 大于則跳轉(zhuǎn)(有符號(hào)數(shù)) Z=0 或者 S=OF
SHR - 邏輯右移指令
SAR - 算術(shù)右移指令
六、循環(huán) 字符串指令和尋址方式
LOOP指令(循環(huán)指令)
25.通常循環(huán)執(zhí)行的次數(shù)放在ECX中,LOOP指令執(zhí)行時(shí):
a.ECX = ECX-1
b.判斷ECX中的值,不為零則轉(zhuǎn)移到標(biāo)號(hào)處執(zhí)行程序,如果為零,則向下執(zhí)行。
LOOPZ,LOOPE 重復(fù)循環(huán),直到零標(biāo)志位Z置1
LOOPNZ,LOOPNE 重復(fù)循環(huán),直到零標(biāo)志位Z清0
串操作
MOVS指令(另一種形式MOVSD)
26.該指令是從一個(gè)地址向另一個(gè)地址復(fù)制數(shù)據(jù)。源地址保存在ESI寄存器中,目的地址保存在EDI寄存器中。
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
MOVSW——拷貝兩個(gè)字節(jié)
MOVSB——拷貝一個(gè)字節(jié)
拷貝的方向取決于方向標(biāo)志位D,D=0時(shí)從后往前拷貝。
REP指令(從一個(gè)地址單元拷貝任意數(shù)目的字節(jié)內(nèi)容到另一個(gè)地址單元)
27.該指令可做為前面介紹的一些指令的前綴,尤其是MOVS指令,該前綴表示當(dāng)前指令需要執(zhí)行的次數(shù)ECX,每次循環(huán)計(jì)數(shù)器ECX的值遞減1,和前面介紹的循環(huán)一樣。
REP MOVS不一定拷貝是4個(gè)字節(jié),它拷貝的大小為【每次拷貝的大小 * ECX】,源指針ESI和目的指針EDI每次遞增4或者遞減4(遞增或遞減取決于方向標(biāo)志位D)。
REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
注:MOVS指令不能將數(shù)據(jù)拷貝到?jīng)]有寫入權(quán)限的內(nèi)存單元中,強(qiáng)制寫入的話會(huì)引發(fā)異常。
類似指令:REPE/REPZ/REPNZ/REPNE
SCASB,SCASW, SCASD。這三個(gè)指令把a(bǔ)l ax eax中的值同edi尋址到的目標(biāo)內(nèi)存中的字節(jié)或字或雙字相比較。(即al,ax,eax與edi尋址后的內(nèi)存值進(jìn)行比較)這些指令在一個(gè)長(zhǎng)字符串或數(shù)組中查找一個(gè)值的時(shí)候特別有用。如果使用REPE(或REP 前綴),REP前綴是當(dāng)ecx寄存器>0時(shí),重復(fù)。 而REPE前綴是零標(biāo)志位(zf=1), 并且ecx>0時(shí)重復(fù)。
REPNE,這個(gè)前綴剛好和REPE是反的。 也就是它是如果我們的ZF=0且ECX>0進(jìn)行重復(fù),只要滿足這兩個(gè)條件它就進(jìn)行重復(fù),如果不滿足則不進(jìn)行重復(fù),所以REPNE一般我們用來(lái)掃描字符串。
(1) lodsb、lodsw:把DS:SI指向的存儲(chǔ)單元中的數(shù)據(jù)裝入AL或AX,然后根據(jù)DF標(biāo)志增減SI
(2) stosb、stosw:把AL或AX中的數(shù)據(jù)裝入ES:DI指向的存儲(chǔ)單元,然后根據(jù)DF標(biāo)志增減DI
(3) movsb、movsw:把DS:SI指向的存儲(chǔ)單元中的數(shù)據(jù)裝入ES:DI指向的存儲(chǔ)單元中,然后根據(jù)DF標(biāo)志分別增減SI和DI
(4) scasb、scasw:把AL或AX中的數(shù)據(jù)與ES:DI指向的存儲(chǔ)單元中的數(shù)據(jù)相減,影響標(biāo)志位,然后根據(jù)DF標(biāo)志分別增減SI和DI
(5) cmpsb、cmpsw:把DS:SI指向的存儲(chǔ)單元中的數(shù)據(jù)與ES:DI指向的存儲(chǔ)單元中的數(shù)據(jù)相減,影響標(biāo)志位,然后根據(jù)DF標(biāo)志分別增減SI和DI
(6) rep:重復(fù)其后的串操作指令。重復(fù)前先判斷CX是否為0,為0就結(jié)束重復(fù),否則CX減1,重復(fù)其后的串操作指令。主要用在MOVS和STOS前。一般不用在LODS前。
上述指令涉及的寄存器:段寄存器DS和ES、變址寄存器SI和DI、累加器AX、計(jì)數(shù)器CX
涉及的標(biāo)志位:DF、AF、CF、OF、PF、SF、ZF
LOOP指令
REP前綴也可以與LOOPS指令配合使用,他們會(huì)重復(fù)執(zhí)行直到計(jì)數(shù)器ECX的值為0.
LODS 指令 :取字符串?dāng)?shù)據(jù)指令(Load String Instruction)
從源地址DS:SI所指向的內(nèi)存單元開始,LODSB LODSW LODSD 取一個(gè)字節(jié)、字或雙字,送入AL、AX或EAX中,并根據(jù)標(biāo)志位DF對(duì)寄存器SI作相應(yīng)增減。該指令的執(zhí)行不影響任何標(biāo)志位。
當(dāng)方向標(biāo)志位DF=0時(shí),則SI自動(dòng)增加1、2或4;DF=1時(shí),SI自動(dòng)減小1、2或4。
STOS指令 : 置字符串?dāng)?shù)據(jù)指令(Store String Instruction)
該指令是把寄存器AL、AX或EAX中的值存于以指針ES:[DI]所指向內(nèi)存單元為起始的一片存儲(chǔ)單元里,并根據(jù)標(biāo)志位DF對(duì)寄存器DI作相應(yīng)增減。該指令不影響任何標(biāo)志位。
MOVS指令:字符串傳送指令(Move String Instruction)
該指令是把指針DS:SI所指向的字節(jié)、字或雙字傳送給指針ES:DI所指向內(nèi)存單元,并根據(jù)標(biāo)志位DF對(duì)寄存器DI和SI作相應(yīng)增減。該指令的執(zhí)行不影響任何標(biāo)志位。
CMPS指令
30.該指令比較ESI和EDI指向內(nèi)存單元的內(nèi)容,該指令執(zhí)行的是算數(shù)減法運(yùn)算。
CMPS DWORD PTR [ESI],DWORD PTR [EDI]
該指令影響零標(biāo)志位Z,所以可以配合REPE/REPZ前綴指令使用,直到計(jì)數(shù)器ECX的值為0或者零標(biāo)志位清0.
sete cl - 設(shè)置指令,根據(jù)ZF標(biāo)志位來(lái)設(shè)置cl的值,如果ZF=1,則cl=1,否則cl=0;
七、斷點(diǎn)
普通斷點(diǎn)【B】——斷點(diǎn)窗口
31.當(dāng)我們?cè)O(shè)置斷點(diǎn)后,OD會(huì)將對(duì)應(yīng)指令處第一個(gè)字節(jié)指令替換成CC。但是為了不影響界面顯示效果,OD會(huì)將CC顯示為原字節(jié)。但是,我們可以在內(nèi)存單元中讀取出其真實(shí)的內(nèi)容,并且可以在反調(diào)試中用此方法來(lái)檢測(cè)斷點(diǎn)。所以,我們?cè)O(shè)置的斷點(diǎn)有時(shí)候莫名其妙的消失了不要感到奇怪,或許說(shuō)這是調(diào)試器的本身的弱點(diǎn)吧。
內(nèi)存斷點(diǎn)
32.不能設(shè)置多個(gè);不會(huì)出現(xiàn)【B】斷點(diǎn)列表和其他的地址。
33.當(dāng)我們對(duì)指定內(nèi)存單元沒(méi)有寫權(quán)限,嘗試寫入的時(shí)候會(huì)觸發(fā)異常,OD會(huì)攔截到這個(gè)異常,并中斷下來(lái),我們看到斷下來(lái)的時(shí)候,OD已經(jīng)將內(nèi)存頁(yè)的訪問(wèn)屬性設(shè)置正常了。
34.對(duì)區(qū)段設(shè)置內(nèi)存斷點(diǎn)【M】,嘗試執(zhí)行當(dāng)前代碼段的任何一條指令都會(huì)觸發(fā)內(nèi)存訪問(wèn)斷點(diǎn)。
比如對(duì)Kernel32.dll設(shè)置斷點(diǎn),則調(diào)用該dll中的函數(shù)GetModuleHandleA會(huì)觸發(fā)斷點(diǎn),并且執(zhí)行GetModuleHandleA的每一條指令都會(huì)觸發(fā)。
35.返回主程序模塊:-Debug-Execute till user code,或者在函數(shù)返回指令處設(shè)置斷點(diǎn),中斷下來(lái)后再按F7或F8單步到主程序代碼中。
硬件斷點(diǎn)(簡(jiǎn)稱HBP)
36.硬件斷點(diǎn)分為硬件執(zhí)行斷點(diǎn)(ON EXECUTION),硬件寫入斷點(diǎn)(ON WRITE),硬件訪問(wèn)斷點(diǎn)(ON ACCESS)3種,OD中最多設(shè)置4個(gè)硬件斷點(diǎn)。
硬件執(zhí)行斷點(diǎn)和普通的CC斷點(diǎn)作用一樣,但硬件執(zhí)行斷點(diǎn)并不會(huì)將指令首字節(jié)修改為CC,所以更難檢測(cè)。
右鍵-Breakpoint-Hardware,on execution
HE 401013
單個(gè)硬件寫入斷點(diǎn)或者硬件訪問(wèn)斷點(diǎn)可以設(shè)置1,2或者4個(gè)字節(jié)的長(zhǎng)度,不論我們選擇的數(shù)據(jù)范圍有多大,只有前4個(gè)字節(jié)會(huì)起作用。
硬件訪問(wèn)/斷點(diǎn)斷在了觸發(fā)硬件斷點(diǎn)的下一條指令處。
條件斷點(diǎn)
EAX==400000
37.條件斷點(diǎn)實(shí)際上就是普通的CC斷點(diǎn),只不過(guò)該斷點(diǎn)的觸發(fā)需要滿足設(shè)置的條件,如果滿足設(shè)置的條件,那么程序就會(huì)中斷下來(lái),如果不滿足條件的話,就和沒(méi)有設(shè)置CC斷點(diǎn)差不多。
條件記錄斷點(diǎn)【L】——日志窗口
38.通過(guò)設(shè)置該斷點(diǎn)來(lái)記錄下設(shè)置的條件的精確值。
我們給一個(gè)API函數(shù)設(shè)置條件記錄斷點(diǎn),程序中有很多地方調(diào)用了這個(gè)API函數(shù),通過(guò)該條件記錄斷點(diǎn)我們可以精確的記錄程序中每處調(diào)用該API函數(shù)傳遞給它的內(nèi)容。
如果程序中有大約100處調(diào)用了該API函數(shù),你可以指定相應(yīng)的條件,比如說(shuō)返回地址。設(shè)置條件為[ESP] == 40137D,那么這100個(gè)函數(shù)調(diào)用中只有返回地址為40137D的會(huì)被記錄下來(lái)。
總結(jié)
以上是生活随笔為你收集整理的OD汇编指令集(不断更新)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 识货app如何关注好友
- 下一篇: 微机原理实验1:字符串匹配程序实验