Ollydbg 編寫指令碼的一些語法及例子(OD指令碼)

GodIand發表於2015-10-14
OllyScript指令碼語言是一個種類彙編的語言。你使用它來控制ODbgScript和指令碼執行.

在後面的文件中, “源運算元” 和 “目的運算元”表示以下含義:
- 十六進位制常數,既沒有字首也沒有字尾。 (例如:是00FF, 而不是 0x00FF 和 00FFh的形式)
  十進位制常數,在字尾中加點. (例如:100. 128.也可以是浮點數128.56,浮點數只能保留小數點後2位)
- 變數,這個變數必須在使用前用Var進行定義
- 32位暫存器 (EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EIP)。
  16位暫存器 (AX, BX, CX, DX, SI, DI, BP,SP)
  8位的暫存器(AL, AH, ... DL, DH)
- 被中括號括起來的記憶體地址 (例如:[401000]指向記憶體地址為401000裡存放分資料, 
  [ecx] 指向記憶體地址為暫存器ecx裡存放分資料).
- 一個標誌位,帶有感嘆號字首(!CF, !PF, !AF, !ZF, !SF, !DF, !OF)
- 字串,也可叫資料序列。其格式為: #6A0000#(數值在兩個“#”號之間),兩個“#”號之間必須包含至少有一個數值。
                             "1234567ABCDEF"
- 包含“?”萬用字元的字串。比如 #6A??00# 或者 #6?0000#

3.1.1 保留變數
------------------------

$RESULT
-------
<RESULT>
儲存某些函式的返回值,比如FIND函式執行後的結果,等等。
在ODbgScript的指令碼除錯視窗,你能觀察到它的變化,並且可以修改它.


$VERSION
--------
<VERSION>
ODBGScript的版本資訊,它是系統保留變數名.
例:
cmp $VERSION, "1.47"  //比較是否大於 1.47版
ja version_above_147  


3.1.2 指令
----------------------------------------------

#INC "檔名"  
---------

一個指令碼檔案包含另外一個指令碼.就像呼叫子程式一樣.兩個指令碼中的變數名不能相同.
例:
#inc "test.txt"    


#LOG
---------
開始記錄執行指令
指令會顯示在OllyDbg的log視窗中,每條記錄前都會加上“-->”的字首
例:
#log


ADD 目的運算元,源運算元
---------
<ADD>
源運算元與目的運算元相加,並把相加的結果儲存到目的運算元中,支援字串相加.
例: 
add x, 0F         //x=x+F
add eax, x        //eax=eax+x
add [401000], 5   //[401000]=[401000]+5
浮點數相加
CMP 目的運算元, 源運算元


AI
------------
<Animate Into>
在OllyDbg中執行“自動步入” [Animate into]操作。
相當於在OllyDbg中按下CTRL+F7
例:
ai

ALLOC 大小
----------
申請記憶體, 你能讀/寫/執行.
例:
  alloc 1000        //新申請記憶體,大小為1000,返回結果$RESULT放著申請記憶體的開始地址.
  free $RESULT, 1000

AN 地址
-------
<ANalyze>
從指定地址處,對程式碼進行分析。
例:
an eip //   相當於在OllyDbg中按 Ctrl+A鍵


AND 目的運算元, 源運算元
-------------
<AND>
源運算元與目的運算元進行邏輯與操作,並將結果儲存到到目的運算元中。
例: 
and x, 0F               //x=x&&f
and eax, x              //eax=eax&&x
and [401000], 5          //[401000]=[401000]&&5


AO
--
<Animate Over>
在OllyDbg中執行“自動步過” [Animate over]操作。
相當於在OllyDbg中按下CTRL+F8
例:
ao

ASK 問題
------------
<ASK>
顯示一個提示輸入框,讓使用者輸入,結果儲存變數$RESULT中(如果使用者按了取消鍵,則$RESULT=0)。
$RESULT_1中放著輸入的長度.
(注:程式將判讀你輸入的是字元,$RESULT_1的結果是輸入字元數的數目,整型/2,中文數*2)
例:
ask "Enter new EIP"
cmp $RESULT, 0
je cancel_pressed
mov eip, $RESULT


ASM 地址, 指令
-----------------
<ASseMble>
修改指定地址的指令。
並將修改後的彙編指令長度儲存到保留變數$RESULT中
例:
asm eip, "mov eax, ecx" //將當前指令修改為 mov eax,ecx

