Log.i53

Themidaのアンパックを目指すブログ改め使い物になるえんじにゃを目指すブログ

OllyScript リファレンス

OllyScript

 OllyScriptはOllyDbgの操作を自動化するためのアセンブリライクな言語で記述できるスクリプト言語です。OllyDbgにおけるデバッグ操作を自動化するための各種コマンドが用意されています。(注:プラグイン名がODbgScriptでスクリプト言語名がOllyScript)


 ドキュメントでは特に明記しない限りコマンドの"src"と"dest"に以下の値を利用することができます:

16進数値

 0で始まるプリフィックスやサフィックスなしの数値はすべて16進数の定数値として扱われます。

00FF // ※0x00FFや00FFhような記法は利用できない

10進数値

 末尾に"."を付加することで10進数の定数値として扱われます。

100.
128.

変数

 VARによってあらかじめ宣言されたものか、MOVコマンドで宣言されたものが変数として扱われます。

レジスタ

メモリ参照

 角カッコによってメモリ値を参照できます。

[401000] // アドレス401000の値を参照
[ecx] // アドレスecxの値を参照

フラグ

 各フラグ名の前に"!"を付加してフラグ値を参照できます(!CF, !PF, !AF, !ZF, !SF, !DF, !OF)

バイト文字列

 "#"囲いでバイトシーケンスが利用できます。ワイルドカードを利用することもできます。

#6A0000# // db 6A 00 00
#6A??00# // db 6A ?? 00
#6?0000# // db 6? 00 00

演算子

 上記の値はすべて以下の演算子(-*/&|^><)と組み合わせることができます。また、"+"演算子は文字列の結合に利用できます:

予約変数

$RESULT

 いくつかのコマンドの実行結果を格納します。コマンドによっては$RESULT_1や$RESULT_2が利用される場合もあります。

$VERSION

 OllyScriptの現在のバージョンが格納されています。

    cmp $VERSION, "0.8"
    ja version_above_08

コマンド

#INC file

 他のスクリプトファイルをインクルードします。

    #inc "anotherscript.txt"

#LOG

 実行されたコマンドのロギングを有効にします。このコマンドはOllyDbgログウィンドウで"-->"プリフィックスで表示されます。

    #log

ADD dest, src

 "src"に"dest"を加算して"dest"に加算結果を格納します。

    add x, 0F
    add eax, x
    add [401000], 5
    add y, " times" // コマンド実行前のyの値が"1000"であれば実行後yは"1000 times"になる

AI

 OllyDbgの"Animate into"を実行します。

    ai

ALLOC size

 新しいメモリページ(読み/書き/実行可能)を割り当てます。

    alloc 1000
    free $RESULT, 1000

AN addr

 アドレスaddrを含むモジュールを分析(OllyDbgのAnalyze機能を実行)します。

    an eip // Analyze機能の実行(CTRL-A押下と同義)

AND dest, src

 "src"と"dest"でAND演算を行い、結果を"dest"に格納します。

    and x, 0F
    and eax, x
    and [401000], 5

AO

 OllyDbgの"Animate over"を実行します

    ao

ASK question

 指定された文字列で入力ボックスを表示して、ユーザに入力を求めます。ユーザが入力した文字列は予約変数$RESULTに格納され、キャンセルボタンが押された場合には0が格納されます。入力された文字列の長さは$RESULT_1に格納されます。

    ask "Enter new EIP"
    cmp $RESULT, 0
    je cancel_pressed
    mov eip, $RESULT

ASM addr, command [,version]

 任意のアドレスでコマンドをアセンブルします。バージョン番号(0,1,...)を変更することで可能な場合は代替となるバイトコードを取得します。アセンブルされたバイト列は予約変数$RESULTに格納されます。

    asm eip, "mov eax,ecx"

ASMTXT addr, file

 任意のアドレスでasmファイルをアセンブルします。

    asmtxt EIP, "myasm.txt"

ATOI str [,base=16]

 文字列を整数値に変換します。
変換結果は予約変数$RESULTに格納されます。

    atoi "F"
    atoi "10", 10

BACKUP addr [,base, size]

 OPENDUMPコマンドのように、指定されたアドレスのデータでダンプウィンドウを生成します。ただし、このダンプウィンドウはデータのバックアップを保持しており、変更内容の表示などに利用できます。予約変数$RESULTにダンプウインドウのHWNDが格納されます。

注意:ファイル内のセーブデータを探す場合、DM(Dump Memory)機能を参照して下さい。

    BACKUP esp
    STO
    STO

BC [addr]

 指定したアドレスの無条件ブレークポイントをクリアします。パラメータなしの場合は全てのブレークポイントがクリアされます。

    bc 401000
    bc x
    bc eip

BD [addr]

 指定したアドレスのブレークポイントを無効化します。パラメータなしの場合は全てのブレークポイントが無効化されます。

    bp 401000
    bd 401000

BEGINSEARCH [start] {commands} ENDSEARCH

 デバッグ中のアプリケーションメモリのコピーを生成して、Findコマンドがこのデータを高速で使用できるようにします。このメモリコピーを解放するためにはメモリ書き込みの前にENDSEARCHを使用しなければなりません。5000回のループで約20%の最適化が見込まれます。

    mov count, 0
    mov start, eip
    beginsearch start
next:
    find #00#, start
    cmp $RESULT,0
    je end
    mov start, $RESULT+1
    add count, 1
    jmp next
end:
    endsearch
    msg count

