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
浙公网安备 33010602011771号