首页 > 系统相关 >C++_Linux二进制格式

C++_Linux二进制格式

时间:2024-11-29 17:48:14浏览次数:5  
标签:可执行文件 文件 二进制 使用 ELF C++ 内存 Linux

C++调试工具

 GDB  适合用于调试代码逻辑错误和程序崩溃,二者结合使用可以大大提高错误排查效率
 Valgrind 和 Memcheck 更适合用于检查程序的内存问题,如内存泄漏、非法内存访问等。
 GFlags 是 VS 中自带的内存检查工具
 gprof 是一个GNU项目中的性能分析工具,用于分析C和C++程序的函数调用图和每个函数的CPU使用时间
 perf:这是Linux下的一个性能分析工具,可以收集CPU使用情况、缓存命中率、分支预测错误等多种性能数据。
 在C++中进行代码覆盖率分析可以使用工具如gcov和lcov
 Google Test 是由 Google 的测试技术团队开发的 C++ 测试框架,也被称为 gtest。
 CppUnit是一个专门为C++设计的单元测试框架,它基于JUnit框架的概念,提供了类似的机制和工具,用于编写和运行C++的单元测试。

内存检查工具

 valgrind 默认使用memcheck工具,就是默认参数—tools=memcheck	 
     Memcheck 会监控程序的每一个内存访问
	检测内存泄漏、越界访问等问题,从而防止程序崩溃 
	 内存泄露(leak): 内存泄漏是指程序中分配的内存未能被释放
	 内存溢出(Memory Overflow) 请求分配的内存超过了系统所能提供的内存大小或者进程所能使用的内存大小
漏报告分为4类:
    definitely lost: 明确泄漏,程序失去了对该内存块的引用。
    indirectly lost: 间接泄漏,某些泄漏的内存块引用了这些内存块。
    possibly lost  : 可能泄漏,程序可能丢失了对内存块的引用,或者这块内存还在使用但未释放。
    still reachable: 程序退出时仍然可达,但未释放的内存块。
	
堆栈跟踪
    in use at exit:
	total heap usage:
	
使用 file 解决类型问题	 
使用 ldd 探索依赖性
使用 readelf 解析并提取ELF库文件 查看 ELF头部 (elf_header)的详细信息
使用  dd 命令用于读取、转换并输出数据’
使用  nm -D 选项要求nm解析动态符号表
使用 strings 来查看二进制文件中的字符串,包括Linux操作系统上的任何其他文件 strings只输出4个或者4个字符以上的字
使用 strace和ltrace 跟踪系统调用和库文件调用
使用 objdump 检查指令集行为  objdump -a
使用 GDB 转储动态字符串缓冲区
strace 
valgrind 	
 
 十六进制转储工具 xxd

内存检测原理

 内存的检测原理。一般情况下,常规关注的内存问题有:内存泄露、内存越界、双重释放、野指针访问。
      内存检测,一般是配合Hook API技术完成的,所谓Hook API,本质就是交换函数地址,	 
      内存检测的本质,核心就在于对  malloc 和 free 函数的监听处理,做了一些额外的工作完成的
	    new和delete的底层也是通过调用 malloc/free 函数完成的
 内存越界:所谓内存越界,就是对内存的读写访问,超出了它的分配范围

1. 内存栈区: 存放局部变量名;
2. 内存堆区: 存放new或者malloc出来的对象;
3. 常数区: 存放局部变量或者全局变量的值;
4. 静态区: 用于存放全局变量或者静态变量;
5. 代码区:二进制代码。
data又可分为读写(RW)区域和只读(RO)区域
   栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等
   堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事
     block 由一系列大小相等的内存块组成。分配内存时先在block中分配,如果block占满则从heap区中分配
 
一个程序被加载到内存中,这块内存首先就存在两种属性:静态分配内存和动态分配内存。 
    静态分配内存:是在程序编译和链接时就确定好的内存。 
    动态分配内存:是在程序加载、调入、执行的时候分配/回收的内存。 
 
C++编译器提出了符号修饰(mangled name)。
  符号修饰实质上是原始函数名称与函数参数编码的组合。这样,函数的每个版本都会获得唯一的名称,并且链接器也不会对重载的函数产生歧义 