ASMTXT 檔案 
-----------------
<ASseMble>
彙編指定檔案中的指令。
將彙編指令長度儲存到保留變數$RESULT中
並將彙編指令行數儲存到保留變數$RESULT_1中
例:
asmtxt EIP,"myasm.txt"//將myasm.txt檔案中的asm轉成opcode後寫入EIP.


ATOI str [, base=16.]
-----------------
轉換字串到16進位制整型,[可以將任何進位制轉成16進位制整型]
返回結果放到 $RESULT 
例:
itoa "F"        //字串"F"轉成了整型,結果會等於F
itoa "10", 10.   //字串"10"代表十進位制,結果會等於A

BC 地址
-------
<BreakPoint Clear>
清除指定地址的斷點。
例:
bc 401000        //清除401000處的斷點
bc x             //清除X(變數值)處的斷點
bc eip           //清除當前EIP處的斷點

BP addr
--------
<BreakPoint>
在指定地址設斷點
例:
bp 401000        //在401000處下斷點
bp x             //在X(變數值)處下斷點 
bp eip           //在當前EIP處下斷點

BPCND 地址, 條件
----------------
<BreakPoint on CoNDition>
在指定地址處,設定條件斷點。
例:
bpcnd 401000, "ECX==1" //當 程式碼執行到401000且 ecx等於1 時,程式暫停

BPD 函式字串
---------------
清除呼叫函式斷點,函式為字串表示.
例:
bpd "GetVersion"   //取消呼叫GetVersion的斷點


BPHWC 地址
----------
<BreakPoint HardWareClear>
刪除指定地址處的硬體斷點。
例:
bphwc 401000 //清除 401000處的斷點
bphwc //不接地址預設清楚全部 等同於bphwcall

BPHWCALL
-----------
清除所有的硬體斷點
例:
BPHWCALL    //清除所有的硬體斷點


BPHWS 地址, 模式
----------------
<BreakPoint HardWare Set>
在指定地址,設定硬體斷點。有三種模式: "r" - 讀取, "w" - 寫入 或者 "x" - 執行.
此斷點只支援1個位元組的動作.
例:
bphws 401000, "x" //當執行到此地址時產生中斷.
Bphws 401000,"r"  //當讀取401000的時候產生中斷


BPL 地址, 表示式
--------------
<BreakPoint of Logging>
在指定地址處設定記錄斷點,將表示式的結果記錄到記錄視窗中。
例:
bpl 401000, "eax" // 每次執行到401000時,都將eax暫存器的結果記錄


BPLCND 地址, 表示式, 條件
-----------------------
<BreakPoint of Logging onCoNDition>
在指定地址處設定記錄斷點,如果條件為真時,將表示式的結果記錄到記錄視窗中。
例:
bplcnd 401000, "eax", "eax > 1" //如果執行到401000時,滿足eax>1,則將eax暫存器的結果記錄


BPMC
----
<BreakPoint Memory Clear>
清除記憶體斷點。
例:
bpmc


BPRM 地址, 大小
---------------
<BreakPoint on ReadMemory>
在指定地址處,設定一個記憶體讀取斷點。 “大小” 是指記憶體中的位元組大小。
例:
bprm 401000, FF //在401000中設定記憶體讀斷點,記憶體中的大小為FF


BPWM 地址, 大小
---------------
<BreakPoint on WriteMemory>
在指定地址處,設定一個記憶體寫入斷點。“大小” 是指記憶體中的位元組大小。
例:
bpwm 401000, FF  //在401000中設定記憶體寫斷點,記憶體中的大小為FF


BPX 函式字串
---------------
設定呼叫函式斷點,函式為字串表示.
返回下了斷點的地址數量,結果儲存在保留變數$RESULT中.
例:
bpx "GetVersion"   //下呼叫GetVersion斷點,斷下的語句為call [xxxxx]

BUF var
-------
轉換字串變數到緩衝區(string/dword variable to a Buffer)
Example: 
mov s, "123"
buf s
log s // output "#313233#