BP addr (ubp)

 指定したアドレスに無条件ブレークポイントを設置します。

    bp 401000
    bp x
    bp eip

BPCND addr, cond

 指定したアドレス"addr"に指定した条件"cond"のブレークポイントを設置します。

    bpcnd 401000, "ECX==1" // アドレス401000にECXが1の時にのみブレークする条件付きブレークポイントを設置

BPD callname

 BPXコマンドによって設置されたブレークポイントを削除します。

    bpd "GetModuleHandleA"

BPGOTO addr, label

 ブレークポイント(通常のINT3またはHBP)時に指定したラベルに自動的にジャンプします。EOBコマンドに類似しています。

    bphws addr
    bpgoto addr, MyLabel
NextBP:
    RUN
    ...
MyLabel:
    ...
    jmp NextBP

BPHWC [addr]

 指定されたアドレスのハードウェアブレークポイントを削除します。アドレスの指定がなければ、全てのハードウェアブレークポイントを削除します。

    bphwc 401000

BPHWS addr, [mode]

 ハードウェアブレークポイントを設置します。モードが"r"であれば-read、 "w"であれば-write、"x"であれば-execute(デフォルト)のブレークポイントとなります。

    bphws 401000, "x"

BPL addr, expr

 アドレス"addr"に式"expr"のロギングブレークポイントを設置します。

    bpl 401000, "eax" // この行を通過した時のEAXの値を記録する

BPLCND addr, expr, cond

 アドレス"addr"に条件"cond"で式"expr"の条件付きロギングブレークポイントを設置します。

    bplcnd 401000, "eax", "eax > 1" // EAX>1の時、この行を通過した時のEAXの値を記録する

BPMC

 メモリブレークポイントをクリアします。

    bpmc

BPRM addr, size

 read-memoryブレークポイントを設置します。ブレークする領域をバイトサイズで指定できます。

    bprm 401000, FF

BPWM addr, size

  write-memoryブレークポイントを設置します。ブレークする領域をバイトサイズで指定できます。

    bpwm 401000, FF

BPX callname

 現在のモジュール内にある全てのAPI呼び出しにブレークポイントを設置します。BPDコマンドによってこれらのブレークポイントを全て削除することができます。

    bpx "GetModuleHandleA"

BUF var

 整数値をバッファに変換します。

    mov s, "123"
    buf s
    log s // #313233# が出力される

CALL label

 指定されたラベルにジャンプしてそれを実行します。JMPコマンドとの違いは、"RET"コマンドが実行された場合に呼び出し元に戻ってくる点のみです。CallとRetコマンドはあなたのスクリプトの構造化と整理の助けになります。

例1 - ボディとパラメータを持つプロシージャ

    var myArg1 
    mov myArg1,5
    Call PROC_myproc2  // 引数は変数"myArg1"を介して渡される
    log myArg1         
    Ret                   //  スクリプトの終わり
PROC_myproc2:
    add myArg1, 1
    RET                  //  'PROC_myproc2'から戻る
// myArg1はグローバル変数であり実際に引数としてプロシージャに渡されているわけではない

例2 - "Func_myFunc1(myArg1, 3)"のようなDIY関数

    var myArg1
    mov myArg1,5
   
    push myArg1 // Arg1
    push 3      // Arg2
    Call Func_myFunc1
    log $RESULT // 返り値を表示
   
    log Local1  // if that were a real local that shouldn't work
    Ret   

Func_myFunc1:
    var Local2  // Passing Arg2 byValue
    pop Local2  // Local2=Arg2

    var Local1  // Passing Arg1 byValue
    pop Local1  // Local1=Arg1

    sub Local1, Local2  
    mov $RESULT, Local1
    RET

CLOSE window

 OllyDbgのMDIウィンドウを閉じます。"window"パラメータは定数値か、HWND(OPENDUMP/BACKUPコマンドの$RESULTなど)を指定できます。

    // 指定できるパラメータ
    SCRIPT, SCRIPTLOG, LOG, CPU
    MODULES, MEMORY, THREADS, BREAKPOINTS
    REFERENCES, SOURCELIST, WATCHES
    WINDOWS, PATCHES, RUNTRACE, CALLSTACK
    TEXT, FILE, HANDLES, SEH, SOURCE

CMP dest, src [,size]

 "dest"と"src"を比較します。アセンブリ言語と同じように動作します。文字列やメモリデータを比較する場合にはSCMPを利用して下さい。

    cmp y, x
    cmp eip, 401000
    je label
    cmp cx, x, 2
    je label

CMT addr, text

 指定されたアドレスにコメントを挿入します。

    cmt eip, "This is the entry point"

COB

 ブレークポイントが発生した後にスクリプトの実行を再開させます。

    COB

COE

 例外が発生した後にスクリプトの実行を再開させます。

    COE

CRET

 関数内のスクリプトを終了するために、CALLコマンドによる呼び出しのスタックをクリアします。

    CRET
    RET

DBH

 kernel32!IsDebuggerPresent()に対してデバッガを隠蔽します。(これは[BYTE [[FS:18]+30]+2] = 0によって行われます)

    dbh

DBS

 kernel32!IsDebuggerPresent()がデバッガを検出できるようにするために、デバッガの隠蔽を解除します。(これは[BYTE [[FS:18]+30]+2] = 1によって行われます)

    dbs

DEC var

 変数から1だけ減算します。

    dec v

