矛与盾的较量(1)——花指令

原创 2002年08月28日 08:57:00
有矛就有盾。
所以我们要讨论加密技术。

我们知道,所有的编译型语言,例如VC、BCB、Delphi和Win32ASM……最终都会把源代码编译成机器能识别的0和1——因此也能够反过来把这些0和1反编译成汇编代码。反编译有什么用呢?试想想,你辛辛苦苦写了一个perfect的软件出来,正准备把它卖上100万份,忽然!在市面上出现了很多仿制你的东西……hoho,不知道你会怎么想呢?反正我是会欲哭无泪的。还有另外一种情况,你的软件是用注册码的形式来授权的,每份license要卖30个美刀。呵呵,正当你在考虑着一年后是去加利福尼亚还是夏威夷度假的时候,你的软件被Crack了——也就是说,你一分钱都不会得到……(啊!我想跳楼啦!!)

所以我们要讨论如何给自己的程序加密。这次就先说说最简单的花指令。

在解释这个“花指令”之前,不妨先做几个小小的实验。

我们先来写一个程序,命名为hua.asm,内容如下:

;***************************************************************
;花指令实验1
;作者:罗聪
;日期:2002-8-21
;***************************************************************
.386
.model flat, stdcall
option casemap:none

include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
include /masm32/include/user32.inc
includelib /masm32/lib/kernel32.lib
includelib /masm32/lib/user32.lib

.data
szText        db    "嘿嘿,这是一个花指令程序……", 0
szCaption    db    "花指令演示 by LC 2002-8-21", 0

.code
main:
    jmp Do_It
Do_It:
    invoke MessageBox, NULL, addr szText, addr szCaption, MB_OK
    invoke ExitProcess, 0
end main


然后用W32Dasm v10来反编译它,得到的结果如下:(由于篇幅所限,这里只列出关键部分)


+++++++++++++++++++ ASSEMBLY CODE LISTING ++++++++++++++++++
//********************** Start of Code in Object .text **************
Program Entry Point = 00401000 (hua.exe File Offset:00001600)



//******************** Program Entry Point ********
:00401000 EB00                    jmp 00401002

* Referenced by a (U)nconditional or ?onditional Jump at Address:
|:00401000(U)
|
:00401002 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"花指令演示 by LC 2002-8-21"
                                  |
:00401004 681F304000              push 0040301F

* Possible StringData Ref from Data Obj ->"嘿嘿,这是一个花指令程序……"
                                  |
:00401009 6800304000              push 00403000
:0040100E 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BBh
                                  |
:00401010 E80D000000              Call 00401022
:00401015 6A00                    push 00000000

* Reference To: KERNEL32.ExitProcess, Ord:0075h
                                  |
:00401017 E800000000              Call 0040101C


哇,好夸张啊!你可能会说。反编译出来的代码几乎是跟源代码一一对应的,这样一来?我们的程序还有什么秘密可言呢?完全可以从反编译的结果中理解程序的功能。

而且我们还可以在W32Dasm的“String Data References”中得到:
"嘿嘿,这个是一个花指令程序……"
"花指令演示 by LC 2002-8-21"


把刚才的源程序稍做修改,来做第二个实验:


;***************************************************************
;花指令实验2
;作者:罗聪
;日期:2002-8-21
;***************************************************************
.386
.model flat, stdcall
option casemap:none

include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
include /masm32/include/user32.inc
includelib /masm32/lib/kernel32.lib
includelib /masm32/lib/user32.lib

.data
szText        db    "嘿嘿,这是一个花指令程序……", 0
szCaption    db    "花指令演示 by LC 2002-8-21", 0

.code
main:
    jz Do_It    ;注意这里和第一个实验中的源程序的区别
    jnz Do_It    ;注意这里和第一个实验中的源程序的区别
Do_It:
    invoke MessageBox, NULL, addr szText, addr szCaption, MB_OK
end main


用W32Dasm反编译一下:

+++++++++++++++++++ ASSEMBLY CODE LISTING ++++++++++++++++++
//********************** Start of Code in Object .text **************
Program Entry Point = 00401000 (hua.exe File Offset:00001600)



//******************** Program Entry Point ********
:00401000 7402                    je 00401004
:00401002 7500                    jne 00401004

* Referenced by a (U)nconditional or ?onditional Jump at Addresses:
|:00401000?, :00401002?
|
:00401004 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"花指令演示 by LC 2002-8-21"
                                  |
:00401006 681F304000              push 0040301F

* Possible StringData Ref from Data Obj ->"嘿嘿,这是一个花指令程序……"
                                  |
