前言
对cm进行调试,手工进行可以了(已经找到了被调试点,也能从应用层最初的断点一步一步的爬过去),因为地址随机化,导致每次都要按照调试笔记,去执行一组循环操作(F2, F9, F7 or F8),经过10几步才到达被调试点, 用时至少5分钟。如果要反复调试一个点,有时手一抖,过了调试点,先将自己搞疯了…。
本来想着好久没搞IDA脚本,先用C语言写一个小程序,输入地址,算出偏移,先去IDA中g那个算好的地址。用了一两天,被折磨的终于忍不住了。
还是要写个IDA脚本, 逃不掉的。
用IDC写起来简单,就花了2个小时,写了一个。
写完用起来,一身轻松。
只需要对应用层的API下第一个断点,F9跑起,F8到了第三方DLL, 载入脚本,一键就到了被调试点。
运行效果
--------------------------------------------------------------------------------
IDC for oci_test_on_vs2010.exe v1.0.0.1
debug for oci_test_on_vs2010.exe
use ida load object program
clear all breakpoint
make sure F2 break on do_oci_task() :: OCIStmtExecute()
F9 run program
F7 into OCIStmtExecute_0 proc near
F8 step to "jmp cs:__imp_OCIStmtExecute"
F2 breakpoint on "jmp cs:__imp_OCIStmtExecute"
then load oci_test_on_vs2010.idc
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
0x7FF778194D6A : OCIStmtExecute_0 :: jmp cs:__imp_OCIStmtExecute
ok : debug now, will go to oran11_nioqrc() :: call near ptr oran11_nsbrecv
please wait a moment ...
PDBSRC: loading symbols for 'D:\app\LostSpeed\product\11.2.0\client_1\bin\oci.dll'...
offset addr 0x18000443D : call rax
PDBSRC: loading symbols for 'D:\app\LostSpeed\product\11.2.0\client_1\bin\oraclient11.dll'...
--------------------------------------------------------------------------------
0x3294B00 : oraclient11_OCIStmtExecute :: xchg ax, ax
offset addr 0x3294B41 : call near ptr oraclient11_kpuexec
7FF920BC42C0: thread has started (tid=9072)
--------------------------------------------------------------------------------
0x33DAD30 : oraclient11_kpuexec :: xchg ax, ax
offset addr 0x33DD351 : call near ptr oraclient11_kpurcsc
--------------------------------------------------------------------------------
0x345B292 : oraclient11_kpurcsc :: xchg ax, ax
offset addr 0x345B323 : call near ptr oraclient11_upirtrc
--------------------------------------------------------------------------------
0x34FAE96 : oraclient11_upirtrc :: xchg ax, ax
offset addr 0x34FAF0D : oraclient11.dll:0000000003C9AF0D call near ptr unk_3CB4B9E
--------------------------------------------------------------------------------
0x3514B9E : loc_3514B9E :: xchg ax, ax
offset addr 0x3515213 : oraclient11.dll:0000000003B25213 call qword ptr [rax+20h]
PDBSRC: loading symbols for 'D:\app\LostSpeed\product\11.2.0\client_1\bin\oran11.dll'...
--------------------------------------------------------------------------------
0x49B85C0 : oran11_nioqwa :: push r15
offset addr 0x49B85F5 : oran11.dll:0000000003D185F5 call r14
--------------------------------------------------------------------------------
0x49B85F8 : :: test eax, eax
offset addr 0x49B85F5 : oran11.dll:0000000003D185F5 call r14
PDBSRC: loading symbols for 'D:\app\LostSpeed\product\11.2.0\client_1\bin\oracommon11.dll'...
--------------------------------------------------------------------------------
0x477D496 : oracommon11_ttcdrv :: xchg ax, ax
offset addr 0x477DA6B : oracommon11.dll:000000000442DA6B call qword ptr [rsi+10h]
--------------------------------------------------------------------------------
0x499438A : oran11_nioqrc :: push r15
offset addr 0x49944C6 : oran11.dll:00000000049044C6 call near ptr oran11_nsbsend
offset addr 0x4994595 : oran11.dll:0000000004904595 call near ptr oran11_nsbrecv
offset addr 0x4994506 : oran11_nsbsend pure data : oran11.dll:00000000054A4506 mov [rbx+20h], rcx
--------------------------------------------------------------------------------
0x49944C6 : :: call near ptr oran11_nsbsend
please debug, nice to meet you :)
IDC脚本
// @file oci_test_on_vs2010.idc
// @brief debug for oci_test_on_vs2010.exe
#include <idc.idc>
#define PROG_FOR_DEBUG "oci_test_on_vs2010.exe"
#define MY_IDC_VER "IDC for " PROG_FOR_DEBUG " v1.0.0.1"
#define LINE_80 "--------------------------------------------------------------------------------"
#define MY_CONDITION_FOR_STARTING_THE_IDC "use ida load object program\n" \
"clear all breakpoint\n" \
"make sure F2 break on do_oci_task() :: OCIStmtExecute()\n" \
"F9 run program\n" \
"F7 into OCIStmtExecute_0 proc near\n" \
"F8 step to \"jmp cs:__imp_OCIStmtExecute\"\n" \
"F2 breakpoint on \"jmp cs:__imp_OCIStmtExecute\"\n" \
"then load oci_test_on_vs2010.idc"
/*
.text:00007FF778194D6A OCIStmtExecute_0 proc near ; CODE XREF: do_oci_task(OCIEnv *,OCIServer *,OCIError *,OCISvcCtx *,OCISession *)+213↑p
.text:00007FF778194D6A jmp cs:__imp_OCIStmtExecute // when run here, can load oci_test_on_vs2010.idc
.text:00007FF778194D6A OCIStmtExecute_0 endp
*/
#define REG_IP "RIP"
// sub function must declare befoe main()
static fn_show_offset_addr(str_tip, ull_addr_now, ull_addr_offset)
{
auto ull_addr_rc;
ull_addr_rc = ull_addr_now + ull_addr_offset;
msg("offset addr 0x%X : %s\r\n", ull_addr_rc, str_tip);
return ull_addr_rc;
}
static fn_f7()
{
StepInto();
wait_for_next_event(WFNE_SUSP | WFNE_CONT, -1);
}
static fn_f8()
{
StepOver();
wait_for_next_event(WFNE_SUSP | WFNE_CONT, -1);
}
static fn_go()
{
wait_for_next_event(WFNE_SUSP | WFNE_CONT, -1);
}
static fn_show_current_line_info()
{
auto l_addr;
auto str_name;
auto str_dasm_code;
l_addr = GetRegValue(REG_IP);
str_name = Name(l_addr);
str_dasm_code = generate_disasm_line(l_addr, GENDSM_FORCE_CODE);
msg("%s\n", LINE_80);
msg("0x%X : %s :: %s\n", l_addr, str_name, str_dasm_code);
}
static fn_get_current_dasm_code()
{
auto l_addr;
auto str_dasm_code;
l_addr = GetRegValue(REG_IP);
str_dasm_code = generate_disasm_line(l_addr, GENDSM_FORCE_CODE);
return str_dasm_code;
}
static fn_get_current_addr()
{
auto l_addr;
l_addr = GetRegValue(REG_IP);
return l_addr;
}
static fn_show_help()
{
auto i_index;
// clear debug output area
for (i_index = 0; i_index < 25; i_index++) {
msg("\n");
}
msg("%s\n", LINE_80);
msg("%s\n", MY_IDC_VER);
msg("debug for %s\n", PROG_FOR_DEBUG);
msg("%s\n", MY_CONDITION_FOR_STARTING_THE_IDC);
msg("%s\n", LINE_80);
}
static fn_add_bp(l_addr)
{
add_bpt(l_addr);
}
static fn_remove_bp(l_addr)
{
del_bpt(l_addr);
}
static main()
{
auto l_addr;
auto l_addr_tmp;
auto str_dasm_code;
fn_show_help();
fn_show_current_line_info();
str_dasm_code = fn_get_current_dasm_code();
if (str_dasm_code != "jmp cs:__imp_OCIStmtExecute") {
msg("error!!!\n");
fn_show_current_line_info();
} else {
msg("ok : debug now, will go to oran11_nioqrc() :: call near ptr oran11_nsbrecv\n");
msg("please wait a moment ...\n");
// step 1
fn_f8();
// step 2
l_addr = fn_get_current_addr();
l_addr = fn_show_offset_addr("call rax", l_addr, 0xb5);
fn_add_bp(l_addr);
fn_go();
fn_remove_bp(l_addr);
fn_f7();
fn_show_current_line_info();
// step 3
l_addr = fn_get_current_addr();
l_addr = fn_show_offset_addr("call near ptr oraclient11_kpuexec", l_addr, 0x41);
fn_add_bp(l_addr);
fn_go();
fn_remove_bp(l_addr);
fn_f7();
fn_show_current_line_info();
// step 4
l_addr = fn_get_current_addr();
l_addr = fn_show_offset_addr("call near ptr oraclient11_kpurcsc", l_addr, 0x2621);
fn_add_bp(l_addr);
fn_go();
fn_remove_bp(l_addr);
fn_f7();
fn_show_current_line_info();
// step 5
l_addr = fn_get_current_addr();
l_addr = fn_show_offset_addr("call near ptr oraclient11_upirtrc", l_addr, 0x91);
fn_add_bp(l_addr);
fn_go();
fn_remove_bp(l_addr);
fn_f7();
fn_show_current_line_info();
// step 6
l_addr = fn_get_current_addr();
l_addr = fn_show_offset_addr("oraclient11.dll:0000000003C9AF0D call near ptr unk_3CB4B9E", l_addr, 0x0000000003B0AF0D - 0x0000000003B0AE96);
fn_add_bp(l_addr);
fn_go();
fn_remove_bp(l_addr);
fn_f7();
fn_show_current_line_info();
// step 7
l_addr = fn_get_current_addr();
l_addr = fn_show_offset_addr("oraclient11.dll:0000000003B25213 call qword ptr [rax+20h]", l_addr, 0x0000000003B25213 - 0x0000000003B24B9E);
fn_add_bp(l_addr);
fn_go();
fn_remove_bp(l_addr);
fn_f7();
fn_show_current_line_info();
// step 8
l_addr = fn_get_current_addr();
l_addr_tmp = l_addr;
l_addr = fn_show_offset_addr("oran11.dll:0000000003D185F5 call r14", l_addr, 0x0000000003D185F5 - 0x0000000003D185C0);
fn_add_bp(l_addr);
fn_go();
fn_remove_bp(l_addr);
fn_f8();
fn_show_current_line_info();
// step 9
// call r14 要经过2次才行, 然后f7进去
l_addr = l_addr_tmp;
l_addr = fn_show_offset_addr("oran11.dll:0000000003D185F5 call r14", l_addr, 0x0000000003D185F5 - 0x0000000003D185C0);
fn_add_bp(l_addr);
fn_go();
fn_remove_bp(l_addr);
fn_f7();
fn_show_current_line_info();
// step 10
l_addr = fn_get_current_addr();
l_addr = fn_show_offset_addr("oracommon11.dll:000000000442DA6B call qword ptr [rsi+10h]", l_addr, 0x000000000442DA6B - 0x000000000442D496);
fn_add_bp(l_addr);
fn_go();
fn_remove_bp(l_addr);
fn_f7();
fn_show_current_line_info();
// step 11
// 到地方了, 对需要调试的地址下最后的断点
l_addr = fn_get_current_addr();
l_addr = fn_show_offset_addr("oran11.dll:00000000049044C6 call near ptr oran11_nsbsend", l_addr, 0x00000000049044C6 - 0x000000000490438A);
fn_add_bp(l_addr);
l_addr = fn_get_current_addr();
l_addr = fn_show_offset_addr("oran11.dll:0000000004904595 call near ptr oran11_nsbrecv", l_addr, 0x0000000004904595 - 0x000000000490438A);
fn_add_bp(l_addr);
l_addr = fn_get_current_addr();
l_addr = fn_show_offset_addr("oran11_nsbsend pure data : oran11.dll:00000000054A4506 mov [rbx+20h], rcx", l_addr, 0x00000000054A4506 - 0x00000000054A438A);
fn_add_bp(l_addr);
fn_go();
fn_show_current_line_info();
// over, 用脚本一键到达调试地点的任务结束
// 已经对多处要调试的点,都下好了断点
// 已经运行到了其中一个断点上,停住了,等待调试
msg("please debug, nice to meet you :)\n");
}
}