DIV op1, op2

 "op1"に"op1/op2"の除算結果を格納します。

    div var, 2 // var = var / 2

DM addr, size, file

 指定ファイル(デフォルトパスはデバッグアプリのディレクトリ)に指定されたアドレスから指定サイズ分だけメモリをダンプします。

    dm 401000, 1F, "c:\dump.bin"

DMA addr, size, file

 指定ファイル(デフォルトパスはデバッグアプリのディレクトリ)に指定されたアドレスから指定サイズ分だけメモリをダンプを追加します。

    dma 401000, 1F, "c:\dump.bin"

DPE filename, ep

 指定された名前でファイルに実行ファイルをダンプします。エントリポイントは"ep"パラメータに設定します。パスは現在ロードされている実行ファイルの相対パスが設定されます。

注意1: PEFileInfo,dwSizeOfImageを使用します。
注意2: PE.sectionHdrに対してdumpfix()を適用します(PointerToRawData = VirtualAddress, SizeOfRawData = VirtualSize)。

    dpe "c:\test.exe", eip

ELSE/ENDIF

 IFxxコマンドを参照して下さい。

EOB label

 次回のブレークポイント発生時に任意のラベルに実行を遷移させます。(ラベルにブレークポイントを割り当てるにはBPGOTOコマンドを参照して下さい)

    eob SOME_LABEL

EOE label

 次回の例外発生時に任意のラベルに実行を遷移させます。

    eoe SOME_LABEL

ERUN [formerly ESTO]

 OllyDbgにおける"Shift-F9"を実行します。例外を無視して実行します。注意: このコマンドに伴い、ESTOコマンドは廃止されました。

    erun

ESTEP

 OllyDbgにおける"Shift-F8"を実行します。例外を無視してステップオーバーで実行します。

    estep

ESTI

 OllyDbgにおける"Shift-F7"を実行します。例外を無視してステップイントゥで実行します。

    esti

EVAL

 変数を含む文字列式を評価します。現在のスクリプトで宣言済みの変数を{}で括ることで文字列に挿入することができます。評価結果は予約変数$RESULTに格納されます。

    var x
    mov x, 1000
    eval "The value of x is {x}" // after this $RESULT is "The value of x is 1000"

EXEC/ENDE

 ターゲットプロセスのコンテキストでEXECとENDEの間の命令を実行します。{}で括られた値はそれらの値によって置換さます。このコマンド利用時にはPUSHA/POPAコマンドが便利です。

    // デバッグアプリケーションにおいていくつかのmov命令を実行する
    mov x, "eax"
    mov y, DEADBEEF
    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"で埋めます。

    fill 401000, 10, 90 // NOP 10h bytes

FIND addr, what

 指定されたアドレス"addr"から指定された値"what"を検索します。見つかった場合には結果が予約変数$RESULTに格納され、見つからなかった場合には0が格納されます。検索文字列にはワイルドカード"??"を含めることができます。

    find eip, #6A00E8# // PUSH 0 にcall命令が続くパターンを検索する
    find eip, #6A??E8# // PUSH ? にcall命令が続くパターンを検索する

FINDCALLS addr [,name]

 逆アセンブリエリア内のすべてのモジュール間呼び出し(DLL呼び出し)を見つけます。2番目のオプションのパラメータで名前(大文字小文字を区別しない)を指定することによって結果をフィルタリングすることができます。リファレンスウィンドウが使用され、その内容が変更され、結果の取得にはGREFコマンドを使用します。

    findcalls eip, "exit"
    gref
    msg $RESULT

FINDCMD addr, cmdstr

 asmコマンドを検索します。";"セパレータを使用することで複数検索することも可能です。このコマンドはOllyDbgの"Search for All Sequences"機能を利用するもので、相対的なcall/jmp命令を見つけることもできます。リファレンスウィンドウが使用され、その内容が変更され、結果の取得にはGREFコマンドを使用します。

// 例1
    mov line,1
    findcmd eip, "xor R32,R32"
next:
    gref line
    cmd $RESULT,0
    je finished
    inc line
    jmp next
finished:

// 例2
    findcmd 401000, "nop;nop;nop"
    msg $RESULT

FINDCMDS (この関数名は将来のバージョンで削除される可能性があります)

 FINDCMDコマンドと同一です。

FINDOP addr, what [, maxsize]

 指定されたアドレスから指定されたバイトで始まる命令を検索します。見つかった命令の先頭アドレスが予約変数$RESULTに格納され、見つからなかった場合には0が格納されます。検索文字列にはワイルドカード"??"を使用することも出来ます。検索範囲を制限するにmaxsizeパラメータで指定して下さい。

    findop 401000, #61# // "POPAD"命令を検索する
    findop 401000, "1"  // = #61#
    findop 401000, #6A??# // "PUSH ??"命令を検索する

FINDOPPREV addr, what

 指定されたアドレスから指定されたバイトで始まる命令を後方検索します。見つかった命令の先頭アドレスが予約変数$RESULTに格納され、見つからなかった場合には0が格納されます。検索文字列にはワイルドカード"??"を使用することも出来ます。

    FINDOPPREV, #68??????00# // "PUSH 00xxxxxx"命令を後方検索する

FINDMEM what [, StartAddr]

 指定した値についてメモリ全体を検索します。見つかった命令の先頭アドレスが予約変数$RESULTに格納され、見つからなかった場合には0が格納されます。検索文字列にはワイルドカード"??"を使用することも出来ます。

    findmem #6A00E8# // "PUSH 0"命令に"call"命令が続く命令シーケンスを検索する
    findmem #6A00E8#, 00400000 // アドレス0x400000以降を検索する

