首页
社区
课程
招聘
[原创]x64dbg脚本 - 解决调试时编排函数调用
2019-9-27 09:53 9628

[原创]x64dbg脚本 - 解决调试时编排函数调用

2019-9-27 09:53
9628

x64dbg脚本 - 解决调试时自定义调用函数方式

一直没怎么使用x64dbg脚本功能,而且官方的文档命令的例子也不多,所以整理了下,解决的问题来原于这次Q3的CTF第5题,在做3DES的时候,程序逻辑为:

           Dest= UserInput[18, 8] 
           v21 = UserInput[16, 8]; = "VXV9/DCo" 
           v22 = UserInput[8, 8];  = "VXV8/wCp" 
           v23 = UserInput[0, 8];  = "VXX/8AKl" 
           des_Func_en(&Dest, &v21, &Dest); // crypt
           des_Func_de(&Dest, &v22, &Dest); // decrypt
           des_Func_en(&Dest, &v23, &Dest); // crypt
           // 执行后此处Dest =  ['0x30', '0x80', '0x3', '0x3f', '0xfd', '0x55', '0x5a', '0x80']

上面的CTF相关的内容就略了,其中需要逆向得到Dest的值,需要对上面的三次调用逆过程执行,基本为:

           Dest =  ['0x30', '0x80', '0x3', '0x3f', '0xfd', '0x55', '0x5a', '0x80']
           v21 = UserInput[16, 8]; = "VXV9/DCo" 
           v22 = UserInput[8, 8];  = "VXV8/wCp" 
           v23 = UserInput[0, 8];  = "VXX/8AKl" 
           des_Func_de(&Dest, &v23, &Dest); // decrypt
           des_Func_en(&Dest, &v22, &Dest); // crypt
           des_Func_de(&Dest, &v21, &Dest); // decrypt

如果手工调试,可以在断点到对应函数后,通过修改参数来实现,但是因为顺序问题,需要3次完成调试,其中在使用脚本语言相关的调试的时候,是可以在调试阶段,动态去调用一些函数,来测试结果的,所以想着是不是有办法做到类似的功能(本来想看是不是有插件可以,没有找到),就开始找办法实现。

实现思路

在二进制里要实现上面的调用,想到的一个思路是通过动态写汇编来执行:
1,先创建一块调试临时内存区域用来存放需要写的汇编;
2,将上面的逆过程以汇编的方式写到内存区域;
3,在调试的时候,执行到合适的断点后,进入上面的汇编获取结果;
根据上面的方式,分别要解决几个问题:
1,内存分配:alloc
2,des_Func_de|des_Func_en的调用参数和地址:通过查看原来的内容获取:

// des_Func_en :
lea rcx,qword ptr ss:[rbp-10]         
lea rdx,qword ptr ss:[rbp-40]         
lea rax,qword ptr ss:[rbp-10]         
mov r8,rcx                            
mov rcx,rax                           
call <lost.sub_4023E4_DES_Func_en>              | call 4023E4(rcx, rdx, r8)
// des_Func_den :
lea rcx,qword ptr ss:[rbp-10]                   
lea rdx,qword ptr ss:[rbp-30]                   
lea rax,qword ptr ss:[rbp-10]                   
mov r8,rcx                                      
mov rcx,rax                                     
call <lost.sub_40202A_DES_Func_de>              | call 40202A(rcx, rdx, r8)

des_Func_de :
3, 写入汇编还是shellcode ?通过查看手册,其实x64dbg的汇编器是可以调用的:asm 命令;
接下来就是coding和debug的过程,不细说了,有一些命令不熟悉,自己也摸索了下;

脚本结果:

// This is a demo of x64dbg 
// In x64dbg script, use cmp and je to work like "if and for " in high class language.
// Note: 22fd30, 22fd20, 22fd10, 22fd00 are fixed addresses in debug. 
// ------------------------------------------------------------------------------------
// set dest = ['0x30', '0x80', '0x3', '0x3f', '0xfd', '0x55', '0x5a', '0x80'] 
Fill 22FD30,30,1;Fill 22FD30+1,80,1;Fill 22FD30+2,03,1;
Fill 22FD30+3,3F,1;Fill 22FD30+4,FD,1;Fill 22FD30+5,55,1;
Fill 22FD30+6,5A,1;Fill 22FD30+7,80,1;
// allocate memory , note: set @address may get faliure.
alloc 0x1000
// write code to memory 
$inst_base=$result + 0x10
$inst_offset=0
asm $inst_base, "mov edx, 0x22FD20"
$inst_offset = $inst_offset + $result
asm $inst_base + $inst_offset, "lea rcx, ss:[rbp-0x10]"
$inst_offset = $inst_offset + $result
asm $inst_base + $inst_offset, "lea rax, ss:[rbp-0x10]"
$inst_offset = $inst_offset + $result
asm $inst_base + $inst_offset, "mov r8, rcx"
$inst_offset = $inst_offset + $result
asm $inst_base + $inst_offset, "mov rcx, rax"
$inst_offset = $inst_offset + $result
log "inst_offset = {0}, result = {1}", $inst_offset, $result
// call 0x40202A(rcx, rdx, r8)
asm $inst_base + $inst_offset, "call 0x40202A"
$inst_offset = $inst_offset + $result
asm $inst_base + $inst_offset, "lea rcx, ss:[rbp-0x10]"
$inst_offset = $inst_offset + $result
asm $inst_base + $inst_offset, "lea rax, ss:[rbp-0x10]"
$inst_offset = $inst_offset + $result
asm $inst_base + $inst_offset, "mov r8, rcx"
$inst_offset = $inst_offset + $result
asm $inst_base + $inst_offset, "mov rcx, rax"
$inst_offset = $inst_offset + $result
asm $inst_base + $inst_offset, "mov edx, 0x22FD10"
$inst_offset = $inst_offset + $result
// call 0x4023E4(rcx, rdx, r8)
asm $inst_base + $inst_offset, "call 0x4023E4"
log "inst_offset = {0}, result = {1}", $inst_offset, $result
$inst_offset = $inst_offset + $result
asm $inst_base + $inst_offset, "lea rcx, ss:[rbp-0x10]"
$inst_offset = $inst_offset + $result
asm $inst_base + $inst_offset, "lea rax, ss:[rbp-0x10]"
$inst_offset = $inst_offset + $result
asm $inst_base + $inst_offset, "mov r8, rcx"
$inst_offset = $inst_offset + $result
asm $inst_base + $inst_offset, "mov rcx, rax"
$inst_offset = $inst_offset + $result
asm $inst_base + $inst_offset, "mov edx, 0x22FD00"
$inst_offset = $inst_offset + $result
// call 0x40202A(rcx, rdx, r8)
asm $inst_base + $inst_offset, "call 0x40202A"
$inst_offset = $inst_offset + $result
asm $inst_base + $inst_offset, "nop"
bp $inst_base + $inst_offset
log "inst_offset = {0}, result = {1}", $inst_offset, $result
// set run point 
rip = $inst_base
run
log "Result = 0x" "{x:bswap([0x22FD30])}" // show 8 bytes info of address 22fd30.
log "Result = 0x" "{mem;8@0x22FD30}"      // Demo how to set size of showed bytes.

说明:最后Demo了一下按字节显示的格式,官方文档没提命令需要加“”,而且有一些格式不加“”也可以,有点乱。

测试结果

完成上面的脚本后,加载lost.exe程序,手动设置断点:
图片描述
程序正常输入:VXX/8AKlVXV8/wCpVXV9/DCo
停在断点后,加载脚本,并执行,在日志界面查看结果:
图片描述


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2019-9-27 17:42 被nevinhappy编辑 ,原因:
收藏
点赞3
打赏
分享
最新回复 (4)
雪    币: 17842
活跃值: (59828)
能力值: (RANK:125 )
在线值:
发帖
回帖
粉丝
Editor 2019-9-27 10:20
3
0
感谢分享~
雪    币: 768
活跃值: (226)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
zmrbak 2019-9-27 10:23
4
0
好文章,感谢分享
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_jaajogiu 2021-6-10 14:27
5
0
你好 有偿求帮忙做个简单的x64dbg插件(我自用)  请问可以留个联系方式吗
游客
登录 | 注册 方可回帖
返回