- 浏览: 70764 次
- 性别:
- 来自: 杭州
最新评论
参考链接:http://timelessname.com/elfbin/
环境要求:linux gcc nasm hexcurse(用来修改elf文件内容)
先尝试用C语言写"Hello,World"程序(名为chello.c):
#include <stdio.h> int main(void) { printf("Hello,World\n"); return 0; }
使用下面命令编译并运行:
[host@myhost linker]$ gcc -o chello chello.c [host@myhost linker]$ ./chello
输出结果:
Hello,World
可以用下面命令查看chello的ELF头部分:
readelf -h chello
输出结果:
ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Intel 80386 Version: 0x1 Entry point address: 0x8048310 Start of program headers: 52 (bytes into file) Start of section headers: 1932 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 8 Size of section headers: 40 (bytes) Number of section headers: 30 Section header string table index: 27
使用下面命令查看chello链接的动态链接库:
ldd chello
输出结果为:
linux-gate.so.1 => (0xb7857000) libc.so.6 => /lib/libc.so.6 (0xb76d2000) /lib/ld-linux.so.2 (0xb7858000)
使用下面命令查看文件类型:
file chello
输出结果:
chello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.27, not stripped
使用下面命令查看文件大小,并使用strip取出符号表,然后查看文件大小:
[host@myhost linker]$ ls -l chello [host@myhost linker]$ strip -s chello [host@myhost linker]$ ls -l chello
输出结果为:
-rwxr-xr-x 1 host users 4746 11月 6 23:07 chello -rwxr-xr-x 1 host users 3036 11月 6 23:15 chello
下面使用汇编代码编写该程序(hello.asm),调用linux中断来实现:
SECTION .data msg: db "Hello,World",10 len: equ $-msg SECTION .text global main main: mov edx,len mov ecx,msg mov ebx,1 mov eax,4 int 0x80 mov ebx,0 mov eax,1 int 0x80
使用下面的命令编译链接并取出生成文件的符号表:
[host@myhost linker]$ nasm -f elf hello.asm [host@myhost linker]$ gcc -o hello hello.o -nostartfiles -nostdlib -nodefaultlibs [host@myhost linker]$ strip -s hello [host@myhost linker]$ ./hello
输出结果为:
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 08048080 Hello,World
再用gcc命令时会产生一个警告,但该文件仍然能够执行。此时文件大小为360个字节。
此处链接命令“gcc -o hello hello.o -nostartfiles -nostdlib -nodefaultlibs"中几个选项英文注解如下(链接 ):
-nostartfiles Do not use the standard system startup files when linking. The standard system libraries are used normally, unless -nostdlib or -nodefaultlibs is used. -nodefaultlibs Do not use the standard system libraries when linking. Only the libraries you specify will be passed to the linker, options specifying linkage of the system libraries, such as -static-libgcc or -shared-libgcc, will be ignored. The standard startup files are used normally, unless -nostartfiles is used. The compiler may generate calls to memcmp, memset, memcpy and memmove. These entries are usually resolved by entries in libc. These entry points should be supplied through some other mechanism when this option is specified. -nostdlib Do not use the standard system startup files or libraries when linking. No startup files and only the libraries you specify will be passed to the linker, options specifying linkage of the system libraries, such as -static-libgcc or -shared-libgcc, will be ignored. The compiler may generate calls to memcmp, memset, memcpy and memmove. These entries are usually resolved by entries in libc. These entry points should be supplied through some other mechanism when this option is specified. One of the standard libraries bypassed by -nostdlib and -nodefaultlibs is libgcc.a, a library of internal subroutines that GCC uses to overcome shortcomings of particular machines, or special needs for some languages. (See Interfacing to GCC Output, for more discussion of libgcc.a.) In most cases, you need libgcc.a even when you want to avoid other standard libraries. In other words, when you specify -nostdlib or -nodefaultlibs you should usually specify -lgcc as well. This ensures that you have no unresolved references to internal GCC library subroutines. (For example, `__main', used to ensure C++ constructors will be called;
此处startupfiles指的是crt0.o(/lib/crt0.o),crtbegin.o,crtend.o。据说crt0.o包含调用main函数(windows下调用WinMainCRTStartup (参考链接 ))的代码,这里使用汇编代码(如果是c程序,则需要链接crt0.o),所以不用链接crt0.o.crtbegin.o和crtend.o据说是用来对c++构造和析构函数进行处理。有一个帖子(Is main required for a c program? also see Why are DJGPP .exe files so large? )说明了不用main函数来编写c程序(其实只是把入口名称换换而已,就像Window应用程序使用WinMain来作为入口函数,只不过使用自己的入口函数,相关的一些处理都需要自己来解决)
使用下面命令得到hello的16进制描述:
hexdump -x hello
输出结果:
0000000 457f 464c 0101 0001 0000 0000 0000 0000 0000010 0002 0003 0001 0000 8080 0804 0034 0000 0000020 00c8 0000 0000 0000 0034 0020 0002 0028 0000030 0004 0003 0001 0000 0000 0000 8000 0804 0000040 8000 0804 00a2 0000 00a2 0000 0005 0000 0000050 1000 0000 0001 0000 00a4 0000 90a4 0804 0000060 90a4 0804 000c 0000 000c 0000 0006 0000 0000070 1000 0000 0000 0000 0000 0000 0000 0000 0000080 0cba 0000 b900 90a4 0804 01bb 0000 b800 0000090 0004 0000 80cd 00bb 0000 b800 0001 0000 00000a0 80cd 0000 6548 6c6c 2c6f 6f57 6c72 0a64 00000b0 2e00 6873 7473 7472 6261 2e00 6574 7478 00000c0 2e00 6164 6174 0000 0000 0000 0000 0000 00000d0 0000 0000 0000 0000 0000 0000 0000 0000 * 00000f0 000b 0000 0001 0000 0006 0000 8080 0804 0000100 0080 0000 0022 0000 0000 0000 0000 0000 0000110 0010 0000 0000 0000 0011 0000 0001 0000 0000120 0003 0000 90a4 0804 00a4 0000 000c 0000 0000130 0000 0000 0000 0000 0004 0000 0000 0000 0000140 0001 0000 0003 0000 0000 0000 0000 0000 0000150 00b0 0000 0017 0000 0000 0000 0000 0000 0000160 0001 0000 0000 0000
分析该文件头(前52个字节)可以知道两个比较重要表的内容,第一个是程序头表(54(0x34)个字节开始,大小为2*32(0x20)个字节),另一个是段头表(200(0xc8)个字节开始,大小为2*40(0x28)个字节),然后根据段头表可以知道代码段(0x80开始34个字节内容)和数据段(0xa4开始12个字节内容)相关信息。比较重要的是前176个字节内容,这部分内容可以分为文件头(52个字节),程序头表(64个字节),空白内容(12个字节),代码段(34个字节),数据段(12个字节,"Hello,World\n")。
先使用下面命令提取hello中前176个字节内容修改权限为可执行:
dd if=hello of=hello.new bs=176 count=1 chmod u+x hello.new
得到文件hello.new,执行该文件可以得到"Hello,World".该文件二进制内容:
0000000 457f 464c 0101 0001 0000 0000 0000 0000 0000010 0002 0003 0001 0000 8080 0804 0034 0000 0000020 00c8 0000 0000 0000 0034 0020 0002 0028 0000030 0004 0003 0001 0000 0000 0000 8000 0804 0000040 8000 0804 00a2 0000 00a2 0000 0005 0000 0000050 1000 0000 0001 0000 00a4 0000 90a4 0804 0000060 90a4 0804 000c 0000 000c 0000 0006 0000 0000070 1000 0000 0000 0000 0000 0000 0000 0000 0000080 0cba 0000 b900 90a4 0804 01bb 0000 b800 0000090 0004 0000 80cd 00bb 0000 b800 0001 0000 00000a0 80cd 0000 6548 6c6c 2c6f 6f57 6c72 0a64
由于数据段大小刚好为12,而文件中有刚好有12个字节空白,可以将数据段(0xa4开始的12个字解)迁移到空白处(0x74开始的12个字节),并将0x86地址的0xa4改为0x74。可以使用hexcurse hello.new修改文件内容,然后用快捷键crtl+s保存,并改名为hello.res.此时执行hello.res可以得到"Hello,World"。
然后我们可以删除最后的12个字节(使用命令dd if=hello.res of=hello.out bs=164 count=1),得到hello.out即为最后的结果,其大小为164个字节。按照原文中描述,该文件应该可以进一步的压缩,不过这需要对代码段中部分做一些改动,有空时再详细研究)
而文件头中还有一个e_entry(0x18地址开始的4个字节,值为0x08048080(0x08048000+0x80(代码段偏移地址))表示程序入口,即从这个地址开始执行指令。代码段中(0x86开始的4个字节(小端法表示,9074 0804)即0x08049074,这个地址是0x08048000+0x1000(代码段虚拟地址所占的空间大小,因为段对齐为0x1000,所以最小为4k大小(分页机制中每个页面的大小))+0x74,这个地址是从原来的地址0x080490a4(这个地址也分别存在于原来的0x0000005c和0x00000060开始的4个字节。但是好像0x0000005c和0x00000060中的值不改业能正常运行,但为了使得数据保持一致,最好还是改掉。)。
另外,hello.out只包含ELF头,程序头,代码段和数据段,并且仍然能正常运行,这也证明了可执行文件中段头表(section Header table)是可选项。
发表评论
-
最小c编译器
2011-11-08 14:09 1429最小c编译器(来源 (最好在linux下操作))代码有好几个 ... -
the development of c language(转)
2011-11-08 09:25 1123c语言之父Dennis Ritchie 写的关于c语言开发历 ... -
C语言,你真的弄懂了么?
2011-11-07 12:42 1732程序(来源 ): #include <stdi ... -
pe文件格式实例解析
2011-11-07 10:05 0环境:windows xp 速龙3000+(即x86兼容32位 ... -
elf文件格式实例解析
2011-11-05 23:00 6287试验环境:archlinux 速龙3000+(即x86兼 ... -
高质量的c源代码
2011-11-03 10:18 1101现在自由软件及开源软件越来越流行,有大量的附带源程序 ... -
fltk 库
2011-09-26 19:47 1775fltk是一个小型、开源、支持OpenGL 、跨平台(win ... -
《Introduction to Computing Systems: From bits and gates to C and beyond》
2011-09-25 23:33 2125很好的一本计算机的入门书,被很多学校采纳作为教材,作者Yale ... -
csapp bufbomb实验
2011-09-16 14:21 4555csapp (《深入理解计算机系统》)一书中有一个关于缓冲区 ... -
the blocks problem(uva 101 or poj 1208)
2011-09-11 20:57 1806题目描述见:uva 101 or poj 1208 ... -
the blocks problem(uva 101 or poj 1208)
2011-09-11 20:56 0题目描述见:uva 101 or poj 1208 ... -
部分排序算法c语言实现
2011-09-02 14:51 994代码比较粗糙,主要是用于对排序算法的理解,因而忽略了边界和容错 ... -
编译器开发相关资源
2011-08-31 08:40 1174开发编译器相关的一些网络资源: how difficu ... -
zoj 1025 Wooden Sticks
2011-07-23 20:25 948题目见:zoj 1025 先对木棒按照长度进行排序,然后再计 ... -
zoj 1088 System Overload
2011-07-23 17:30 1139约瑟夫环 (josephus problem )问题, ... -
zoj 1091 Knight Moves
2011-07-23 09:05 820题目见zoj 1091 使用宽度搜索优先来求解, ... -
zoj 1078 palindrom numbers
2011-07-22 19:31 1123题目见zoj 1078 主要是判断一个整数在基数为2 ... -
zoj 1006 do the untwist
2011-07-22 13:24 905题目见zoj 1006 或poj 1317 简单 ... -
zoj 3488 conic section
2011-07-22 12:23 973题目见zoj 3488 很简单的题目,却没能一次搞定,因 ... -
zoj 1005 jugs
2011-07-22 11:43 811题目内容见zoj1005 由于A,B互素且A的容 ...
相关推荐
ReadELF, ELF格式分析程序源码 ReadELF, ELF格式分析程序源码 ReadELF, ELF格式分析程序源码 ReadELF, ELF格式分析程序源码 ReadELF, ELF格式分析程序源码
一个简单的x86架构下的汇编语言脚本示例,用于在Linux环境下使用NASM汇编器编写一个程序,该程序会在控制台上输出"Hello, World!"。 编译与运行: 首先,你需要安装NASM汇编器。在大多数Linux发行版中,你可以使用包...
我们首先像这样编译和链接 helloworld 程序: patmos-clang -o hello.elf hello.c 使用 Patmos 模拟器pasim执行二进制文件会做我们期望它做的事情: pasim hello.elf # (make run) Hello world. 为了使 hello...
支持32位/64位elf文件自适应解析、可解析elf文件头、程序头、节头、字符表、符号表、hash表、版本定义表、版本依赖表、动态信息表等。 更多详细介绍请访问:...
介绍了LinuxELF格式可执行程序,描述了将代码嵌入目标文件的方法
摘要:本文实现了如下功能:让某elf程序运行后先执行一个特别的附件功能(附加功能是:创建一个指定文件写入hello,world的字符串)后再继续运行该elf程序
大家对于Hello World程序应该非常熟悉,随便使用哪一种语言,即使还不熟悉的语言...本文就是以一个最基本的C语言版本Hello World程序为基础,了解Linux下ELF文件的格式,分析并验证ELF文件和加载和动态链接的具有实现。
一个简单程序解析ELF
将elf文件转换为hex文件的小程序,使用前安装arm-none-eabi编译工具链,复制到elf文件所在目录双击执行,若当前文件没有.elf文件,则会提示 No such file,若转换成功则会在目录内生成HexFile.hex文件
ELF标准的目的是为软件开发人员提供一组二进制接口定义,这些接口可以延伸到多种操作环境,从而减少重新编码、重新编译程序的需要。接口的内容包括目标模块格式、可执行文件格式以及调试记录信息与格式等。
Intel语法 Intel语法是由Intel公司为其处理器编写官方文档时所采用的语法。...编译:nasm -f elf32 hello_world.asm -o hello_world.o 链接:ld -m elf_i386 hello_world.o -o hello_world 运行:./hello_world
nupkg格式的C#库文件,专门用来解析elf类文件的,使用的时候先加载安装这个库,怎么安装自行百度C# nupkg, 然后using包含ELFSharp.ELF.XXX的命名空间,然后就可以操作对应的函数了, 实例: var elf = ELFReader....
EXECUTABLE AND LINKABLE FORMAT (ELF) ELF(可执行链接格式)手册 Portable Formats Specification, Version 1.1 Tool Interface Standards (TIS) ___________________________________________ 1. 目标文件...
ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。实际上,一个文件中不一定包含全部内容,而且它们的位置也未必如同所示这样...
基于内核秘钥保留服务的ELF签名程序和验证模块 https://blog.csdn.net/qq_42584874/article/details/123629196使用方法
《ELF文件格式分析.pdf》文档,非常不错的elf格式参考文档,参考elf解析过程,能很快掌握elf文件格式
1、quartus ii软件版本在13.0及以上2、quartus ii编译生成的sof文件输出目录为根目录下的output_files文件夹下。很多从老版本修改过来工程sof输出目录在工程根目录,因此需要用户自行修改脚本和cof文件3、nios ii的...
分析了ELF文件中symbol
uefi-elf-bootloader 该存储库包含一个简单的UEFI ELF引导程序,该引导程序加载了一个简单的演示内核。 它为x86-64裸机系统提供了UEFI引导程序的极其基本的示例实现,尽管该示例应可移植到其他体系结构。 该存储库的...