FREE addr [, size]

 ALLOCコマンドによって割り当てられたメモリブロックを開放します。サイズが与えられない場合、メモリブロック全体をドロップします。

    alloc 1000
    free $RESULT

GAPI addr #BETA#

 API呼び出し情報を取得します。API情報は予約変数$RESULTに格納されます。シンボリック名がAPI関数である場合、以下のように値が格納されます:

注意:このコマンドとGNコマンドの違いは、GNがIATのアドレスを指しているのに対して、GAPIは直接的にAPIを取得することが可能なコードアドレスを取得することです。ソフトウェアブレークポイントはコードを0xCCに改変するため、本コマンドの実行前にAPIに設置しているソフトウェアブレークポイントをクリアしておきましょう。ソフトウェアブレークポイントがクリアされていない場合、正しい結果が得られなくなる可能性があります。

    // 指定アドレスのコードがAPI呼び出しであるかどうかを調べる
    //   API呼び出しであれば予約変数に結果を格納
    //   API呼び出しでなければ予約変数に0を格納
    GAPI 401000 (call kernel32.ExitProcess)
    GAPI the EIP 

GBPM (beta)

 最後のメモリブレークポイントアドレスを取得し、そのDWORD値を予約変数$RESULTに格納します。

    gbpm

GBPR

 最後のブレークポイントの要因を調べ、そのDWORD値を予約変数$RESULTに格納します。

    gbpr
    cmp $RESULT, 10
    je SelectNormalBP
    cmp $RESULT, 20
    je SelectMemBP
    cmp $RESULT, 40
    je SelectHwBP
    jmp NextBP

GCI addr, info

 指定したアドレスにあるアセンブリ命令の情報を取得します。"info"には取得したい情報に応じて以下を指定することができます:

  • COMMAND: アセンブリ命令のOPCODE文字列
  • CONDITION: {disasm.condition}
  • DESTINATION: jmp/call命令のディスティネーション
  • SIZE: 命令のバイトサイズ
  • TYPE: C_xxxの1つ(OllyDbg Plugin APIを参照)
    GCI eip, DESTINATION

GCMT addr

 指定したアドレスにあるコメント、自動コメント、または分析コメントを取得します。

GMA name, info

 モジュール名を省略してGMIコマンドを呼び出すことができます。

    GMA "KERNEL32", MODULEBASE

GFO addr

 指定したアドレスのファイルオフセットを取得します。

GLBL addr

 指定したアドレスのラベルを取得します。

GMEMI addr, info

 指定したアドレスが属するメモリブロックについての情報を取得します。"info"には取得したい情報に応じてMEMORYBASE、MEMORYSIZE、MEMORYOWNERを指定できます。情報が見つからなかった場合には、予約変数$RESULTには0が格納されます。

    // addrが属するメモリブロックのメモリベースへのアドレスが$RESULTに格納される
    GMEMI addr, MEMORYBASE 

GMEXP moduleaddr, info, [num]

 モジュール内のエクスポートアドレスと名前を取得します。"info"には取得したい情報に応じてADDRESS、LABEL、COUNTを指定できます。

    gma "KERNEL32", MODULEBASE
    mov addr, $RESULT
    GMEXP addr, COUNT
    log $RESULT
    GMEXP addr, LABEL, 1
    log $RESULT
    GMEXP addr, ADDRESS, 1
    log $RESULT

GMI addr, info

 指定したアドレスが属するモジュールについての情報を取得します。"info"には取得したい情報に応じて以下を指定できます。

  • MODULEBASE: モジュールベース
  • MODULESIZE: モジュールサイズ
  • CODEBASE: コードセクション
  • CODESIZE: コードセクションサイズ
  • ENTRY: エントリポイント
  • NSECT
  • DATABASE: データセクション
  • EDATATABLE: エクスポート関数情報セクション
  • EDATASIZE: エクスポート関数情報セクションサイズ
  • IDATABASE: インポート関数情報セクション
  • IDATATABLE: インポート関数情報セクションサイズ
  • RESBASE: リソースセクション
  • RESSIZE: リソースセクションサイズ
  • RELOCTABLE: 再配置情報セクション
  • RELOCSIZE: 再配置情報セクションサイズ
  • NAME: 実行ファイル名
  • PATH: ディレクトリパス
  • VERSION: バージョン
    GMI eip, CODEBASE // eipが属するモジュールのコードベースのアドレスを$RESULTに格納
    GMI eip, VERSION // バージョンが$RESULTに格納される

GMIMP moduleaddr, info, [num]

 モジュール内のインポートアドレスと名前を取得します。"info"には取得したい情報に応じてADDRESS, LABEL, MODULE, NAME, COUNTを指定できます。例えば、LABELの結果が"KERNEL32.CopyFileEx"であったならば、MODULEの結果は"KERNEL32"となりNAMEの結果は"CopyFileEx"となります。

    gma "USER32", MODULEBASE
    mov addr, $RESULT
    GMIMP addr, COUNT
    log $RESULT
    GMIMP addr, LABEL, 1
    log $RESULT
    GMIMP addr, ADDRESS, 1
    log $RESULT

