OD脚本指令大全

<table cellspacing="0" class="t_table" style="width:98%"><tbody><tr><td width="190">指令</td><td width="213"><div align="left">全称</div></td><td width="407"><div align="left">解释</div></td><td width="445"><div align="left">示例</div></td></tr><tr><td colspan="4" width="1255">在后面的文档中, “源操作数” 和 “目的操作数”表示以下含义:<br>
    - 十六进制常数,既没有前缀也没有后缀。 (例如:是00FF, 而不是 0x00FF 和 00FFh的形式)<br>
      十进制常数,在后缀中加点. (例如:100.  128.也可以是浮点数128.56,浮点数只能保留小数点后2位)<br>
    - 变量,这个变量必须在使用前用Var进行定义<br>
    - 32位寄存器 (EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EIP)。<br>
      16位寄存器 (AX, BX, CX, DX, SI, DI,  BP,SP)<br>
      8位的寄存器(AL, AH, ... DL, DH)<br>
    - 被中括号括起来的内存地址 (例如:[401000]指向内存地址为401000里存放分数据, <br>
      [ecx] 指向内存地址为寄存器ecx里存放分数据).<br>
    - 一个标志位,带有感叹号前缀(!CF, !PF, !AF, !ZF, !SF, !DF, !OF)<br>
    - 字符串,也可叫数据序列。其格式为: #6A0000#(数值在两个“#”号之间),两个“#”号之间必须包含至少有一个数值。<br>
                                  "1234567ABCDEF"<br>
    - 包含“?”通配符的字符串。比如 #6A??00# 或者 #6?0000#</td></tr><tr><td width="190">$RESULT</td><td width="213"><div align="left"><RESULT></div></td><td width="407"><div align="left">保存某些函数的返回值,比如FIND函数运行后的结果,等等。<br>
    在ODbgScript的脚本调试窗口,你能观察到它的变化,并且可以修改它.</div></td><td width="445"><div align="left"></div></td></tr><tr><td width="190">$VERSION</td><td width="213"><div align="left"><VERSION></div></td><td width="407"><div align="left">ODBGScript的版本信息,它是系统保留变量名.</div></td><td width="445"><div align="left">例:<br>
    cmp $VERSION, "1.47"  //比较是否大于 1.47版<br>
    ja version_above_147  </div></td></tr><tr><td width="190">#INC "文件名"</td><td width="213"><div align="left"></div></td><td width="407">一个脚本文件包含另外一个脚本.就像调用子程序一样.两个脚本中的变量名不能相同.</td><td width="445"><div align="left">例:<br>
    #inc "test.txt" </div></td></tr><tr><td width="190">#LOG</td><td width="213"><div align="left"></div></td><td width="407">开始记录运行指令<br>
    指令会显示在<a href="https://www.52pojie.cn/thread-350397-1-1.html" target="_blank" class="relatedlink">OllyDbg</a>的log窗口中,每条记录前都会加上“-->”的前缀</td><td width="445"><div align="left">例:<br>
    #log</div></td></tr><tr><td width="190">ADD</td><td width="213"><div align="left"><ADD></div></td><td width="407"><div align="left">源操作数与目的操作数相加,并把相加的结果保存到目的操作数中,支持字符串相加.</div></td><td width="445"><div align="left">例: <br>
    add x, 0F         //x=x+F<br>
    add eax, x        //eax=eax+x<br>
    add [401000], 5    //[401000]=[401000]+5<br>
    浮点数相加<br>
    CMP 目的操作数, 源操作数 </div></td></tr><tr><td width="190">AI</td><td><div align="left"><Animate Into></div></td><td width="407"><div align="left">在OllyDbg中执行“自动步入”  [Animate into]操作。<br>
    相当于在OllyDbg中按下CTRL+F7</div></td><td width="445"><div align="left">例:<br>
    ai</div></td></tr><tr><td>ALLOC</td><td width="213"><div align="left"></div></td><td width="407">申请内存, 你能读/写/执行</td><td width="445"><div align="left">例:<br>
    alloc 1000         //新申请内存,大小为1000,返回结果$RESULT放着申请内存的开始地址.<br>
    free $RESULT, 1000</div></td></tr><tr><td width="190">AN 地址</td><td><div align="left"><ANalyze></div></td><td width="407"><div align="left">从指定地址处,对代码进行分析</div></td><td width="445"><div align="left">例:<br>
    an eip //    相当于在OllyDbg中按 Ctrl+A键</div></td></tr><tr><td width="190">AND 目的操作数, 源操作数</td><td width="213"><div align="left"><AND></div></td><td width="407"><div align="left">源操作数与目的操作数进行逻辑与操作,并将结果保存到到目的操作数中</div></td><td width="445"><div align="left">例: <br>
    and x, 0F                //x=x&&f<br>
    and eax, x               //eax=eax&&x<br>
    and [401000], 5          //[401000]=[401000]&&5<br>
    <br>
    </div></td></tr><tr><td width="190">AO</td><td width="213"><div align="left"><Animate  Over></div></td><td width="407"><div align="left">在OllyDbg中执行“自动步过”  [Animate over]操作。<br>
    相当于在OllyDbg中按下CTRL+F8</div></td><td width="445"><div align="left">例:<br>
    ao</div></td></tr><tr><td width="190">ASK 问题</td><td width="213"><div align="left"><ASK></div></td><td width="407"><div align="left">显示一个提示输入框,让用户输入,结果保存变量$RESULT中(如果用户按了取消键,则$RESULT=0)。<br>
    $RESULT_1中放着输入的长度.<br>
    (注:程序将判读你输入的是字符,$RESULT_1的结果是输入字符数的数目,整型/2,中文数*2)</div></td><td width="445"><div align="left">例:<br>
    ask "Enter new EIP"<br>
    cmp $RESULT, 0<br>
    je cancel_pressed<br>
    mov eip, $RESULT</div></td></tr><tr><td width="190">ASM 地址, 指令</td><td width="213"><div align="left"><ASseMble></div></td><td width="407"><div align="left">修改指定地址的指令。<br>
    并将修改后的汇编指令长度保存到保留变量$RESULT中</div></td><td width="445"><div align="left">例:<br>
    asm eip, "mov eax, ecx" //将当前指令修改为 mov eax,ecx</div></td></tr><tr><td width="190">ASMTXT 文件</td><td width="213"><div align="left"><ASseMble></div></td><td width="407"><div align="left">汇编指定文件中的指令<br>
    将汇编指令长度保存到保留变量$RESULT中<br>
    并将汇编指令行数保存到保留变量$RESULT_1中</div></td><td width="445"><div align="left">例:<br>
    asmtxt EIP,"myasm.txt"//将myasm.txt文件中的asm转成opcode后写入EIP.</div></td></tr><tr><td width="190">ATOI str [, base=16.]</td><td width="213"><div align="left"></div></td><td width="407">转换字符串到16进制整型,[可以将任何进制转成16进制整型]<br>
    返回结果放到 $RESULT </td><td width="445"><div align="left">例:<br>
    itoa "F"        //字符串"F"转成了整型,结果会等于F<br>
    itoa "10", 10.   //字符串"10"代表十进制,结果会等于A</div></td></tr><tr><td width="190">BC 地址</td><td width="213"><div align="left"><BreakPoint  Clear></div></td><td width="407"><div align="left">清除指定地址的断点</div></td><td width="445"><div align="left">例:<br>
    bc 401000         //清除401000处的断点<br>
    bc x              //清除X(变量值)处的断点<br>
    bc eip            //清除当前EIP处的断点</div></td></tr><tr><td width="190">BP 地址</td><td width="213"><div align="left"><BreakPoint></div></td><td width="407"><div align="left">在指定地址设断点</div></td><td width="445"><div align="left">例:<br>
    bp 401000         //在401000处下断点<br>
    bp x              //在X(变量值)处下断点 <br>
    bp eip           //在当前EIP处下断点</div></td></tr><tr><td width="190">BPCND 地址, 条件</td><td width="213"><div align="left"><BreakPoint  on CoNDition></div></td><td width="407"><div align="left">在指定地址处,设置条件断点。</div></td><td width="445"><div align="left">例:<br>
    bpcnd 401000, "ECX==1" //当 代码执行到401000且  ecx等于1 时,程序暂停</div></td></tr><tr><td width="190">BPD 函数字符串</td><td width="213"><div align="left"></div></td><td width="407">清除调用函数断点,函数为字符串表示.</td><td width="445"><div align="left">例:<br>
    bpd "GetVersion"   //取消呼叫GetVersion的断点</div></td></tr><tr><td width="190">BPHWC 地址</td><td width="213"><div align="left"><BreakPoint  HardWareClear></div></td><td width="407"><div align="left">删除指定地址处的硬件断点</div></td><td width="445"><div align="left">例:<br>
    bphwc 401000 //清除 401000处的断点<br>
    bphwc //不接地址默认清楚全部 等同于bphwcall</div></td></tr><tr><td width="190">BPHWCALL</td><td width="213"><div align="left"></div></td><td width="407">清除所有的硬件断点</td><td width="445"><div align="left">例:<br>
    BPHWCALL     //清除所有的硬件断点</div></td></tr><tr><td width="190">BPHWS 地址, 模式</td><td width="213"><div align="left"><BreakPoint  HardWare Set></div></td><td width="407"><div align="left">在指定地址,设置硬件断点。有三种模式: "r" - 读取, "w" - 写入 或者 "x" - 执行.<br>
    此断点只支持1个字节的动作.</div></td><td width="445"><div align="left">例:<br>
    bphws 401000, "x" //当执行到此地址时产生中断.<br>
    Bphws 401000,"r"  //当读取401000的时候产生中断</div></td></tr><tr><td width="190">BPL 地址, 表达式</td><td width="213"><div align="left"><BreakPoint  of Logging></div></td><td width="407"><div align="left">在指定地址处设置记录断点,将表达式的结果记录到记录窗口中。</div></td><td width="445"><div align="left">例:<br>
    bpl 401000, "eax" // 每次执行到401000时,都将eax寄存器的结果记录</div></td></tr><tr><td width="190">BPLCND 地址, 表达式, 条件</td><td width="213"><div align="left"><BreakPoint  of <br>
    Logging onCoNDition></div></td><td width="407"><div align="left">在指定地址处设置记录断点,如果条件为真时,将表达式的结果记录到记录窗口中。</div></td><td width="445"><div align="left">例:<br>
    bplcnd 401000, "eax", "eax >  1" //如果执行到401000时,满足eax>1,则将eax寄存器的结果记录</div></td></tr><tr><td width="190">BPMC</td><td width="213"><div align="left"><BreakPoint  Memory Clear></div></td><td width="407"><div align="left">清除内存断点。</div></td><td width="445"><div align="left">例:<br>
    bpmc</div></td></tr><tr><td width="190">BPRM 地址, 大小</td><td width="213"><div align="left"><BreakPoint  on ReadMemory></div></td><td width="407"><div align="left">在指定地址处,设置一个内存读取断点。 “大小” 是指内存中的字节大小。</div></td><td width="445"><div align="left">例:<br>
    bprm 401000, FF //在401000中设置内存读断点,内存中的大小为FF</div></td></tr><tr><td width="190">BPWM 地址, 大小</td><td width="213"><div align="left"><BreakPoint  on WriteMemory></div></td><td width="407"><div align="left">在指定地址处,设置一个内存写入断点。“大小” 是指内存中的字节大小。</div></td><td width="445"><div align="left">例:<br>
    bpwm 401000, FF   //在401000中设置内存写断点,内存中的大小为FF</div></td></tr><tr><td width="190">BPX 函数字符串</td><td width="213"><div align="left"></div></td><td width="407">设置调用函数断点,函数为字符串表示.<br>
    返回下了断点的地址数量,结果保存在保留变量$RESULT中.</td><td width="445"><div align="left">例:<br>
    bpx "GetVersion"   //下呼叫GetVersion断点,断下的语句为call [xxxxx]</div></td></tr><tr><td width="190">BUF var</td><td width="213"><div align="left">string/dword  variable to a Buffer</div></td><td width="407"><div align="left">转换字符串变量到缓冲区</div></td><td width="445"><div align="left">例:<br>
    mov s, "123"<br>
    buf s<br>
    log s // output "#313233#</div></td></tr><tr><td width="190">CMP 目的操作数, 源操作数</td><td width="213"><div align="left"><CoMPare></div></td><td width="407"><div align="left">比较 目的操作数与源操作数的大小,和其对应的汇编指令作用相同<br>
    可以是各种数值,甚至可以是字符串(对大小不敏感).</div></td><td width="445"><div align="left">例: <br>
    cmp y, x        //比较两个变量(Y和X)的大小,<br>
    cmp eip, 401000   //比较EIP和401000的大小<br>
    这里可以设置比较的数的长度 比如 cmp [eip],#ff25#,2 这里比较EIP所在的指令 前两个字节是否是FF25<br>
    测试代码如下:<br>
    00581DAC    $- FF25 C0B55B00 jmp     dword  ptr [5BB5C0]</div></td></tr><tr><td width="190">CMT 地址, 字符串</td><td width="213"><div align="left"><CoMmenT></div></td><td width="407"><div align="left">在指定地址处,加入注释。</div></td><td width="445"><div align="left">例:<br>
    cmt eip, "这是入口" //当前地址处 加上“这是入口”的注释</div></td></tr><tr><td width="190">COB</td><td width="213"><div align="left"><Continue  On Breakpoint></div></td><td width="407"><div align="left">发生中断后,让脚本继续执行(移除EOB指令)</div></td><td width="445"><div align="left">例:<br>
    COB</div></td></tr><tr><td width="190">COE</td><td width="213"><div align="left"><Continue  OnException><br>
    (移除EOE指令)</div></td><td width="407"><div align="left">发生异常后,让脚本继续执行</div></td><td width="445"><div align="left">例:<br>
    COE</div></td></tr><tr><td width="190">DBH</td><td width="213"><div align="left"><DeBuggerHided> </div></td><td width="407"><div align="left">隐藏调试器</div></td><td width="445"><div align="left">例:<br>
    dbh</div></td></tr><tr><td width="190">DBS</td><td width="213"><div align="left"><DeBugger  Show></div></td><td width="407"><div align="left">对隐藏的调试器操作进行恢复,不再隐藏。</div></td><td width="445"><div align="left">例:<br>
    dbs</div></td></tr><tr><td width="190">DEC 变量</td><td width="213"><div align="left"><DECrement  by 1></div></td><td width="407"><div align="left">对变量进行减一操作</div></td><td width="445"><div align="left">例:<br>
    dec v           //V=V-1</div></td></tr><tr><td width="190">DIV 目的操作数, 源操作数</td><td width="213"><div align="left"><div></div></td><td width="407"><div align="left">源操作数与目的操作数进行除法操作,并将结果保存到到目的操作数中。</div></td><td width="445"><div align="left">例: <br>
    div x, 0F       //X=X/0F<br>
    div eax, x      //eax=eax/x<br>
    div [401000], 5  //[401000]/5</div></td></tr><tr><td width="190">DM 地址, 大小, 文件名</td><td width="213"><div align="left"><Dump  Memory></div></td><td width="407"><div align="left">从指定地址处开始,在内存中提取指定大小的数据,并保存到指定的文件中</div></td><td width="445"><div align="left">例:<br>
    dm 401000, 1F, "c:\dump.bin"</div></td></tr><tr><td width="190">DMA 地址, 大小, 文件名</td><td width="213"><div align="left"><Dump  Memory Appended></div></td><td width="407"><div align="left">从指定地址处开始,在内存中提取指定大小的数据,并保存到指定的文件中;如<br>
    果指定文件已存在,则将数据追加到指定文件尾部。</div></td><td width="445"><div align="left">例:<br>
    dma 401000, 1F, "c:\dump.bin"</div></td></tr><tr><td width="190">DPE 文件名, 入口</td><td width="213"><div align="left"><Dump  Process with Entrypoint></div></td><td width="407"><div align="left">提取执行模块到指定文件中。<br>
    “入口”用来设定入口地址。<br>
    这个命令用来抓取文件,还是比较好用的,因为直接利用了OD强大的内存管理功能.</div></td><td width="445"><div align="left">例:<br>
    dpe "c:\test.exe", eip //入口为当前地址,保存为C盘下test.exe</div></td></tr><tr><td width="190">EOB 标签</td><td width="213"><div align="left"><Execution  On Breakpoint></div></td><td width="407"><div align="left">在下次中断发生时,跳转到指定标签处。<br>
    此功能和EOE命令常常让新手迷惑不解,其实就是遇见中断做脚本的流程转向.<br>
    如果还有不懂,请看下文的答疑解惑章节.</div></td><td width="445"><div align="left">例:<br>
    eob SOME_LABEL</div></td></tr><tr><td width="190">EOE 标签</td><td width="213"><div align="left"><Execution  On Exception></div></td><td width="407"><div align="left">在下次异常发生时,跳转到指定标签处。</div></td><td width="445"><div align="left">例:<br>
    eoe SOME_LABEL</div></td></tr><tr><td width="190">ESTI</td><td width="213"><div align="left"><Exception  STep Into></div></td><td><div align="left">相当于在OllyDbg按  SHIFT-F7。</div></td><td width="445"><div align="left">例:<br>
    esti</div></td></tr><tr><td width="190">ESTO</td><td width="213"><div align="left"><Exception  STep cOntinue></div></td><td width="407"><div align="left">相当于在OllyDbg按 SHIFT+F9。</div></td><td width="445"><div align="left">例:<br>
    esto<br>
    一般来说用这个 不用F9多 因为Shift+F9  忽略异常运行</div></td></tr><tr><td width="190">EVAL </td><td width="213"><div align="left"><EVALuate></div></td><td width="407"><div align="left">计算含义变量的表达式。<br>
    变量必须已经在脚本中声明。<br>
    注意:<br>
    插到字符串中时,要放在大括号{ }中。<br>
    结果保存在保留变量$RESULT中.<br>
    这句和其它语句结合将产生很多的变化,用好它将让你的脚本十分灵活.</div></td><td width="445"><div align="left">例:<br>
    var x<br>
    mov x, 1000<br>
    eval "x的值是 { x  }" // 执行后$RESULT为 "x的值是00001000"</div></td></tr><tr><td width="190">EXEC/ENDE</td><td width="213"><div align="left"><EXECute/END  of Execute></div></td><td width="407"><div align="left">对当前调试进程,执行在EXEC和ENDE之间的指令。<br>
    有这个命令就是你可以直接跳入进程,对进程进行直接控制.<br>
    它的原理就是取当前进程的信息进行保存,然后新分配一个代码内存区(可读/写/执行.大小1000)<br>
    调用OD汇编器将你的汇编语句转成OPcode,将OPcode拷贝到代码区,然后将EIP指向你的代码开头.<br>
    然后将控制权交给你.执行完后将EIP归还原位,然后将控制权交还ODbgScript.<br>
    这里的好处就是让你以很高的效率来避免在较慢的脚本环境运行需要高效的操作.<br>
    !注意:由于进程控制权交给你了,那么,你的代码有效性将只有你自己来控制了.<br>
    !注意:执行后不保存现场.这都需要你来做工作.(要保存现场,你可以使用pushad,popad)<br>
    有大括号的,会被大括号中的变量的值替代。</div></td><td width="445"><div align="left">例:<br>
    // 以下是做移动操作<br>
    var x<br>
    var y<br>
    mov x, "eax"<br>
    mov y, "0DEADBEEF"<br>
    exec<br>
    mov {x},{y}     //到进程中新开的代码区去,mov eax,0DEADBEEF 将被执行<br>
    mov ecx, {x}     //mov ecx,eax 将被执行<br>
    ende<br>
    // 以下是调用调试程序的ExitProcess函数<br>
    exec<br>
    push 0<br>
    call ExitProcess<br>
    ende<br>
    ret</div></td></tr><tr><td width="190">FILL 地址,长度,值</td><td width="213"><div align="left"></div></td><td width="407">从地址addr开始填充长度为len的值value<br>
    !注:value的值最大8个字节,可以为寄存器值,标志位值,变量值,16进制值,10进制值,[]指针操作数.</td><td width="445"><div align="left">如:<br>
    fill 401000,10,90       //NOP 10h个字节<br>
    fill 401000,ff,[eax]      //取出[eax]值,填充到401000,长度为ff<br>
    fill 401000,ff,$RESULT    //将变量$RESULT的值填充到401000,长度为ff</div></td></tr><tr><td width="190">FIND 地址, 查找内容 ,[最大大小]</td><td width="213"><div align="left"><FIND></div></td><td width="407"><div align="left">从指定地址开始在内存中查找指定的内容。<br>
    如果查找成功,地址会保存到保留变量$RESULT中,否则$RESULT将等于 0。<br>
    查找的串支持通配符“??”(见下面的例子)。<br>
    ##中的为HEX,""中的为字符串,什么都不带的为内存数据<br>
    !注:输入的16进制字符必须是成偶数<br>
       从1.52版开始支持直接变量和数据查找.</div></td><td width="445"><div align="left">例:<br>
    find eip, #6A00E8# // 查找一个Call,其的第一个参数为0 (push 0)<br>
    find eip, #6A??E8# // 查找一个带参数的Call,一个?代表一个字符常量<br>
    find eip,"kernel32.dll" //查找字符串"kernel32.dll"<br>
    find eip,"ker???32.d??" //查找带通配符的?字符串,一个?代表一个字符串常量<br>
                           (请注意这里的通配符?和HEX中的?不同)<br>
    <br>
    find eip,15ff     //查找内存数据15ff(代码为ff115)<br>
    (mov tmp,#ff15#<br>
     find eip,tmp )   //查找变量tmp中的数值,tmp=ff15<br>
    (mov tmp,"kernel32.dll"<br>
    find eip,tmp  )   //查找变量tmp中的字符串"kernel32.dll"<br>
    (mov tmp,15ff<br>
     find eip,tmp    //查找变量tmp中的内存数据15ff(注意和#ff15#区别)<br>
    (ask "输入需要的数据"<br>
    find eip,$RESULT      //输入的为#ff15#,"Kernel32.dll",15ff就同上面三例子<br>
    <br>
    find eip,#ff15#,ff //从EIP开始,FF大小范围内,查找字符ff15,</div></td></tr><tr><td width="190">FINDCMDS 地址, 查找内容</td><td width="213"><div align="left"><FIND  command></div></td><td width="407"><div align="left">从指定地址开始查找指定命令序列。 <br>
    如果查找成功,地址会保存到保留变量$RESULT中,否则$RESULT将等于 0。<br>
    注:命令序列分割请使用;号(分号).</div></td><td width="445"><div align="left">例:<br>
    findcmd 401000, "push eax;mov eax,edx"  //    寻找"push eax和mov eax,edx"命令序列</div></td></tr><tr><td width="190">FINDOP 地址, 查找内容,[查找范围]</td><td width="213"><div align="left"><FIND  OPcode></div></td><td width="407"><div align="left">从指定地址开始查找指定一个指令,这个指令是以指定内容为开始的。  <br>
    如果查找成功,地址会保存到保留变量$RESULT中,否则$RESULT将等于 0。<br>
    查找的串支持通配符“??”(见下面的例子)。<br>
    注意:findop由于是opcode查找,不支持字符串查找.<br>
        findop和find的区别是findop查找到的必须是opcode.<br>
    1.52起支持直接变量和内存数据</div></td><td width="445"><div align="left">例:<br>
    findop 401000, #61# // find next POPAD<br>
    findop 401000, #6A??# // find next PUSH of something<br>
    译者注:<br>
    对比一下FIND 和FINDDOP的区别:<br>
    地址          数据              代码<br>
    00401007      B8 3300         MOV    EAX, 33<br>
    0040100C     33F6           XOR     ESI,ESI<br>
    find 401007,  #33#   //$RESULT等于401008<br>
    finddop 401007, #33#  //$RESULT等于40100C</div></td></tr><tr><td width="190">FINDMEM what [, StartAddr]</td><td width="213"><div align="left"></div></td><td width="407">从整个内存开始在内存中查找指定的内容<br>
    如果查找成功,地址会保存到保留变量$RESULT中,否则$RESULT将等于 0。<br>
    查找的串支持通配符“??”(见下面的例子)。</td><td width="445"><div align="left">Example:<br>
    findmem #6A00E8# // find a PUSH 0 followed by some kind ofcall<br>
    findmem #6A00E8#, 00400000 // search it after address00400000<br>
    此命令查找十六进制的变量有为有效,因为Find不会把变量当然一个十六进制来查找。</div></td></tr><tr><td width="190">FREE 地址 大小</td><td width="213"><div align="left"></div></td><td width="407">释放由ALLOC申请的内存.</td><td width="445"><div align="left">Example:<br>
     alloc 1000<br>
     free $RESULT, 1000</div></td></tr><tr><td width="190">GAPI 地址</td><td width="213"><div align="left"></div></td><td width="407">获得指定代码处的API调用信息<br>
    API信息保存到保留变量$RESULT中。<br>
    如果符号名是一个API函数,则<br>
    $RESULT保存API信息<br>
    $RESULT_1保存链接库名(比如 kernal32)<br>
    $RESULT_2保存符号名(比如 ExitProcess)。<br>
    $RESULT_3保存调用地址XXXX(比如  call xxxxx)<br>
    注意:这个和GN的区别是GN必须指向IAT地址<br>
        而GAPI直接给出代码地址就可得出API<br>
        还有如果你是在此处下了软件断点,请先清除断点再用此句,因为软件断点修改了代码为CC<br>
    这里如果不清除此处的软件断点,将造成这句不能很好的识别.</td><td width="445"><div align="left">例:<br>
    GAPI 401000    (callkernal32.ExitProcess)<br>
    GAPI EIP   //查看当前代码是否是API调用,不是则返回0</div></td></tr><tr><td width="190">GCMT 地址</td><td width="213"><div align="left"></div></td><td width="407">获得指定地址处的解释</td><td width="445"></td></tr><tr><td width="190">GCI 地址, 信息</td><td width="213"><div align="left"></div></td><td width="407">获得制定地址的汇编指令信息<br>
    "info"可以是:<br>
    -汇编指令字符串 例:gci  eip,COMMAND<br>
     就象用OPCODE eip一样<br>
    -目标地址 ,例: gci eip,DESTINATION<br>
      用于jump/call/return指令<br>
    -命令长度,例: gci  eip,SIZE<br>
    -类型, 例:gci eip,TYPE<br>
    -条件,例:gci  eip,CONDITION<br>
    返回值:$RESULT <br>
    -得到指令目标地址(DESTINATION) </td><td width="445"><div align="left">比如 :<br>
    004B3DF0    0F85 D7010000   jnz     004B3FCD<br>
    EIP:004B3DF0  <br>
    gci eip,DESTINATION<br>
    这里的$RESULT等于004B3FCD</div></td></tr><tr><td width="190">GMEMI 地址, 信息</td><td width="213"><div align="left"></div></td><td width="407">获得指定地址处内存的信息.<br>
    信息可以是 MEMORYBASE,  MEMORYSIZE or MEMORYOWNER</td><td width="445"><div align="left">Example:<br>
    GMEMI addr, MEMORYBASE // After this $RESULT is the address tothe memory  base of the memory block to which addr belongs</div></td></tr><tr><td width="190">GMI 地址, 信息</td><td width="213"><div align="left"><Get  Module Info></div></td><td width="407"><div align="left">获得指定地址所在模块的相关信息<br>
    “信息”可以是<br>
      MODULEBASE:   模块基地址(baseaddress of  module in the memory space of debugged process)<br>
      MODULESIZE:   模块大小(totalsize  occupied by module, not necessarily contiguous memory)<br>
      CODEBASE:    代码段基地址<br>
      CODESIZE:    代码段大小(size of  executable code, as stays in COFFheader. In some cases, OllyDbg may correct  definitely invalid codesize)<br>
      DATABASE:    数据段基地址<br>
      RESBASE:     资源段基地址<br>
      RESSIZE:      资源段大小<br>
      <a href="https://www.52pojie.cn/thread-675251-1-1.html" target="_blank" class="relatedlink">IDA</a>TATABLE:   输入表基地址(baseaddress of  import data table, as stays in COFF header)<br>
      entry:       模块入口(ddressof module's entry point, as  stays in COFF header)<br>
      nsect:       节数目(Numberof  sections in the module)<br>
    (如果您想在将来的版本中,获得更多的信息,请联系我)。<br>
    信息会保存到保留变量$RESULT中 (如果没有找到信息,则$RESULT等于0).</div></td><td width="445"><div align="left">例:<br>
    GMI eip, CODEBASE // 这条指令执行后,$RESULT等于当前所在模块的代码段基地址。</div></td></tr><tr><td width="190">GN 地址</td><td width="213"><div align="left"><Get  Name></div></td><td width="407"><div align="left">获得指定IAT地址的符号名(比如指向API函数)。<br>
    符号名将保存到保留变量$RESULT中。<br>
    如果符号名是一个API函数,则<br>
    $RESULT是符号名<br>
    $RESULT_1保存链接库名(比如 kernal32)<br>
    $RESULT_2保存符号名(比如 ExitProcess)。</div></td><td width="445"><div align="left">例:<br>
    gn 450100</div></td></tr><tr><td width="190">GO 地址</td><td width="213"><div align="left"><GO></div></td><td width="407"><div align="left">执行到指定地址处 </div></td><td width="445"><div align="left">例:<br>
    go 401005</div></td></tr><tr><td width="190">GPA 函数名, 动态链接库名</td><td width="213"><div align="left"><Get  Procedure Address></div></td><td width="407"><div align="left">在指定的动态链接库中,获得指定函数的地址。<br>
    如果查找成功,地址会保存到保留变量$RESULT中,否则$RESULT将等于 0。<br>
    在设置API函数断点时,这个指令非常有效。(API断点API)</div></td><td width="445"><div align="left">例:<br>
    gpa "MessageBoxA",  "user32.dll" //这条指令执行后,$RESULT等于函数MessageBoxA的地址,您可以<br>
    使用"bp $RESULT"设置断点。</div></td></tr><tr><td width="190">HANDLE x, y, class</td><td width="213"><div align="left"></div></td><td>返回指定点(16进制)子窗口指定类的句柄</td><td width="445"><div align="left"></div></td></tr><tr><td width="190">INC 变量</td><td width="213"><div align="left"><INCrement  by 1></div></td><td width="407"><div align="left">对变量进行加一操作</div></td><td width="445"><div align="left">例:<br>
    inc v</div></td></tr><tr><td width="190">ITOA n [, base=16.]</td><td width="213"><div align="left"></div></td><td width="407">转化一个整数到字符串<br>
    结果放在 $RESULT </td><td width="445"><div align="left">Example:<br>
    itoa F<br>
    itoa 10., 10.</div></td></tr><tr><td width="190">JA 标签</td><td width="213"><div align="left"><Jump  if Above></div></td><td rowspan="6" width="407">在cmp命令后使用. 和其对应的汇编指令作用相同.</td><td width="445"><div align="left">例:<br>
    ja SOME_LABEL</div></td></tr><tr><td width="190">JAE 标签</td><td width="213"><div align="left"><jump  if Above or Equal></div></td><td width="445"><div align="left">例:<br>
    jae SOME_LABEL</div></td></tr><tr><td width="190">JB 标签</td><td width="213"><div align="left"><Jump  if Below></div></td><td width="445"><div align="left">例:<br>
    jb SOME_LABEL</div></td></tr><tr><td width="190">JBE 标签</td><td width="213"><div align="left"><Jump  if Below or Equal></div></td><td width="445"><div align="left">例:<br>
    jbe SOME_LABEL</div></td></tr><tr><td width="190">JE 标签</td><td width="213"><div align="left"><Jump  if Equal></div></td><td width="445"><div align="left">例:<br>
    je SOME_LABEL</div></td></tr><tr><td width="190">JNE 标签</td><td width="213"><div align="left"><Jump  if Not Equal></div></td><td width="445"><div align="left">例:<br>
    jne SOME_LABEL</div></td></tr><tr><td width="190">JMP 标签</td><td width="213"><div align="left"><JuMP></div></td><td width="407"><div align="left">跳转到指定标签.</div></td><td width="445"><div align="left">例:<br>
    jmp SOME_LABEL</div></td></tr><tr><td width="190">KEY vkcode [, shift [, ctrl]]</td><td width="213"><div align="left"></div></td><td width="407">仿真按下键盘.<br>
    这个命令可以模仿OD中任意快捷键的功能<br>
    比如脚本ctrl+F2重新载入功能 就可以通过KEY  71,0,1来模拟<br>
    vkcode(虚拟键码)的具体值可以查询masm环境下的windows.inc文件<br>
    比如:<br>
    VK_F2                                equ 71h<br>
    所以 模拟ctrl+f2 就是 KEY 71,0,1<br>
    这里的vkcode都是16进制的</td><td width="445"><div align="left">Example:<br>
    key 20<br>
    key 20, 1 //Shift+space<br>
    key 20, 0, 1 //Ctrl+space</div></td></tr><tr><td width="190">LBL 地址, 字符串</td><td width="213"><div align="left"><LaBel  Insert></div></td><td width="407"><div align="left">在指定地址处插入一个标签</div></td><td width="445"><div align="left">例:<br>
    lbl eip, "NiceJump"</div></td></tr><tr><td width="190">LC</td><td width="213"><div align="left"></div></td><td width="407">清理LOG窗口</td><td width="445"><div align="left"></div></td></tr><tr><td width="190">LCLR</td><td width="213"><div align="left"></div></td><td width="407">清理Script Log窗口</td><td width="445"><div align="left"></div></td></tr><tr><td width="190">LEN str</td><td width="213"><div align="left"></div></td><td width="407">获得字符串长度,结果放在$RESULT</td><td width="445"><div align="left">Example:<br>
    len "NiceJump"<br>
    msg $RESULT</div></td></tr><tr><td width="190">LM 地址, 大小, filename</td><td width="213"><div align="left"></div></td><td width="407">引导Dm文件进内存</td><td width="445"><div align="left">Example:<br>
      lm 0x401000, 0x100,  "test.bin"</div></td></tr><tr><td width="190">LOG 源操作数</td><td width="213"><div align="left"><log></div></td><td width="407"><div align="left">将源操作数输出到OllyDbg的记录窗口[log window]中。<br>
    如果源操作数 是一个字符串常量,则原样记录。<br>
    如果源操作数 是一个变量或一个寄存器,则记录名称及其存放的数值</div></td><td width="445"><div align="left">例:<br>
    log "Hello world" // 记录为 "Hello world"<br>
    var x<br>
    mov x, 10<br>
    log x // 记录为 "x  = 00000010" </div></td></tr><tr><td width="190">MOV 目的操作数, 源操作数,最大字节</td><td width="213"><div align="left"><MOV></div></td><td width="407"><div align="left">将源操作数移动到目的操作数中。<br>
    源操作数可以是一个十六进制序列格式#某个十六进制序列#,例如:#1234#。<br>
    提醒:十六进制序列的位长只能是偶数,比如2, 4, 6, 8等等。</div></td><td width="445"><div align="left">例: <br>
    mov x, 0F                     //将F传给变量x<br>
    mov y, "Hello world"             //将字符串"Hello  world"传给变量y<br>
    mov eax, ecx                   //同汇编<br>
    mov [ecx], #00DEAD00BEEF00#      //将##内的内容传到ecx的地址中<br>
    mov !CF, 1                    //赋值!CF标志寄存器为1<br>
    mov !DF, !PF                  //将!PF赋值给!DF<br>
    mov [403000], "Hello world"       //直接将字符串"Helloworld"传送到403000的地址中<br>
    mov eax,[401000],1             //只取401000地址中的一个字节长度的内容传送到eax中(新功能)</div></td></tr><tr><td width="190">MSG 消息</td><td><div align="left"><MeSsaGe></div></td><td width="407"><div align="left">将指定消息,显示到一个对话框中。</div></td><td width="445"><div align="left">例:<br>
    MSG "脚本运行完毕"</div></td></tr><tr><td width="190">MSGYN 消息</td><td width="213"><div align="left"><MeSsaGe  Yes or No></div></td><td width="407"><div align="left">将指定消息,显示到一个对话框中,这个对话框有“是”、“否”按钮。<br>
    如果点“是”,保留变量  $RESULT 等于1,否则保留变量$RESULT等于0 。</div></td><td width="445"><div align="left">例:<br>
    MSGYN "继续?"</div></td></tr><tr><td width="190">MUL 目的操作数, 源操作数</td><td width="213"><div align="left"><mul></div></td><td width="407"><div align="left">源操作数与目的操作数进行乘法操作,并将结果保存到到目的操作数中。</div></td><td width="445"><div align="left">例: <br>
    mul x, 0F<br>
    mul eax, x<br>
    mul [401000], 5</div></td></tr><tr><td>NEG 操作数</td><td width="213"><div align="left"><NEG></div></td><td width="407"><div align="left">操作数做取补操作,并将结果保存到到操作数中。</div></td><td width="445"><div align="left">例: <br>
    NEG x, 0F<br>
    NEG eax<br>
    NEG [401000]</div></td></tr><tr><td width="190">NOT 操作数</td><td width="213"><div align="left"><NOT></div></td><td width="407"><div align="left">操作数做逻辑非操作,并将结果保存到到操作数中。</div></td><td width="445"><div align="left">例: <br>
    NOT x, 0F<br>
    NOT eax<br>
    NOT [401000]</div></td></tr><tr><td width="190">OPCODE 地址</td><td width="213"><div align="left"></div></td><td width="407">反汇编指定地址处的代码.<br>
    $RESULT是opcode<br>
    $RESULT_1是汇编代码<br>
    $RESULT_2是字节数<br>
    如果不是opcode,$RESULT_2将返回0</td><td width="445"><div align="left">Example:  <br>
    opcode 00401000</div></td></tr><tr><td width="190">opentrace</td><td width="213"><div align="left"></div></td><td width="407">打开运行跟踪功能,关闭它请使用TC</td><td width="445"><div align="left"></div></td></tr><tr><td width="190">OR 目的操作数, 源操作数</td><td width="213"><div align="left"><OR></div></td><td width="407"><div align="left">源操作数和目的操作数做逻辑或操作,并将结果保存到到目的操作数中。</div></td><td width="445"><div align="left">例: <br>
    or x, 0F<br>
    or eax, x<br>
    or [401000], 5</div></td></tr><tr><td width="190">PAUSE</td><td width="213"><div align="left"><PAUSE></div></td><td width="407"><div align="left">暂停脚本运行。可以通过插件菜单恢复脚本运行。</div></td><td width="445"><div align="left">例:<br>
    pause</div></td></tr><tr><td width="190">PREOP 地址</td><td width="213"><div align="left"></div></td><td width="407">回溯指定地址的汇编命令</td><td width="445"><div align="left">Example:<br>
    preop eip</div></td></tr><tr><td width="190">READSTR 地址,maxsize</td><td width="213"><div align="left"></div></td><td width="407">从addr处读指定大小的字符串</td><td width="445"><div align="left">Example:<br>
        readstr 401000,15</div></td></tr><tr><td width="190">REF 地址</td><td width="213"><div align="left"></div></td><td width="407">相当于在OllyDbg按 Ctrl R.</td><td width="445"><div align="left">Example:<br>
    continue:<br>
    REF eip<br>
    log $RESULT<br>
    log $RESULT_1<br>
    log $RESULT_2<br>
    cmp $RESULT,0<br>
    jne continue</div></td></tr><tr><td width="190">REPL 地址, 查找字符串, 替换字符串, 长度</td><td width="213"><div align="left"><REPLace></div></td><td width="407"><div align="left">在指定地址开始,在指定长度的字节范围内,用“替换字符串”替换“查找字符串”。<br>
    允许使用通配符</div></td><td width="445"><div align="left">例:<br>
    repl eip, #6a00#, #6b00#, 10<br>
    repl eip, #??00#, #??01#, 10<br>
    repl 401000, #41#, #90#, 1F</div></td></tr><tr><td width="190">RESET</td><td width="213"><div align="left"></div></td><td width="407">OD重新加载程序(相当于ctlr+f2)</td><td width="445"><div align="left"></div></td></tr><tr><td width="190">RET</td><td width="213"><div align="left"><RETurn></div></td><td width="407"><div align="left">退出脚本。</div></td><td width="445"><div align="left">例:<br>
    ret</div></td></tr><tr><td width="190">REV</td><td width="213"><div align="left"></div></td><td width="407">字节反转.(注意是字节反转,不是位反转)</td><td width="445"><div align="left">Example:<br>
    rev 01020304 //$RESULT = 04030201</div></td></tr><tr><td width="190">ROL 目的操作数, n</td><td width="213"><div align="left"></div></td><td width="407">循环左移目的操作数,n比特位;并将结果保存到到目的操作数中。</td><td width="445"><div align="left">例:<br>
    mov x, 00000010<br>
    ROL x, 8 // x is now 00001000</div></td></tr><tr><td width="190">ROR 目的操作数, n</td><td width="213"><div align="left"></div></td><td width="407">循环右移目的操作数,n比特位;并将结果保存到到目的操作数中。</td><td width="445"><div align="left">例:<br>
    mov x, 00000010<br>
    ROR x, 8 </div></td></tr><tr><td width="190">RTR</td><td width="213"><div align="left"><Run  To Return></div></td><td width="407"><div align="left">执行到返回<br>
    相当于在OllyDbg中执行 "Run to return" [Ctrl+F9]操作。</div></td><td width="445"><div align="left">例:<br>
    rtr</div></td></tr><tr><td width="190">RTU</td><td width="213"><div align="left"><Run  To User code></div></td><td width="407"><div align="left">返回到用户代码区<br>
    相当于在OllyDbg中执行 "Run to user code"[Alt+F9] 操作。</div></td><td width="445"><div align="left">例:<br>
    rtu</div></td></tr><tr><td width="190">RUN</td><td width="213"><div align="left"></div></td><td width="407"><RUN><br>
    让OD继续运行相当于在OllyDbg中按 F9</td><td width="445"><div align="left">例:<br>
    run</div></td></tr><tr><td width="190">SCMP dest, src</td><td width="213"><div align="left"></div></td><td width="407">字符串比较.</td><td width="445"><div align="left">Example:  <br>
    cmp x, "KERNEL32.DLL"<br>
    cmp [eax], "Hello World"</div></td></tr><tr><td width="190">SCMPI dest, src</td><td width="213"><div align="left"></div></td><td width="407">字符串比较(大小写不敏感)</td><td width="445"><div align="left">Example:  <br>
    cmp sVar, "KERNEL32.DLL"<br>
    cmp [eax], "Hello World"</div></td></tr><tr><td width="190">SETOPTION</td><td width="213"><div align="left"></div></td><td width="407">调出调试设置(Option)菜单,设置好后按确定后继续执行脚本<br>
    注意:此选项是为了可以在执行脚本的过程中可以调出调试设置异常,跟踪等等设置</td><td width="445"><div align="left"></div></td></tr><tr><td width="190">SHL 目的操作数, n</td><td width="213"><div align="left"></div></td><td width="407">左移目的操作数,n比特位;并将结果保存到到目的操作数中</td><td width="445"><div align="left">例:<br>
    mov x, 00000010<br>
    shl x, 8 // x is now 00001000</div></td></tr><tr><td width="190">SHR 目的操作数, n</td><td width="213"><div align="left"><SHift  Right></div></td><td width="407"><div align="left">右移目的操作数,n 比特位;并将结果保存到到目的操作数中</div></td><td width="445"><div align="left">例:<br>
    mov x, 00001000<br>
    shr x, 8 // x is now 00000010</div></td></tr><tr><td width="190">STI</td><td><div align="left"><STep Into></div></td><td width="407"><div align="left">相当于在OllyDbg中按 F7,单步步入。</div></td><td width="445"><div align="left">例:<br>
    sti</div></td></tr><tr><td width="190">STO</td><td width="213"><div align="left"><STep  Over></div></td><td width="407"><div align="left">相当于在OllyDbg中按 F8,单步步过。</div></td><td width="445"><div align="left">例:<br>
    sto</div></td></tr><tr><td width="190">SUB dest, src</td><td width="213"><div align="left"></div></td><td width="407">源数据减目的数据</td><td width="445"><div align="left">Example:  <br>
    sub x, 0F<br>
    sub eax, x<br>
    sub [401000], 5</div></td></tr><tr><td width="190">TC</td><td width="213"><div align="left"></div></td><td>相当于在OllyDbg中  "关闭运行跟踪"</td><td width="445"><div align="left">Example:<br>
    tc</div></td></tr><tr><td width="190">TI</td><td width="213"><div align="left"></div></td><td width="407">相当于在OllyDbg中按 CTRL-F7,单步跟踪。</td><td width="445"><div align="left">Example:<br>
    ti</div></td></tr><tr><td width="190">TICND cond</td><td width="213"><div align="left"><Trace  Into Condition></div></td><td width="407"><div align="left">执行 "Trace into" 操作,直到条件为真时停止。</div></td><td width="445"><div align="left">例:<br>
    ticnd "eip > 40100A" // 当 eip >40100A 时停止</div></td></tr><tr><td width="190">TICK [var [,reftime]]</td><td width="213"><div align="left"></div></td><td width="407">脚步运行时间(microsec)<br>
    如果是2次变量,则得出为时间差</td><td width="445"><div align="left">Example:<br>
    tick time<br>
    msg time //time since script startup<br>
    tick time,time<br>
    msg $RESULT //time since last TICK, DWORD value</div></td></tr><tr><td width="190">TO</td><td width="213"><div align="left"><Trace  Over></div></td><td width="407"><div align="left">相当于在OllyDbg中执行 "Trace over" 操作。</div></td><td width="445"><div align="left">例:<br>
    to</div></td></tr><tr><td width="190">TOCND cond</td><td width="213"><div align="left"><Trace  Over Condition></div></td><td width="407"><div align="left">执行 "Trace over" 操作,直到条件为真时停止。</div></td><td width="445"><div align="left">例:<br>
    tocnd "eip > 40100A" // 当 eip >40100A 时停止</div></td></tr><tr><td>VAR</td><td width="213"><div align="left"><VARiable></div></td><td width="407"><div align="left">在脚本中,声明一个变量。<br>
    必须在变量使用先声明。<br>
    注意:变量名最好是由字母和数字组合成的容易识别的变量名<br>
        +-/等等符号最好不要附加在变量中,以免引起不可预测的错误<br>
    由于为了兼容以前的系统,请不要将A,B,C,D,E,F作为变量.</div></td><td width="445"><div align="left">例: <br>
    var tmp</div></td></tr><tr><td width="190">XOR 目的操作数, 源操作数</td><td width="213"><div align="left"><XOR></div></td><td width="407"><div align="left">源操作数与目的操作数进行异或操作,并将结果保存到到目的操作数中。</div></td><td width="445"><div align="left">例: <br>
    xor x, 0F<br>
    xor eax, x<br>
    xor [401000], 5</div></td></tr><tr><td width="190">WRT file, data</td><td width="213"><div align="left"></div></td><td width="407">写数据给文件 (覆盖)</td><td width="445"><div align="left">Example:  <br>
    wrt "out.txt", "Data:\r\nOk\r\n"<br>
    wrt sFile, ebx</div></td></tr><tr><td width="190">WRTA file, data</td><td width="213"><div align="left"></div></td><td width="407">附加数据到文件中(文件结尾)</td><td width="445"><div align="left">Example:  <br>
    wrta sFile, "hello world\r\n"<br>
    如果文件不存在 将会创建文件</div></td></tr><tr><td width="190">IFA,IFAE,IFB,IFBE IFG,IFGE,IFL,IFLE IFEQ/IFNEQ..ELSE/ENDIF</td><td width="213"><div align="left"></div></td><td width="407">这些命令是构建IF块的,类似于高级语言的语法,具体含义与汇编类似。</td><td width="445"><div align="left">Example:  <br>
    ifneq $RESULT,0<br>
        ifa flg,$RESULT<br>
            mov flg,$RESULT<br>
        endif<br>
    endif</div></td></tr><tr><td colspan="4">您可以使用“//”在任何地方进行注释。</td></tr><tr><td colspan="4">块注释必须另外起一行并以 “”作为结束,“
/”也必须另起一行。</td></tr></tbody></table>

猜你喜欢

转载自blog.51cto.com/haidragon/2121501
今日推荐