CMP 目的運算元, 源運算元
-------------
<CoMPare>
比較 目的運算元與源運算元的大小,和其對應的彙編指令作用相同。
可以是各種數值,甚至可以是字串(對大小不敏感).
例: 
cmp y, x        //比較兩個變數(Y和X)的大小,
cmp eip, 401000   //比較EIP和401000的大小
這裡可以設定比較的數的長度 比如 cmp [eip],#ff25#,2 這裡比較EIP所在的指令 前兩個位元組是否是FF25
測試程式碼如下:
00581DAC   $- FF25 C0B55B00 jmp     dword ptr [5BB5C0]



CMT 地址, 字串
--------------
<CoMmenT>
在指定地址處,加入註釋。
例:
cmt eip, "這是入口" //當前地址處 加上“這是入口”的註釋

COB
---
<Continue On Breakpoint>
發生中斷後,讓指令碼繼續執行(移除EOB指令)
例:
COB

COE
---
<Continue OnException>(移除EOE指令)
發生異常後,讓指令碼繼續執行
例:
COE

DBH
---
<DeBuggerHided> 
隱藏偵錯程式
例:
dbh

DBS
---
<DeBugger Show>
對隱藏的偵錯程式操作進行恢復,不再隱藏。
例:
dbs

DEC 變數
-------
<DECrement by 1>
對變數進行減一操作
例:
dec v          //V=V-1


DIV 目的運算元, 源運算元
-------------
<div>
源運算元與目的運算元進行除法操作,並將結果儲存到到目的運算元中。
例: 
div x, 0F       //X=X/0F
div eax, x      //eax=eax/x
div [401000], 5  //[401000]/5


DM 地址, 大小, 檔名
-------------------
<Dump Memory>
從指定地址處開始,在記憶體中提取指定大小的資料,並儲存到指定的檔案中
例:
dm 401000, 1F, "c:\dump.bin"

DMA 地址, 大小, 檔名
-------------------
<Dump Memory Appended>
從指定地址處開始,在記憶體中提取指定大小的資料,並儲存到指定的檔案中;如
果指定檔案已存在,則將資料追加到指定檔案尾部。
例:
dma 401000, 1F, "c:\dump.bin"

DPE 檔名, 入口
----------------
<Dump Process with Entrypoint>
提取執行模組到指定檔案中。
“入口”用來設定入口地址。
這個命令用來抓取檔案,還是比較好用的,因為直接利用了OD強大的記憶體管理功能.
例:
dpe "c:\test.exe", eip //入口為當前地址,儲存為C盤下test.exe

EOB 標籤
---------
<Execution On Breakpoint>
在下次中斷髮生時,跳轉到指定標籤處。
此功能和EOE命令常常讓新手迷惑不解,其實就是遇見中斷做指令碼的流程轉向.
如果還有不懂,請看下文的答疑解惑章節.
例:
eob SOME_LABEL

EOE 標籤
---------
<Execution On Exception>
在下次異常發生時,跳轉到指定標籤處。
例:
eoe SOME_LABEL

ESTI
----
<Exception STep Into>
相當於在OllyDbg按 SHIFT-F7。
例:
esti

ESTO
----
<Exception STep cOntinue>
相當於在OllyDbg按 SHIFT+F9。
例:
esto
一般來說用這個 不用F9多 因為Shift+F9 忽略異常執行

EVAL 
----
<EVALuate>
計算含義變數的表示式。
變數必須已經在指令碼中宣告。
注意:插到字串中時,要放在大括號{ }中。
結果儲存在保留變數$RESULT中.
這句和其它語句結合將產生很多的變化,用好它將讓你的指令碼十分靈活.
例:
var x
mov x, 1000
eval "x的值是 { x }" // 執行後$RESULT為 "x的值是00001000"


EXEC/ENDE
---------
<EXECute/END of Execute>
對當前除錯程式,執行在EXEC和ENDE之間的指令。
有這個命令就是你可以直接跳入程式,對程式進行直接控制.
它的原理就是取當前程式的資訊進行儲存,然後新分配一個程式碼記憶體區(可讀/寫/執行.大小1000)
呼叫OD彙編器將你的彙編語句轉成OPcode,將OPcode拷貝到程式碼區,然後將EIP指向你的程式碼開頭.
然後將控制權交給你.執行完後將EIP歸還原位,然後將控制權交還ODbgScript.
這裡的好處就是讓你以很高的效率來避免在較慢的指令碼環境執行需要高效的操作.
!注意:由於程式控制權交給你了,那麼,你的程式碼有效性將只有你自己來控制了.
!注意:執行後不儲存現場.這都需要你來做工作.(要儲存現場,你可以使用pushad,popad)
有大括號的,會被大括號中的變數的值替代。
例:
// 以下是做移動操作
var x
var y
mov x, "eax"
mov y, "0DEADBEEF"
exec
mov {x},{y}     //到程式中新開的程式碼區去,mov eax,0DEADBEEF 將被執行
mov ecx, {x}    //mov ecx,eax 將被執行
ende
// 以下是呼叫除錯程式的ExitProcess函式
exec
push 0
call ExitProcess
ende
ret