GPA proc, lib, [0,1]

 指定されたライブラリ内にある指定されたプロシージャのアドレスを取得します。プロシージャが見つかった場合には予約変数$RESULTにアドレスが格納され、見つからなかった場合には$RESULTに0が格納されます。このコマンドはAPIブレークポイントを設置する場合に便利です。メモリ内のライブラリを維持する場合には3番目のパラメータに"1"を指定してください。

    gpa "MessageBoxA", "user32.dll" // $RESULTに"user32!MessageBoxA"のアドレスが格納される
    bp $RESULT // "user32!MessageBoxA"にBPを設置する

GN addr

 指定されたアドレスのシンボル名(例えば、それが指すAPI)を取得します。予約変数$RESULTに取得した名前が格納されます。この名前がAPIであれば、$RESULT_1にはそのライブラリ名(例えば、kernel32)が格納され、$RESULT_2にはAPI名(例えば、ExitProcess)が格納されます。

    gn 401000

GO addr

 指定したアドレスを実行します。(SoftIceのGに似た操作)

    go 401005

GOTO label

 JMPコマンドと同一です。

GPP proc, lib, [0,1]

 GPAを呼び出して、API引数の数とAPIの種類を返します。

  • $RESULT: ref->addr
  • $RESULT_1: disasm.result // コマンドテキスト
  • $RESULT_2: disasm.comment

GOPI addr, index, info

 ASMコマンドのオペランドについての情報を取得します。"index"は1から3の間で指定します。"info"には以下を指定できます:

    GOPI eip, 1, SIZE

 "info"パラメータに"TYPE"を指定した時のより詳細な情報については以下のとおりです:

    DEC_TYPEMASK  0x1F           // Type of memory byte
    DEC_UNKNOWN  0x00            // Unknown type
    DEC_BYTE     0x01            // Accessed as byte
    DEC_WORD     0x02            // Accessed as short
    DEC_NEXTDATA 0x03            // Subsequent byte of data
    DEC_DWORD    0x04            // Accessed as long
    DEC_FLOAT4   0x05            // Accessed as float
    DEC_FWORD    0x06            // Accessed as descriptor/long pointer
    DEC_FLOAT8   0x07            // Accessed as double
    DEC_QWORD    0x08            // Accessed as 8-byte integer
    DEC_FLOAT10  0x09            // Accessed as long double
    DEC_TBYTE    0x0A            // Accessed as 10-byte integer
    DEC_STRING   0x0B            // Zero-terminated ASCII string
    DEC_UNICODE  0x0C            // Zero-terminated UNICODE string
    DEC_3DNOW    0x0D            // Accessed as 3Dnow operand
    DEC_SSE      0x0E            // Accessed as SSE operand
    DEC_TEXT     0x10            // For use in t_result only
    DEC_BYTESW   0x11            // Accessed as byte index to switch
    DEC_NEXTCODE 0x13            // Subsequent byte of command
    DEC_COMMAND  0x1D            // First byte of command
    DEC_JMPDEST  0x1E            // Jump destination
    DEC_CALLDEST 0x1F            // Call (and maybe jump) destination

    DEC_PROCMASK 0x60            // Procedure analysis
    DEC_PROC     0x20            // Start of procedure
    DEC_PBODY    0x40            // Body of procedure
    DEC_PEND     0x60            // End of procedure
    DEC_CHECKED  0x80            // Byte was analysed
    DEC_SIGNED   0x100           // For use in t_result only

GPI key

 Get Process Information(プロセス情報の取得)です。keyパラメータには、取得したい情報に応じてHPROCESS, PROCESSID, HMAINTHREAD, MAINTHREADID, MAINBASE, PROCESSNAME, EXEFILENAME, CURRENTDIR, SYSTEMDIRを指定できます。

GREF [line]

 リファレンスウィンドウで指定した行からアドレスを取得します。このとき0は必ずCPUの初期EIPになるため最初の行を取得するには"line"に1を指定します。パラメータが指定されない場合、GREFはリファレンスウィンドウのエントリ数を返します。

    FINDCMD "push eax"
    GREF 1
    msg $RESULT
    GREF 2
    msg $RESULT

GRO addr

 相対オフセットを取得します。オフセットが見つかった場合には予約変数$RESULTに格納され、見つからなかった場合には0が格納されます。

GSL [where]

 Get Selection Limits、CPUASM | CPUDUMP | CPUSTACK ウインドウで現在選択されている行のSTART/ENDアドレスおよびSIZEがそれぞれ$RESULT、$RESULT_1、$RESULT_2に格納されます。"where"はCPUDASM, CPUDUMP, CPUSTACKを選択でき、デフォルトはCPUDASMです。

    gsl CPUDUMP

GSTR addr, [arg1]

 指定したアドレスからnullで終了する文字列を取得します。少なくとも"arg1"に指定された文字列長である必要があります。

  • $RESULT: 文字列
  • $RESULT_1: 文字列長
    gstr 401000     ; 指定されない場合"arg1"のデフォルトは2
    gstr 401000, 20 ; 少なくとも20

GSTRW addr, [arg1]

 指定したアドレスからUnicode文字列を取得します。少なくとも"arg1"に指定された文字列長である必要があります。

  • $RESULT: 文字列(ASCII)
  • $RESULT_1: 文字列長
  • $RESULT_2: Unicode文字列
    gstrw 401000     ; 指定されない場合"arg1"のデフォルトは2
    gstrw 401000, 20 ; 少なくとも20

HANDLE x, y, class

 指定した座標x,yの指定したクラルの子ウィンドウのハンドル(16進数値であることに注意)を返します。

