首页
社区
课程
招聘
[求助]程序容易被爆破的原因是什么?
发表于: 2008-12-13 14:53 4484

[求助]程序容易被爆破的原因是什么?

2008-12-13 14:53
4484
我刚刚学破解,有一些想法请大家帮解答。

我发现有的程序很容易找到关键跳,然后就被爆破了;

可是有的程序却找不到关键跳,想爆破都不行。

为何有的好爆破,有的却爆破不了,

请问这两种程序的区别在哪里啊?

如果以后自己编程序,如何才能避免被爆破呢?

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 415
活跃值: (34)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
最简单的办法程序里面多处验证
2008-12-13 15:11
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
3
爆破,说白了就是你的判断逻辑太简单,比如if()...else...,或者类似的。

这样的逻辑,只要将你的 if 逻辑改成 if not逻辑,或者干脆改成if (true)就是通常所说的破解。

如果不使用这种简单的程序逻辑结构,比如用数据驱动代替条件判断。最简单的比如C++的运行时多态,或者退化到C的跳转表或函数指针表。

完全防爆破的方法是不存在的。但是,多一个if逻辑,就多一份爆破的可能。虽然即使不用if,也是可能爆破的,但“jmp [eax*4+0xXXXXXXXX]”的方式总比“cmp eax,1 \ je 0xXXXXXXXX”的代码隐蔽性更强一些的。

以上是从编程方面说的,再加上其它一些ANTI的方法或扰乱的方法,比如SEH,动态解码指令,或者加保护壳等,可以大大增加跟踪的难度,至少会让那些只会查找“字符串”,只会修改“关键跳”的新手望而却步了。
2008-12-13 19:08
0
雪    币: 27
活跃值: (127)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
4
你说得很好啊,看来以后还要多多学习。

还想问一个,你说到的“C的跳转表或函数指针表”,是什么意思啊。

在C语言中好像没听过这些词语,能指点下吗?
2008-12-13 21:27
0
雪    币: 27
活跃值: (127)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
5
哦,我在网上找到这方面的内容了。

谢谢你给我的启发。
2008-12-13 21:40
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
6
我说得也不准确,跳转表在汇编语言中程序员是可控制在,在C中跳转表通常是编译器优化的结果。

但函数指针表,则是C程序员可以控制的东西。实际上在C++中的运行时多态,就是基于函数表的原理,只不过是从另一个角度抽象了,被叫做vTable了。

举个例子:

void    DoRealWork(void*p)
{
    //这个函数是注册版本的
}

void    DoTrialWork(void*p)
{
    //这个函数演示版本的
}

void    DoNothing(void*p)
{
    //这个函数是什么都不做的,比如试用期过了等等。
}

typedef void (*function_ptr)(void*);

functin_ptr    theFunctions[16]=
{
&DoRealWork,
&ExitProcess,
NULL,
&ExitProcess,
NULL,
&DoNothing,
&DoNothing,
...
};

这样,你设计一个算法,将日期、用名、注册码进行一定的处理,结果返回一个整数值。然后用这个值去索引函数表,并调用,类似这样:

void DoWork(void*p)
{
    functin_ptr f = theFunctions[ CheckRegistInfo( name, code, date )];

   f(p);
}

在这面这个函数里,并没有if结构,那么简单的爆破便不成立了,当然跟踪高手在弄明白了这其中的流程之后,要破解还是可能的,毕竟没有百分百不可破解的软件。

关键在于CheckRegistInfo函数,当正确时返回什么值,不正确时返回什么值等等,这个算法很重要,而且最好是只使用算术和逻辑运算,而不使用条件语句,如if等。

另外,还可以将函数表可以设计为更大,比如256个指针,而CheckRegistInfo函数返回unsigned char类型的值,这样你的算法设计便更加灵活,并且正确的函数散列于其中,其它部分填充一些无效的,或迷惑的值,而在外面用SEH将函数指针的调用包装起来。这样,试图单纯从数据上分析来逆向就会很难了,从而解密者不得不去分析CheckRegistInfo函数的计算过程。不过它即使分析清楚了,也很可能不知道究竟返回值是几才是正确的,所以还得去检查函数表中的指针的有效性。

此法具有一定效果,特别对于初级的解密者,可以说逆向的难度还是比较大的。如果再加上其它一些干扰手段,我个人认为可以达到中级以上的强度。

不过以上全部只是思路,算是抛砖引玉,编程功力高的人可以试试,也欢迎讨论。
2008-12-13 21:58
0
雪    币: 427
活跃值: (65)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
好高深、、
看高人讨论
2008-12-13 22:08
0
雪    币: 27
活跃值: (127)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
8
哇,真有意思啊。

你的介绍真是让我大开眼界啊,原来为了防止破解,在编程的时候还有这么多的手段。

我以前学编程,只是想着怎么去实现我要做的功能,从来都没往防破解这方面去考虑。

你说得太棒了,让我马上就想试试这个方法。

最后有一点没看明白,

“在外面用SEH将函数指针的调用包装起来”是何意?

PS:我对SEH只是停留在听说的阶段,还没有细细学过。

另外,我对算法的设计,也完全是毫无经验的。

你提到“最好是只使用算术和逻辑运算,而不使用条件语句”,

不知是为何这样?

再次感谢你的帮助,让我在学习中看到了曙光。

谢谢。
2008-12-14 11:11
0
雪    币: 27
活跃值: (127)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
9
哦,我知道了,CheckRegistInfo的算法“只使用算术和逻辑运算,而不使用条件语句”,

这样做还是为了防爆破的。

其他知识我会上网继续搜索的,谢谢。
2008-12-14 11:20
0
雪    币: 27
活跃值: (127)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
10
顶起,希望书呆彭再帮看看。
2008-12-14 18:12
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
11
在外层用SEH,拿我给出的例子来说,函数表中有用的函数在其中的分布是非常散的,它们之前的间隙,可以用一些占位函数(如DoNothing)填充,也可以用无效的值(比如NULL)来填充。

如果填充的值当中有无效的函数指针,那么在调用时肯定会引发异常。为此,加上SEH。
2008-12-14 18:50
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
高人都在这里高谈阔论啊,我却在这里坐井观天。
2008-12-14 19:08
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
很高深。。这是长期实践得来的。
2008-12-15 18:07
0
游客
登录 | 注册 方可回帖
返回
//