2019-07-22

关键字:/system/bin/sh: xxx: No such file or directory

虽然说 Android 也是基于 Linux 的,但总归来说它们的编译链还是很有可能不一样的,这就导致编译出来的程序有可能不能通用,即使它们都是基于 Linux 的。

而有些不能通用的根本原因在于程序运行时所依赖的环境不满足,比如常见的就是一些库文件缺失了。

笔者这边有个需求,需要将一个第三方的,原本目标运行环境是 Linux 嵌入式环境的可执行程序在 Android4.4 的环境上运行起来。

刚一接到这个需求的时候我就一阵头大,一想到编译链不同我就两脚发软。

果然,刚一想运行这一程序,它就给报了一个这样的错误提示

/system/bin/sh: ./system/home1/ctstor/ctserver: No such file or directory

想都不带想的,肯定是编译链不同导致运行环境不满足使得程序不能运行的。

但问题还得解决啊,总不能直接就和领导说编译链不同搞不了吧。

怎么办呢?看看它到底缺了些什么。

用纯正 Linux 环境来看一下这个可执行程序的环境依赖信息。笔者这边是将程序放到 ubuntu 下去分析,因为笔者的 Android4.4 上没有相关程序。

通过以下命令查看这个可执行程序的编译依赖信息

readelf -l xxx

结果如下所示

Elf file type is EXEC (Executable file)

Entry point0xe6e0There are8 program headers, starting at offset 52Program Headers:

Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align

EXIDX0x00be90 0x00013e90 0x00013e90 0x00008 0x00008 R 0x4PHDR0x000034 0x00008034 0x00008034 0x00100 0x00100 R E 0x4INTERP0x000134 0x00008134 0x00008134 0x00013 0x00013 R 0x1[Requesting program interpreter:/lib/ld-linux.so.3]

LOAD0x000000 0x00008000 0x00008000 0x0be9c 0x0be9c R E 0x8000LOAD0x00c000 0x0001c000 0x0001c000 0x0067c 0x006cc RW 0x8000DYNAMIC0x00c01c 0x0001c01c 0x0001c01c 0x00130 0x00130 RW 0x4NOTE0x000148 0x00008148 0x00008148 0x00020 0x00020 R 0x4GNU_STACK0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4Section to Segment mapping:

Segment Sections...00.ARM.exidx01

02.interp03 .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .ARM.exidx .eh_frame04.init_array .fini_array .jcr .dynamic .got .data .bss05.dynamic06 .note.ABI-tag07

可以看到上面红色加粗的部分表明程序的运行需要一个 “解释器” 。说白了就是要想加载这个程序,运行环境中必须要有上面黄色加粗部分的库,就是 /lib/ld-linux.so.3 库。

那这是不是说,只要我将这个库放到指定路径下,它就可以加载了呢?试一下就知道了。

不过在这之前,我们还有一个关键的步骤:必须要知道这个可执行程序所使用的编译链。

笔者这边有个文档,记载了它的编译链为: arm-none-linux-gnueabi

直接去网上下载这个编译链,然后在里面找到 ld-linux.so.3 库,再放进 Android 开发板中去就好了。

这里要注意,它要求的是根目录下的 lib 目录,Android4.4 系统默认是不带 /lib 目录的。要自己创建。

先开一下根目录的操作仅限

mount -o remount r,w /

当然,这一步不见得都能执行成功,如果执行不成功,那就得您自个去找找原因了。

然后再 mkdir /lib 并将 ld-linux.so.3 下载到这个目录下去。

这里也有一个关键点:不能修改创建出来的目录以及下载下去的文件的权限。否则的话,在运行的时候是会报 permission denied 错误的。

然后试一下,这个程序果然不报前面那个 No such file or directory 的错误了。但是报了另外一个错误

error while loading shared libraries: libqte.so.3: cannot open shared object file: No such file or directory

还是 No such file or directory 错误,只不过是另外一个 No such file or directory 错误。而且这个错误也很明显,就是运行时的动态库缺失。

这个时候,得再回到前面 ubuntu 中去看看这个可执行程序在运行时期需要什么库依赖。

readelf -d xxx

然后可以看到下列结果

Dynamic section at offset 0xc01c contains 33entries:

Tag Type Name/Value0x00000001 (NEEDED) Shared library: [libqte.so.3]0x00000001 (NEEDED) Shared library: [libts-0.0.so.0]0x00000001 (NEEDED) Shared library: [librt.so.1]0x00000001 (NEEDED) Shared library: [libpthread.so.0]0x00000001 (NEEDED) Shared library: [libdl.so.2]0x00000001 (NEEDED) Shared library: [libstdc++.so.6]0x00000001 (NEEDED) Shared library: [libm.so.6]0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]0x00000001 (NEEDED) Shared library: [libc.so.6]0x0000000f (RPATH) Library rpath: [/usr/qte338-target2/lib]0x0000000c (INIT) 0xd778

0x0000000d (FINI) 0x1317c

0x00000019 (INIT_ARRAY) 0x1c000

0x0000001b (INIT_ARRAYSZ) 20(bytes)0x0000001a (FINI_ARRAY) 0x1c014

0x0000001c (FINI_ARRAYSZ) 4(bytes)0x00000004 (HASH) 0x8168

0x00000005 (STRTAB) 0xa184

0x00000006 (SYMTAB) 0x8b24

0x0000000a (STRSZ) 10293(bytes)0x0000000b (SYMENT) 16(bytes)0x00000015 (DEBUG) 0x0

0x00000003 (PLTGOT) 0x1c14c