HISTORY (0,1)

 スクリプト経過ウィンドウにて値の履歴を有効または無効にすることができます。これは例えば、ループ処理を高速化するために利用することができます。

    history 0 // 無効化
    history 1 // 有効化

IFA,IFAE,IFB,IFBE x, y, [z]

 それぞれJA, JAE, JB, JBEと同様の条件文です。CMPコマンドのパラメータも参照します。パラメータを指定しない場合、IFコマンドは最後に使用されたCMPコマンドの結果を利用します。

    IFB $VERSION, "1.82"
        MSG "This script requires ODBGScript version 1.82"
        RET
    ENDIF

IFEQ x, y, [z]

 "等しいかどうか"を判定するための簡単な条件文です。CMPコマンドのパラメータも参照します。パラメータを指定しない場合、IFコマンドは最後に使用されたCMPコマンドの結果を利用します。

    IFEQ val, 0
        log "val = 0"
    ELSE
        log "val <> 0"
    ENDIF

IFNEQ x, y, [z]

 "等しくないかどうか"を判定するための簡単な条件文です。CMPコマンドのパラメータも参照します。パラメータを指定しない場合、IFコマンドは最後に使用されたCMPコマンドの結果を利用します。

    IFNEQ val, 0
        log "val <> 0"
    ELSE
        log "val = 0"
    ENDIF

INC var

 変数に1加算します。

    inc v

INIR key, def

 ollydbg.iniのODBGScrip Key値を読み込みます。"def"値は戻り値のタイプ(文字列かDWORD値か)を決定します。

    inir "key", ""
    inir "key", 0

INIW key, val

 ollydbg.iniにODBGScrip Key値を書き込みます。"val"は文字列かDOWRD値を与えることができます。

    iniw "key", "x"
    iniw "key", 10.

ITOA n [, base=16.]

 整数を文字列に変換します。予約変数$RESULTに結果となる文字列が格納されます。

    itoa F
    itoa 10., 10.

JA label

 CMPコマンドの後に使用する条件ジャンプコマンドです。

    ja SOME_LABEL

JAE label

 CMPコマンドの後に使用する条件ジャンプコマンドです。

    jae SOME_LABEL

JB label

 CMPコマンドの後に使用する条件ジャンプコマンドです。

    jb SOME_LABEL

JBE label

 CMPコマンドの後に使用する条件ジャンプコマンドです。

    jbe SOME_LABEL

JE label (JZ)

 CMPコマンドの後に使用する条件ジャンプコマンドです。

    je SOME_LABEL

JMP label

 labelに対する無条件ジャンプコマンドです。ラベルは文字列変数で定義できます。

    jmp SOME_LABEL

JNE label (JNZ)

 CMPコマンドの後に使用する条件ジャンプコマンドです。

    jne SOME_LABEL

KEY vkcode [, shift [, ctrl]]

 グローバルキーボードのショートカットをエミュレートします。

    key 20
    key 20, 1 //Shift+space
    key 20, 0, 1 //Ctrl+space

LBL addr, text

 指定したアドレスにラベルを挿入します。

    lbl eip, "NiceJump"

LC

 メインログウィンドウをクリアします。

LCLR

 スクリプトログウィンドウをクリアします。

LEN str

 文字列長を取得します。

    len "NiceJump"
    msg $RESULT

LM addr, size, filename

 メモリ内にダンプファイルをロードします。LMコマンドはDMコマンドの対となるものです。

    ; ファイル全体をコピー
    lm 401000, 0, "test.bin"
    ; 最初の100バイトだけコピー
    lm 401000, 100, "test.bin"

LOADLIB dllname

 デバッグされたプログラムのメモリ内にDLLをロードします。ロードされたライブラリの戻りアドレスなどにブレークポイントを設置する際に便利です。

    pusha
    loadlib "user32.dll"
    popa 

LOG src [,prefix]

 OllyDbgのログウィンドウに"src"で与えた文字列を記録します。"src"が定数文字列である場合には、その文字列がそのまま記録されます。"src"が変数やレジスタである場合には、その値が名前とともに記録されます。オプションの2番目のパラメータでデフォルトのプリフィックスを置き換えることができます。

    log "Hello world" // 文字列"Hello world"が記録される
    var x
    mov x, 10
    log x // 文字列"x: 00000010"が記録される
    log x, "" // 文字列"00000010"が記録される

LOGBUF var [,linecount [,separator]]

 メモリダンプのような文字列やバッファを記録します。これは大きなデータの記録に便利です。

MOV dest, src [,size]

 "src"から"dest"への代入です。"src"にはフォーマット #<任意のhex文字列># で長いhex文字列(例えば、"#12345678#"など)を利用できます。16進数文字列の桁数は偶数でなければならないことに注意して下さい。

    mov x, 0F
    mov y, "Hello world"
    mov eax, ecx
    mov [ecx], #00DEAD00BEEF00#
    mov !CF, 1
    mov !DF, !PF
    mov [403000], "Hello world"

MEMCPY dest,src,size

 "src"アドレスから"dst"アドレスに"size"バイトだけメモリをコピーします。これはMOVコマンドを利用した時のmov [dst],[src],sizeと同一の操作となります。

    gma "OLE32",CODEBASE
    mov base, $RESULT
    gma "OLE32",CODESIZE
    mov size, $RESULT
    alloc size
    mov dst, $RESULT
    MEMCPY dst,base,size
    ...
    free dst

