序言:
本题使用了父子进程守护、壳、SMC、反调试、DES算法、多个坑等设计,难度不低,可惜多解,现仅提交140组答案,
破解此题需要攻击者具备解壳或动态调试能力、跟踪父子进程、熟谙DES算法细节和直觉(否则栽在坑里了)。
一、侦壳、PE格式,试运行了解作品(套路),未知壳,作品有窗口还有错误提示(容易找到合适的断点位置)
二、解壳:
// 破解本题无需真的脱掉壳,只需要找到OEP,利用OD脚本进行自动断在OEP并Patch代码即可。
// OD载入,停在这里:
// 跟入CALL 44701F,省略一系列解码过程,破解此题不需要关心这些,只需要找到OEP
// 来到OEP
// 可以写个OD脚本,自动断OEP
三、分析子进程的坑
// OD加载运行后,只出来一个带窗口进程,与正常运行的双进程不同,说明这是个坑
// 是坑也得分析不是?bp GetDlgItemTextW
// 返回程序
// CALL 401A40 为子进程算法,跟进
// 异或累加 == 0x127514D 就是个很直白的坑
// 此时想到父进程必然有小动作
// 找到加载窗口的位置(父进程不显示窗口,所以在相关位置必有选择)
//置父子进程标志位的地方
四、分析父进程小动作
// 正常运行之后,OD附加父进程,对CODE段下访问断点,断到
// 父进程再设断点
// 410ADA CALL EAX 有小动作,跟进
// 堆栈
// 将子进程 4017BD 位置用 9090 NOP掉
// 还有小动作
// 堆栈
// [15BFE44] = E9 BB 08 00 00
// 将子进程 401A43 位置用 E9 BB 08 00 00 修改
// 至此,已经分析清楚父进程对子进程的两处代码修改,后续调试我们就脱离父进程
// OD脚本模拟父进程自动patch代码
五、分析第一段算法
// 重新再来(代码已经patch)
// 跟踪改变后的流程,动态申请内存0x5000字节,用于存放待解密数据
// 用于读取自身0x5000字节待解密数据
// 获取输入并转换格式十六进制
// 第一段算法暴露(SMC)
// 异或解密后比较
// 据此写Python穷举第一段注册码(穷举第9、10位,组合很少,秒出)
// 找到 sn_9_10: E1,找到 sn_1_8: 75A29C09,因此第一段注册码(sn_1-10):“75A29C09E1”
六、分析第二段算法
// 上述解密后的动态申请的内存作为函数运行(DES+奇数位取反)
// 接下来跟进 CALL EDI,痛苦就此开始,第一眼判断可能位DES算法,使用工具计算结果不符,无奈跟进去分析,巨复杂
// 初步判断作者可能对DES的几个表做了调整,因此我花费了时间自己码了DES代码,对每一个DES步骤、表格进行检查(这工作量你懂得)
// 结果......DES解密过程没有问题,与标准的相同!!!真正的手脚在于DES末尾IP-1逆置换、交换左右32bit结束后,作者竟然将bit的奇数位取反!!!
// DES 解密末尾的坑:
// 所以破解算法思路变成了将解密结果先bit奇数位取反,然后用“19930907”密钥进行DES加密,结果就是注册码的第二段
// CALL EDI 必须返回“!HelloHaniella!” 字符串
// 比如,要使 CALL EDI 返回:
// 二进制
// --> 奇数位取反(下标偶数位)
// 转回十六进制和字符串
// 以“19930907”为密钥加密“嬧掀婆馑拿掀扑嫪”得到“80217C048420956C15DA309FF2B69170”
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)