常見暫存器以及常見彙編指令,常見爆破指令 good

findumars發表於2013-12-26

CPU的任務就是執行存放在儲存器裡的指令序列。為此,除要完成算術邏輯操作外,還需要擔負CPU和儲存器以及I/O之間的資料傳送任務。早期的CPU晶片只包括運算器和控制器兩大部分。到了近幾年,為了使儲存器速度能更好地與運算器的速度相匹配,又在晶片中引入了高速緩衝儲存器。

除了高速緩衝儲存器之外的組成,大體上可以分為3個部分:
   1.算術邏輯部件ALU(arithmetic logic unit)用來進行算術和邏輯運算。這部分與我們的關係不太大,我們沒必要管它。
   2.控制邏輯。同樣與我們的關係不大。
   3.這個才是最最重要的。工作暫存器,它在計算機中起著重要的作用,每一個暫存器相當於運算器中的一個儲存單元,但它的存取速度卻賊快賊快,比儲存器要快很多了。它用來存放計算過程中所需要的或所得到的各種資訊,包括運算元地址、運算元及運算的中間結果等。下面我們專門的介紹這些暫存器。

大體上來說,你需要掌握的暫存器,有十六個,我一個一個給介紹給你:
      首先,介紹通用暫存器。
      一共八個,分別是EAX、EBX、ECX、EDX、ESP、EBP、EDI、ESI。
      其中,EAX—EDX這四個暫存器又可稱為資料暫存器,你除了直接訪問外,還可分別對其高十六位和低十六位(還計的我說它們是32位的嗎?)進行訪問。它們的低十六位就是把它們前邊兒的E去掉,即EAX的低十六位就是AX。而且它們的低十六位又可以分別進行八位訪問,也就是說,AX還可以再進行分解,即AX還可分為AH(高八位)AL(低八位)。其它三個暫存器請自行推斷。這樣的話,你就可以應付各種情況,如果你想操作的是一個八位資料,那麼可以用
      MOV AL (八位資料)或MOV AH
      十六位資料,可以用MOV AX
      三十二位的話,就用MOV EAX
      ───────────────────────
      │ │ │ │
      │ │ │ │
      │ 高十六位 EAX AH AX AL │
      │ │ │ │
      │ │ │ │
      ───────────────────────
      這四個暫存器,主要就是用來暫時存放計算過程中所用的運算元、結果或其它資訊。
      而ESP、EBP、EDI、ESI這四個呢,就只能用字來訪問,它們的主要用途就是在儲存器定址時,提供偏移地址。因此,它們可以稱為指標或變址暫存器。話說回來,從386以後,所有的暫存器都可以用來儲存記憶體地址。(這裡給你講一個小知識,你在破解的時候是不是看到過[EBX]這樣的形式呢?這就是說此時EBX中裝的是一個記憶體地址,而真正要訪問的,就是那那個記憶體單元中所儲存的值)。

      在這幾個暫存器中,ESP稱為堆疊指標寄存。堆疊是一個很重要的概念,它是以“後進先出”方式工作的一個儲存區,它必須存在於堆疊段中,因而其段地址存放於SS暫存器中。它只有一個出入口,所以只有一個堆疊指標暫存器。ESP的內容在任何時候都指向當前的棧頂。我這樣說你可能會覺的還是不明白,那我舉個例子吧,知道民工蓋房吧,假設有兩個民工,一個民工(以下簡稱民工A)要向地上鋪磚,另一個民工(以下簡稱民工B)給民工A遞磚,民工A趴在地上,手邊是民工B從遠處搬來的板磚,他拿起來就用,民工B從遠處搬來後,就還放在那一堆磚上,這樣,民工A拿著用後,民工B隨既就又補了上去,這就是後進先出。你在腦子裡想象一下這個這程。有沒有想明白,民工A永遠是從最上邊開始拿磚。堆疊就是這樣,它的基址開始於一個高地址,然後每當有資料入棧,它就向低地址的方向進行儲存。相應的入棧指令是PUSH。每當有資料入棧,ESP就跟著改變,總之,它永遠指向最後一個壓入棧的資料。之後,如果要用壓入堆疊的資料,就用出棧指令將其取出。相應的指令是POP,POP指令執行後,ESP會加上相應的資料位數。

      特別是現在到了Win32系統下面,堆疊的作用更是不可忽視,API所用的資料,均是靠堆疊來傳送的,即先將要傳送的資料壓入堆疊,然後CALL至API函式,API函式會在函式體內用出棧指令將相應的資料出棧。然後進行操作。以後你就會知道這點的重要性了。許多明碼比較的軟體,一般都是在關鍵CALL前,將真假兩個註冊碼壓入棧。然後在CALL內出棧後進行比較。所以,只要找到個關鍵CALL,就能在壓棧指令處,下d命令來檢視真正的註冊碼。具體內容會在後面詳細介紹,本章暫不予討論。

      另外還有EBP,它稱為基址指標暫存器,它們都可以與堆疊段暫存器SS聯用來確定堆疊中的某一儲存單元的地址,ESP用來指示段頂的偏移地址,而EBP可作為堆疊區中的一個基地址以便訪問堆疊中的資訊。ESI(源變址暫存器)和EDI(目的變址暫存器)一般與資料段暫存器DS聯用,用來確定資料段中某一儲存單元的地址。這兩個變址暫存器有自動增量和自動減量的功能,可以很方便地用於變址。在串處理指令中,ESI和EDI作為隱含的源變址和目的變址暫存器時,ESI和DS聯用,EDI和附加段ES聯用,分別達到在資料段和附加段中定址的目的。目前暫時不明白不要緊。

      接下來,接下來,介紹一下專用暫存器,呵呵,有沒有被這個名字嚇倒?看起來怪專業的。
      所謂的專用暫存器,有兩個,一個是EIP,一個是FLAGS。
      我們先來說這個EIP,可以說,EIP算是所有暫存器中最重要的一個了。它的意思就是指令指標暫存器,它用來存放程式碼段中的偏移地址。在程式執行的過程中,它始終指向下一條指令的首地址。它與段暫存器CS聯用確定下一條指令的實體地址。當這一地址送到儲存器後,控制器可以取得下一條要執行的指令,而控制器一旦取得這條指令就馬上修改EIP的內容,使它始終指向下一條指令的首地址。可見,計算機就是用EIP暫存器來控制指令序列的執行流程的。

      那些跳轉指令,就是通過修改EIP的值來達到相應的目的的。
      再接著我們說一下這個FLAGS,標誌暫存器,又稱PSW(program status
      word),即程式狀態暫存器。這一個是存放條件標誌碼、控制標誌和系統標誌的暫存器。
      其實我們根本不需要太多的去了解它,你目前只需知道它的工作原理就成了,我舉個例子吧:
      Cmp EAX,EBX ;用EAX與EBX相減, NZ 00470395 ;不相等的話,就跳到這裡;
      這兩條指令很簡單,就是用EAX暫存器裝的數減去EBX暫存器中裝的數。來比較這兩個數是不是相等,
