解密入門教學(二)— 看雪學院
位
一個二進制位 ~ 一位
八位 ~ 一個字節
在內存中,以字節爲單位存儲信息。每一個字節單元給以一個唯一的存儲器地址(即物理地址)
八個二進制位 ~ 八位 ~ 一個字節 即可表示所有ASCII碼~ 一個英文字符或數字
十六個二進制位 ~ 十六位~ 兩個字節~ 兩個內存單元~ 一個漢字
三十二位 ~ 雙字
六十四位 ~ 四字
需要掌握的十六個寄存器
通用寄存器
八個,分別是EAX EBX ECX EDX ESP EBP EDI ESI
EAX EBX ECX EDX數據寄存器
主要用於暫時存放計算過程中所用的操作數、結果或其他信息。
除直接訪問外,還可分別對其高十六位和低十六位進行訪問。低十六位就是把它們前面的E去掉,即EAX的低十六位爲AX。
它們的低十六位又可以分別進行八位訪問。即AX還可分爲高八位AH和低八位AL。
所以,想操作的是一個八位數據:MOV AL或MOV AH
一個十六位數據:MOV AX
一個三十二位數據:MOV EAX
ESP EBP EDI ESI變址寄存器
主要用於在存儲器尋址時,提供偏移地址。只能用字來訪問。
沒看懂的一段:從386以後,所有的寄存器都可以用來存儲內存地址。(這裏給你講一個小知識,你在破解的時候是不是看到過[EBX]這樣的形式呢?這就是說此時EBX中裝的是一個內存地址,而真正要訪問的,就是那那個內存單元中所存儲的值)。
ESP堆棧指針寄存
堆棧是以“後進先出”方式工作的一個存儲區,它必須存在於堆棧段中,因而其段地址存放於SS寄存器中。它只有一個出入口,所以只有一個堆棧指針寄存器。
ESP的內容在任何時候都指向當前的棧頂。
堆棧的基址開始於一個高地址,然後每當有數據入棧,它就向低地址的方向進行存儲。相應的入棧指令是PUSH。
每當有一個數據入棧,ESP就跟着改變。總之,它永遠指向最後一個壓入棧的數據。
如果要用壓入棧的數據,就用相應的出棧指令POP,POP指令執行後,ESP會加上相應的數據位數。
原文摘錄:特別是現在到了Win32系統下面,堆棧的作用更是不可忽視,API所用的數據,均是靠堆棧來傳送的,即先將要傳送的數據壓入堆棧,然後CALL至API函數,API函數會在函數體內用出棧指令將相應的數據出棧,然後進行操作。許多明碼比較的軟件,一般都是在關鍵CALL前,將真假兩個註冊碼壓入棧。然後在CALL內出棧後進行比較。所以,只要找到這個關鍵CALL,就能在壓棧指令處,下d命令來查看真正的註冊碼。
EBP基址指針寄存器
ESP和EBP都可以與堆棧段寄存器SS聯用來確定堆棧中的某一存儲單元的地址。
ESP用來指示段頂的偏移地址,而EBP可作爲堆棧區中的一個基地址以便訪問堆棧中的信息。
ESI(源變址寄存器)和EDI(目的變址寄存器)一般與數據段寄存器DS聯用,用來確定數據段中某一存儲單元的地址。這兩個變址寄存器有自動增量和自動減量的功能,可以很方便地用於變址。
在串處理指令中,ESI和EDI作爲隱含的源變址和目的變址寄存器時,ESI和DS聯用,EDI和附加段ES聯用,分別達到在數據段和附加段中尋址的目的。
專用寄存器
兩個,EIP FLAGS
EIP指令指針寄存器 最重要哦!
用於存放代碼段中的偏移地址。在程序運行的過程中,它始終指向下一條指令的首地址。它與段寄存器CS聯用確定下一條指令的物理地址。
當這一地址送到存儲器後,控制器可以取得下一條要執行的指令,而控制器一旦取得這條指令就馬上修改EIP的內容,使它始終指向那些跳轉指令。
FLAGS標誌寄存器
又稱PSW(program status word)程序狀態寄存器
用於存放條件標識碼、控制標識和系統標識的寄存器。(標識:zhi四聲)
指令舉例:
Cmp EAX,EBX ; 用EAX EBX相減
JNZ 00470395 ; 不相等的話,就跳到這裏
這兩條指令就是用EAX裝的數減去EBX裝的數,來比較這兩個數是否相等。當Cmp指令執行後,就會在FLAGS的ZF(zero flag)零標誌位上置相應值,如果結果爲0,也就是他們兩個相等的話,ZF置1,否則置0。
其它還有OF(溢出標誌)SF(符號標誌)CF(進位標誌)AF(輔助進位標誌)PF(奇偶標誌)
段寄存器
六個,CS代碼段 DS數據段 ES附加段 SS堆棧段 FS附加段 GS附加段
常用匯編指令
CMP A,B 比較A與B。其中A B可以是寄存器或內存地址,也可同時是兩個寄存器,但不能同時都是內存地址。(許多明碼比較的軟件就用這個指令)
MOV A,B 把B的值送給A。其中A B可以是寄存器或內存地址,也可以同時是兩個寄存器,但不能同時都是內存地址。
Xor a,a 異或操作,主要是用來將a清空
LEA 裝入地址。例:LEA DX,string 將字符的地址裝入DX寄存器。
PUSH 壓棧
POP 出棧
ADD 加法指令。格式ADD DST,SRC
執行的操作:(DST)<-(SRC)+(DST)
SUB 減法指令。格式SUB DST,SRC
執行的操作:(DST)<-(DST)-(SRC)
MUL 無符號乘法指令。格式MUL SRC
執行的操作:字節操作(AX)<-(AL)*(SRC)
字操作 (DX,AX)<-(AX)*(SRC)
雙字操作(EDX,EAX)<-(EAX)*(SRC)
DIV 無符號除法指令。格式DIV SRC
執行的操作:字節操作(AL)<-(AX)/(SRC)的商
(AH)<-(AX)/(SRC)的餘數[1]
字操作 (AX)<-(DX,AX)/(SRC)的商
(DX)<-(DX,AX)/(SRC)的餘數[2]
雙字操作(EAX)<-(EDX,EAX)/(SRC)的商
(EDX)<-(EDX,EAX)/(SRC)的餘數[3]
[1]16們被除數在AX中,8位除數爲源操作數,結果的8位商在AL中,8位餘數在AH中。
[2]32位被除數在DX,AX中。其中DX爲高位字,16位除數爲源操作數,結果的16位商在AX中,16位餘數在DX中。
[3]64位的被除數在EDX,EAX中。其中EDX爲高位雙字;32位除數爲源操作數,結果的32位商在EAX中,32位餘數在EDX中。
NOP 無作用,可以用來抹去相應語句
CALL 調用子程序
控制轉移指令:
JE JZ 若相等則跳
JNE JNZ 若不相等則跳
JMP 無條件跳
JB JL 若小於則跳
JA JG 若大於則跳
JGE 若大於等於則跳
JLE 若小於等於則跳
進制轉換(計算機基礎課程中學過,在此不再重複)
Q&A
Q:寄存器可以隨便用麼,有沒有什麼限制?寫個程序的時候那些變量什麼的可以放在任意的寄存器麼?
A:寄存器有它的使用機制,及各個寄存器都有着明確的分工。
數據寄存器(EAX-EDX)它們都是通用寄存器,即在軟件中,任何數據都可存放於此。但除此之外,它們又可以用於各自的專用目的。
EAX可作爲累加器來使用,所以EAX是算數運算的主要寄存器。在乘除法等指令中指定用來存放操作數。比如在乘法中用AL或AX或EAX來裝被乘數,而AX或DX:AX或EAX或EDX:EAX則用來裝最後的積。
EBX一般在計算存儲器地址時用作基址寄存器。
ECX常用來保存計數值,如在移位指令它用來裝位移量、循環和串處理指令中作隱含的計數器。
EDX一般在作雙字長運算時把DX和AX組在一起存放一個雙字長數。
例:二進制數01101000110101000100100111010001,要把它寄存起來,就可以把0110100011010100(即高十六位)放在DX中,把0100100111010001(即低十六位)放在AX中,這個數表示爲DX:AX。當然完全可以用一個EDX就把這個數給裝下。此外,還可以用EDX:EAX來裝一個64位數據。
推薦的彙編參考書:《80x86彙編語言程序設計》沈美明主編