刘涛涛的扭曲变化加密

来源:互联网 发布:linux删除一个文件 编辑:程序博客网 时间:2024/05/15 08:28

今天本来打算把国内某视频转换软件写个注册机,锻炼自己,结果弄了一天都不知道这软件怎么回事,也没加密,后来才发现时刘涛涛的扭曲变换加密,果然够变态


网上找的爆破方法,虽说爆破没技术含量,but,这软件爆破也挺难啊


先附上扭曲变换加密的思想:

转载自:http://www.liutaotao.com/nqby.txt


扭曲变换加密作者:刘涛涛 me@liutaotao.com网址:http://liutaotao.com/nqby.txt一,一般来讲,加密就是加壳我们经常考虑,一个可执行文件,怎么样加密才能安全呢?一般用的手段,是加壳。加壳工具的工作原理,就是把可执行文件的代码与数据都进行加密变换,作为数据存放。生成的目标文件入口代码是加壳软件准备好的防跟踪代码。经过漫长的防跟踪代码后,会把原始可执行文件的代码与数据段恢复,然后跳转到原来的入口处,继续运行。这样做的缺点是,不管你的加密多强,防跟踪代码多牛,只要一运行,在内存中就全部恢复了。只要把内存映象dump下来,反汇编一下,就清清楚楚了。甚至有工具可以直接把dump下来的内存映象存为可执行文件。这样加密就彻底失败了。简单加壳是不安全的,这大家都知道了。我们一般把上述简单的加壳方式叫“压缩壳”。所以现在的加壳软件都在上述“压缩壳”的基础上,多做了一些工作,比如:* 防止内存被 dump 。这实际上是不可能做到的。因为Windows操作系统就不是一个安全系统,你怎么可能做到内存不被dump呢?曾有一个壳,我用了多种方法dump都不成功。但最后还是找到了一个方法成功dump了。我这才惊叹dump原来有这么多种方法,真是防不胜防。* 修改文件入口代码。因为一般软件都是用常用的几种编译器编译生成的。如果加壳软件知道你是用什么编译器编的(这很容易),把入口代码破坏掉,用另外一段功能类似的代码替换它。这样dump下来的代码就比较难找到正确的入口,直接被存为一个EXE的可能性就小多了。但还是会被反汇编的。* 还有一些加壳软件,支持对一个或几个重点函数加密。甚至使用了虚拟机。但他们都只能重点加密少数几个函数,不可能把所有函数都加密。而且对这个函数还有很多要求。这可以想象。如果用汇编写一个函数,不加ret它可能连函数结束地址都找不到,怎么可能加密呢******尽管加壳软件可以使用以上多种技术防止被跟踪,分析,还原,但我认为,它们仍然没没摆脱“壳”的这个中心思想。以上的这些技术不过是在“壳”的大前提下所做的一些小的插曲。它仍然是不安全的二,扭曲编译的思想做个比喻。加壳保护就好比是你桌上有宝贝,为了保护它,你在屋外围了一圈铁丝网。只要有人突破了这道铁丝网,进入你的屋子,一眼就看到了桌上的宝贝。这当然不安全。重点函数加密的思想,就好比是,我屋外围了一圈铁丝网,我还把宝贝放进了保险箱里。如果有人突破了铁丝网,进入屋子,一眼就看到了保险箱。虽然保险箱不会被轻易打开,但他如果把保险箱搬走,慢慢分析呢?这也不够安全。最安全的,就是进了屋子,却什么也找不着。没有目标,这才是最让人头疼的。现在的编译器,都是追求生成高效率的运行代码。这些代码的模式基本一成不变。有经验的程序员看反汇编代码简单跟看源码一样,毫无秘密可言。如果我们有一个编译器,它的编译目标不是为了高效,而是为了防止被读懂,那该多好啊!我有C++源码,我能看懂。一旦编译,谁也别想通过反汇编看懂我想做什么,或者很难。遗憾的是,这样的编译器还没有。如果我们自己编一个这样的编译器呢?不现实。工作量太大了。即使是找一个开源的C++编译器来改工作量也不得了。直接做一个会加密的编译器行不通。而一旦编译连接生成EXE后,就只能加壳了。难道就没有办法了吗?我想出一个主意,就是加密编译的中间文件OBJ,输出ASM文件,用ML编译成OBJ,然后再link连接!这个方法有几个好处:* OBJ文件格式相对简单。不象处理C++源文件那么工作量大。* OBJ文件中保留了很多源文件的信息,比如符号名,代码与数据,标号等等。方便加密。这些信息很多在LINK的过程中被丢掉了。所以LINK为EXE后再处理就极不方便了。* 这是一个全新的思想!对代码的加密已经不限于加壳,而是加密每一个函数,每一条指令。再也没有一目了然的汇编了。* 可以很容易设定加密的强度。可以根据需要,对一部分代码轻量级加密,而对另一部分代码重点加密。* 可以嵌套加密。重复使用几种加密变换,无限制地使代码膨胀* 因为是加密OBJ文件,所以不管DLL还是EXE都可顺利加密,驱动程序也可以基于这个思想,我们的加密软件就要出台了!我们暂时叫它扭曲变换器 1.0三,扭曲变换器有了思想,就开始动手编码。原以为OBJ文件格式是有文档的,工程进度应该很快。没想到其中还是有很多内容需要考虑。每每说这是最后一个问题,解决了就没事了,却总是后延。前前后后居然写了差不多半年时间。主要遇到的技术问题:* 汇编器ML会把所有的代码放到一个段中,这是不可以的。CL则通常是一个函数一个段。* 汇编器ML不能生成 COMDAT 段。尽管文档中讲它支持COMMON,但加了这个关键字无效果。* 汇编器ML不支持 WEAKEXTERN* 汇编器ML只支持 defaultlib 这一个 drectve 关键字,其它 export, include 等关键字不支持.总之,CL编译的OBJ其中有很多属性是ML无法生成的。微软的masm真的该升级了。还有一些问题:* 分不清代码与数据。数据段中肯定是数据,但代码段中却有可能不是代码,是数据。这时如果你试图反汇编它,就会出错。* ?????不管怎样,这些问题都一一解决了(别问我怎么做的)。采用的代码扭曲方法:* 用 JMP 把代码打乱。这已经不是什么新鲜的招数了,但它依然有效。* 用 JMP 把多个函数缠绕在一起。这样可以让分析者找不到函数从什么地方开始,到什么地方结束。* 把 call 改掉。破解者对 call 是极敏感的,这举可以让他找不到一个 call。比如,我可以把call sub1     改为:mov eax, offset sub1 + 3push offset @1sub eax, 3jmp eax    @1:* 把 ret 改掉。破解者对 ret 是极敏感的,这举可以让他找不到一个 ret。比如,我可以把ret写作push ecxmov ecx, [esp+4]add esp,8jmp ecx* 改条件跳。条件跳也是极敏感的指令,比如我们可以把        cmp reg1, reg2        jge L_DST         L_NEXT:写作:        push eax        mov eax, reg1        sub eax, reg2        shr eax, 1fh        neg eax        and eax, L2 - L1        add eax, L1        jmp eax    L1:        pop eax        jmp L_DST    L2:        pop eax    L_NEXT: 再看这个,你能看懂是什么意思吗push offset @@L - offset L_3 + 23hjmp L_1L_2:        jz L_3        ret 4L_3:               add dword ptr [esp+4], offset L_3 - 23h        add esp,4         retL_1:call L_2        ...这里出现了call和ret,但又不是一般所期望的那种。这里的call不代表你发现了一个函数调用。这里的ret不代表是一个函数的结束。* 使用堆栈代替寄存器。比如:MOV     EAX, DWORD PTR [ECX+0AD8h]PUSH    EAXMOV     ECX, DWORD PTR [EAX]可以写作:PUSH    EAXPUSH    ECXMOV     EAX, DWORD PTR [ESP]ADD     EAX, 0AD8hMOV     EAX, DWORD PTR [EAX]MOV     DWORD PTR [ESP+04h], EAXPUSH    DWORD PTR [ESP+04h]MOV     EAX, DWORD PTR [ESP]MOV     DWORD PTR [ESP+08h], EAXMOV     EAX, DWORD PTR [ESP]MOV     EAX, DWORD PTR [EAX]MOV     DWORD PTR [ESP+04h], EAXMOV     EAX, DWORD PTR [ESP]MOV     ECX, DWORD PTR [ESP+04h]ADD     ESP, 08h你能看懂吗?很明显,这个变换是不可逆变换。因为它本来使用了哪个寄存器,已经没有办法知道了。* ……还可以想出很多扭曲变换的方法。化繁为简只有一种方法,化简为繁可以有无穷多种方法。还有一些功能:* 在C语言中,使用 #pragma code_seg(".code$curve_NoChange") 来指示后面的代码不做任何加密。因为有时候有些代码含有大量的循环,加密它会严重影响效率。* 在C语言中,使用 #pragma code_seg(".code$curve_Max") 来指示后面的代码重点加密。比如后面是与注册算法相关。现在的扭曲变换器我叫它1.0版,已经非常稳定了。我用它把VC6的库文件LIB都处理了一遍,再用LIB.exe工具写回LIB文件中,我们就有了一套加密后的库。如果用这套库来LINK你的软件,分析者就很难从汇编中找到哪个是printf哪个是strcpy,IDA也无法识别MFC静态链接的库函数了。能把VC6的库都加密一遍不出错,我相信它已经很强壮很稳定了。用它来加密我们做的一个共享软件,就再也没人写出注册机了。去读懂大量的经过以上变换的代码是不可想象的。但还是有人暴破了,真佩服他。我会不断丰富加密方法,让暴破者都放弃。现在的扭曲变换器还只支持VC6使用的COFF格式的OBJ,下一步,要分析一下VS2005的OBJ格式,尽快支持它。我经常喜欢反汇编一下,分析点什么东西。我有不少朋友也经常在做反汇编或破解的工作。我不希望扭曲变换器在网上一公布,被广泛使用。有一天我想分析点什么却无法下手。所以,这软件暂时还不提供下载,也不出售。如果你有一段小程序想测试一下,可以把OBJ发给我,我加密一下给你。如果你有一个商业项目需要安全地加密,也可以谈谈。附上一个为CCG写的crackme,用扭曲变换器加密,带部分源码,供参考。http://liutaotao.com/CrackMe.zipLiuTaoTao2006.7.7