FILL addr,len,value
-------------------------
從地址addr開始填充長度為len的值value
!注:value的值最大8個位元組,可以為暫存器值,標誌位值,變數值,16進位制值,10進位制值,[]指標運算元.
如:
fill 401000,10,90       //NOP 10h個位元組
fill 401000,ff,[eax]      //取出[eax]值,填充到401000,長度為ff
fill 401000,ff,$RESULT    //將變數$RESULT的值填充到401000,長度為ff

FIND 地址, 查詢內容 ,[最大大小]
---------------
<FIND>
從指定地址開始在記憶體中查詢指定的內容。
如果查詢成功,地址會儲存到保留變數$RESULT中,否則$RESULT將等於 0。
查詢的串支援萬用字元“??”(見下面的例子)。
##中的為HEX,""中的為字串,什麼都不帶的為記憶體資料
!注:輸入的16進位制字元必須是成偶數
   從1.52版開始支援直接變數和資料查詢.
例:
find eip, #6A00E8# // 查詢一個Call,其的第一個引數為0 (push 0)
find eip, #6A??E8# // 查詢一個帶引數的Call,一個?代表一個字元常量
find eip,"kernel32.dll" //查詢字串"kernel32.dll"
find eip,"ker???32.d??" //查詢帶萬用字元的?字串,一個?代表一個字串常量
                       (請注意這裡的萬用字元?和HEX中的?不同)

find eip,15ff     //查詢記憶體資料15ff(程式碼為ff115)
(mov tmp,#ff15#
 find eip,tmp )   //查詢變數tmp中的數值,tmp=ff15
