良许Linux教程网 干货合集 从汇编看C++程序的条件判断语句

从汇编看C++程序的条件判断语句

在当今时代,如果有人熟练地使用汇编语言编写程序,可能会被当作与众不同的人对待。即使是研究逆向工程的人大多只能说他们懂得一些汇编语言,真正精通汇编的人非常少。

对于开发人员来说,我也认为汇编语言确实没有什么用处。

简洁性是汇编语言的优点,同时也是它的缺点。正因为它过于简洁,要实现一个简单的功能就需要很多的代码。

有时候看到一大段汇编代码我也会感到头疼,但由于工作需求,我不得不研究高级语言在底层的实现过程,所以写了这篇文章。

让我们从一个简单的 C++ 小程序开始。

image-20240128205127982
image-20240128205127982

这个程序功能很简单,就是输入一个整数,然后判断它是不是和123456相等,如果相等就输出you are right,如果错误就输出you are wrong

然后把生成的exe文件利用反汇编工具再还原成汇编语言。

image-20240128205130966
image-20240128205130966

上面这张图是程序的开头部分。

image-20240128205133916
image-20240128205133916

而这张图是结尾部分。

可以看到,这个程序的起始地址是00FA1000而结束地址是00FA2FF。也就是说,要实现这么一个小小的功能,要用到几千行汇编代码。如果大家都这么开发,怕是累死也写不出个啥。

不过这里面的大部分代码都是编译器帮我们生成的,真正执行判断操作的代码大概就只有下面这几行。

image-20240128205137214
image-20240128205137214

我先是在命令行里面输入了123,在00FA1082处下了一个断点,然后回车,程序就断下来了。

image-20240128205140063
image-20240128205140063

关键的判断操作就是 cmp dword ptr ss:[ebp-0x8],0x1E240

这个操作的意思是,把0x1E240这个数和内存里面地址为[ebp-0x8]的数据进行比较。

0x1E240转换为10进制可以看到就是123456,也就是触发you are right的整数。

image-20240128205143041
image-20240128205143041

从右边的寄存器窗口可以看到寄存器ebp的值为00CFFB48,则[ebp-0x8]=00CFFB40

从数据窗口可以看到00CFFB40处的值为7B。

image-20240128205146504
image-20240128205146504

转换成10进制刚好为123,也就是我刚才输入的数。

image-20240128205149076
image-20240128205149076

如果两者相等的话,则会把zf标志位置为1,若不相等,zf位为0。

现在可以从右边的寄存器窗口看到,zf位为0,则jnz跳转就成立,从而跳过you are right而去执行you are wrong

到了最后,在00FA10AE处的指令是jmp short Project1.00FA1060。jmp是无条件跳转指令。这条指令执行会跳回到刚开始要求用户输入整数的操作,相当于实现了while的功能。

现在假设这个程序是个付费软件,要求用户来输入一个密钥来解锁软件。如果我让这个if条件恒成立,那么我就能实现在不知道密钥的情况下来使用这个软件。

在反汇编窗口里面,只需要把jnz short Project1.00FA10A1 全部用nop代替就完全,就可以直接忽略掉cmp dword ptr ss:[ebp-0x8],0x1E240对zf位的影响,从而直接执行you are right

image-20240128205152176
image-20240128205152176

也就是说,我随便输入一个值,程序都会给我返回you are right

image-20240128205154835
image-20240128205154835

事实上,不光是C++,绝大部分高级语言在底层都是这么实现判断的。所以,为了防止写个软件出来老是被人白嫖,研究一下在底层判断语句是怎么实现的还是很重要的。

最简单的防白嫖手段就是加壳。尤其在是这种关键跳转的地方一定要使用加壳工具进行保护,防止被别人轻而易举地就定位到关键跳的位置。其次就是加花指令,这个方法的本质就是构造恒成立跳转,增加一些没用的跳转,既不对程序本身造成影响,也可以干扰别人对关键跳转的判断。

最最无敌的一种办法就是用网络验证。尽管这也不能保证百分之百不会被白嫖,但确实是非常有效的而且相对容易的办法了。不过它的缺点就是,如果服务器崩了,软件就不能运行了,这对于用户来说是无法接受的。

在技术上的对抗永远是在底层,并且是没有尽头的。现实往往又是道高一尺魔高一丈,而正是在这种矛与盾的攻防较量中,技术才不断地向前发展,才能为客户提供更为安全,可靠,便捷的服务。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部