:0040100B 6800304000              push 00403000
:00401010 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BBh
                                  |
:00401012 E801000000              Call 00401018


可以看出,这时的W32Dasm反编译出来的汇编指令还是正确的。但是W32Dasm其实已经逐渐落入我们设下的“陷阱”了。

下面我们来做第三个实验,把源程序改成:

;***************************************************************
;花指令实验3
;作者:罗聪
;日期:2002-8-21
;***************************************************************
.386
.model flat, stdcall
option casemap:none

include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
include /masm32/include/user32.inc
includelib /masm32/lib/kernel32.lib
includelib /masm32/lib/user32.lib

.data
szText        db    "嘿嘿,这是一个花指令程序……", 0
szCaption    db    "花指令演示 by LC 2002-8-21", 0

.code
main:
    jz Do_It    ;注意这里和第一个实验中的源程序的区别
    jnz Do_It    ;注意这里和第一个实验中的源程序的区别
    db 0E8h        ;注意这里和第二个实验中的源程序的区别
Do_It:
    invoke MessageBox, NULL, addr szText, addr szCaption, MB_OK
    invoke ExitProcess, 0
end main


我们来看看W32Dasm中反编译出来的东西:

+++++++++++++++++++ ASSEMBLY CODE LISTING ++++++++++++++++++
//********************** Start of Code in Object .text **************
Program Entry Point = 00401000 (hua.exe File Offset:00001600)



//******************** Program Entry Point ********
:00401000 7403                    je 00401005
:00401002 7501                    jne 00401005
:00401004 E86A00681D              call 1DA81073
:00401009 304000                  xor byte ptr [eax+00], al

* Possible StringData Ref from Data Obj ->"嘿嘿,这是一个花指令程序……"
                                  |
:0040100C 6800304000              push 00403000
:00401011 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BBh
                                  |
:00401013 E80E000000              Call 00401026
:00401018 6A00                    push 00000000

* Reference To: KERNEL32.ExitProcess, Ord:0075h
                                  |
:0040101A E801000000              Call 00401020


呵呵,很明显了,这时的 00401004 到 00401009 行出错了,而且这时查看“String Data References”,也只剩下了:
"嘿嘿,这是一个花指令程序……"


让我们进一步隐藏信息,做第四个实验:

;***************************************************************
;花指令实验4
;作者:罗聪
;日期:2002-8-21
;***************************************************************
.386
.model flat, stdcall
option casemap:none

include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
include /masm32/include/user32.inc
includelib /masm32/lib/kernel32.lib
includelib /masm32/lib/user32.lib

.data
szText        db    "嘿嘿,这是一个花指令程序……", 0
szCaption    db    "花指令演示 by LC 2002-8-21", 0

.code
main:
    jz Do_It    ;注意这里和第一个实验中的源程序的区别
    jnz Do_It    ;注意这里和第一个实验中的源程序的区别
    db 0E8h        ;注意这里和第二个实验中的源程序的区别
Do_It:
    lea eax, szText        ;注意这里和第三个实验中的源程序的区别
    lea ebx, szCaption    ;注意这里和第三个实验中的源程序的区别
    invoke MessageBox, NULL, eax, ebx, MB_OK    ;注意这里和第三个实验中的源程序的区别
    invoke ExitProcess, 0
end main


编译,再用W32Dasm反编译,得到的是:

+++++++++++++++++++ ASSEMBLY CODE LISTING ++++++++++++++++++
//********************** Start of Code in Object .text **************
Program Entry Point = 00401000 (hua.exe File Offset:00001600)



//******************** Program Entry Point ********
:00401000 7403                    je 00401005
:00401002 7501                    jne 00401005
:00401004 E88D050030              call 30401596
:00401009 40                      inc eax
:0040100A 008D1D1D3040            add byte ptr [ebp+40301D1D], cl
:00401010 006A00                  add byte ptr [edx+00], ch
:00401013 53                      push ebx
:00401014 50                      push eax
:00401015 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BBh
                                  |
:00401017 E80E000000              Call 0040102A
:0040101C 6A00                    push 00000000

* Reference To: KERNEL32.ExitProcess, Ord:0075h
                                  |
:0040101E E801000000              Call 00401024



呵呵,这次不但面目全非了,而且“String Data References”按钮已经变成了灰色。什么蛛丝马迹都没有了。

各位看官看到这里明白了吗?其实花指令就是人为地构造一些“陷阱”和一些无用的字节。例如第二个实验中的:

jz Do_It
jnz Do_It

