51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 3856|回复: 1
打印 上一主题 下一主题

64位Centos7上汇编运行32位程序

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2018-3-1 17:16:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. 首先贴上源代码。

  2. #文件名test.s
  3. .data
  4. msg: .string "$0</span>-<span class="hljs-variable">$8=%d\n"
  5. .text
  6. .global _start
  7. _start:
  8. movl $0, %eax
  9. movl $8, %ebx
  10. subl %ebx, %eax
  11. pushl %eax
  12. lea msg, %eax
  13. pushl %eax
  14. call printf
  15. movl $0, %ebx
  16. movl $1, %eax
  17. int $0x80
复制代码
功能非常简单,就是计算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软件包。
  1. [root@localhost ~]# yum search glibc
  2. 已加载插件:fastestmirror, langpacks
  3. Loading mirror speeds from cached hostfile
  4. * base: mirrors.sina.cn
  5. * extras: mirrors.sina.cn
  6. * updates: mirrors.cqu.edu.cn
  7. ================================= N/S matched: glibc =================================
  8. glibc-common.x86_64 : Common binaries and locale data for glibc
  9. compat-glibc.x86_64 : Compatibility C library
  10. compat-glibc-headers.x86_64 : Header files for development using standard C libraries.
  11. glibc.i686 : The GNU libc libraries
  12. glibc.x86_64 : The GNU libc libraries
  13. glibc-devel.i686 : Object files for development using standard C libraries.
  14. glibc-devel.x86_64 : Object files for development using standard C libraries.
  15. glibc-headers.x86_64 : Header files for development using standard C libraries.
  16. glibc-static.i686 : C library static libraries for -static linking.
  17. glibc-static.x86_64 : C library static libraries for -static linking.
  18. glibc-utils.x86_64 : Development utilities from GNU C library
  19. kdesdk-kmtrace.x86_64 : Assist with malloc debugging using glibc's "mtrace"
  20.                       : functionality
  21. kernel-headers.x86_64 : Header files for the Linux kernel for use by glibc
  22. latrace.i686 : LD_AUDIT feature frontend for glibc 2.4+
  23. latrace.x86_64 : LD_AUDIT feature frontend for glibc 2.4+

  24.   名称和简介匹配 only,使用“search all”试试。
  25. [root@localhost ~]# yum install glibc.i686

  26. 要安装32位的就选glibc.i686,64位就选glibc.x86_64。这里肯定选前者了。现在重新链接试下

  27. [root@localhost ~]# ld -m elf_i386 -lc -otest test.o
  28. ld: skipping incompatible /usr/lib64/libc.so when searching for -lc
  29. ld: cannot find test.o: 没有那个文件或目录
  30. [root@localhost ~]#
复制代码
-l选项指定c函数库libc.so,因为动态函数库命名格式libxxx.so,所以只用写xxx就可以了。提示说找到
了一个不兼容的/usr/lib64/libc.so,为什么是在64位目录下找呢?我们用的是64位系统当然要在64位
目录下找了。其实并不是这个逻辑,这和/etc/ld.so.conf配置文件有关。我们可以用-L命令指定搜索
的目录
  1. [root@localhost 文档]# ld -melf_i386 -lc -L /usr/lib -otest test.o
  2. [root@localhost 文档]# ./test
  3. -bash: ./test: 权限不够
复制代码
纳尼,又出现问题了。我一度认为这是权限问题,root账户不应该阿。于是检查用户权限设置和
SELinux,发现没有问题。为了这个程序我花费了两天的时间,实在是耗不起时间,我放弃了。今
天早上来,想试试运气,在这里看到了一篇文章 [原创]Linux环境汇编语言编程初步——使用C库
函数 。试了一下结果成功了。
  1. [root@localhost 文档]# ld -melf_i386 --dynamic-link /usr/lib/ld-linux.so.2 -lc -L /usr/lib -otest test.o
  2. [root@localhost 文档]# ./test
  3. $0</span>-<span class="hljs-variable">$8=-8
  4. [root@localhost 文档]#

  5. 文章中的作者解释说,ld-linux.so.2是动态加载器用来查找libc.so的。那默认的动态加载器是什么呢?

  6. [root@localhost 文档]# ll -Z /usr/lib64 | grep ld-linux
  7. lrwxrwxrwx. root root system_u:object_r:lib_t:s0       ld-linux-x86-64.so.2 -> ld-2.17.so
  8. lrwxrwxrwx. root root system_u:object_r:lib_t:s0       ld-lsb-x86-64.so.3 -> ld-linux-x86-64.so.2
  9. [root@localhost 文档]# ll -Z /usr/lib | grep ld-linux
  10. lrwxrwxrwx. root root system_u:object_r:lib_t:s0       ld-linux.so.2 -> ld-2.17.so
  11. [root@localhost 文档]#
复制代码
ld-linux.so.2和ld-linux-x86-64.so.2都是链接文件,都指向ld-2.17.so。但他们指向的是不同的文件,因
为在不同的目录。我猜测默认的加载器应该是ld-linux-x86-64.so.2,可能因为它是64位函数库的加载
器所以无法读取32位函数库的程序。就先这么理解吧,不能把时间都耗在这里,还要继续往前走,不
是吗?

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-11-24 06:15 , Processed in 0.063377 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表