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 可以判断出一条指令 修复花指令很有用 比如: 修复带参数的EB花指令 通过SIZE和3 TYPE和58 就可以寻找修复 TYPE的值是通过 gci 004B52FD,TYPE得到的 然后用于判断其他地方是否一样
- 004B52FD /2E:EB 01 jmp short 004B5301
- 004B5300 |F0:8D740D D3 lock lea esi, dword ptr [ebp+ecx-2D]
- 004B5305 2BF1 sub esi, ecx
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 注释
------------
您可以使用“//”在任何地方进行注释。
块注释必须另外起一行并以 “”作为结束,“*/”也必须另起一行。
摘自互联网
{ 【翻译】编写IDA插件 -------------------------------------------------------------------------------- 标 题: 【翻译】编写IDA插件 作 者: 月中人 时 间: 2006-08-29,08:48 链 接: } { 两篇已翻译好的有关IDA插件开发的文章 -------------------------------------------------------------------------------- 标 题: 两篇已翻译好的有关IDA插件开发的文章 作 者: jhlqb 时 间: 2006-09-02,12:00 链 接: } 有关IDA的手工脱壳,推荐一篇: { 【翻译】用IDA的调试器来手工脱壳(PE格式文件) -------------------------------------------------------------------------------- 标 题: 【翻译】用IDA的调试器来手工脱壳(PE格式文件) 作 者: 4nil 时 间: 2005-01-14,09:35 链 接: 【转帖】[翻译]IDA Plugin 编写基础 } 介绍一篇IDA的ABC文章: { IDA简易教程: } OD的脚本编写: { 标 题: 调试好帮手ODbgScript 入门系列(一)-认识ODbgScript【原创】 作 者: hnhuqiong 时 间: 2006-05-21,21:16 链 接: } 附Ollydbg常用快捷键: Alt+E → Modules窗口,查找输入函数 Ctrl+N → 查找名称标志,选择你要下断的内容 Shift+F9 → 强制继续执行跟踪或称拦截信息步进跟踪 F12 → 暂时停止 F10 → 打开反汇编选项菜单 F9 → 运行键 F8 → 单步跟踪结束 F7 → 单步跟踪 F3 → 打开快捷键 F2 → 下断点快捷键 Ctrl+F9 → 返回到跟踪 Ctrl+F8 → 自动步进扫描,按F12可停止 Ctrl+F7 → 同上,功能略有不同 Ctrl+F6 → 回到OL主窗口 Ctrl+F2 → 重新开始 Art+F2 → 结束跟踪 Enter → 进制转换计算 Art+L → 打开日志窗口 Art+C → 快速回到程序入口 Ctrl+S → 打开查找命令次序窗口 Shift+F2 → 打开附加选项窗口 Shift+F4 → 打开条件对话窗 Ctrl+E → 编辑机器码 Ctrl+G → 输入跟随地址 Space → 填充或修改汇编内容(NOP修改) ----------------------------------------------------------------------------------- OD的支持的命令 表达式 CALC 表达式 -------------计算表达式的值 ? 表达式 --------------同上 表达式 ---------------(第一个字符不能是字母) 同上 WATCH表达式------------- 添加监视 W 表达式 ---------------同上 反汇编器 AT 表达式------------- 在反汇编中跟随 FOLLOW--------------- 表达式 同上 ORIG ----------------前往实际的 EIP * ------------------同上 转存和堆栈 D 表达式----------- ---在转存中跟随 DUMP 表达式 -------------同上 DA [表达式]------- ------转存为汇编格式 DB [表达式] -------------转存为十六进制(hex)字节格式 DC [表达式] -------------作为ASCII 文本转存 DD [表达式] -------------作为地址(堆栈格式)转存 DU [表达式] -------------作为 UNICODE 文本转存 DW [表达式]------------- 转存为十六进制(hex)字格式 STK 表达式-------------- 在堆栈中跟随 汇编 A 表达式 [,命令]----------- 在地址处汇编 标号和注释 L 表达式, 标号 ------------为地址指派符号标号 C 表达式, 注释 ------------在地址处作注释 断点命令 BP 表达式 [,条件] -----------在地址处设置 INT3 断点 BPX 标号 ----------------在当前模块内部的每个调用外部'标号'处设置断点 BC 表达式 ---------------删除地址处的断点 MR 表达式1 [,表达式2] ---------设置访问范围的内存断点 MW 表达式1 [,表达式2] ---------设置写入范围的内存断点 MD -------------------移除内存断点 HR 表达式 ---------------在访问地址处设置一个字节的硬件断点 HW 表达式 ---------------在写入地址处设置一个字节的的硬件断点 HE 表达式 ---------------在执行地址处设置硬件断点 HD [表达式] --------------移除地址处的硬件断点 跟踪命令 STOP -----------------暂停执行 PAUSE -----------------同上 RUN ------------------运行程序 G [表达式] ---------------运行到地址处 GE [表达式] --------------跳过意外的句柄并运行到地址处 S -------------------单步进入 SI------------------- 同上 SO -------------------单步跳过 T [表达式] ---------------跟踪进入到地址处 TI [表达式] ---------------同上 TO [表达式] ---------------跟踪跳过到地址处 TC 条件 -----------------跟踪进入到条件处 TOC 条件 -----------------跟踪跳过到条件处 TR --------------------执行到返回 TU --------------------执行到用户代码 OllyDbg 窗口 LOG -------------------查看日志窗口 MOD -------------------查看可执行模块 MEM -------------------查看内存窗口 CPU -------------------查看 CPU 窗口 CS --------------------查看调用堆栈 BRK --------------------查看断点窗口 OPT --------------------编辑选项 杂项命令 EXIT -------------------关闭 OllyDbg QUIT -------------------同上 OPEN [文件名] --------------打开待调试的可执行文件 CLOSE ------------------关闭调试的程序 RST -------------------重新载入当前程序 HELP -------------------显示本帮助 HELP OllyDbg ---------------显示 OllyDbg 帮助 HELP API函数帮助完整文件名 --------显示 API