其实这个跟 jmp Do_It 还不是一样吗?(呵呵,如果在大学的期末考试里这样写,一定会被判不及格……)

是的,其实程序原有的功能和逻辑还是一样的,我们只不过是换了一种表现形式而已。然而,反编译工具是没有人脑那么智能的,它们往往就会把这些指令理解错,从而错误地确定了指令的起始位置。

要实现这种绝对跳转的功能,还可以用很多的方法,例如:

Push Do_It
ret


花指令是很容易理解的,不过大家要注意适时而用,不要滥用啊,能起到迷惑破解者和隐藏信息的作用就行了,不然将来要维护代码时,我怕被迷惑的反而是你自己哦,呵呵……

 

(文章来源 & 更多我的原创文章:http://laoluoc.yeah.net

失业的程序员(十四):兄和弟,矛和盾

先说明一下,延迟在csdn发这个系列的原因吧,希望各位亲能够谅解  1、  前段时间发现有若干SEO做的“很不错”的无良网站和冒牌网站,每周二待我在csdn一更新后立马转载,几乎是同步的2、转载也就算...
  • shenyisyn
  • shenyisyn
  • 2013年06月14日 15:17
  • 9487

矛与盾

我的世界里充满了矛盾。早上出门,仔仔细细锁好了两扇门,然后出去,看见那只奶牛猫守在楼梯口等我。看见我,它惨叫,真的是从喉咙深处发出的惨叫。走到它的窝旁边,没有水,没有吃的,什么也没有。蹲在那里愣了半天...
  • unimoon
  • unimoon
  • 2005年11月30日 21:55
  • 1239

矛与盾的较量(2)——CRC原理篇

下载本节例子程序 (4.29 KB)(特别感谢汇编高手 dREAMtHEATER 对我的代码作出了相当好的优化!请参观他的主页)上一节我们介绍了花指令,不过花指令毕竟是一种很简单的东西,基本上入了门的...
  • itaolu
  • itaolu
  • 2002年09月02日 09:05
  • 2322

矛与盾:二进制漏洞攻防思想对抗

原文   http://www.freebuf.com/articles/system/127207.htm l 0×0二进制漏洞 二进制漏洞是可执行文件(PE、ELF文件等)因编...
  • a627088424
  • a627088424
  • 2017年02月24日 15:29
  • 547

矛与盾的较量(4)——奇妙的Base64编码

各位看官应该都是资深的网虫了,小弟斗胆在此问问大家,平时上网时,除了泡MM、到论坛灌水、扔版砖……之外,进行的最多的是什么活动?对了,你一定会说:是收发电子邮件!(谁敢说自己没收/发过电子邮件的?拉出...
  • jbgtwang
  • jbgtwang
  • 2008年12月09日 17:18
  • 391

矛~盾

我是一个矛盾的人。          眼看着毕业典礼即将落成,身份再也不是大学生。在校的时候无时无刻不期待自己能够经济独立人格独立,真正有一份工作开始努力赚薪水的时候又无比怀念念书的时候。眼看着人...
  • languobeibei
  • languobeibei
  • 2016年06月30日 17:40
  • 213

索尼爱立信的矛与盾

    它曾凭借中高端策略从全球市场第20位蹿升至第4位,  但现在因为这一战略而停滞不前。  文|CBN记者 刘长江 2008年07月17日13:49   吴佩玲终于感到轻松了一些。作为戴德...
  • liuxk99
  • liuxk99
  • 2008年07月23日 19:35
  • 519

论【IT需求】中的矛与盾

SELECT MAX(需求) AS 真正的需求 FROM 需求表 WHERE 1=1 GROUP BY 客户,购买者,管理者,投资者,使用者,咨询人员,项目经理,开发人员 --ORDER BY...
  • u010192842
  • u010192842
  • 2013年11月19日 11:33
  • 851

矛和盾

说真的 我现在还年轻 想多学点 但是又不知道学什么好 我是一中专生 毕业了 很喜欢电脑 我想更多的了解他 但是我没有什么人教 自学时间太长 我家庭不太富裕 但也能吃饱 长时间在家坐着也不是个事 不知道...
  • asd456asd456789
  • asd456asd456789
  • 2010年12月19日 23:38
  • 72

蓝桥杯——说好的进阶之砝码称重(贪心算法)

5个砝码 用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量。 如果只有5个砝码,重量分别是1,3,9,27,81。则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两个盘中)。...
  • hymanxq
  • hymanxq
  • 2014年05月10日 07:34
  • 4323
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:矛与盾的较量(1)——花指令
举报原因:
原因补充:

(最多只允许输入30个字)