0x00000002 (PLTRELSZ) 2608(bytes)0x00000014(PLTREL) REL0x00000017 (JMPREL) 0xcd48

0x00000011 (REL) 0xcd08

0x00000012 (RELSZ) 64(bytes)0x00000013 (RELENT) 8(bytes)0x6ffffffe (VERNEED) 0xcc88

0x6fffffff (VERNEEDNUM) 4

0x6ffffff0 (VERSYM) 0xc9ba

0x00000000 (NULL) 0x0

然后就很清晰了,将上面的几个标示为 NEEDED 的库文件全部拷贝到 /lib 目录下。这些库文件一般都可以在指定的编译链中找到,如果有一些特殊的库不是直接包含在编译链中的,那就得另想办法去寻找了。一般而言,稍微负点责任的程序提供方都会将这些库一并给过来的。

在弄好库文件以后,再去运行就发现可以了。我们的原本目标运行环境是嵌入式 Linux 环境的可执行程序就在 Android 下跑起来了。

安卓跑linux程序_Android下运行Linux可执行程序相关推荐

  1. 安卓跑linux程序_Android 运行 Linux 可执行程序

    /**************************************************************************** * Android 运行 Linux 可执行 ...

  2. linux 下怎么将可执行文件做成镜像 开机就能运行这个可执行文件,圣诞老人的ELFs:在没有execve的情况下运行Linux可执行文件...

    这篇博客是年度的12 Days of HaXmas系列博客中的第11篇. Executable and Linkable Format ( ELF ) 是许多类Unix操作系统(如Linux,大多数现 ...

  3. 鸿蒙os能运行win软件吗,暂无在Windows、Linux、Android下运行华为鸿蒙OS的模拟器

    在网络上有人开发出了Flmage,用它可以模拟运行谷歌的Fuchsia OS,然后有人想是不是也有同样的工具能够运行华为鸿蒙OS(HarmonyOS).可惜的是,在Windows.Linux.Andr ...

  4. Android在Shell环境下运行Linux命令

    Android的底层其实linux,所以可以在android shell下运行linux命令,尤其是经过root处理的Android系统,基本上可以通过调用linux命令完全操作手机,下面的RootC ...

  5. 成功解决Windows10环境下运行Linux系统下的.sh文件

    成功解决Windows10环境下运行Linux系统下的.sh文件 目录 解决问题 解决方法 解决问题 Windows10环境下运行Linux系统下的.sh文件 解决方法 .sh是shell scrip ...

  6. 解决Vmware虚拟机下运行Linux电脑发出声音

    在Vmware虚拟机下运行Linux,电脑会发出嘟嘟的声音,总结为以下两种问题: 1.启动Vmware打开Linux和关闭Linux发出声音 在Vmware虚拟机上安装了Linux系统,每次打开和关闭 ...

  7. 在win7中访问删除linux硬盘分区,win7和linux双系统下,删除linux不能启动win7的解决方法...

    win7和linux双系统下,删除linux不能启动win7的解决方法 (6页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 双系统下删除 ...

  8. 小技巧:让linux程序在后台运行

    有些时候,我们需要在终端启动一个程序,并使之运行--但是如果关闭终端,那么这个程序也就随着关闭了.那么有没有什么方法在关闭终端后,让已经从这个终端启动的程序继续运行呢? 前置知识: xterm,con ...

  9. 如何在linux centos 环境下运行.exe文件

    linux是不能运行window下的可执行文件的,必须借助于wine.百度了以下wine如下: Wine ("Wine Is Not an Emulator" 的 递归缩写)是一个 ...

最新文章

  1. java明星养成游戏_#IT明星不是梦#Java14不得不知的5个新功能
  2. 算法训练营03-数组链表
  3. html效果属性是,htmltransition属性
  4. 母函数——找单词(hdu2082)
  5. 适用初学者的5种Python数据输入技术
  6. 假期还剩 2 天,Python 爬取途牛网,揭秘哪里人少景美!
  7. 机器学习模型可解释性进行到底 ——PDPICE图(三)
  8. 【软件分析/静态程序分析学习笔记】1.静态程序分析(Static Program Analysis)介绍
  9. 【道高一尺,魔高一丈】Python爬虫之如何应对网站反爬虫策略
  10. 十大顶级大数据可视化工具
  11. 12行代码拿下所有lol皮肤!!Python超简单爬虫【内附详细教学 】
  12. The server cannot or will not process the request due to something that is perceived to be a client.
  13. 【PMP】项目生命周期和开发生命周期
  14. 制作WINDOWS图标
  15. Daily English(每日一句)
  16. iOS逆向-支付宝基金之统计实时收益
  17. java找不到或无法加载主类
  18. 水仙花数的while方法
  19. 一个人有怎样的心灵,就拥有怎样的世界。----人是自己观念的奴隶
  20. python 获取当前网页_你好,想知道python scrapy 如何获取当前页面url?

热门文章

  1. OptaPlanner –具有真实道路距离的车辆路线
  2. 使用Project Lombok减少Java应用程序中的样板代码
  3. 使用Spring Roo进行概念验证
  4. Spring Boot –现代Java应用程序的基础
  5. JDeveloper中的Java反编译器
  6. 为什么我会在2012年的新企业Java项目中使用Java EE而不是Spring
  7. 高级SmartGWT教程,第2部分
  8. java 提取url参数_Java提取URL某个参数的值
  9. java swing 左上角图标_科学网—Matlab: 学习GUI(修改窗口左上角图标而不warning) - 刘磊的博文...
  10. mongodb数据库淘汰_mongodb 内存数据淘汰策略