C++编程

 代码覆盖率就是测试过程中已经被执行过的代码占准备测试总代码量的比例和程度	 
 单元测试(Unit Testing)是一种编程方法,用于验证代码中的最小可测试单元(通常是函数、方法或模块)是否按照预期工作。
 
 vDSO 全称为 virtual dynamic shared object
     linux-vdso.so.1  不是一个实实在在的文件
	  vsyscall 
	  vdso 是vsyscall的主要替代方案,全称是Virtual Dynamic Shared Object. 这是一个虚拟动态链接库
	  
	用户空间和内核空间之间,有一个叫做Syscall(系统调用, system call)的中间层,是连接用户态和内核态的桥梁  
	  
 
    /proc/self/maps
	   不同的进程访问该目录时获得的信息是不同的 内容等价于/proc/本进程pid/
	   proc/self/目录来获取自己的系统信息,而不用每次都获取pid
  通过实践来培养编程技能 
      
	  libstdc++是Linux系统中常用的两个库文件 ibstdc++  gcc
	  libc是Linux下原来的标准C库,后来 glibc  eglibc的主要特性是为了更好的支持嵌入式架构 
	  C语言标准库(glibc)、数学库(libm)、线程库(libpthread)、动态链接库(ld.so)等

linux

 : a.out(assembler and link editor output 汇编器和链接编辑器的输出)、
    COFF (Common Object File Format 通用对象文件格式)、
	ELF  (Executable and Linking Format 可执行和链接格式)	
       为段 (Segment)或节(Section)	并调用函数 mmap()把段内容加载到内存中	
	:编译(compile)、连接(link,也可称为链接、联接)、加载(load)

ELF 文件有三种类型:
   可重定位文件:也就是通常称的目标文件,后缀为.o。
   共享文件:也就是通常称的库文件,后缀为.so。
   可执行文件:本文主要讨论的文件格 式	
   Core dump(core),运行过程中崩溃时自动生成,用于调试

file : 
  某个文件的基本类型,例如究竟文件时属于 ASCII 或者是 data 文件,或者是 binary 类型, 
   且其中有没有使用到 共享库(share library) 等等的信息,就可以利用 file 这个命令来查看。
  
  第一个最后显示的是 stripped 第二个是 not stripped 。而且对于同样名字的动态库
   elf格式中符号表的内容会比a.out格式的丰富的多。
     但是这些符号表可以用 strip工具去除,这样的话这个文件就无法让debug程序跟踪了,但是会生成比较小的可执行文件

   strip命令是一个强大且实用的工具,主要用于去除可执行文件、共享库文件(.so文件)以及目标文件(.o文件)中的符号表和调试信息
      直接用于二进制文件的处
	  
共享库(so(shared object))	 动态链接库(SHARED LIBRARIES)
readelf -h pie_binary | grep Type:     
 
     ELF 64-bit LSB shared object	
     ELF 64-bit LSB executable,	
	
     .so(Shared Object)文
	 
 注:“LSB executable”(ET_EXEC)和"LSB shared object"(ET_DYN)的区别是什么?

    在Linux内核/动态加载程序中
	  ET_EXEC与ET_DYN的主要作用是
	   通知可执行文件是否可以通过ASLR放置在随机存储器中。
	   GCC在编译时,默认会增加-pie选项,使得生成的ELF是ET_DYN的。
	   PIE可执行文件是DYN的,它们可以被地址随机化,就像共享库so一样。

 可执行文件可共享 
	LSB shared object可以执行的原因主要是因为它利用了Linux系统的动态链接机制和ELF格式的灵活性,
	  使得共享库文件既可以在编译时被链接为可执行文件,
	   也可以在运行时被动态链接器加载和执行 
	 
	 
	对于.a文件,用file命令查看,只能.a: current ar archive
     ------解决方案--------------------------------------------------------
     objdump -a xx.a 
	  
	 # 生成共享库
     add_library(mylib SHARED ${SOURCES}) 
	 add_library(libhello SHARED hello.c) #生成动态库文件
     add_library(libhello STATIC hello.c) #生成静态库文件
	 
	 target_link_libraries 命令为目标指定依赖库,在本例中 hello.c 被编译为库文件,并将其链接进 hello 程 序。
		
使用 file 解决类型问题	 
使用 ldd 探索依赖性
使用 readelf 解析并提取ELF库文件 查看 ELF头部 (elf_header)的详细信息
使用  dd 命令用于读取、转换并输出数据’
使用  nm -D 选项要求nm解析动态符号表
使用 strings 来查看二进制文件中的字符串,包括Linux操作系统上的任何其他文件 strings只输出4个或者4个字符以上的字
使用 strace和ltrace 跟踪系统调用和库文件调用
使用 objdump 检查指令集行为  objdump -a
使用 GDB 转储动态字符串缓冲区
strace 
valgrind 		  