(mov tmp,"kernel32.dll"
find eip,tmp  )   //查詢變數tmp中的字串"kernel32.dll"
(mov tmp,15ff
 find eip,tmp    //查詢變數tmp中的記憶體資料15ff(注意和#ff15#區別)
(ask "輸入需要的資料"
find eip,$RESULT      //輸入的為#ff15#,"Kernel32.dll",15ff就同上面三例子

find eip,#ff15#,ff //從EIP開始,FF大小範圍內,查詢字元ff15,


FINDCMD 地址, 查詢內容
-----------------
<FIND command>
從指定地址開始查詢指定一個命令。 
如果查詢成功,地址會儲存到保留變數$RESULT中,否則$RESULT將等於 0。
例:
findcmd 401000, "push eax" // find "push eax"


FINDCMDS 地址, 查詢內容
-----------------
<FIND command>
從指定地址開始查詢指定命令序列。 
如果查詢成功,地址會儲存到保留變數$RESULT中,否則$RESULT將等於 0。
注:命令序列分割請使用;號(分號).

例:
findcmd 401000, "push eax;mov eax,edx" //    尋找"push eax和mov eax,edx"命令序列


FINDOP 地址, 查詢內容,[查詢範圍]
-----------------
<FIND OPcode>
從指定地址開始查詢指定一個指令,這個指令是以指定內容為開始的。 
如果查詢成功,地址會儲存到保留變數$RESULT中,否則$RESULT將等於 0。
查詢的串支援萬用字元“??”(見下面的例子)。
注意:findop由於是opcode查詢,不支援字串查詢.
    findop和find的區別是findop查詢到的必須是opcode.
1.52起支援直接變數和記憶體資料
例:
findop 401000, #61# // find next POPAD
findop 401000, #6A??# // find next PUSH of something
譯者注:
對比一下FIND 和FINDDOP的區別:
地址         資料              程式碼
00401007     B8 3300         MOV    EAX, 33
0040100C     33F6           XOR     ESI,ESI
find 401007,  #33#   //$RESULT等於401008
finddop 401007, #33#  //$RESULT等於40100C


FINDMEM what [, StartAddr]
--------------------------
從整個記憶體開始在記憶體中查詢指定的內容
如果查詢成功,地址會儲存到保留變數$RESULT中,否則$RESULT將等於 0。
查詢的串支援萬用字元“??”(見下面的例子)。
Example:
findmem #6A00E8# // find a PUSH 0 followed by some kind ofcall
findmem #6A00E8#, 00400000 // search it after address00400000
此命令查詢十六進位制的變數有為有效,因為Find不會把變數當然一個十六進位制來查詢。

FREE
FREE 地址 大小
-----------
釋放由ALLOC申請的記憶體.
Example:
 alloc 1000
 free $RESULT, 1000

GAPI
GAPI 地址
------------
獲得指定程式碼處的API呼叫資訊
API資訊儲存到保留變數$RESULT中。
如果符號名是一個API函式,則
$RESULT儲存API資訊
$RESULT_1儲存連結庫名(比如 kernal32)
$RESULT_2儲存符號名(比如 ExitProcess)。
$RESULT_3儲存呼叫地址XXXX(比如 call xxxxx)
注意:這個和GN的區別是GN必須指向IAT地址
    而GAPI直接給出程式碼地址就可得出API
    還有如果你是在此處下了軟體斷點,請先清除斷點再用此句,因為軟體斷點修改了程式碼為CC
這裡如果不清除此處的軟體斷點,將造成這句不能很好的識別.
例:
GAPI 401000   (callkernal32.ExitProcess)
GAPI EIP   //檢視當前程式碼是否是API呼叫,不是則返回0

 
GCMT addr
---------
獲得指定地址處的解釋

GCI addr, info
--------------
獲得制定地址的彙編指令資訊
"info"可以是:
-彙編指令字串 例:gci eip,COMMAND
 就象用OPCODE eip一樣
-目標地址 ,例: gci eip,DESTINATION
  用於jump/call/return指令
-命令長度,例: gci eip,SIZE
-型別, 例:gci eip,TYPE
-條件,例:gci eip,CONDITION
返回值:$RESULT
-得到指令目標地址(DESTINATION) 
比如 :
004B3DF0   0F85 D7010000   jnz     004B3FCD
EIP:004B3DF0  
gci eip,DESTINATION
這裡的$RESULT等於004B3FCD

SIZE 和 TYPE 可以判斷出一條指令 修復花指令很有用 比如:
[plain] view plaincopy
  1. 004B52FD   /2E:EB 01                     jmp     short 004B5301  
  2. 004B5300   |F0:8D740D D3                 lock lea esi, dword ptr [ebp+ecx-2D]       
  3. 004B5305    2BF1                         sub     esi, ecx  
修復帶引數的EB花指令 通過SIZE和3 TYPE和58 就可以尋找修復 TYPE的值是通過 gci 004B52FD,TYPE得到的 然後用於判斷其他地方是否一樣

GMEMI addr, info
----------------
獲得指定地址處記憶體的資訊.
資訊可以是 MEMORYBASE, MEMORYSIZE or MEMORYOWNER
Example:
GMEMI addr, MEMORYBASE // After this $RESULT is the address tothe memory base of the memory block to which addr belongs

GMI 地址, 資訊
--------------
<Get Module Info>
獲得指定地址所在模組的相關資訊。
“資訊”可以是
  MODULEBASE:   模組基地址(baseaddress of module in the memory space of debugged process)
  MODULESIZE:   模組大小(totalsize occupied by module, not necessarily contiguous memory)
  CODEBASE:    程式碼段基地址
  CODESIZE:    程式碼段大小(size of executable code, as stays in COFFheader. In some cases, OllyDbg may correct definitely invalid codesize)
  DATABASE:    資料段基地址
  RESBASE:     資源段基地址
  RESSIZE:     資源段大小
  IDATATABLE:   輸入表基地址(baseaddress of import data table, as stays in COFF header)
  entry:       模組入口(ddressof module's entry point, as stays in COFF header)
  nsect:       節數目(Numberof sections in the module)
(如果您想在將來的版本中,獲得更多的資訊,請聯絡我)。
資訊會儲存到保留變數$RESULT中 (如果沒有找到資訊,則$RESULT等於0).
例:
GMI eip, CODEBASE // 這條指令執行後,$RESULT等於當前所在模組的程式碼段基地址。

GN 地址
-------
<Get Name>
獲得指定IAT地址的符號名(比如指向API函式)。
符號名將儲存到保留變數$RESULT中。
如果符號名是一個API函式,則
$RESULT是符號名
$RESULT_1儲存連結庫名(比如 kernal32)
$RESULT_2儲存符號名(比如 ExitProcess)。
例:
gn 450100

GO 地址
-------
<GO>
執行到指定地址處 
例:
go 401005

GPA 函式名, 動態連結庫名
-------------
<Get Procedure Address>
在指定的動態連結庫中,獲得指定函式的地址。
如果查詢成功,地址會儲存到保留變數$RESULT中,否則$RESULT將等於 0。
在設定API函式斷點時,這個指令非常有效。(API斷點API)
例:
gpa "MessageBoxA", "user32.dll" //這條指令執行後,$RESULT等於函式MessageBoxA的地址,您可以
使用"bp $RESULT"設定斷點。

GPI key
-------------
獲得程式的資訊.
這個資訊可以是HPROCESS,PROCESSID,HMAINTHREAD,MAINTHREADID,MAINBASE,
PROCESSNAME,EXEFILENAME,CURRENTDIR,SYSTEMDIR

CURRENTDIR:當前PE檔案全路徑目錄


GPP key
--------------
find API parameters number and types

HANDLE x, y, class
---------------------
返回指定點(16進位制)子視窗指定類的控制程式碼


INC 變數
-------
<INCrement by 1>
對變數進行加一操作
例:
inc v

ITOA n [, base=16.]
-----------------
轉化一個整數到字串
結果放在 $RESULT 
Example:
itoa F
itoa 10., 10.
JA 標籤
--------
<Jump if Above>
在cmp命令後使用. 和其對應的彙編指令作用相同.
例:
ja SOME_LABEL

JAE 標籤
---------
<jump if Above or Equal>
cmp. 和其對應的彙編指令作用相同.
例:
jae SOME_LABEL

JB 標籤
--------
<Jump if Below>
在cmp命令後使用.  和其對應的彙編指令作用相同.
例:
jb SOME_LABEL

JBE 標籤
---------
<Jump if Below or Equal>
在cmp命令後使用。和其對應的彙編指令作用相同.
例:
jbe SOME_LABEL

JE 標籤
--------
<Jump if Equal>
在cmp命令後使用.  和其對應的彙編指令作用相同.
例:
je SOME_LABEL

JMP 標籤
---------
<JuMP>
跳轉到指定標籤.
例:
jmp SOME_LABEL

JNE 標籤
---------
<Jump if Not Equal>
在cmp命令後使用.  和其對應的彙編指令作用相同.
例:
jne SOME_LABEL

KEY vkcode [, shift [, ctrl]]
--------------------------
模擬按下鍵盤.
Example:
key 20
key 20, 1 //Shift+space
key 20, 0, 1 //Ctrl+space

這個命令可以模仿OD中任意快捷鍵的功能 
比如指令碼ctrl+F2重新載入功能 就可以通過KEY 71,0,1來模擬
vkcode(虛擬鍵碼)的具體值可以查詢masm環境下的windows.inc檔案 
比如:
VK_F2                                equ 71h
所以 模擬ctrl+f2 就是 KEY 71,0,1

這裡的vkcode都是16進位制的

LBL 地址, 字串
--------------
<LaBel Insert>
在指定地址處插入一個標籤
例:
lbl eip, "NiceJump"

LC
----
清理LOG視窗

LCLR
----
清理Script Log視窗

LEN str
--------------
獲得字串長度,結果放在$RESULT
Example:
len "NiceJump"
msg $RESULT
LM addr, size, filename
-------
引導Dm檔案進記憶體
Example:
  lm 0x401000, 0x100, "test.bin"
  
LOG 源運算元
-------
<log>
將源運算元輸出到OllyDbg的記錄視窗[log window]中。
如果源運算元 是一個字串常量,則原樣記錄。
如果源運算元 是一個變數或一個暫存器,則記錄名稱及其存放的數值
例:
log "Hello world" // 記錄為 "Hello world"
var x
mov x, 10
log x // 記錄為 "x = 00000010" 

MOV 目的運算元, 源運算元,最大位元組
-------------
<MOV>
將源運算元移動到目的運算元中。
源運算元可以是一個十六進位制序列格式#某個十六進位制序列#,例如:#1234#。
提醒:十六進位制序列的位長只能是偶數,比如2, 4, 6, 8等等。
例: 
mov x, 0F                     //將F傳給變數x
mov y, "Hello world"            //將字串"Hello world"傳給變數y
mov eax, ecx                   //同彙編
mov [ecx], #00DEAD00BEEF00#      //將##內的內容傳到ecx的地址中
mov !CF, 1                    //賦值!CF標誌暫存器為1
mov !DF, !PF                  //將!PF賦值給!DF
mov [403000], "Hello world"      //直接將字串"Helloworld"傳送到403000的地址中
mov eax,[401000],1             //只取401000地址中的一個位元組長度的內容傳送到eax中(新功能)

MSG 訊息
-----------
<MeSsaGe>
將指定訊息,顯示到一個對話方塊中。
例:
MSG "指令碼暫停"

MSGYN message
-----------
<MeSsaGe Yes or No>
將指定訊息,顯示到一個對話方塊中,這個對話方塊有“是”、“否”按鈕。
如果點“是”,保留變數 $RESULT 等於1,否則保留變數$RESULT等於0 。
例:
MSGYN "繼續?"


MUL 目的運算元, 源運算元
-------------
<mul>
源運算元與目的運算元進行乘法操作,並將結果儲存到到目的運算元中。
例: 
mul x, 0F
mul eax, x
mul [401000], 5

NEG 運算元
-------------
<NEG>
運算元做取補操作,並將結果儲存到到運算元中。
例: 
NEG x, 0F
NEG eax
NEG [401000]

NOT 運算元
-------------
<NOT>
運算元做邏輯非操作,並將結果儲存到到運算元中。
例: 
NOT x, 0F
NOT eax
NOT [401000]


OPCODE addr
-----------
反彙編指定地址處的程式碼.
$RESULT是opcode
$RESULT_1是彙編程式碼
$RESULT_2是位元組數
如果不是opcode,$RESULT_2將返回0
Example: 
opcode 00401000

opentrace
------------
開啟執行跟蹤功能,關閉它請使用TC


OR 目的運算元, 源運算元
-------------
<OR>
源運算元和目的運算元做邏輯或操作,並將結果儲存到到目的運算元中。
例: 
or x, 0F
or eax, x
or [401000], 5

PAUSE
-----
<PAUSE>
暫停指令碼執行。可以通過外掛選單恢復指令碼執行。
例:
pause


PREOP addr
----------
回溯指定地址的彙編命令
注意: 這個命令並不能真實的反映EIP前的包含jmp的命令
Example:
preop eip


READSTR addr,maxsize
-----------
從addr處讀指定大小的字串
Example:
    readstr 401000,15

REF addr
--------
相當於在OllyDbg按 Ctrl R.
$RESULT variable is set to the first referenceaddr 
$RESULT_1 to the opcode (text asmcommand) 
$RESULT_2 to the comment (like referencewindow). 
Repeat "REF addr" until $RESULT=0 to get next refs
Example:
continue:
REF eip
log $RESULT
log $RESULT_1
log $RESULT_2
cmp $RESULT,0
jne continue

REPL addr, find, repl, len
--------------------------
REPL 地址, 查詢字串, 替換字串, 長度
--------------------------
<REPLace>
在指定地址開始,在指定長度的位元組範圍內,用“替換字串”替換“查詢字串”。
允許使用萬用字元
例:
repl eip, #6a00#, #6b00#, 10
repl eip, #??00#, #??01#, 10
repl 401000, #41#, #90#, 1F

RESET
---------------------------
OD重新載入程式(相當於ctlr+f2)


RET
---
<RETurn>
退出指令碼。
例:
ret

REV
---
位元組反轉.(注意是位元組反轉,不是位反轉)
Example:
rev 01020304 //$RESULT = 04030201

ROL 目的運算元, n
-------------
迴圈左移目的運算元,n位元位;並將結果儲存到到目的運算元中。
例:
mov x, 00000010
ROL x, 8 // x is now 00001000


ROR 目的運算元, n
-------------
迴圈右移目的運算元,n位元位;並將結果儲存到到目的運算元中。
例:
mov x, 00000010
ROR x, 8 


RTR
---
<Run To Return>
執行到返回
相當於在OllyDbg中執行 "Run to return" [Ctrl+F9]操作。
例:
rtr

RTU
---
<Run To User code>
返回到使用者程式碼區
相當於在OllyDbg中執行 "Run to user code"[Alt+F9] 操作。
例:
rtu


RUN
---
<RUN>
讓OD繼續執行
相當於在OllyDbg中按 F9。
例:
run

SCMP dest, src
-------------
字串比較. 
Example: 
cmp x, "KERNEL32.DLL"
cmp [eax], "Hello World"
SCMPI dest, src
-------------
字串比較(大小寫不敏感)
Example: 
cmp sVar, "KERNEL32.DLL"
cmp [eax], "Hello World"

SETOPTION
-------------
調出除錯設定(Option)選單,設定好後按確定後繼續執行指令碼
注意:此選項是為了可以在執行指令碼的過程中可以調出除錯設定異常,跟蹤等等設定

SHL 目的運算元, n
-------------
左移目的運算元,n位元位;並將結果儲存到到目的運算元中。
例:
mov x, 00000010
shl x, 8 // x is now 00001000

SHR 目的運算元, n
-------------
<SHift Right>
右移目的運算元,n 位元位;並將結果儲存到到目的運算元中。
例:
mov x, 00001000
shr x, 8 // x is now 00000010

STI
---
<STep Into>
相當於在OllyDbg中按 F7,單步步入。
例:
sti

STO
---
<STep Over>
相當於在OllyDbg中按 F8,單步步過。
例:
sto


SUB dest, src
-------------
源資料減目的資料
Example: 
sub x, 0F
sub eax, x
sub [401000], 5


TC
--
相當於在OllyDbg中 "關閉執行跟蹤"
Example:
tc

TI
--
相當於在OllyDbg中按 CTRL-F7,單步跟蹤。
Example:
ti
TICND cond
----------
<Trace Into Condition>
執行 "Trace into" 操作,直到條件為真時停止。
例:
ticnd "eip > 40100A" // 當 eip >40100A 時停止


TICK [var [,reftime]]
-------------------
腳步執行時間(microsec)
如果是2次變數,則得出為時間差
Example:
tick time
msg time //time since script startup
tick time,time
msg $RESULT //time since last TICK, DWORD value

TO
--
<Trace Over>
相當於在OllyDbg中執行 "Trace over" 操作。
例:
to

TOCND cond
----------
<Trace Over Condition>
執行 "Trace over" 操作,直到條件為真時停止。
例:
tocnd "eip > 40100A" // 當 eip >40100A 時停止

VAR
---
<VARiable>
在指令碼中,宣告一個變數。
必須在變數使用先宣告。
注意:變數名最好是由字母和數字組合成的容易識別的變數名
    +-*/等等符號最好不要附加在變數中,以免引起不可預測的錯誤
由於為了相容以前的系統,請不要將A,B,C,D,E,F作為變數.
例: 
var tmp

XOR 目的運算元, 源運算元
-------------
<XOR>
源運算元與目的運算元進行異或操作,並將結果儲存到到目的運算元中。
例: 
xor x, 0F
xor eax, x
xor [401000], 5

WRT file, data
-------------
寫資料給檔案 (覆蓋)
Numbers are wrote as strings... for the moment
Example: 
wrt "out.txt", "Data:\r\nOk\r\n"
wrt sFile, ebx

WRTA file, data
-------------
附加資料到檔案中(檔案結尾)
Example: 
wrta sFile, "hello world\r\n"
如果檔案不存在 將會建立檔案

IFA,IFAE,IFB,IFBE IFG,IFGE,IFL,IFLE IFEQ/IFNEQ..ELSE/ENDIF
-------------
這些命令是構建IF塊的,類似於高階語言的語法,具體含義與彙編類似。
Example: 
ifneq $RESULT,0
    ifa flg,$RESULT
        mov flg,$RESULT
    endif
endif


3.2 標籤
----------
定義標籤,要在標籤名後面要加上一個冒號.
例:
SOME_LABEL:

3.3 註釋
------------
您可以使用“//”在任何地方進行註釋。
塊註釋必須另外起一行並以 “”作為結束,“*/”也必須另起一行。

相關文章