转载自:http://hi.baidu.com/hypkb/item/f53d5064f5dc740ca0cf0f50


爆破某视频转换软件(扭曲变换加密)

无聊的时候,朋友推介给我的,他就说他电脑上除了这个以外都是破解版...一时间就产生极大兴趣.

下来以后,查壳,没壳,然后注册的时候直接弹出一个MessageBox...心想这么简单怎么没人去破解
于是直接bp MessageBoxA,断下来以后开始看代码,发现不对劲
每几行就是一个跳转,每几行就是一个假的RET,都搞不清哪是函数头,哪是函数尾.几乎所有的指令都是[esp+sth]之类的...
然后才知道是刘涛涛的扭曲变换加密...后来经人提醒软件名是WinXXX的都要小心...比如刘涛涛的另一个软件WinMount
更多关于扭曲变换加密请看这里:http://www.liutaotao.com/nqby.txt
刘涛涛原话:我保证,悬赏20万都不会有人逆它!

心想这下子的话,估计下什么Windows API可能都不会轻松,可能断下去以后连函数在哪里返回,甚至看都看花你.于是我就想着从其他方面下手.

然后发现"register"字符串可能是突破口,找了下面三个地方.
00466774 push    0078127C register
004F0A5F push    0078127C register
005F4789 push    0078127C register
由于是扭曲变换加密.所以只要三个都点进去看下里面的代码哪个的比较简单,看不懂就不管他了.:-D(又一个懒招...),看下只有第二个register的比较简单.如下:
004F0A48  |.   FF15 F4A67600 call     dword ptr [<&imagehlp.MapFileAnd>;   imagehlp.MapFileAndCheckSumA
004F0A4E  |.   E8 7AEAFAFF   call    0049F4CD                         ;   (initial cpu selection)
004F0A53  |.  84C0          test    al, al
004F0A55  |.  0F85 BE000000 jnz     004F0B19
004F0A5B  |.  885C24 74     mov      byte ptr [esp+74], bl
004F0A5F  |>  68 7C127800   push    0078127C                         ;   register
imagehlp.MapFileAndCheckSumA看名字就知道是文件效验,跟进去发现了CreateFileA等一系列文件操作的函数就大抵能肯定了
在猜一下call 0049F4CD估计是在检验是不是注册用户的(自己测试一下那个函数在哪个时候被调用也能知道.)

如果想完美爆破的话,我想应该改call 0049F4CD不过你很难知道那函数在哪里返回,之前发现config.ini存放RegName和RegCode跟进去发现跑到了ENVC.dll领空,貌似算法也是在里面的.
而且程序对ENVC.dll有效验的,所以想要完美破解的难度就相当高了.
不过根据我的测试,本软件的唯一限制就是未注册的话在转换后的视频有个水印,嗯 这样子的话,我只要去掉那个水印那不也算是"完美破解"了

料想在我们按下开始转换按钮程序肯定会判断注册否,于是我们在按按钮之前先在call 0049F4CD内下断即:
0049F4CD       81EC 08020000 sub     esp, 208
(当然也可以去bp imagehlp.MapFileAndCheckSumA,结果都一样.)
断下来以后,看堆栈
0012BCB4   004EFBAD     返回到 WinMPGVi.004EFBAD 来自 WinMPGVi.0049F4CD
于是奔去004EFBAD处
004EFBA2   .   FF15 F4A67600 call     dword ptr [<&imagehlp.MapFileAnd>;   imagehlp.MapFileAndCheckSumA
004EFBA8   .   E8 20F9FAFF   call    0049F4CD                         ;   (initial cpu selection)
...
004EFBAF   .  75 6E         jnz      short 004EFC1F
...
004EFC1E   .   C3            retn
...
004EFC30   .  74 0B         je       short 004EFC3D
中间的那个retn相当于jmp,扭曲变换加密里面这种伪retn随处可见...
未注册的话retn会直接跳走,那我们只要不让他跳就可以了,于是把往回跳的je short 004EFC3D直接nop掉.
测试一下OK.水印去除.

后来发现其他几次判断注册的地方也可以这样子爆破掉,只不过意义不大,没有改变到他的功能,经过这次经验我深深体会到扭曲变换加密的强大之处,写起来只有这么点,其中历经多少艰辛坎坷我就不说了,呵呵


原创粉丝点击