64位Centos7上汇编运行32位程序
2017-10-22 16:39
176 查看
64位Centos7上汇编运行32位程序
首先贴上源代码。#文件名test.s .data msg: .string "$0</span>-<span class="hljs-variable">$8=%d\n" .text .global _start _start: movl $0, %eax movl $8, %ebx subl %ebx, %eax pushl %eax lea msg, %eax pushl %eax call printf movl $0, %ebx movl $1, %eax int $0x801
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[/code]
功能非常简单,就是计算eax减去ebx的值,然后调用c语言printf函数输出(参数列表中的参数逆向压入堆栈,然后“call printf“即可)。
汇编
上面的代码采用的是AT&T语法,所以使用GNU as汇编器。命令如下
as –32 -otest.o test.s
关键是–32选项,它告诉汇编器这是32位的程序。否则,默认生成64位的目标文件。
链接
在Linux系统中许多软件都会使用彼此提供的函数库来完成特殊的功能。Linux中的函数库分为动态函数库和静态函数库。
静态函数库。这类函数库通常扩展名为libxxx.a。在程序编译的时候会直接被整合到程序中,生成的程序可以独立执行。程序文件通常比较大,当函数库升级时整个程序需要重新编译才能使用新版本的函数库。
动态函数库。这类函数库的扩展名为libxxx.so。在程序编译时候,程序中仅会保留指向函数库的Pointer而已,程序执行时需要函数库时会根据这个Pointer去相应的路径读取。程序文件比较小,函数库升级不需要重新编译程序就可使用新版的函数库(前提是函数库的名称路径不变)。
上面说了这么多,是因为后面碰到的问题与这个概念相关。先用链接命令尝试一下,当然是会报错的。
[liu@localhost 文档]$ ld -m elf_i386 -otest test.o test.o:在函数‘_start’中:
(.text+0x15):对‘printf’未定义的引用
-m选项是用来生成32位程序的,照着写就好了。因为printf是c语言的库函数,我们这里使用的是动态链接,所以的链接的时候需要指明函数库。但是,我们的平台是64位的,当然不可能包含32位的函数库,所以这里要先安装linux系统提供的c语言函数库glibc。这里偷下懒,复制一下百度百科的解释。
glibc是GNU发布的libc库,即c运行库。glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。
glibc 的主体,分布 /lib 与 /usr/lib 中,包括 libc 标准 C 函式库、libm 数学函式库、libcrypt加密与编码函式库、libdb 资料库函式库、libpthread 行程多执行绪函式库、libnss 网路服务函式库 ….等等。这些都是可分享函式库,档名都以 .so 做结尾。/lib/ld*.so 是程式与函式库连结的工具。有的用于程式编译时将程式与函式库内的函式物件连结,在只支援静态连结的系统中,此连结方式就是直接将所需的物件自函式库中抽出来与程式的可执行档相连,而在支援可分享函式库的系统中,在程式编译时期的连结只是在执行档中纪录了那些函式物件是存在那个函式库档案中,等该程式开始执行时,则由另一个负责动态连结的ld*.so 将所需的函式库连结好并执行。 一般而言,负责程式编译时期的连结器档名为 ld. so,而负责程式执行时的动态连结器档名为ld- .so 或 ld-linux. so (在 GNU/Linux 系统中)。
搜索可用的glibc软件包。
[root@localhost ~]# yum search glibc 已加载插件:fastestmirror, langpacks Loading mirror speeds from cached hostfile * base: mirrors.sina.cn * extras: mirrors.sina.cn * updates: mirrors.cqu.edu.cn ================================= N/S matched: glibc ================================= glibc-common.x86_64 : Common binaries and locale data for glibc compat-glibc.x86_64 : Compatibility C library compat-glibc-headers.x86_64 : Header files for development using standard C libraries. glibc.i686 : The GNU libc libraries glibc.x86_64 : The GNU libc libraries glibc-devel.i686 : Object files for development using standard C libraries. glibc-devel.x86_64 : Object files for development using standard C libraries. glibc-headers.x86_64 : Header files for development using standard C libraries. glibc-static.i686 : C library static libraries for -static linking. glibc-static.x86_64 : C library static libraries for -static linking. glibc-utils.x86_64 : Development utilities from GNU C library kdesdk-kmtrace.x86_64 : Assist with malloc debugging using glibc's "mtrace" : functionality kernel-headers.x86_64 : Header files for the Linux kernel for use by glibc latrace.i686 : LD_AUDIT feature frontend for glibc 2.4+ latrace.x86_64 : LD_AUDIT feature frontend for glibc 2.4+ 名称和简介匹配 only,使用“search all”试试。 [root@localhost ~]# yum install glibc.i6861
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[/code]
要安装32位的就选glibc.i686,64位就选glibc.x86_64。这里肯定选前者了。现在重新链接试下
[root@localhost ~]# ld -m elf_i386 -lc -otest test.o ld: skipping incompatible /usr/lib64/libc.so when searching for -lc ld: cannot find test.o: 没有那个文件或目录 [root@localhost ~]#1
2
3
4
[/code]
-l选项指定c函数库libc.so,因为动态函数库命名格式libxxx.so,所以只用写xxx就可以了。提示说找到了一个不兼容的/usr/lib64/libc.so,为什么是在64位目录下找呢?我们用的是64位系统当然要在64位目录下找了。其实并不是这个逻辑,这和/etc/ld.so.conf配置文件有关。我们可以用-L命令指定搜索的目录
[root@localhost 文档]# ld -melf_i386 -lc -L /usr/lib -otest test.o [root@localhost 文档]# ./test -bash: ./test: 权限不够1
2
3
[/code]
纳尼,又出现问题了。我一度认为这是权限问题,root账户不应该阿。于是检查用户权限设置和SELinux,发现没有问题。为了这个程序我花费了两天的时间,实在是耗不起时间,我放弃了。今天早上来,想试试运气,在这里看到了一篇文章 [原创]Linux环境汇编语言编程初步——使用C库函数 。试了一下结果成功了。
[root@localhost 文档]# ld -melf_i386 --dynamic-link /usr/lib/ld-linux.so.2 -lc -L /usr/lib -otest test.o [root@localhost 文档]# ./test $0</span>-<span class="hljs-variable">$8=-8 [root@localhost 文档]#1
2
3
4
5
[/code]
文章中的作者解释说,ld-linux.so.2是动态加载器用来查找libc.so的。那默认的动态加载器是什么呢?
[root@localhost 文档]# ll -Z /usr/lib64 | grep ld-linux lrwxrwxrwx. root root system_u:object_r:lib_t:s0 ld-linux-x86-64.so.2 -> ld-2.17.so lrwxrwxrwx. root root system_u:object_r:lib_t:s0 ld-lsb-x86-64.so.3 -> ld-linux-x86-64.so.2 [root@localhost 文档]# ll -Z /usr/lib | grep ld-linux lrwxrwxrwx. root root system_u:object_r:lib_t:s0 ld-linux.so.2 -> ld-2.17.so [root@localhost 文档]#1
2
3
4
5
6
7
[/code]
ld-linux.so.2和ld-linux-x86-64.so.2都是链接文件,都指向ld-2.17.so。但他们指向的是不同的文件,因为在不同的目录。我猜测默认的加载器应该是ld-linux-x86-64.so.2,可能因为它是64位函数库的加载器所以无法读取32位函数库的程序。就先这么理解吧,不能把时间都耗在这里,还要继续往前走,不是吗?
转载自:http://blog.csdn.net/liushihuidfg/article/details/46442209
相关文章推荐
- 64位Centos7上汇编运行32位程序
- 在64位机器上VS2012编译的32位程序在XP系统上运行提示Wow64EnableWow64FsRedirection无法定位于输入点
- 64位系统运行32位Oracle程序解决方案
- 如何在64位机器上运行32位程序
- 64位的系统可以让IIS在32位的环境下运行asp.net程序(转)
- 在64位的windows server 2003运行IIS6运行32位的.NET程序
- 在64位的windows server 2003运行IIS6运行32位的.NET程序
- 64位linux不能运行32位程序,问题解决方案
- 64位系统上运行32位程序的内存限制
- 64位 ubuntu 14.04 运行32位程序
- WOW64(判断32位程序运行在64位环境下)
- 64位linux 系统运行32位程序解决方法
- 解决.NET 32位程序运行在64位操作系统下的兼容性问题
- 64位win2003 IIS6运行32位的.NET程序
- Ubuntu64位下运行32位的程序
- 64位系统下编译32位的汇编程序
- 32位汇编程序在64位Ubuntu上的汇编和连接
- 在64位系统下编译32位汇编程序
- 检测windows 32位程序是否运行在64位系统上
- 汇编———64位电脑编译链接32位汇编程序错误与解决方法