-
-
[原创]【2019看雪CTF】Q2赛季 第七题 部落冲突 脱壳小记
-
发表于:
2019-7-3 00:24
6550
-
[原创]【2019看雪CTF】Q2赛季 第七题 部落冲突 脱壳小记
这一题真是不会做。只能做做前面的准备工作,脱下壳什么的。
一下载文件就被杀软杀了,可能有壳。
先拖进ida看了眼,果然有壳。目前入口处的部分伪代码如下(asm代码量有点大):
主要流程如下:
期间还有IsDebuggerPresent
(strong OD无影响)、CheckRemoteDebuggerPr
等反调试手段。
此处取的API是壳运行所用,创建互斥体及创建文件是与原程序代码遥相呼应起到反调试作用(更改数据)。
解码的数据为原PE4个Section的数据,偏移为0x400-0x9CA00
,解码操作为与0x55
异或。其实原PE被删了IMPORT TABLE,编码了Section后存放于地址0x4D0824,即文件偏移0x2C24。
进入write_data_and_api_4CE864
函数后,先分别copy了原PE的头及4个Section到原虚拟地址处,再开始构建api调用机制。
原PE的IAT在虚拟地址0x421000,IT在0x42E034(基本被删完了)。为了阻止脱壳运行,在IAT部分也进行了点动作,壳不再在跳到OEP之前恢复IAT,而是构造了一种API间接调用的机制。此机制将call api变成了call 堆地址,IAT中存放的是堆地址,各堆中预设了代码,进行某些其它操作后,跳到API执行。预设代码有6种,随机分配,这样脚本恢复IAT就比较麻烦了,得先确定各代码堆对应的预设代码种类。此处用到了由原IT转换而来的表,位于虚拟地址0x59B000,文件偏移0xCC800,结构与IT有点类似,库文件名和API hash异或编码了。
此机制的构建过程比较清晰,不多说。组装好的中转代码其中一种典型样式如下:
6种代码样式中,跳到api均使用了push ;ret
的方式。
构建完API中转调用后,会调用sub_4CFD74
,实际操作为与0异或,开始地址为0x401000,大小为0x1D600,操作完后与改写0x4CE010处的参数,这一次操作实际是为后面解码作准备。此处也有反调试,如检测到调试,会改变异或值(加上0x85)。
sub_4CFD74
还会在间接调用API时被调用,进行解码,具体情况如下:
write_data_and_api_4CE864
函数返回后就直接jmp到了OEP。
做题时看得没这么细致,看了下壳的大概结构,直接在jmp oep处patch成了死循环,运行程序再attach,然后dump。然后走一步看一步。
先发现IAT有猫腻,尝试多次终于用OD脚本获得IAT表;然后又发现dump下来的代码中还有SMC,IAT修复后(增加区段,改了IAT地址),SMC之后的代码call api就出问题了。
后来一想,其实可以直接从文件中把编码后的原PE分离开,然后解码,最后再修复IAT应该好点,至少文件小一半。
我当时的完整做法是:
最后附上脱壳之后的文件。不知是否还有问题。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)