HTML5技术

如何实现在Windows上运行Linux程序,附示例代码 - q303248153(7)

字号+ 作者:H5之家 来源:H5之家 2017-05-16 14:00 我要评论( )

还记得我们上面使用readelf读取到的信息吗? 程序头: TypeOffsetVirtAddrPhysAddrFileSizMemSizFlags Align PHDR0x0000000000000040 0x0000000000400040 0x00000000004000400x00000000000001f8 0x00000000000001f8

还记得我们上面使用readelf读取到的信息吗?

程序头: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040 0x00000000000001f8 0x00000000000001f8 R E 8 INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238 0x000000000000001c 0x000000000000001c R 1 [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x00000000000007d4 0x00000000000007d4 R E 200000 LOAD 0x0000000000000e10 0x0000000000600e10 0x0000000000600e10 0x0000000000000228 0x0000000000000230 RW 200000 DYNAMIC 0x0000000000000e28 0x0000000000600e28 0x0000000000600e28 0x00000000000001d0 0x00000000000001d0 RW 8 NOTE 0x0000000000000254 0x0000000000400254 0x0000000000400254 0x0000000000000044 0x0000000000000044 R 4 GNU_EH_FRAME 0x0000000000000680 0x0000000000400680 0x0000000000400680 0x000000000000003c 0x000000000000003c R 4 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 10 GNU_RELRO 0x0000000000000e10 0x0000000000600e10 0x0000000000600e10 0x00000000000001f0 0x00000000000001f0 R 1

这里面类型是LOAD的头代表需要加载文件的内容到内存,
Offset是文件的偏移值, VirtAddr是虚拟内存地址, FileSiz是需要加载的文件大小, MemSiz是需要分配的内存大小, Flags是内存的访问权限,
这个示例不考虑访问权限(统一使用PAGE_EXECUTE_READWRITE).

这个程序有两个LOAD头, 第一个包含了代码和只读数据(.data, .init, .rodata等节的内容), 第二个包含了可写数据(.init_array, .fini_array等节的内容).

把LOAD头对应的内容加载到指定的内存地址后我们就完成了构想中的第2个第3个步骤, 现在代码和数据都在内存中了.

接下来我们还需要处理动态链接的函数, 处理所需的信息可以从DYNAMIC头得到
DYNAMIC头包含的信息有

Dynamic section at offset 0xe28 contains 24 entries: 标记 类型 名称/值 0x0000000000000001 (NEEDED) 共享库:[libc.so.6] 0x000000000000000c (INIT) 0x4003c8 0x000000000000000d (FINI) 0x400624 0x0000000000000019 (INIT_ARRAY) 0x600e10 0x000000000000001b (INIT_ARRAYSZ) 8 (bytes) 0x000000000000001a (FINI_ARRAY) 0x600e18 0x000000000000001c (FINI_ARRAYSZ) 8 (bytes) 0x000000006ffffef5 (GNU_HASH) 0x400298 0x0000000000000005 (STRTAB) 0x400318 0x0000000000000006 (SYMTAB) 0x4002b8 0x000000000000000a (STRSZ) 63 (bytes) 0x000000000000000b (SYMENT) 24 (bytes) 0x0000000000000015 (DEBUG) 0x0 0x0000000000000003 (PLTGOT) 0x601000 0x0000000000000002 (PLTRELSZ) 48 (bytes) 0x0000000000000014 (PLTREL) RELA 0x0000000000000017 (JMPREL) 0x400398 0x0000000000000007 (RELA) 0x400380 0x0000000000000008 (RELASZ) 24 (bytes) 0x0000000000000009 (RELAENT) 24 (bytes) 0x000000006ffffffe (VERNEED) 0x400360 0x000000006fffffff (VERNEEDNUM) 1 0x000000006ffffff0 (VERSYM) 0x400358 0x0000000000000000 (NULL) 0x0

一个个看上面代码中涉及到的类型

重定位节 '.rela.plt' 位于偏移量 0x398 含有 2 个条目: 偏移量 信息 类型 符号值 符号名称 + 加数 000000601018 000100000007 R_X86_64_JUMP_SLO 0000000000000000 printf@GLIBC_2.2.5 + 0 000000601020 000200000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0 Symbol table '.dynsym' contains 4 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2) 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2) 3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__

在遍历完程序头以后, 我们可以知道有两个动态链接的函数需要重定位, 它们分别是__libc_start_main和printf, 其中__libc_start_main负责调用main函数
接下来让我们需要设置这些函数的地址

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 通用网页调用本地应用程序方案(windows平台) - 小龙女先生

    通用网页调用本地应用程序方案(windows平台) - 小龙女先生

    2017-05-16 13:00

  • H5到底如何做视频直播 - 郭东生blog

    H5到底如何做视频直播 - 郭东生blog

    2017-05-13 11:01

  • cordova 基本命令 以及如何添加,删除插件 - huangenai

    cordova 基本命令 以及如何添加,删除插件 - huangenai

    2017-05-13 09:00

  • 如何快速处理线上故障 - 倒骑的驴

    如何快速处理线上故障 - 倒骑的驴

    2017-05-02 12:01

网友点评
i