【中级篇】多线程混淆技术的原理与实现


风晓
风晓 2023-12-31 11:17:52 54441
分类专栏: 资讯

引言

多线程混淆是一种让软件具备不确定性的一种反分析方法,它主要是利用了操作系统时间分片和多线程机制,由于线程间共享程序内存,每个线程的不同仅在于寄存器、堆栈以及线程局部存储(TLS),因此可以让一个线程替另一个线程执行任务。举例而言,假设A、B两个线程,A线程需要执行一个函数,函数功能是进书房随机取一本书,函数返回这本书的指针。如果用线程B替换线程A,那么可以这样设计。首先线程A进入函数,然后告诉线程B,我进来了,线程B让线程A等待,然后线程B替线程A取书,然后交给线程A,线程A拿到书后继续执行,线程B则空转等待。

意义

前面绕一个大弯,让一个线程替代另一个线程去执行一段代码,这样做有什么意义呢?单纯从执行效率上讲当然是没有任何意义的,而且会带来很多开销,但是站在软件保护的角度上看就非常有意义了,下面分别站在A线程和B线程的角度进行具体分析。

  • 对于A线程来说,它不需要管哪个线程具体负责执行,A甚至不需要知道这个函数干了些什么,它只需要等返回结果,这种功能分离的机制非常类似于基于网络的软件保护方法。就是我将输入给你,然后等待返回结果,把中间过程看成是一个黑盒子。
  • 对B线程而言,其执行可以具有不确定性,前面用B线程代替了A线程的执行,这是最简单的一个例子。但如果B不是一个线程,而是一个线程池呢,每次A进入到函数时就从线程池中随机取一个空闲的线程作为执行线程,则每次的执行线程是不确定的,调试器难以自动跟踪随机选取的线程。

运行时多态性

实际上多线程混淆技术的核心思想就是使软件具备运行时的多态性。简单解释何为运行时多态性,首先解释何为多态性。多态性是软件保护的一种机制,常用于恶意软件的自我保护中,恶意软件通过将自己的代码改变,但是又保持原有功能完全不变,从而改变自身的某些特征以躲避杀毒软件的查杀。可见多态性就是软件对自己进行等价变形,但传统的多态性是静态的,软件执行后在内存中并不会随着运行的过程而自我变形,一般软件是执行开始阶段或程序关闭前,才会重新生成新的“变形”程序。而运行时多态性是指软件在运行的过程中可以自我变形或可以实现路径多态性。

软件运行时多态性可以通过多线程混淆来实现(当然还有其它的方法,本文不展开)。由于线程数可以任意指定,执行线程可以随机选取,理论上当有块代码和个执行线程时,路径的可能性共有为��种。

具体实现

由于实现细节有些繁琐,这里仅给出代码流程。多线程混淆的思想是比较容易理解的,我们将多态性中用来具体执行的线程记为工作线程,而原线程记为用户线程,则具体可以分8步。

  1. 用户线程将必要信息告诉工作线程调度器,具体而言需要将所有寄存器和执行代码的起始位置保存到栈,同时需要讲此时的栈顶位置即esp的值,自己的线程Handle告诉工作线程调度器,然后自己进行空循环,等待操作系统切换线程;
  2. 工作线程调度器分配一个空闲的工作线程,并将用户线程传来的信息告诉该线程;
  3. 工作线程首先根据Handle暂停用户线程,防止自己在执行的过程中改变了堆栈会影响用户线程的执行;
  4. 工作线程保存自己原来的状态,即将所有寄存器的值入栈,保存自己的esp的位置。接着根据用户线程传来的esp,将自己的栈切换到目标栈的位置,然后根据用户线程保存在栈中的寄存器的值,将自己的寄存器的值设置为跟用户线程完全相同;
  5. 工作线程跟踪栈中保存的执行代码起始位置,跳转到该处开始执行;
  6. 工作线程执行完毕后保存所有寄存器到栈,并切换回自己的栈;
  7. 工作线程恢复用户线程的执行;
  8. 用户线程根据工作线程保存在栈中的寄存器将自己的寄存器的状态更新,然后继续往后执行。

小结与展望

前面提到了用多个线程替待一个线程的执行,工作线程执行完毕后最终还会返回到用户线程,这种策略是替身机制,其实还有其它的策略,比如用多线程完全取代一个线程,即工作线程执行完后不返回用户线程而且继续往前执行,或者将用户线程也纳入到线程池中,这种策略类似于接力跑。

代码运行时多态性的思想是软件保护研究的前沿领域,其本质和核心是为了增加了程序的复杂度,当程序的复杂度高到现有硬件条件无法遍历分析时,保护就算取得了成效。传统的静态混淆技术难以抵抗动态分析,静态混淆是预置了很多混淆项,但这些预置的混淆代码具有固定的控制流,不可能在量级上提高程序的复杂度。而传统的动态混淆技术又仅做了程序的动态加解密。无论是自生成代码技术还是自修改代码技术,很多论文中仅提到了将明文窗口大小减小,比如采用更细粒度的分片方式等,或者让明文窗口的时间缩短,比如加入冲突锁定,一旦代码冲突解锁则立即释放明文代码。这些传统的动态混淆思路距离真正的混淆还有很远的距离。

代码执行时多态性才是真正的解决途径,如果采用接力跑机制,对于每一个线程而言,其执行的代码都是不确定的,其调度是由操作系统指定的,具有不可预料性。最重要的是,由于其多样化程度可以指数级上升,因此可以用较少的代价换取较高的复杂度。

网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。

本文链接:https://www.xckfsq.com/news/show.html?id=33219
赞同 0
评论 0 条
风晓L1
粉丝 1 发表 522 + 关注 私信
上周热门
WPS City Talk · 校招西安站来了!  3767
服贸会|范渊荣获年度创新领军人物!王欣分享安恒信息“AI+安全”探索  3693
有在找工作的IT人吗?  3655
字节跳动“安全范儿”高校挑战赛来袭!三大赛道,赢 80 万专项基金!  3615
阿B秋招线下宣讲行程来啦,速速报名!  3609
字节跳动校招 | 电商业务 2025 校园招聘进行中!五大职类热招,等你来投!  3601
麒麟天御安全域管平台升级!为企业管理保驾护航  3585
烽火通信2025届校园招聘宣讲行程发布!!  3421
2024海洋能源产业融合发展论坛暨博览会同期活动-海洋能源与数字化智能化论坛成功举办  3382
华为全联接大会2024丨软通动力分论坛精彩议程抢先看!  3356
本周热议
我的信创开放社区兼职赚钱历程 40
今天你签到了吗? 27
如何玩转信创开放社区—从小白进阶到专家 15
信创开放社区邀请他人注册的具体步骤如下 15
方德桌面操作系统 14
我有15积分有什么用? 13
用抖音玩法闯信创开放社区——用平台宣传企业产品服务 13
如何让你先人一步获得悬赏问题信息?(创作者必看) 12
2024中国信创产业发展大会暨中国信息科技创新与应用博览会 9
中央国家机关政府采购中心:应当将CPU、操作系统符合安全可靠测评要求纳入采购需求 8

加入交流群

请使用微信扫一扫!