MSG message

 指定されたメッセージ文字列でメッセージボックスを表示します。

    MSG "Script paused"

MSGYN message

 指定されたメッセージとYES,NOボタンを持つメッセージボックスを表示します。予約変数$RESULTには、YESボタンが押された場合には1、それ以外が押された場合には0が格納されます。

    MSGYN "Continue?"

MUL op1, op2

 "op1"と"op2"の乗算結果を"op1"に格納します。

    mul op1, 10 // op1 = op1 * 10

NAMES addr

 モジュールのネームウィンドウを開きます(Ctrl+N)。"addr"はモジュールアドレスを指定します。

NEG op

 "neg eax"と同一の操作を実行します。

NOT op

 "not eax"と同一の操作を実行します。

OLLY info

 Ollydbgの情報を取得します。取得したい情報に応じて"info"には以下を指定します:

  • PID: OllydbgのプロセスIDを取得
  • HWND: Ollydbgのメインウィンドウハンドルを取得
  • THREAD: Ollydbgのメインスレッドハンドルを取得
  • THREADID; OllydbgのメインスレッドIDを取得
  • PATH: Ollydbgのフルパスを取得
  • EXE: Ollydbg.EXE
  • INI: Ollydbg.INI
  • DIR: Ollydbgのディレクトリを取得
    OLLY PID
    mov pid, $RESULT
    OLLY HWND
    mov hwnd, $RESULT

OR dest, src

 "src"と"dest"にOR演算を実行して、その結果を"dest"に格納します。

    or x, 0F
    or eax, x
    or [401000], 5

OPCODE addr

 $RESULT変数に指定したアドレスのオペコードバイトを、$RESULT_1変数にニーモニック(例:"MOV ECX,EAX")を、$RESULT_2変数にオペコード長を格納します。無効なオペコードであれば$RESULT_2に0が格納されます。"addr"はオペコード長で増加していくため、このコマンドによりステップフォーワードを実行することも可能です。

    opcode 00401000

OPENDUMP addr [,base,size]

 指定したアドレスで新しいダンプウィンドウを生成します。$RESULTには新しいウインドウのHWNDが格納されます。

OPENTRACE

 ライントレースウインドウを開きます。

PAUSE

 スクリプトの実行を一時停止します。スクリプトプラグインメニューから再開することができます。

    pause

POP dw

 スタックからDWORD値を取得して"dw"に格納します。

POPA

 プラグインメモリから(PUSHAコマンドによって保持された)全てのレジスタを復元します。

PREOP addr

 指定されたアドレスの直前の命令のアドレスを取得します。
注意:jmp命令の前の実際に実行されたコマンドのEIP値を取得するものではありません。

    preop eip

PUSH dw

 スタックにDWORD値"dw"を追加します。

PUSHA

 プラグインメモリ内の全てのレジスタを保持します。これは後でPOPAコマンドによって復元できます。このコマンドではスタックは使用されていません。

RBP [arg1]

 ブレークポイントを復元します。arg1には"STRICT"を指定することができます。"STRICT"が指定された場合、一度全てのソフトウェアブレークポイントを削除した後で全てのハードウェアおよびソフトウェアブレークポイントが復元されます。arg1が指定されない場合には、RBP実行前の復元対象ではないソフトウェアブレークポイントも削除されずに保持されます。

    rbp
    rbp STRICT

READSTR str, len

 $RESULTに文字列"str"を"len"文字だけコピーします。

REF addr, [LOCATION]

 OllyDbgにおける"Find references to .. Selected command"および"Find references"機能(Ctrl+R)を実行します。LOCATIONにMEMORYを指定してメモリブロックを検索する(デフォルト)か、CODEを指定してモジュールのコードを検索するか、MODULEを指定してモジュール全体を検索するか選択できます。最初に参照されるアドレスが$RESULTに格納され、$RESULT_1にオペコード、$RESULT_2にそのコメントが格納されます。"REF addr"は次のリファレンスが参照できなくなる($RESULT = 0)まで繰り返し形で使用します。REFコマンドのカウンタはaddrが変更されたときか、addrに0が指定された時にクリアされます。

    REF 0 // RESET REF
continue:
    REF eip,CODE
    log $RESULT
    log $RESULT_1
    log $RESULT_2
    cmp $RESULT,0
    jne continue

REFRESH (バージョン1.60で追加)

 メモリマップ、モジュール、逆アセンブリウインドウを再描画します。

RESET

 ターゲットプロセスを再読み込み(OllyDbgにおけるCtrl+F2)します。

REPL addr, find, repl, len

 指定したアドレス"addr"から"len"バイトだけ、"repl"で"find"を置換します。ワイルドカードを利用することも出来ます。

    repl eip, #6a00#, #6b00#, 10
    repl eip, #??00#, #??01#, 10
    repl 401000, #41#, #90#, 1F

RET

 スクリプトを終了するから、CALLコマンドの呼び出し元に戻ります。

REV what

 DWORD値を反転します。

    rev 01020304
    // $RESULT = 04030201

ROL op, count

 "rol eax, cl"と同一の操作を実行します。

    mov x, 00000010
    ROL x, 8 

ROR op, count

 "ror eax, cl"と同一の操作を実行します。

    mov x, 00000010
    ROR x, 8 

RTR

 Ollydbgにおける"Run to return"機能(Ctrl+F9)を実行します。

    rtr

RTU

 OllyDbgにおける"Run to user code"機能(Alt+F9)を実行します。

    rtu

