OD脚本帮助
ODbgScript腳本編寫資料與示例
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
浮點數相加
add x,16.50 ? ? ? ? ? ?//x=x+16.50
(字符串相加)
add y, " times" ? ? ? ?// 如果在次之前y="1000" ,則在執行完此指令之后y="1000 times"
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 HardWare Clear>
刪除指定地址處的硬件斷點。
例:
bphwc 401000 //清除 401000處的斷點
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 on CoNDition>
在指定地址處設置記錄斷點,如果條件為真時,將表達式的結果記錄到記錄窗口中。
例:
bplcnd 401000, "eax", "eax > 1" // 如果執行到401000時,滿足eax>1,則將eax寄存器的結果記錄
BPMC
----
<BreakPoint Memory Clear>
清除內存斷點。
例:
bpmc
BPRM 地址, 大小
---------------
<BreakPoint on Read Memory>
在指定地址處,設置一個內存讀取斷點。 “大小” 是指內存中的字節大小。
例:
bprm 401000, FF ? ? ?//在401000中設置內存讀斷點,內存中的大小為FF
BPWM 地址, 大小
---------------
<BreakPoint on Write Memory>
在指定地址處,設置一個內存寫入斷點。“大小” 是指內存中的字節大小。
例:
bpwm 401000, FF ? ? ? //在401000中設置內存寫斷點,內存中的大小為FF
BPX 函數字符串
---------------
設置調用函數斷點,函數為字符串表示.
返回下了斷點的地址數量,結果保存在保留變量$RESULT中.
例:
bpx "GetVersion" ? ? ? //下呼叫GetVersion斷點,斷下的語句為 call [xxxxx]
CMP 目的操作數, 源操作數
-------------
<CoMPare>
比較 目的操作數與源操作數的大小,和其對應的匯編指令作用相同。
可以是各種數值,甚至可以是字符串(對大小不敏感).
例:?
cmp y, x ? ? ? ? ? ? ?//比較兩個變量(Y和X)的大小,
cmp eip, 401000 ? ? ? //比較EIP和401000的大小
CMT 地址, 字符串
--------------
<CoMmenT>
在指定地址處,加入注釋。
例:
cmt eip, "這是入口" //當前地址處 加上“這是入口”的注釋
COB
---
<Continue On Breakpoint>
發生中斷后,讓腳本繼續執行(移除EOB指令)
例:
COB
COE
---
<Continue On Exception>(移除EOE指令)
發生異常后,讓腳本繼續執行
例:
COE
DBH
---
<DeBugger Hided>?
隱藏調試器
例:
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 Entry point>
提取執行模塊到指定文件中。
“入口”用來設定入口地址。
這個命令用來抓取文件,還是比較好用的,因為直接利用了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
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,
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 of call
findmem #6A00E8#, 00400000 // search it after address 00400000
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 ? ? ? (call kernal32.ExitProcess)
GAPI EIP ? ? ? //查看當前代碼是否是API調用,不是則返回0
GCMT addr
---------
獲得指定地址處的解釋
GMEMI addr, info
----------------
獲得指定地址處內存的信息.
信息可以是 MEMORYBASE, MEMORYSIZE or MEMORYOWNER
Example:
GMEMI addr, MEMORYBASE // After this $RESULT is the address to the memory base of the memory block to
which addr belongs
GMI 地址, 信息
--------------
<Get Module Info>
獲得指定地址所在模塊的相關信息。
“信息”可以是模塊基地址[MODULEBASE], 模塊大小[MODULESIZE], 代碼段基地址[CODEBASE] 或者 代碼段大小
[CODESIZE]?
(如果您想在將來的版本中,獲得更多的信息,請聯系我)。
信息會保存到保留變量$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函數斷點時,這個指令非常有效。
例:
gpa "MessageBoxA", "user32.dll" // 這條指令執行后,$RESULT等于函數MessageBoxA的地址,您可以
使用"bp $RESULT"設置斷點。
GPI key
-------------
獲得進程的信息.
這個信息可以是
HPROCESS,PROCESSID,HMAINTHREAD,MAINTHREADID,MAINBASE,PROCESSNAME,EXEFILENAME,CURRENTDIR,SYSTEMDIR
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
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" ? ? ? ? ? //直接將字符串"Hello world"傳送到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 reference addr?
$RESULT_1 to the opcode (text asm command)?
$RESULT_2 to the comment (like reference window).?
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
---------------------------
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 時停止
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"
3.2 標簽
----------
定義標簽,要在標簽名后面要加上一個冒號.
例:
SOME_LABEL:
3.3 注釋
------------
您可以使用“//”在任何地方進行注釋。
塊注釋必須另外起一行并以 “/*”做為開始,以“*/”作為結束,“*/”也必須另起一行。
例:
/*
您的注釋
*/
3.4 菜單
---------
ODBGScript的主菜單包含了下面幾項:
- Run script...[運行腳本...]: 用戶選擇一個腳本,并運行這個腳本。
- Abort [中止]: 中止腳本運行
- Pause [暫停]: 暫停腳本運行
- Resume[恢復]: 恢復腳本運行
-腳本運行窗口:動態觀察腳本運行
-腳本日志窗口:記錄腳本運行情況
- About [關于]: 顯示此插件信息
3.5 Script Window
-----------------
腳本窗口是ODbgScript內置的,它能讓你調試和觀察你的腳本.
你能在這里為腳本設置斷點,調試腳本,編輯變量還能手工執行腳本命令
4. 嵌入其他的插件
---------------------------------
您可以在您的插件中調用OllyScrip,并且運行一個腳本。
使用類似于下面的代碼進行調用:
HMODULE hMod = GetModuleHandle("OllyScript.dll");
if(hMod) // 檢測是否被其他插件加載
{?
// 獲得輸出函數地址
int (*pFunc)(char*) = (int (*)(char*)) GetProcAddress(hMod, "ExecuteScript");
if(pFunc) // 檢查是否獲得輸出函數
pFunc("myscript.txt"); // 執行輸出函數
=============================================================================
示例:
1: ESP定律脫“NsPacK”
var addr ? ? ? ? ? ? ? ? ? ?//聲明一個變量
sto ? ? ? ? ? ? ? ? ? ? ? ? ? ?//F8單步
sto ? ? ? ? ? ? ? ? ? ? ? ? ? ?//F8單步
mov addr,esp ? ? ? ? ? //將源操作數移動到目的操作數中
bphws addr,"r" ? ? ? ? ?//下斷 hr esp
run ? ? ? ? ? ? ? ? ? ? ? ? ? //F9運行
BPHWC addr ? ? ? ? ? ?//刪除斷點
sto ? ? ? ? ? ? ? ? ? ? ? ? ? ?//F8單步
sto ? ? ? ? ? ? ? ? ? ? ? ? ? ?//F8單步
cmt eip, "This is the OEP! ? ? ? //在指定地址處,加入注釋
ret ? ? ? ? ? ? ? ? ? ? ? ? ? //結束
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
浮點數相加
add x,16.50 ? ? ? ? ? ?//x=x+16.50
(字符串相加)
add y, " times" ? ? ? ?// 如果在次之前y="1000" ,則在執行完此指令之后y="1000 times"
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 HardWare Clear>
刪除指定地址處的硬件斷點。
例:
bphwc 401000 //清除 401000處的斷點
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 on CoNDition>
在指定地址處設置記錄斷點,如果條件為真時,將表達式的結果記錄到記錄窗口中。
例:
bplcnd 401000, "eax", "eax > 1" // 如果執行到401000時,滿足eax>1,則將eax寄存器的結果記錄
BPMC
----
<BreakPoint Memory Clear>
清除內存斷點。
例:
bpmc
BPRM 地址, 大小
---------------
<BreakPoint on Read Memory>
在指定地址處,設置一個內存讀取斷點。 “大小” 是指內存中的字節大小。
例:
bprm 401000, FF ? ? ?//在401000中設置內存讀斷點,內存中的大小為FF
BPWM 地址, 大小
---------------
<BreakPoint on Write Memory>
在指定地址處,設置一個內存寫入斷點。“大小” 是指內存中的字節大小。
例:
bpwm 401000, FF ? ? ? //在401000中設置內存寫斷點,內存中的大小為FF
BPX 函數字符串
---------------
設置調用函數斷點,函數為字符串表示.
返回下了斷點的地址數量,結果保存在保留變量$RESULT中.
例:
bpx "GetVersion" ? ? ? //下呼叫GetVersion斷點,斷下的語句為 call [xxxxx]
CMP 目的操作數, 源操作數
-------------
<CoMPare>
比較 目的操作數與源操作數的大小,和其對應的匯編指令作用相同。
可以是各種數值,甚至可以是字符串(對大小不敏感).
例:?
cmp y, x ? ? ? ? ? ? ?//比較兩個變量(Y和X)的大小,
cmp eip, 401000 ? ? ? //比較EIP和401000的大小
CMT 地址, 字符串
--------------
<CoMmenT>
在指定地址處,加入注釋。
例:
cmt eip, "這是入口" //當前地址處 加上“這是入口”的注釋
COB
---
<Continue On Breakpoint>
發生中斷后,讓腳本繼續執行(移除EOB指令)
例:
COB
COE
---
<Continue On Exception>(移除EOE指令)
發生異常后,讓腳本繼續執行
例:
COE
DBH
---
<DeBugger Hided>?
隱藏調試器
例:
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 Entry point>
提取執行模塊到指定文件中。
“入口”用來設定入口地址。
這個命令用來抓取文件,還是比較好用的,因為直接利用了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
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,
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 of call
findmem #6A00E8#, 00400000 // search it after address 00400000
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 ? ? ? (call kernal32.ExitProcess)
GAPI EIP ? ? ? //查看當前代碼是否是API調用,不是則返回0
GCMT addr
---------
獲得指定地址處的解釋
GMEMI addr, info
----------------
獲得指定地址處內存的信息.
信息可以是 MEMORYBASE, MEMORYSIZE or MEMORYOWNER
Example:
GMEMI addr, MEMORYBASE // After this $RESULT is the address to the memory base of the memory block to
which addr belongs
GMI 地址, 信息
--------------
<Get Module Info>
獲得指定地址所在模塊的相關信息。
“信息”可以是模塊基地址[MODULEBASE], 模塊大小[MODULESIZE], 代碼段基地址[CODEBASE] 或者 代碼段大小
[CODESIZE]?
(如果您想在將來的版本中,獲得更多的信息,請聯系我)。
信息會保存到保留變量$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函數斷點時,這個指令非常有效。
例:
gpa "MessageBoxA", "user32.dll" // 這條指令執行后,$RESULT等于函數MessageBoxA的地址,您可以
使用"bp $RESULT"設置斷點。
GPI key
-------------
獲得進程的信息.
這個信息可以是
HPROCESS,PROCESSID,HMAINTHREAD,MAINTHREADID,MAINBASE,PROCESSNAME,EXEFILENAME,CURRENTDIR,SYSTEMDIR
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
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" ? ? ? ? ? //直接將字符串"Hello world"傳送到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 reference addr?
$RESULT_1 to the opcode (text asm command)?
$RESULT_2 to the comment (like reference window).?
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
---------------------------
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 時停止
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"
3.2 標簽
----------
定義標簽,要在標簽名后面要加上一個冒號.
例:
SOME_LABEL:
3.3 注釋
------------
您可以使用“//”在任何地方進行注釋。
塊注釋必須另外起一行并以 “/*”做為開始,以“*/”作為結束,“*/”也必須另起一行。
例:
/*
您的注釋
*/
3.4 菜單
---------
ODBGScript的主菜單包含了下面幾項:
- Run script...[運行腳本...]: 用戶選擇一個腳本,并運行這個腳本。
- Abort [中止]: 中止腳本運行
- Pause [暫停]: 暫停腳本運行
- Resume[恢復]: 恢復腳本運行
-腳本運行窗口:動態觀察腳本運行
-腳本日志窗口:記錄腳本運行情況
- About [關于]: 顯示此插件信息
3.5 Script Window
-----------------
腳本窗口是ODbgScript內置的,它能讓你調試和觀察你的腳本.
你能在這里為腳本設置斷點,調試腳本,編輯變量還能手工執行腳本命令
4. 嵌入其他的插件
---------------------------------
您可以在您的插件中調用OllyScrip,并且運行一個腳本。
使用類似于下面的代碼進行調用:
HMODULE hMod = GetModuleHandle("OllyScript.dll");
if(hMod) // 檢測是否被其他插件加載
{?
// 獲得輸出函數地址
int (*pFunc)(char*) = (int (*)(char*)) GetProcAddress(hMod, "ExecuteScript");
if(pFunc) // 檢查是否獲得輸出函數
pFunc("myscript.txt"); // 執行輸出函數
=============================================================================
示例:
1: ESP定律脫“NsPacK”
var addr ? ? ? ? ? ? ? ? ? ?//聲明一個變量
sto ? ? ? ? ? ? ? ? ? ? ? ? ? ?//F8單步
sto ? ? ? ? ? ? ? ? ? ? ? ? ? ?//F8單步
mov addr,esp ? ? ? ? ? //將源操作數移動到目的操作數中
bphws addr,"r" ? ? ? ? ?//下斷 hr esp
run ? ? ? ? ? ? ? ? ? ? ? ? ? //F9運行
BPHWC addr ? ? ? ? ? ?//刪除斷點
sto ? ? ? ? ? ? ? ? ? ? ? ? ? ?//F8單步
sto ? ? ? ? ? ? ? ? ? ? ? ? ? ?//F8單步
cmt eip, "This is the OEP! ? ? ? //在指定地址處,加入注釋
ret ? ? ? ? ? ? ? ? ? ? ? ? ? //結束
總結
- 上一篇: IDA来远程调试Linux程序
- 下一篇: OD关键字搜索