當Cmp指令執行過後,就會在FLAGS的ZF(zero flag)零標誌位上置相應值,如果結果為0,也就是他們兩個相等的話,ZF置1,否則置0。其它還有OF(溢位標誌)SF(符號標誌)CF(進位標誌)AF(輔助進位標誌)PF(奇偶標誌)等。

      這些你目前沒必要了解那麼清楚,會用相應的轉移指令就行了。
      最後要介紹的就是段暫存器了(剛才是誰說的櫻紅?反正不是我)
      這部分暫存器一共六個,分別是CS程式碼段,DS資料段,ES附加段,SS堆疊段,FS以及GS這兩個還是附加段。
      其實現在到了Win32環境下,段暫存器以經不如DOS時代那樣重要了。 所以,我們知道就行了。

 

你可以去參考一些書籍。我始終覺的,你案頭有一本講彙編的書是非常非常有必要的,我這邊兒是清華版的《80x86組合語言程式設計》沈美明主編,46元。  

      我們接下來就再講一講一些常用的彙編指令吧。(由於考慮到目前以經有了相應的帖子,所以,我只是從彙編指令中,挑出一些最常用,需要掌握的,更多內容,還請參見書本。)

      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 減法指令 格式UB DST,SRC 執行的操作:(DST)<-(DST)-(SRC)
      MUL 無符號乘法指令 格式: MUL SRC
      執行的操作:位元組操作(AX)<-(AL)*(SRC);字操作(DX,AX)<-(AX)*(SRC);雙字操作:(EDX,EAX)<-(EAX)*(SRC)

      DIV 無符號除法指令 格式IV SRC
      執行的操作:位元組操作:16們被除數在AX中,8位除數為源運算元,結果的8位商在AL中,8位餘數在AH中。表示為:
      (AL)<-(AX)/(SRC)的商,(AH)<-(AX)/(SRC)的餘數。字操作:32位被除數在DX,AX中。其中DX為高位字,16位除數為源運算元,結果的16位商在AX中,16位餘數在DX中。表示為:(AX)<-(DX,AX)/(SRC)的商,(DX)<-(DX,AX)/(SRC)的餘數。

      雙字操作:64位的被除數在EDX,EAX中。其中EDX為高位雙字;32位除數為源運算元,結果的32位商在EAX中,32位餘數在EDX中。表示為:

      (EAX)<-(EDX,EAX)/(SRC)的商,(EDX)<-(EDX,EAX)/(SRC)的餘數。
      NOP 無作用,可以用來抹去相應的語句,這樣的話,嘿嘿嘿…
      CALL呼叫子程式,你可以把它當作高階語言中的過程來理解。
      控制轉移指令:
      JE 或JZ 若相等則跳
      JNE或JNZ 若不相等則跳
      JMP 無條件跳
      JB 若小於則跳
      JA 若大於則跳
      JG 若大於則跳
      JGE 若大於等於則跳
      JL 若小於則跳
      JLE 若小於等於則跳

      Q:彙編對我來說不成問題,可我為什麼總是不上手呢?
      A:呵呵,這樣的老鳥倒還有不少,他們把彙編用的相當熟練,但是,只是因為經驗的原因,所以才覺的不上手的,許多人當初不也都這樣嗎?最起碼我就是,見了CALL就跟進,呵呵,倒跟了不少API,所以對於這部分,你只需多練練手以及掌握一些分析的技巧就成了。

      Q:暫存器可以隨便用麼,有沒有什麼限制?寫個程式的時候那些變數什麼的可以放在任意的暫存器麼?
      A:呵呵,我現在就來回答樓上朋友的問題。
      暫存器有它的使用機制,及各個暫存器都有著明確的分工。
      如小翠兒
      如資料暫存器(EAX-EDX),它們都是通用暫存器,及在軟體中,任何資料都可存放於此。但是除此之外,它們又可以都可以用於各自的專用目的。

      例如:
      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位資料,這個你會推斷出來吧。

      而ESP、EBP、EDI、ESI,我上邊兒以經大概介紹的差不多了,所以這裡不說它們了。
      當然還有其它的一些限制,因為我們只是要看程式的彙編程式碼(人家寫好了的,肯定不會犯錯誤吧),而不是要去寫,所以可以不必掌握。有性趣的話,去看相關書籍。

      另外再說一下你的最後一個問題“寫個程式的時候那些變數什麼的可以放在任意的暫存器麼?
      ”這句話我不明白你要問的是什麼。我想你可能是把一些關點給搞錯了,變數這詞通常都是出現在高階語言中的,而你用高階語言寫程式的話,完全不用理解那些暫存器什麼的,這些都跟高階語言沒什麼關係。但是最終,高階語言也還是把你寫的程式轉換為對暫存器、內部儲存器的操作。

 

                 所謂的機器碼。就是你看到的那些個十六進位制資料了。它們與彙編指令是一一對應的。
      以下這幾個是爆破時要用到的,其它的如果感興趣,可自行檢視相關資料:
      JZ=74;JNZ=75;JMP=EB;Nop=90

摘自《破解基礎知識》PYG 5.4 Craker引導學習小組≯本電子書由[PYG]菜兒編輯製作 版權歸原作者所有:2006-9-6 

 

相關文章