RUN

 OllyDbgにおけるF9を実行します。例外を無視したい時にはERUNコマンドを使用しましょう。

    run

SBP(Store Break Point)

 全てのハードウェアおよびソフトウェアブレークポイントを格納して、RBPコマンドで復元することができます。

SCMP dest, src [,size]

 "src"と"dest"の文字列を比較します。"size"パラメータで比較する文字数を指定できます。

    var sVar
    mov sVar, "Hello World"
    scmp sVar, "Hello", 5
    je Okay
    log "Error."
Okay:

SCMPI dest, src [,size]

 "src"と"dest"の文字列を比較します。SCMPと異なり文字の大小は区別しません。"size"パラメータで比較する文字数を指定できます。

    var sVar
    mov sVar, "HELLO WORLD"
    scmpi sVar, "Hell", 4
    je Okay
    log "Error."
Okay:

SETOPTION

 デバッギングパラメータを変更するために、OllyDbgのオプションウィンドウを開きます。スクリプトはオプションウィンドウを閉じた時に再開されます。

SHL dest, src

 "dest"を"src"回左にビットシフトして、その結果を"dest"に格納します。

    mov x, 00000010
    shl x, 8 // x -> 00001000

SHR dest, src

 "dest"を"src"回右にビットシフトして、その結果を"dest"に格納します。

    mov x, 00001000
    shr x, 8 // x -> 00000010

STEP

 OllyDbgにおけるステップオーバー(F8)を実行します。STOコマンドと同一です。

    step

STI

 OllyDbgにおけるステップイントゥ(F7)を実行します。

    sti

 

STO

 OllyDbgにおけるステップオーバー(F8)を実行します。STEPコマンドと同一です。

    sto

STR var

 変数を文字列(バッファまたはDWORD値)に変換します。

SUB dest, src

 "dest"から"src"を減算します。

    sub x, 0F
    sub eax, x
    sub [401000], 5 

TC

 OllyDbgのライントレースをキャンセルします。

    tc

TEST dest,src

 "src"と"dest"のAND演算を行い、演算結果を保持せずにフラグレジスタのみ更新します。これにより、CF, OF, PF, SF, ZFフラグが更新される可能性があります。

TI

 OllyDbgのトレースイン機能(CTRL+F7)を実行します。

    ti

TICK [var [,reftime]]

 スクリプトの実行時間(マイクロ秒)を指定された変数に格納します。"reftime"パラメータが指定されている場合、$RESULTにreftimeからの経過時間が格納されます。"reftime"パラメータが設定されていない場合には、"ms"のフォーマットで実行時間が$RESULTに格納されます。

    tick time
    msg time		// スクリプト開始からの経過時間
    tick time,time	
    msg $RESULT		// 最後のTICK呼び出しからの経過時間

TICND cond

 条件"cond"が真になるまでトレースインし続けます。

    ticnd "eip > 40100A" // "eip > 40100A"であればトレースを停止する

TO

 OllyDbgのトレースオーバー機能を実行します。

    to

TOCND cond

 条件"cond"が真になるまでトレースオーバーし続けます。

    tocnd "eip > 40100A" // "eip > 40100A"であればトレースを停止する

UNICODE enable

 Unicodeモードを有効にします。

    UNICODE 1
    ...

VAR

 スクリプトで使用される変数を宣言します。

    var x

XOR dest, src

 "src"と"dest"のXOR演算を行い、結果を"dest"に格納します。

    xor x, 0F
    xor eax, x
    xor [401000], 5

XCHG dest, src

 "src"と"dest"の値を入替えます。

WRT file, data

 ファイルを書き込みます。セパレータは"\r\n"です。

    wrt "out.txt", "Data:\r\nOk\r\n"
    wrt sFile, ebx

WRTA file, data [, separator]

 ファイルに書き加えます。デフォルトのセパレータは"\r\n"です。

    wrt sFile, "hello world"
    wrta sFile, 0ABCD, ""
    wrta sFile, "Windows CR, "\r\n"

ラベル

 ラベルは、ラベル名の後にコロンを付加して定義することができます。

    SOME_LABEL:

コメント

 コメントは";"または"//"で挿入することができます。コメント行は、スクリプトウィンドウ内mの";"から表示されます。"/*"と"*/"で囲んだ部分がコメントブロックになります。

メニュー

 OllyScriptのメインメニューは以下の項目を含んでいます:

スクリプトウィンドウ

 スクリプトウィンドウはスクリプトデバッグや実行経過の確認のための機能です。スクリプトウィンドウ上で、スクリプトへのブレークポイントの設置、スクリプトデバッグ、変数の編集やコマンドのマニュアル実行が可能となります。

他のプラグインとの統合

 他のプラグインからOllyScriptを呼び出し、スクリプトを実行させることができます。以下に示すようなソースコードを導入して下さい:

HMODULE hMod = GetModuleHandle("ODbgScript.dll");
if(hMod) // プラグインがロードされているか確認
{
	// エクスポート関数のアドレスを取得
	int (*pFunc)(char*) = (int (*)(char*)) GetProcAddress(hMod, "ExecuteScript");
	if(pFunc) // 関数がエクスポートされているか確認
		pFunc("myscript.txt"); // エクスポート関数の実行
}

 DebugScriptのDLLエントリも有効です。OllyDBG ODBG_plugincmd()やConditional Log Breakpoints内からもスクリプトコマンドを実行できます。