论SMC的实现(1) -- 基础实现手法&&坑点规避 (转下一篇)

环境配置:Visual Studio 2019 关闭动态基址,打开固定基址,关闭全程序优化,优化级别OD,关闭SDL检查,全段可读可写可执行,发布版本为Release。

SMC(Self Modifying Code) 即动态代码加密技术
简单的来说,就是对我们代码的一段关键代码进行加密,并在程序运行到这段代码之前进行解密。 这么做的目的是对我们的一些核心代码进行保护,避免被检测出来或者别人静态的分析。而常规的SMC手法大致有以下两种:
①获取到关键代码的机器码,将其放入我们的一个数组里,运行时执行代码。(类shellcode)
②程序编译后,使用工具定位到关键代码处,编写脚本进行加密。再执行时就是解密执行了。(程序本身已经写好对关键代码处的解密)

这里的实现方式①通常是对函数进行处理。因为程序要将数组里的数据作为代码执行的话,比较常规的思路有:使用VirtualAlloc或者VirtualPortect函数为这段数据分配内存空间,或者修改保护属性,使其可执行后,为其定义一个函数指针,再到程序里通过解密后函数指针的方式进行调用。
不过该方式需要注意
(1). 确保原函数被编译的时候没有采取随机基址,这一点非常重要。我的开发环境是vs2019,而在vs下不仅得关闭随机基址,还得把固定基址那一栏得开起来,不然地址有的时候也会有问题。(项目属性->连接器->高级)
(2). 函数指针的写法对刚开始写的py门可能需要琢磨好一会,这里推荐使用网络上一些现成的例子。不过我这里的例子会在第二篇写,进度快的同学可以百度如 “VirtualAlloc/VirtualProtct执行shellcode”
(3).我们要想获取具备一些功能的机器码其实不用像写shellcode那样硬抠,这里我们完全可以写一个带有这个函数的程序,然后使用ida打开,用如idapy或idc脚本来输出这个函数。(脚本同样也会在第二篇提到,等不及的同学可以自行学习一下ida脚本的写法,博主个人比较推荐使用idapython)
而又或者,使其对应内存区域可执行后,通过内联汇编的方式,解密后jmp跳转或call到该区域,从而实现加密函数的调用。
这个手法在这几种里相对来说有点花里胡哨。不过可以不用在意函数指针的那种,可能对新人不太友好的调用方式。此处的坑点在于,我们扒下来的这段代码需要和我们的内联汇编严丝合缝的匹配在一起。比如如果我们的这段代码是一个函数的话,我们得使用call函数去调用,并且如果有参数还得使用push传参进去。而就算是很正常的一段代码,我们也需要注意下是否有可能会对栈进行破坏。不过这一点倒是不常出现。

而实现方式①的好处其实和shellcode是一个道理。我们可以十分方便的迁移我们的核心代码,甚至你代码写得好的话,它就是一段shellcode。理论上极其灵活
不过也还有需要注意的点:(1)我们的代码不能涉及到全局数组的调用。(2)我们的代码不能有如多个函数的左右调用。前者涉及到地址的问题(除非你干脆把那一大段机器码全搬过来了),后者则涉及到地址,栈的问题。

那么下一篇我们就结合实例来讲一下

你可能感兴趣的:(逆向工程,汇编语言,程序career,安全)