c语言程序的入口是哪部分,C语言入口函数和LD_PRELOAD环境变量
零.C语言入口函数
从第一天学习C语言开始,我们的脑子里就深深烙下这样一个概念:C语言程序总是从main()函数开始执行,main()函数结束,程序也就结束了.在平时的练习中貌似这没有问题,但事实真的是这样吗?测试一下,
点击(此处)折叠或打开
#include
#include
#include
int enter(void)
{
printf("the start function!\n");
return 0;
}
编译:
打印处一页错误,其中有这样一条:
crt1.o:In function `__start':(.text+0x20): undefined reference to `main'
字面翻译就是:在函数_start中,main没有定义. __start函数是什么?main还要定义?crtl.o又是什么?带着疑问,我打开了百度.在其中搜到这样一份伪代码:
section .text:
__start:
:
init stack;
init heap;
open stdin;
open stdout;
open stderr;
:
push argv;
push argc;
call _main; (调用 main)
:
destory heap;
close stdin;
close stdout;
close stderr;
:
call __exit;
终于找到了,原来main就躲在crt1.o中,再看__start函数,"start"?不是开始的意思吗?难道每一个C程序就是从这开始的吗?
原来,对于“crt1.o”这个文件,其中crt是“C runtime library”的缩写,其含义是“C运时库”,C运行时库除了给我们提供必要的库函数调用(如memcpy、printf、malloc等)之外,它提供的另一个最重要的功能是为应用程序 添加启动函数。C运行时库启动函数的主要功能为 进行程序的初始化 ,对全局变量进行赋初值 ,加载用户程序的入口函数 。
soga,那这是不是意味着我们可以修改所要加载的入口函数呢?原来还有这样一条命令:
gcc *.c -e -nostartfiles
其中, *.c 为程序的源文件,-e为修改函数的入口地址,e == entrance ,后面的 就指明要替换的函数,-nostartfiles选项的作用是 通知编译器不自动加入启动函数以及别的库级别的初始化 ,这样就不会调用到crt1.o中的_start函数!测试一下,
点击(此处)折叠或打开
#include
#include
#include
int enter(void)
{
printf("the start function!\n");
return 0;
}
编译通过,运行:
the start function!
段错误 (核心已转储)
成功运行enter函数,但提示了段错误.
原来,在编译的时候加上了-nostartfiles这个选项的同时,使得最后的return语句不能正常执行。解决方案是,把程序最后的return语句改成exit()函数,因为return是将控制权交给调用函数,此时我们已经没有调用__start这个函数了,自然就没有enter的调用函数,然而exit()函数是将控制权交给内核,所以能够成功退出.
运行结果:
the start function!
一.LD_PRELOAD
在将LD_PRELOAD之前,我们先来了解一下两种链接方式
静态链接:由链接器在 链接时 将库的内容加入到可执行程序中.
动态链接:在可执行文件 装载时或运行时(注意与静态链接的区别) ,由操作系统的装载程序加载库.
通俗地讲,一种是无论程序运行与否,都加载库(静态库);另一种是只有执行到那一部分代码时,才加载库(动态库).
在Linux的动态链接库的世界中,LD_PRELOAD就是这样一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义 在程序运行前 优先加载的动态链接库 .这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数 .通过这个环境变量,我们可以 在主程序和其动态链接库的中间加载别的动态链接库 ,甚至覆盖正常的函数库.
说了这么多,是不是有点模糊?举个例子,
首先先编写一个“strcmp”函数,就将它命名为passwd.c
点击(此处)折叠或打开
#include
int strcmp(const char *str1,const char *str2)
{
puts(str1);
puts(str2);
return 0;
}
执行下面的语句:
gcc passwd.c -shared -o passwd.so -fPIC
其中,-shared选项的意思是将passwd.c编译链接成为一个动态库.*.so在Linux中为共享库——shared object,用于动态链接,和Windows下的dll差不多.
在shell中执行程序时,shell会提供一组环境变量.其中export的作用就是新增一个环境变量,供后续执行的程序使用.export的效力仅及于该此登陆操作.
对于-fPIC,-f后面跟一些编译选项,PIC是其中一种,表示生成位置无关代码(Position Independent Code),位置无关码就是可以在进程的任意内存位置执行的目标码,动态链接库必须使用.
然后,我们就用passwd.so这个库来进行优先替换:
export LD_PRELOAD=./passwd.so
我们知道,strcmp()的功能是比较两个字符串,但是在这里我们用passwd.so来代替系统的动态库,测试一下,
点击(此处)折叠或打开
#include
#include
#include
int main(int argc, char *argv[])
{
char *str = "abcdef";
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;
}
运行结果:
Please input the passwd:
123456
123456
abcdef
Login succeed!
就这样,strcmp()成功被我们替换了...
参考博文---------------------http://blog.sina.com.cn/s/blog_76a864e20101ehuz.html
c语言程序的入口是哪部分,C语言入口函数和LD_PRELOAD环境变量相关推荐
- c语言sin函数返回nan,C语言入口函数和LD_PRELOAD环境变量
零.C语言入口函数 从第一天学习C语言开始,我们的脑子里就深深烙下这样一个概念:C语言程序总是从main()函数开始执行,main()函数结束,程序也就结束了.在平时的练习中貌似这没有问题,但事实真的 ...
- c语言1000内亲密对数,《C语言程序的设计上机指导》项目五函数及其应用.pptx
<C语言程序的设计上机指导>项目五函数及其应用.pptx 项目五 函数及其应用 本章重点 文本 C语言程序结构. 函数定义与函数声明. 函数的调用. 变量的存储属性. 任务一 关于函数应用 ...
- c语言程序第一章编程,c语言程序的设计第一章 C语言编程入门.ppt
c语言程序的设计第一章 C语言编程入门 第1章 C语言编程入门 本章是本书的入门篇,专为初学者熟悉编程过程.掌握程序结构而准备的. 本章学习目标 ? 1)? 能够通过模仿与改变来构造带有测试函数的C语 ...
- 统计字符 c语言程序,统计字符个数的C语言程序.doc
统计字符个数的C语言程序.doc 下载提示(请认真阅读)1.请仔细阅读文档,确保文档完整性,对于不预览.不比对内容而直接下载带来的问题本站不予受理. 2.下载的文档,不会出现我们的网址水印. 3.该文 ...
- c语言程序与设计苏小红,c语言程序设计苏小红
<实验教学示范中心建设教材·国家精品课程主讲教材:C语言程序设计(第2版)>是一本兼具趣味性和实用性的C语言程序设计教材.全书由13章组成,内容包括:为什么要学C语言,C数据类型,简单的算 ...
- 电子时钟单片机c语言程序,51单片机电子时钟C语言程序
本程序基于ATM89系列单片机的电子时钟C语言程序,能显示月日时分秒,同时还能调节其值!显示方式用六个8段数码管! #include//头文件 #define uchar unsigned char/ ...
- c语言程序中的基本功能,c语言程序中的基本功能模块为什么?
c语言程序中的基本功能模块为"函数".一个C语言程序可以由一个主函数和若干个函数构成:一个大的应用程序一般应该分为多个程序模块,每一个模块用来实现一个功能,而模块的功能是由函数完成 ...
- 重庆理工大学c语言程序实验报告,重庆理工大学-C语言程序实验报告.doc
重庆理工大学-C语言程序实验报告 程序设计基础C实验报告 PAGE 47 <程序设计基础C> 实 验 报 告 教学班级: 学号: 姓名: 课程教师: 实验辅导教师: 重庆理工大学计算机学院 ...
- c语言程序中cost的作用,C语言考试题基础版(21页)-原创力文档
if (x>y)z=x; s=z*z;elsez=y;s=1/(z*z); if (x>y) z=x; s=z*z; else z=y;s=1/(z*z); 7. B. C. PAd, P ...
最新文章
- mysql被拖垮_说几个拖垮系统的小细节!
- CNN和VGGNet-16背后的架构
- 为什么大家看到不错的文章更愿意收藏而不是点赞?
- python计算器基础知识_Python基础(一):将Python当做计算器、编程的第一步
- 数据结构---前序和中序遍历的二叉树序列还原二叉树
- mfc函数调用堆栈溢出_01 JavaScript 调用堆栈
- SQLAlchemy engine.Engine
- java 远程监控文件系统_Java 文件系统监控(WatchService)
- 启动Eureka客户端服务时报错:java.net.ConnectException: Connection refused:connect
- 2.7配置自定义的Formatters
- Mac如何在回收站中恢复丢失数据
- MySQL中 slave_compressed_protocol=ON 的压缩效果实验
- Orchard Core 使用工作流处理页面提交
- PHP伪原创文章自动生成,api生成伪原创-爱发狗一键伪原创生成原创文章
- stdafx有什么用(包含相关问题分析)
- fileman命令的帮助+?
- 通过GDI+修改jpg文件EXIF属性
- android framework之priv-app,系统特权app权限那些坑
- 20161204 要一同转向父亲
- VBS ADODB操作帮助手册
热门文章
- git stash命令的用法
- Angular ngClick command parse
- IBASE archive pre-processing report RIBARCHV
- SAP CRM PPR调试截图,头都搞大了,希望这问题这辈子只遇到这次
- jmeter(三)参数化
- linux脚本计时,Linux用脚本实现“时分秒“倒计时功能
- 上下界网络流-无源汇可行流与有源汇最大流
- pyqt5必须和python对应_python 使用PyQt5
- java 继承和内部类_Java自学-接口与继承 内部类
- mysql班次和排班怎么设计表_java 员工轮询值班排班 开发设计(mysql+redis)