该程序没有壳,有三处简单的反调试,patch掉后,通过输入的检测后,会有三段解密函数来还原出一个dll,通过文件映射向dll内传递flag的密文,在dll中进行aes解密,最终得到flag。

运行一下,查看其输出结果。

首先使用Exeinfo查壳,发现没有壳,是X64的程序。

用X64dbg打开发现有地址随机化,用CFF关闭地址随机化OptionHandle->DllCharacteristics
,便于后续继续分析。

在main函数处下断点,运行后发现有弹框并退出进程,则判断有TLS反调试。

使用ida查看TLS函数处,发现有IsDebuggerPresent反调试和四个加密的数组。

手动Path掉反调试,继续分析,等待数组的内容解密后可以看到解密后的字符串。

- NtQueryInformationProcess 取进程信息函数,可以用于反调试(有调试端口,可以检测进程是否被调试)。
- ZwQueryInformationThread 获取线程信息,可以用于反调试。
- NtQueryApcThread apc队列
APC注入可以让一个线程在它正常的执行路径运行之前执行一些其他的代码,每一个线程都有一个附加的APC队列,他们在线程处于可警告的时候才被处理(WaitForSingObjectEx,SleepEx)。
异步过程调用,apc可以看成就是内核里的定时器,为了给自己一个在本函数返回后还能执行的一次机会,有很多操作是需要在函数返回后才能执行.类似于析构函数但不完全是。
反反调试:跟进IsDebuggerPresent
API中,进行如下修改即可。

位置:mian函数->beginthreadex
中的线程启动函数(140009180)-> sub_140008B20。
使用快照遍历进程获取进程的md5值与原有的md5值进行判断,当存在指定进程时则退出程序,这里可以判断为反调试。

反反调试方案:patch掉exit函数即可。
md5加密算法的识别
md5加密的两个特征:
- 加密后的字符是32位。
- 在md5函数中有查表相关的操作。

md5对比值

据此可以判断其为md5算法。
这里为线程启动函数中的第二个函数,里面全部都是进行反调试的代码,除了调用常见的IsDebuggerPresent
和CheckRemoteDebuggerPresent
来进行反调试,还调用了TLS解密后的函数NtQueryInformationProcess
和ZwQueryInformationThread
来进行DebugPort调试端口的判断。

反反调试:直接patch掉这个函数即可。
顺利进入到main函数,开始下一步的分析,进入sub_140009C20
函数中。
可以看到为全局变量qword_140016178
,qword_140016180
申请堆空间的操作。
跟进其中的sub_1400086C0
函数内,发现了疑似函数参数内有编号0x10001~0x10003。

依次跟进这些函数中。

这里跟进函数中的虚表的第二项可以看到对应的虚函数的地址。

跳到对应的函数地址sub_14000a8a0
去查看,发现有对原有数据进行异或的操作。

跟进去byte_1400111A0
可以看到,其为一大段数据,长度为19456,这里可能藏有一个文件。

继续分析剩下的两个sub_140008370
、sub_1400083F0
发现其结构与sub_14000a8a0
中一致,找到虚表中的虚函数地址依次跟进去。


发现其都对byte_1400111A0
数组内的数据进行了变换的操作,同时由于if判断条件的不同,各对其中的一部分数据做变换,猜测其可能为解密的函数,并与之前传入的ID可能有所关联。
退出去sub_1400086C0
函数,回到sub_140009C20
中,接着往下分析。
可以看到创建事件对象的操作,结合上述解密函数里有SetEvent设置事件对象的操作,猜测这里是为了防止重复对数据进行变换。

接着往下跟进sub_140008850
,可以看到这里获取函数地址的操作,而这几个函数的名称是在上面分析过的TLS函数中解密的。

此时第一个函数sub_140009c20分析完毕,再次回到main函数中。
可以看到其有创建线程的操作,跟进其线程启动函数StatAddress中去。

跟进去后,依次对其中的函数来进行分析。

首先进入第一个函数sub_140008B20
中去,进行分析。
[注意]看雪招聘,专注安全领域的专业人才平台!
最后于 2021-3-9 17:14
被flag0编辑
,原因: 有遗漏