原创 菜农的加密理论---天下无贼论

2007-11-15 19:41 5346 4 4 分类: MCU/ 嵌入式

讨论继续在: http://bbs.21ic.com/club/bbs/ShowAnnounce.asp?id=2754150 


      菜农的加密理论---天下无贼论



1.版权信息的保存
虽然芯片被解密而能够得到BIN及HEX格式的文件,但产品的版权信息
并未被篡改。


这个信息被明文或密文读出后会通过一定途径发布出去。
那么解密芯片者必须再进行逆向工程来掩盖他们不光彩的事实。
所以保护产品的版权信息可能最为重要。


2.程序入口的保护
在逆向工程,最终要做到真正的代码和数据的分离工作。
其首要解决的就是如何找到正确的程序入口地址,然后在进行二次扫描
等基础工作。
当扫描程序遇到分支后,必然要做出正确的判断。
其一路分支继续往后扫描,另一路分支将记录分支的入口地址的分支状态
以便为二(多)次扫描做出前期的准备工作。


分支状态对于51来讲可简化用扫描次数及位置号来替代。
即 0--从未扫描到过 最后生成为数据。例 DB 55H
   1--操作码
   2--操作数1
   3--操作数2
   4--待定入口(入口进待扫描队列)


每次扫描的选择入口地址的分支状态必须为0。否则本次扫描失败!
直到遇到LJMP/AJMP/SJMP/JMP @DPTR/RET/RETI停止本次扫描


依此类推。直到全部扫描结束。


分析以上的扫描原理及步骤,我们可以造假一些数据或代码使其1次或二次
扫描终止,最后迫使其采用强行(不按以上规则)扫描,从而得不出人能看懂
的汇编代码。


3.程序出口的保护
当全部扫描工作结束后,代码和数据将会自然分离。
由于扫描规则的约束,数据中也会包含一些代码。
例如源程序中从未调用过的子程序的“泄露代码”。


他们一般以RET/RETI结束,以PUSH XXX开始。故很容易将泄露代码逆向出来。
从而找出原作者没调用或没成型的方法。


4.CRC变量位置和CRC运算子程序保护
要想实现以上3种保护,必须防止逆向者篡改版权信息,代码入口地址及相应
的出入口保护的代码不被其强行改写或用NOP,DB 00H等填充,以便达到最终
逆向成功的目的。


由于MCU资源和时间速度等限制,应该采用简洁而枯燥乏味的代码组合。常见
的有累加/异或/移位等算法。


累加和异或是基于单(多)字节操作的,而移位是基于单个位操作的。


故要枯燥乏味肯定要数移位更胜任了,所以常用CRC运算。


CRC运算有正运算和逆运算(菜农没看过相应报道和文章)之分,也有左右移位
之别。更有变化无测的“权”(菜农想不了起什么好听的名字)


分析和论述到此,上述4点本人认为比较重要。


现在举2个实际例子说明如何保护代码和数据不被逆向为汇编助记符。


例1 如何保护版本信息
;------------------------------------------------------------------------------;
;   版本信息区
;------------------------------------------------------------------------------;
 DB    02H;伪造LJMP指令
;------------------------------------------------------------------------------;
;大家可以试试修改下面任意数据的结果~~~
;------------------------------------------------------------------------------;
HotPowerMessage:;敌人找看不见HotPowerMessage入口地址但能知道~~~
 DB    "HotPower@126.com 2007.11.13";CRC8结果为0xc5
 DB    0C5H;以上版本信息区字符串的CRC8结果,这样可以保证全局变量CRC永远为0!!!
 DB    0;版本信息区结尾标志
;------------------------------------------------------------------------------;
程序祥见:阻止反汇编软件汇编演示程序(天下无贼版),当然这还只是个入门之类的提高版


假设版本信息区为字符串"HotPower@126.com 2007.11.13",那么其右移CRC8运算后结果为0C5H
如果我们再以0C5H做一次运算后,CRC的结果必为0!!!!!!!!!!!!!!!!!


为什么我们还要不辞劳苦地再进行一次CRC运算呢???为什么很多软件被轻易解码呢???


道理就在这里面!!!


