第三次讲座盲点整理(编译与链接)——课程设计里的密码原来就是虚设!

        真不知道刘欢学长都是从哪里学到的这些技巧,简直是让我佩服地五体投地。今天本来是想总结一篇博客,结果发现想要总结的东西在一篇里根本总结不完。大神就是大神,在两个小时的时间里讲的知识,让我回味了一天,都没有回味结束

        还记得学期在课程设计的时候,王小银老师对我们做的程序提出一个建议性要求——加入密码验证。当时觉得这是一个很恐怖的东西,密码这样一门高深的学问,我们这三天打鱼两天晒网学了一年C语言的孩子们,怎么可能去写出来一个密码程序?!

        后来有一天突发奇想,先在一个文件中写入密码信息,再把输入的字符串和从保存密码的文件中读取出的字符串利用strcmp函数进行比较,如果返回结果是0,不就可以了嘛!兴奋地立即去动手实现。把密码设成了123456,用这个方法果然可行。

    if(strcmp(str1,str2) == 0)

    {

    ……

    }

        就这么美滋滋地过了两三天。直到有一天,在输密码的时候,一不小心输成了12345,落了个6,结果竟然也成功地login了。我顿感慌张,如法炮制,在尝试了1,12,123,1234之后,发现竟然都可以成功地login。看来仅仅用一个strcmp还是不行。

想了想,还应该再加上一个strlen函数,于是,又美美地把验证密码的语句改写成了这样:

    if(strcmp(str1,str2) == 0 && (strlen(str1) == strlen(str2)))

    {

    ……

    }

        于是,最终,一个带着这样的“密码程序”的课程设计作品,就这么上去了


        今天,讲到C语言的编译与链接的时候,刘欢学长又把我们课程设计中大家的加密程序提了出来。他让一位同学把程序中的原密码随意修改,自己背对过去,改好后,不打开原程序,刘欢学长在电脑上敲了几行代码后,被修改后的密码竟然活生生地自己打印到了终端上!!!

        在听了讲解后,不禁顿感C语言简直是太神奇。现把实现原理整理在下面:

        先用strcmp编写一个简单的“密码程序”:

#include <stdio.h>
#include <stdlib.h>                                                             
#include <string.h>

int main( int argc,char *agrv[] )
{
    char *str = "gengjinkai";
    char pass[10];
    printf("Please input the passwd:\n");
    gets(pass);
    if( strcmp(pass,str) == 0 ) 
    {   
        printf("Login succeed!\n");
    }   
    else
    {   
        printf("Passwd incorrect!\n");
        exit(0);
    }   
    return 0;
}



        然后,要开始做手脚了 ,拿strcmp函数来进行开刀:

        先编写一个“strcmp”函数,就将它命名为passwd.c

#include <stdio.h>                                                              

int strcmp(const char *str1,const char *str2)
{
    puts(str1);
    puts(str2);
    return 0;
}


        执行下面的语句:

gcc passwd.c -shared -o passwd.so
        其中, -shared选项的意思是将passwd.c编译链接成为一个动态库。*.so在Linux中为共享库——shared object用于动态连接,和Windows下的dll差不多

        然后,主角出场——Linux系统中的LD_PRELOAD

        一般来说,程序的链接分为静态链接和动态链接,静态链接就是把所有所引用到的函数或变量全部地编译到可执行文件中。动态链接则不会把函数编译到可执行文件中,而是在程序运行时动态地载入函数库,也就是运行链接。所以,对于动态链接来说,必然需要一个动态链接库。动态链接库的好处在于,一旦动态库中的函数发生变化,对于可执行程序来说是透明的,可执行程序无需重新编译。

        在Linux的动态链接库的世界中,LD_PRELOAD就是这样一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。

        那么好,我们就passwd.so这个库来进行优先替换:

export LD_PRELOAD=./passwd.so

        在shell中执行程序时,shell会提供一组环境变 量。其中export的作用就是新增一个境变量,供后续执行的程序使用。export的效力仅及于该此登陆操作。

        此时,再次执行程序,

Please input the passwd:
123
123
gengjinkai
Login succeed!
         可以看出,程序中调用的strcmp函数已经成功地被我们替换成了passwd.so库中的strcmp函数!我们输入的密码123和正确的密码gengjinkai已经都被成功地打印出来了!


         贴出来一个关于LD_PRELOAD的文章,有时间了解学习下。

         http://blog.csdn.net/haoel/article/details/1602108




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值