OD脚本编写资料与示例Word下载.docx
《OD脚本编写资料与示例Word下载.docx》由会员分享,可在线阅读,更多相关《OD脚本编写资料与示例Word下载.docx(38页珍藏版)》请在冰点文库上搜索。
例:
cmp$VERSION,"
1.47"
//比较是否大于1.47版
javersion_above_147
3.1.2指令
--------------
#INC"
文件名"
---------
一个脚本文件包含另外一个脚本.就像调用子程序一样.两个脚本中的变量名不能相同.
例:
#inc"
test.txt"
#LOG
----
开始记录运行指令
指令会显示在OllyDbg的log窗口中,每条记录前都会加上“-->
”的前缀
#log
ADD目的操作数,源操作数
-------------
ADD>
源操作数与目的操作数相加,并把相加的结果保存到目的操作数中,支持字符串相加.
addx,0F//x=x+F
addeax,x//eax=eax+x
add[401000],5//[401000]=[401000]+5
浮点数相加
addx,16.50//x=x+16.50
(字符串相加)
addy,"
times"
//如果在次之前y="
1000"
,则在执行完此指令之后y="
1000times"
AI
--
AnimateInto>
在OllyDbg中执行“自动步入”[Animateinto]操作。
相当于在OllyDbg中按下CTRL+F7
ai
ALLOC大小
----------
申请内存,你能读/写/执行.
alloc1000//新申请内存,大小为1000,返回结果$RESULT放着申请的内存开始地址.
free$RESULT,1000
AN地址
ANalyze>
从指定地址处,对代码进行分析。
aneip//相当于在OllyDbg中按Ctrl+A键
AND目的操作数,源操作数
AND>
源操作数与目的操作数进行逻辑与操作,并将结果保存到到目的操作数中。
andx,0F//x=x&
&
f
andeax,x//eax=eax&
x
and[401000],5//[401000]=[401000]&
5
AO
AnimateOver>
在OllyDbg中执行“自动步过”[Animateover]操作。
相当于在OllyDbg中按下CTRL+F8
ao
ASK问题
------------
ASK>
显示一个提示输入框,让用户输入,结果保存变量$RESULT中(如果用户按了取消键,则$RESULT=0)。
$RESULT_1中放着输入的长度.
(注:
程序将判读你输入的是字符,$RESULT_1的结果是输入字符数的数目,整型/2,中文数*2)
ask"
EnternewEIP"
cmp$RESULT,0
jecancel_pressed
moveip,$RESULT
ASM地址,指令
-----------------
ASseMble>
修改指定地址的指令。
并将修改后的汇编指令长度保存到保留变量$RESULT中
asmeip,"
moveax,ecx"
//将当前指令修改为moveax,ecx
ASMTXT文件
汇编指定文件中的指令。
将汇编指令保存到保留变量$RESULT中
并将汇编指令长度保存到保留变量$RESULT_1中
asmtxtEIP,"
myasm.txt"
//将myasm.txt文件中的asm转成opcode后写入EIP.
ATOIstr[,base=16.]
转换字符串到16进制整型,[可以将任何进制转成16进制整型]
返回结果放到$RESULT
itoa"
F"
//字符串"
转成了整型,结果会等于F
10"
10.//字符串"
代表十进制,结果会等于A
BC地址
BreakPointClear>
清除指定地址的断点。
bc401000//清除401000处的断点
bcx//清除X(变量值)处的断点
bceip//清除当前EIP处的断点
BPaddr
BreakPoint>
在指定地址设断点
bp401000//在401000处下断点
bpx//在X(变量值)处下断点
bpeip//在当前EIP处下断点
BPCND地址,条件
----------------
BreakPointonCoNDition>
在指定地址处,设置条件断点。
bpcnd401000,"
ECX==1"
//当代码执行到401000且ecx等于1时,程序暂停
BPD函数字符串
---------------
清除调用函数断点,函数为字符串表示.
bpd"
GetVersion"
//取消呼叫GetVersion的断点
BPHWC地址
BreakPointHardWareClear>
删除指定地址处的硬件断点。
bphwc401000//清除401000处的断点
BPHWCALL
-----------
清除所有的硬件断点
BPHWCALL//清除所有的硬件断点
BPHWS地址,模式
BreakPointHardWareSet>
在指定地址,设置硬件断点。
有三种模式:
r"
-读取,"
w"
-写入或者"
x"
-执行.
此断点只支持1个字节的动作.
bphws401000,"
//当执行到此地址时发生中断.
Bphws401000,"
//当读取401000的时候,发送中断
BPL地址,表达式
BreakPointofLogging>
在指定地址处设置记录断点,将表达式的结果记录到记录窗口中。
bpl401000,"
eax"
//每次执行到401000时,都将eax寄存器的结果记录
BPLCND地址,表达式,条件
-----------------------
BreakPointofLoggingonCoNDition>
在指定地址处设置记录断点,如果条件为真时,将表达式的结果记录到记录窗口中。
bplcnd401000,"
"
eax>
1"
//如果执行到401000时,满足eax>
1,则将eax寄存器的结果记录
BPMC
BreakPointMemoryClear>
清除内存断点。
bpmc
BPRM地址,大小
BreakPointonReadMemory>
在指定地址处,设置一个内存读取断点。
“大小”是指内存中的字节大小。
bprm401000,FF//在401000中设置内存读断点,内存中的大小为FF
BPWM地址,大小
BreakPointonWriteMemory>
在指定地址处,设置一个内存写入断点。
“大小”是指内存中的字节大小。
bpwm401000,FF//在401000中设置内存写断点,内存中的大小为FF
BPX函数字符串
设置调用函数断点,函数为字符串表示.
返回下了断点的地址数量,结果保存在保留变量$RESULT中.
bpx"
//下呼叫GetVersion断点,断下的语句为call[xxxxx]
CMP目的操作数,源操作数
CoMPare>
比较目的操作数与源操作数的大小,和其对应的汇编指令作用相同。
可以是各种数值,甚至可以是字符串(对大小不敏感).
cmpy,x//比较两个变量(Y和X)的大小,
cmpeip,401000//比较EIP和401000的大小
CMT地址,字符串
CoMmenT>
在指定地址处,加入注释。
cmteip,"
这是入口"
//当前地址处加上“这是入口”的注释
COB
---
ContinueOnBreakpoint>
发生中断后,让脚本继续执行(移除EOB指令)
COE
ContinueOnException>
(移除EOE指令)
发生异常后,让脚本继续执行
DBH
DeBuggerHided>
隐藏调试器
dbh
DBS
DeBuggerShow>
对隐藏的调试器操作进行恢复,不再隐藏。
dbs
DEC变量
DECrementby1>
对变量进行减一操作
decv//V=V-1
DIV目的操作数,源操作数
div>
源操作数与目的操作数进行除法操作,并将结果保存到到目的操作数中。
divx,0F//X=X/0F
diveax,x//eax=eax/x
div[401000],5//[401000]/5
DM地址,大小,文件名
-------------------
DumpMemory>
从指定地址处开始,在内存中提取指定大小的数据,并保存到指定的文件中
dm401000,1F,"
c:
\dump.bin"
DMA地址,大小,文件名
DumpMemoryAppended>
从指定地址处开始,在内存中提取指定大小的数据,并保存到指定的文件中;
如
果指定文件已存在,则将数据追加到指定文件尾部。
dma401000,1F,"
DPE文件名,入口
DumpProcesswithEntrypoint>
提取执行模块到指定文件中。
“入口”用来设定入口地址。
这个命令用来抓取文件,还是比较好用的,因为直接利用了OD强大的内存管理功能.
dpe"
\test.exe"
eip//入口为当前地址,保存为C盘下test.exe
EOB标签
ExecutionOnBreakpoint>
在下次中断发生时,跳转到指定标签处。
此功能和EOE命令常常让新手迷惑不解,其实就是遇见中断做脚本的流程转向.
如果还有不懂,请看下文的答疑解惑章节.
eobSOME_LABEL
EOE标签
ExecutionOnException>
在下次异常发生时,跳转到指定标签处。
eoeSOME_LABEL
ESTI
ExceptionSTepInto>
相当于在OllyDbg按SHIFT-F7。
esti
ESTO
ExceptionSTepcOntinue>
相当于在OllyDbg按SHIFT-F9。
esto
EVAL
EVALuate>
计算含义变量的表达式。
变量必须已经在脚本中声明。
注意:
插到字符串中时,要放在大括号{}中。
结果保存在保留变量$RESULT中.
这句和其它语句结合将产生很多的变化,用好它将让你的脚本十分灵活.
varx
movx,1000
eval"
x的值是{x}"
//执行后$RESULT为"
x的值是00001000"
EXEC/ENDE
EXECute/ENDofExecute>
对当前调试进程,执行在EXEC和ENDE之间的指令。
有这个命令就是你可以直接跳入进程,对进程进行直接控制.
它的原理就是取当前进程的信息进行保存,然后新分配一个代码内存区(可读/写/执行.大小1000)
调用OD汇编器将你的汇编语句转成OPcode,将OPcode拷贝到代码区,然后将EIP指向你的代码开头.
然后将控制权交给你.执行完后将EIP归还原位,然后将控制权交还ODbgScript.
这里的好处就是让你以很高的效率来避免在较慢的脚本环境运行需要高效的操作.
!
由于进程控制权交给你了,那么,你的代码有效性将只有你自己来控制了.
执行后不保存现场.这都需要你来做工作.(要保存现场,你可以使用pushad,popad)
有大括号的,会被大括号中的变量的值替代。
//以下是做移动操作
vary
movx,"
movy,"
0DEADBEEF"
exec
mov{x},{y}//到进程中新开的代码区去,moveax,0DEADBEEF将被执行
movecx,{x}//movecx,eax将被执行
ende
//以下是调用调试程序的ExitProcess函数
push0
callExitProcess
ret
FILLaddr,len,value
-------------------------
从地址addr开始填充长度为len的值value
注:
value的值最大8个字节,可以为寄存器值,标志位值,变量值,16进制值,10进制值,[]指针操作数.
如:
fill401000,10,90//NOP10h个字节
fill401000,ff,[eax]//取出[eax]值,填充到401000,长度为ff
fill401000,ff,$RESULT//将变量$RESULT的值填充到401000,长度为ff
FIND地址,查找内容,[最大大小]
FIND>
从指定地址开始在内存中查找指定的内容。
如果查找成功,地址会保存到保留变量$RESULT中,否则$RESULT将等于0。
查找的串支持通配符“?
”(见下面的例子)。
##中的为HEX,"
"
中的为字符串,什么都不带的为内存数据
输入的16进制字符必须是成偶数
从1.52版开始支持直接变量和数据查找.
findeip,#6A00E8#//查找一个Call,其的第一个参数为0(push0)
findeip,#6A?
E8#//查找一个带参数的Call,一个?
代表一个字符常量
findeip,"
kernel32.dll"
//查找字符串"
ker?
32.d?
//查找带通配符的?
字符串,一个?
代表一个字符串常量
(请注意这里的通配符?
和HEX中的?
不同)
findeip,15ff//查找内存数据15ff(代码为ff115)
(movtmp,#ff15#
findeip,tmp)//查找变量tmp中的数值,tmp=ff15
(movtmp,"
findeip,tmp)//查找变量tmp中的字符串"
(movtmp,15ff
findeip,tmp//查找变量tmp中的内存数据15ff(注意和#ff15#区别)
(ask"
输入需要的数据"
findeip,$RESULT//输入的为#ff15#,"
Kernel32.dll"
15ff就同上面三例子
findeip,#ff15#,ff//从EIP开始,FF大小范围内,查找字符ff15,
FINDOP地址,查找内容,[查找范围]
FINDOPcode>
从指定地址开始查找指定一个指令,这个指令是以指定内容为开始的。
findop由于是opcode查找,不支持字符串查找.
findop和find的区别是findop查找到的必须是opcode.
1.52起支持直接变量和内存数据
findop401000,#61#//findnextPOPAD
findop401000,#6A?
#//findnextPUSHofsomething
译者注:
对比一下FIND和FINDDOP的区别:
地址数据代码
00401007B83300MOVEAX,33
0040100C33F6XORESI,ESI
find401007,#33#//$RESULT等于401008
finddop401007,#33#//$RESULT等于40100C
FINDMEMwhat[,StartAddr]
--------------------------
从整个内存开始在内存中查找指定的内容
Example:
findmem#6A00E8#//findaPUSH0followedbysomekindofcall
findmem#6A00E8#,00400000//searchitafteraddress00400000
FREE
FREE地址大小
释放由ALLOC申请的内存.
alloc1000
GAPI
GAPI地址
获得指定代码处的API调用信息
API信息保存到保留变量$RESULT中。
如果符号名是一个API函数,则
$RESULT保存API信息
$RESULT_1保存链接库名(比如kernal32)
$RESULT_2保存符号名(比如ExitProcess)。
$RESULT_3保存调用地址XXXX(比如callxxxxx)
这个和GN的区别是GN必须指向IAT地址
而GAPI直接给出代码地址就可得出API
还有如果你是在此处下了软件断点,请先清除断点再用此句,因为软件断点修改了代码为CC
这里如果不清除此处的软件断点,将造成这句不能很好的识别.
GAPI401000(callkernal32.ExitProcess)
GAPIEIP//查看当前代码是否是API调用,不是则返回0
GCMTaddr
获得指定地址处的解释
GMEMIaddr,info
获得指定地址处内存的信息.
信息可以是MEMORYBASE,MEMORYSIZEorMEMORYOWNER
GMEMIaddr,MEMORYBASE//Afterthis$RESULTistheaddresstothememorybaseofthememoryblockto
whichaddrbelongs
GMI地址,信息
GetModuleInfo>
获得指定地址所在模块的相关信息。
“信息”可以是模块基地址[MODULEBASE],模块大小[MODULESIZE],代码段基地址[CODEBASE]或者代码段大小
[CODESIZE]
(如果您想在将来的版本中,获得更多的信息,请联系我)。
信息会保存到保留变量$RESULT中(如果没有找到信息,则$RESULT等于0).
GMIeip,CODEBASE//这条指令执行后,$RESULT等于当前所在模块的代码段基地址。
GN地址
GetName>
获得指定IAT地址的符号名(比如指向API函数)。
符号名将保存到保留变量$RESULT中。
$RESULT是符号名
gn450100
GO地址
GO>
执行到指定地址处
go401005
GPA函数名,动态链接库名
GetProcedureAddress>
在指定的动态链接库中,获得指定函数的地址。
在设置API函数断点时,这个指令非常有效。
gpa"
MessageBoxA"
user32.dll"
//这条指令执行后,$RESULT等于函数MessageBoxA的地址,您可以
使用"
bp$RESULT"
设置断