如果逆向者找到相应的条件分支语句中包含比较05CH的信息,那么这个程序不攻自破!!!


举个我1分钟就逆向的一个例子:
有个PC软件和PC并口0x378通信,但俺的并口地址为0x3bc.故它不支持俺。要求对方改成可选地址的。
回复是忘了,即使改也要收费即3天左右。


晕!!不就是将78 03改为bc 03吗???


俺用UE搜索整个EXE文件就只有3个地方有。几次实验通过了。


所以重要信息不要留给逆向者空子!!!


当然所谓“艺高人胆大”,你明码给他版本信息,他“汉化”后程序用不成就知道遇到对手了。
他会坐下来与你较量。


所以CRC运算后千万不敢立即做出处理!!!而要像病毒一样随后爆发,这会使他更难受的。且记!!!


例2 如何保护代码出口(RET/RETI)


;---------------------------------------------------------------------;
;   出口保护代码
;---------------------------------------------------------------------;
COMMAND0_EXIT:
 MOV   A,CRC;因为信息没修改CRC就为0,修改程序就就飞~~~哈哈,看你晕不晕
 JZ    $+3;肯定运行NOP;RETI
 DB    12H;CRC校验和,伪装的LCALL指令
 DB    00H;结尾符实际为NOP指令
;用RETI迷惑反汇编,以为是某个中断服务程序
 RETI;返回到MAINLOOP


菜农一生发表和隐藏的一些自已都认为是臭美的方法和独到见解,都包含着运气的成分。
当然这也和辛勤耕作有很大关系,回报也是很自然的事。


拿这个CRC的地址来说吧,我随手将他定义在30H处,根本没多想。应该这是51人最开始想的地方。
他们绝不会想20H~2FH这奢侈的地方,所以30H自然作为首选。


开始编程时是这样写的:
COMMAND0_EXIT:
 MOV   A,CRC;因为信息没修改CRC就为0,修改程序就就飞~~~哈哈,看你晕不晕
 JZ    $+3;肯定运行NOP;RETI
 DW    1200H
;用RETI迷惑反汇编,以为是某个中断服务程序
 RETI;返回到MAINLOOP
 DB    00H;待计算CRC校验和,伪装的LCALL指令
 DB    00H;结尾符实际为NOP指令


写完后才发现前面已经有00H结尾符,故改为
COMMAND0_EXIT:
 MOV   A,CRC;因为信息没修改CRC就为0,修改程序就就飞~~~哈哈,看你晕不晕
 JZ    $+3;肯定运行NOP;RETI
 DB    00H;待计算CRC校验和,伪装的LCALL指令
 DB    00H;结尾符实际为NOP指令
;用RETI迷惑反汇编,以为是某个中断服务程序
 RETI;返回到MAINLOOP



 MOV   A,CRC;因为信息没修改CRC就为0,修改程序就就飞~~~哈哈,看你晕不晕
 JZ    $+3;肯定运行NOP;RETI
两句进行CRC运算后惊奇地发现---苍天呀,是我需要的12H!!!!!!!!!!


故就成了最终的程序:
COMMAND0_EXIT:
 MOV   A,CRC;因为信息没修改CRC就为0,修改程序就就飞~~~哈哈,看你晕不晕
 JZ    $+3;肯定运行NOP;RETI
 DB    12H;已计算出上2句的CRC校验和值,伪装的LCALL指令
 DB    00H;结尾符实际为NOP指令
;用RETI迷惑反汇编,以为是某个中断服务程序
 RETI;返回到MAINLOOP


原因:当初CRC这个全局变量位置在30H才导致了这个神仙想要得到的结果之一(还有02H)



至于为什么要有这些保护及它的作用,为了不晕到一大片观众,就到这里吧。


菜农被21IC的程序匠人双规并令俺面壁思过逼交脑浆之作,俺无奈献出本文。


望大家不晕~~~先到这里,以后再提高提高~~~


雁塔山野村夫  菜农HotPower  
                           2007.11.15 思过于西安大雁塔菜地.


 


点击下载: 阻止反汇编软件汇编演示程序(天下无贼版)压缩包


rar

文章评论0条评论)

登录后参与讨论
我要评论
0
4
关闭 站长推荐上一条 /2 下一条