ollydbg脚本学习

1. 脚本文件格式

// 注释以 // 开头
// 脚本扩展名: .osc 或 .txt

var variable_name          // 声明变量
mov variable_name, value   // 赋值
cmp variable, value        // 比较
je label_name              // 条件跳转

label_name:                // 标签定义
// 代码块

2. 基本语法结构

// 示例:简单的跟踪脚本
var counter
var target_address

START:
    mov counter, 0
    mov target_address, 00401000
    
    bp target_address          // 设置断点
    run                        // 运行程序
    sto                        // 单步步过
    
    inc counter               // 计数器加1
    cmp counter, 100
    jb START                  // 循环
    
    msg "脚本执行完成"         // 显示消息
    ret

3、核心脚本命令

// 设置断点
bp address                   // 软件断点
bphws address, "type"        // 硬件断点 (type: "r", "w", "x")
bpm address, size, "type"    // 内存断点

// 断点管理
bc address                   // 清除断点
bpd address                  // 禁用断点
bpe address                  // 启用断点

// 条件断点
bpcnd address, "condition"   // 条件断点
bpl address, "expression"    // 记录断点

// 示例
bp 00401000                  // 在入口点设断点
bphws 00401000, "x"          // 执行断点
bpm 00401000, 4, "w"         // 内存写入断点

4. 程序控制命令

run                          // 运行程序 (F9)
sto                          // 单步步过 (F8)
sti                          // 单步步入 (F7)
pause                        // 暂停程序

// 执行到指定地址
eob address                  // 执行到断点
eoe address                  // 执行到表达式为真

// 示例
run                         // 运行
sti                         // 步入call
sto                         // 步过call
pause                       // 暂停

5.寄存器和内存操作

// 寄存器操作
mov eax, 12345678           // 设置寄存器
mov [eax], 0x90             // 写入内存
cmp eax, ebx                // 比较寄存器

// 内存读写操作
dm address, "type", size    // 读取内存 (type: db, dw, dd)
pm address, value           // 写入内存

// 示例
mov eax, [401000]           // 读取内存到eax
mov [401000], 0x90          // 写入nop
dm 401000, "db", 100        // 显示100字节
pm 401000, 0xCC             // 写入int3

6.变量和表达式

var var1, var2, var3        // 声明变量
mov var1, 0x401000          // 赋值
add var1, 100               // 加法
sub var1, 50                // 减法
mul var1, 2                 // 乘法
div var1, 4                 // 除法

// 逻辑运算
and var1, 0xFF              // 与运算
or var1, 0x100              // 或运算
xor var1, 0xFF              // 异或运算
not var1                    // 非运算

// 示例
var base_addr
mov base_addr, eip          // 当前EIP
add base_addr, 0x1000       // 偏移

7.实例telock脱壳脚本

// telock_unpack.osc
var oep
var delta_ebp
var iat_start
var iat_size

// 初始化
mov oep, 0
mov delta_ebp, 0
mov iat_start, 0
mov iat_size, 0

START:
    // 隐藏调试器
    gpi "PROCESSNAME"
    cmp $RESULT, "ollydbg.exe"
    je HIDE_DEBUGGER
    
    // 设置入口点断点
    gmi eip, MODULEBASE
    mov $MODULEBASE, $RESULT
    bp $MODULEBASE
    
    // 运行到入口点
    run
    pause
    
    // 分析Telock特征
    find eip, #60E8000000005D81ED#  // pushad; call $+5; pop ebp; sub ebp, xxx
    cmp $RESULT, 0
    je NOT_TELOCK
    
    // 记录delta值
    mov delta_ebp, ebp
    msg "Telock delta: $delta_ebp"
    
    // 跟踪到OEP
    find eip, #61C3#  // popad ret
    cmp $RESULT, 0
    je FIND_OEP
    
    mov oep, $RESULT
    sub oep, 10      // 调整到popad前
    
    // 设置OEP断点
    bp oep
    run
    
    // 转储内存
    dumpeip           // dump当前模块
    msg "OEP found at: $oep"
    
    // 修复IAT
    call FIND_IAT
    call FIX_IAT
    
    msg "脱壳完成!"
    ret

FIND_OEP:
    // 使用内存断点查找OEP
    bpm $MODULEBASE+1000, 1000, "x"
    run
    pause
    
    mov oep, eip
    bc $MODULEBASE+1000
    jmp START
    
FIND_IAT:
    // 查找IAT区域
    var iat_candidate
    mov iat_candidate, $MODULEBASE+3000
    
    find iat_candidate, #FF15#  // call dword ptr [xxx]
    cmp $RESULT, 0
    je NO_IAT
    
    mov iat_start, $RESULT
    add iat_start, 2
    
    // 计算IAT大小
    mov iat_size, 0
    mov eax, iat_start
    
    IAT_LOOP:
        cmp [eax], 0
        je IAT_END
        add iat_size, 4
        add eax, 4
        jmp IAT_LOOP
    
    IAT_END:
        msg "IAT found: start=$iat_start, size=$iat_size"
        ret

FIX_IAT:
    // 使用ImpREC修复IAT
    exec "ImpREC.exe"
    // 等待ImpREC启动
    pause 2000
    
    // 自动化ImpREC操作
    // 这里需要窗口自动化,比较复杂
    msg "请手动使用ImpREC修复IAT"
    ret

HIDE_DEBUGGER:
    // 调用StrongOD隐藏调试器
    exec "StrongOD.dll", "HideDebugger"
    jmp START

NOT_TELOCK:
    msg "不是Telock保护的程序"
    ret

 

posted @ 2026-02-10 08:34  hopeccie  阅读(48)  评论(0)    收藏  举报