可执行文件外,
 动态链接库(DDL,Dynamic Linking Library)、静态链接库(Static Linking Library) 均采用可执行文件格式存储。
 它们在Window下均按照PE-COFF格式存储;
 Linux下均按照ELF格式存储。只是文件名后缀不同而已。
 
 动态链接库:Windows的.dll、Linux的.so
 静态链接库:Windows的.lib、Linux的.a
     可重定位文件(Relocatable File):ETL_REL。一般为.o文件。可以被链接成可执行文件或共享目标文件。静态链接库属于可重定位文件。
     可执行文件(Executable File):ET_EXEC。可以直接执行的程序。
     共享目标文件(Shared Object File):ET_DYN。一般为.so文件。有两种情况可以使用
	    链接器将其与其他可重定位文件、共享目标文件链接成新的目标文件;
        动态链接器将其与其他共享目标文件、结合一个可执行文件,创建进程映像。

参考

 https://www.cnblogs.com/lqerio/p/12110482.html	 
 成为一名二进制分析师需要用到的Linux二进制分析工具有哪些? https://zhuanlan.zhihu.com/p/429283972

标签:可执行文件,文件,二进制,使用,ELF,C++,内存,Linux
From: https://www.cnblogs.com/ytwang/p/18577215

相关文章

  • C++下的gRPC与protobuf使用和介绍
    目录gRPC允许定义四类服务方法流是会结束的stream(流式传输)编写流程客户端使用ClientReader客户端使用ClientWriter客户端使用ClientReaderWriter服务器端gRPC允许定义四类服务方法一元RPC:客户端发送一次请求,等待服务端响应结构,会话结束,就像一次普通的函数调用这样简单......
  • C++11-lambda表达式
    目录 1.labmda的表达式1.1.仿函数的使用  1.2lambda表达式的书写 1.3lambda的捕获列表1.3.1传值捕捉1.3.2mutable可以修改拷贝对象  1.3.3 引用捕获 1.3.4混合捕捉  1.4函数对象与lambda表达式 1.5  lambda和仿函数的比较......
  • Linux服务器部署java项目(一)
    前一阵子实验室的项目要部署在服务器上(ubuntu22.04),记录一下部署的过程1.jdk1.8安装解压安装包tar-zxvfjdk版本号加配置文件sudovim/etc/profile.d/my_env.sh#JAVA_HOMEexportJAVA_HOME=/opt/jdk1.8.0_191exportPATH=$PATH:$JAVA_HOME/bin测试是否安......
  • linux下简单制作iso,img镜像文件
       解压rpmrpm2cpio*.rpm|cpio-div https://www.cnblogs.com/sztom/p/10184766.html 1.如果你是直接从cd压制iso文件的,执行sudoumount/dev/cdromddif=/dev/cdromof=file.isobs=10242.如果你要把某个文件或者目录压到iso文件中,需要使用mkisofs这个工具。......
  • 今天你学C++了吗——C++中的类与对象(第三集)
    ♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥♥♥♥我们一起努力成为更好的自己~♥♥♥♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥✨✨✨✨✨✨......
  • c++判断字符串全是字母或数字
    使用std::all_of判断字符串是否全为字母、数字或字母数字#include<iostream>#include<string>#include<algorithm>#include<cctype>//用于isdigit,isalpha等函数//std::islower(ch);//判断字符是否是小写字母//std::isupper(ch);//判断字符是否是大写字母......
  • Linux netstat 命令详解
    简介netstat全称是:networkstatistics,是一个用于监控、排除网络连接故障、路由表的命令行工具,它提供关于网络统计和socket连接的详细信息。安装sudoaptinstallnet-tools#ForDebian/Ubuntusudoyuminstallnet-tools#ForCentOS/RHEL常用选项示例查看所有连接......
  • 10C++选择结构(4)——教学
    一、switch语句(第25课成绩等级)问题:风之巅小学规定,若测试成绩大于或等于90分为“A”,大于或等于70分小于90分为“B”,大于或等于60分小于70分为“C”,60分以下为“D”。试编一程序,输入一个成绩,输出它的等级。流程图如下:用if语句处理多个分支时需使用if-else-if结构,分支越多,嵌套......
  • Linux常用命令之usermod命令详解
    usermod命令详解usermod命令在Linux和Unix系统中用于修改用户账户的属性。它允许系统管理员更改用户的主目录、默认shell、用户ID(UID)、组ID(GID)等。以下是对usermod命令的详细解释,包括其语法、选项和示例。基本语法usermod[选项]用户名常用选项-cC......
  • Linux驱动开发之LCD显示和触摸
    目录LCD屏幕显示LCD相关参数FramebufferDRM驱动框架LCD屏幕触摸MT协议LCD屏幕显示LCD(LiquidCrystalDisplay),即液晶显示器,是一种数显技术,可以通过液晶和彩色过滤器过滤光源并在平面板上产生图像,是现在最常用到的显示器。而液晶本身不能发光,只能通过对光线的穿透和反......