文章目录

  • 一、完整代码示例
  • 二、执行结果
  • 三、博客资源

一、完整代码示例


使用 Python 解析 ELF 文件完整代码示例 :

# coding=utf-8
# 解析 elf 文件需要导入的依赖库
# 安装 pyelftools 库成功 , 安装 elftools 库会报错
from elftools.elf.elffile import ELFFile
# 导入 Capstone 反汇编框架 , 用于解析 ELF 文件
from capstone import *def main():# 要解析的动态库路径elf_path = r'libwtcrypto.so'# 打开 elf 文件file = open(elf_path, 'rb')# 创建 ELFFile 对象 , 该对象是核心对象elf_file = ELFFile(file)# 打印 elf 文件头print(elf_file.header)# 打印 程序头入口 个数print(elf_file.num_segments())# 打印 节区头入口 个数print(elf_file.num_sections())# 遍历打印 程序头入口for segment in elf_file.iter_segments():print(segment.header)# 遍历打印 节区头入口for section in elf_file.iter_sections():print('name:', section.name)print('header', section.header)# 使用 Capstone 反汇编框架# 节区入口名称是 .text , 表示该节区数据是代码数据if section.name == '.text':# 获取节区地址file.seek(section.header['sh_addr'])# 获取节区大小sh_size = section.header['sh_size']# 读取 节区 二进制数据#   这是需要反汇编的机器码数据raw = file.read(sh_size)# 创建 Capstone 实例对象capstone = Cs(CS_ARCH_X86, CS_MODE_32)# 此处设置为 true , 表示需要显示细节 , 打开后 , 会标明每条汇编代码中对寄存器的影响#   如 : 本条汇编代码中 , 会读写哪些寄存器capstone.detail = True# 向汇编解析器中传入 节区数据 对应的 二进制数据 , 这些二进制数据都是机器码数据#   即 , 需要反汇编这些二进制数据为 汇编 代码# 第一个参数设置二进制数据# 第二个参数指的是读取 raw 二进制数据的起始地址 , 一般设置 0 即可# 得到的是反汇编后的汇编代码列表 , 如果反汇编失败 , 此处为空disasm = capstone.disasm(raw, 0)# 遍历反汇编代码列表for line in disasm:# 打印每行汇编代码的 地址 , 指令 , 操作对象text = '%08X: %s %s ' % (line.address, line.mnemonic, line.op_str)# 统计汇编代码行的字符串个数 , 保证在第 55 字节处打印寄存器读写信息# 00000000: push ebx                                     ; 读寄存器:esp 写寄存器:esp ; 机器码 :53length = len(text)if length < 55:text += ' ' * (55 - length)text += ';'# 读取操作影响到的寄存器if hasattr(line, 'regs_read') and len(line.regs_read) > 0:text += ' 读寄存器:'for j, r in enumerate(line.regs_read):if j > 0:text += ','text += '%s' % line.reg_name(r)# 写出操作影响到的寄存器if hasattr(line, 'regs_write') and len(line.regs_write) > 0:text += ' 写寄存器:'for j, r in enumerate(line.regs_write):if j > 0:text += ','text += '%s' % line.reg_name(r)text += ' ; 机器码 :'# 打印 本条汇编代码对应的 机器码for i in range(line.size):text += '%02X ' % line.bytes[i]# 打印最终数据print(text)pass# 关闭文件file.close()passif __name__ == '__main__':main()

二、执行结果


D:\001_Develop\022_Python\Python39\python.exe C:/Users/octop/PycharmProjects/ELF_Parser/main.py
Container({'e_ident': Container({'EI_MAG': [127, 69, 76, 70], 'EI_CLASS': 'ELFCLASS32', 'EI_DATA': 'ELFDATA2LSB', 'EI_VERSION': 'EV_CURRENT', 'EI_OSABI': 'ELFOSABI_SYSV', 'EI_ABIVERSION': 0}), 'e_type': 'ET_DYN', 'e_machine': 'EM_386', 'e_version': 'EV_CURRENT', 'e_entry': 0, 'e_phoff': 52, 'e_shoff': 16652, 'e_flags': 0, 'e_ehsize': 52, 'e_phentsize': 32, 'e_phnum': 7, 'e_shentsize': 40, 'e_shnum': 21, 'e_shstrndx': 20})
7
21
Container({'p_type': 'PT_PHDR', 'p_offset': 52, 'p_vaddr': 52, 'p_paddr': 52, 'p_filesz': 224, 'p_memsz': 224, 'p_flags': 4, 'p_align': 4})
Container({'p_type': 'PT_LOAD', 'p_offset': 0, 'p_vaddr': 0, 'p_paddr': 0, 'p_filesz': 11872, 'p_memsz': 11872, 'p_flags': 5, 'p_align': 4096})
Container({'p_type': 'PT_LOAD', 'p_offset': 15944, 'p_vaddr': 20040, 'p_paddr': 20040, 'p_filesz': 444, 'p_memsz': 4568, 'p_flags': 6, 'p_align': 4096})
Container({'p_type': 'PT_DYNAMIC', 'p_offset': 15956, 'p_vaddr': 20052, 'p_paddr': 20052, 'p_filesz': 272, 'p_memsz': 272, 'p_flags': 6, 'p_align': 4})
Container({'p_type': 'PT_GNU_EH_FRAME', 'p_offset': 11716, 'p_vaddr': 11716, 'p_paddr': 11716, 'p_filesz': 156, 'p_memsz': 156, 'p_flags': 4, 'p_align': 4})
Container({'p_type': 'PT_GNU_STACK', 'p_offset': 0, 'p_vaddr': 0, 'p_paddr': 0, 'p_filesz': 0, 'p_memsz': 0, 'p_flags': 6, 'p_align': 0})
Container({'p_type': 'PT_GNU_RELRO', 'p_offset': 15944, 'p_vaddr': 20040, 'p_paddr': 20040, 'p_filesz': 440, 'p_memsz': 440, 'p_flags': 6, 'p_align': 4})
name:
header Container({'sh_name': 0, 'sh_type': 'SHT_NULL', 'sh_flags': 0, 'sh_addr': 0, 'sh_offset': 0, 'sh_size': 0, 'sh_link': 0, 'sh_info': 0, 'sh_addralign': 0, 'sh_entsize': 0})
name: .dynsym
header Container({'sh_name': 11, 'sh_type': 'SHT_DYNSYM', 'sh_flags': 2, 'sh_addr': 276, 'sh_offset': 276, 'sh_size': 832, 'sh_link': 2, 'sh_info': 1, 'sh_addralign': 4, 'sh_entsize': 16})
name: .dynstr
header Container({'sh_name': 19, 'sh_type': 'SHT_STRTAB', 'sh_flags': 2, 'sh_addr': 1108, 'sh_offset': 1108, 'sh_size': 892, 'sh_link': 0, 'sh_info': 0, 'sh_addralign': 1, 'sh_entsize': 0})
name: .hash
header Container({'sh_name': 27, 'sh_type': 'SHT_HASH', 'sh_flags': 2, 'sh_addr': 2000, 'sh_offset': 2000, 'sh_size': 364, 'sh_link': 1, 'sh_info': 0, 'sh_addralign': 4, 'sh_entsize': 4})
name: .rel.dyn
header Container({'sh_name': 33, 'sh_type': 'SHT_REL', 'sh_flags': 2, 'sh_addr': 2364, 'sh_offset': 2364, 'sh_size': 24, 'sh_link': 1, 'sh_info': 0, 'sh_addralign': 4, 'sh_entsize': 8})
name: .rel.plt
header Container({'sh_name': 42, 'sh_type': 'SHT_REL', 'sh_flags': 2, 'sh_addr': 2388, 'sh_offset': 2388, 'sh_size': 280, 'sh_link': 1, 'sh_info': 6, 'sh_addralign': 4, 'sh_entsize': 8})
name: .plt
header Container({'sh_name': 46, 'sh_type': 'SHT_PROGBITS', 'sh_flags': 6, 'sh_addr': 2672, 'sh_offset': 2672, 'sh_size': 576, 'sh_link': 0, 'sh_info': 0, 'sh_addralign': 16, 'sh_entsize': 4})
name: .text
header Container({'sh_name': 51, 'sh_type': 'SHT_PROGBITS', 'sh_flags': 6, 'sh_addr': 3248, 'sh_offset': 3248, 'sh_size': 6327, 'sh_link': 0, 'sh_info': 0, 'sh_addralign': 16, 'sh_entsize': 0})
00000000: push ebx                                     ; 读寄存器:esp. 写寄存器:esp ; 机器码 :53
00000001: call 0xab                                    ; 读寄存器:esp,eip. 写寄存器:esp ; 机器码 :E8 A5 00 00 00
00000006: add ebx, 0x42b2                              ;. 写寄存器:eflags ; 机器码 :81 C3 B2 42 00 00
0000000C: lea esp, [esp - 0x18]                        ; ; 机器码 :8D 64 24 E8
00000010: lea eax, [ebx + 0x98]                        ; ; 机器码 :8D 83 98 00 00 00
00000016: mov dword ptr [esp], eax                     ; ; 机器码 :89 04 24
00000019: call 0xfffffdf0                              ; 读寄存器:esp,eip. 写寄存器:esp ; 机器码 :E8 D2 FD FF FF
0000001E: lea esp, [esp + 0x18]                        ; ; 机器码 :8D 64 24 18
00000022: pop ebx                                      ; 读寄存器:esp. 写寄存器:esp ; 机器码 :5B
00000023: ret                                          ; 读寄存器:esp. 写寄存器:esp ; 机器码 :C3
00000024: add byte ptr [eax], al                       ;. 写寄存器:eflags ; 机器码 :00 00
00000026: add byte ptr [eax], al                       ;. 写寄存器:eflags ; 机器码 :00 00
00000028: add byte ptr [eax], al                       ;. 写寄存器:eflags ; 机器码 :00 00
0000002A: add byte ptr [eax], al                       ;. 写寄存器:eflags ; 机器码 :00 00
0000002C: add byte ptr [eax], al                       ;. 写寄存器:eflags ; 机器码 :00 00
0000002E: add byte ptr [eax], al                       ;. 写寄存器:eflags ; 机器码 :00 00
00000030: lea esp, [esp - 0xc]                         ; ; 机器码 :8D 64 24 F4
00000034: mov eax, dword ptr [esp + 0x10]              ; ; 机器码 :8B 44 24 10
00000038: test eax, eax                                ;. 写寄存器:eflags ; 机器码 :85 C0
0000003A: je 0x3e                                      ; 读寄存器:eflags ; 机器码 :74 02
0000003C: call eax                                     ; 读寄存器:esp. 写寄存器:esp ; 机器码 :FF D0

三、博客资源


GitHub : https://github.com/han1202012/ELF_Parser

【Android 逆向】使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 完整代码示例 ) ★★★相关推荐

  1. 【Android 逆向】使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )

    文章目录 一.创建 Capstone 反汇编解析器实例对象 二.设置 Cs 汇编解析器显示细节 一.创建 Capstone 反汇编解析器实例对象 使用 Capstone 反汇编框架 , 首先创建 Ca ...

  2. 【Android 逆向】使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 反汇编二进制机器码 | 打印反汇编数据 )

    文章目录 一.反汇编二进制机器码 二.打印反汇编数据 一.反汇编二进制机器码 在创建 Capstone 实例对象 , 并设置 detail 属性为 True ; 在之前读取了 节区 二进制数据 , 这 ...

  3. C++模板学习02(类模板)(类模板语法、类模板与函数模板的区别、类模板中的成员函数创建时机、类模板对象做函数参数、类模板与继承、类模板成员函数类外实现、类模板分文件编写、类模板与友元)

    C++引用详情(引用的基本语法,注意事项,做函数的参数以及引用的本质,常量引用) 函数高级C++(函数的默认参数,函数的占位参数,函数重载的基本语法以及注意事项) C++类和对象-封装(属性和行为作为 ...

  4. python中for循环流程图_Python While循环语句实例演示及原理解析

    这篇文章主要介绍了Python While循环语句实例演示及原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Python 编程中 while ...

  5. python读取图像数据流_浅谈TensorFlow中读取图像数据的三种方式

    本文面对三种常常遇到的情况,总结三种读取数据的方式,分别用于处理单张图片.大量图片,和TFRecorder读取方式.并且还补充了功能相近的tf函数. 1.处理单张图片 我们训练完模型之后,常常要用图片 ...

  6. python伪造请求头x-forwarded-for的作用_Pyspider中给爬虫伪造随机请求头的实例

    Pyspider 中采用了 tornado 库来做 http 请求,在请求过程中可以添加各种参数,例如请求链接超时时间,请求传输数据超时时间,请求头等等,但是根据pyspider的原始框架,给爬虫添加 ...

  7. python网络通信传输的数据类型_Python网络编程中的网络数据和网络错误。

    上一个章节我们说的是套接字名和DNS.这篇文章我们主要解决下面问题. 我们在两台主机之间建立与关闭TCP流连接以及UDP数据报连接后.我们应该怎么准备我们需要传输的数据,该怎么对数据进行编码与格式化. ...

  8. python逐行读取txt写入excel_python 读取txt中每行数据,并且保存到excel中的实例

    使用xlwt读取txt文件内容,并且写入到excel中,代码如下,已经加了注释. 代码简单,具体代码如下: # coding=utf-8 ''' main function:主要实现把txt中的每行数 ...

  9. 将大量有规律txt文本数据转换成xml格式,在导入excel,生成excel文件,在导入spass中,对数据进行分析

    [文本数据 2.txt]下面是其中两条 Title-题名: 供应链竞争力内涵与模型构建研究 Author-作者: 余晖;张文杰; Organ-单位: 北京交通大学经济管理学院; Source-文献来源 ...

最新文章

  1. lvs后端realserver的vip管理脚本lvs-realsvr.sh
  2. EditText和TextView出现中文、英文等string串的排版问题
  3. Microsoft Build 2016 有关微软公有云Azure
  4. iOS夯实:RunLoop
  5. AVL树(一)之 C语言的实现
  6. canvas实现半圆环形进度条
  7. kafka命令行操作
  8. 八点建议写出优雅的 Java 代码
  9. 打孔屏+屏下指纹!这届iPhone全是安卓玩剩下的
  10. 汇编语言---内存变量的地址
  11. [hihocoder][Offer收割]编程练习赛46
  12. wxWindows的事件表机制
  13. 数据结构与算法学习网
  14. usc计算机博士游戏专业,USC工科博士专业排名,必然得仔细的看
  15. 山大计算机学院教务处,山东大学本科生院教务系统
  16. gels imagej 图片处理_科研论文作图之ImageJ
  17. 电机与拖动基础--第二章第二节
  18. 今日推荐:2068个开源的网站模板【免费下载】
  19. ASP.NET Core 和 EF Core系列教程——CRUD
  20. 想提高跨境电商转化率?采用这几个技巧!

热门文章

  1. memcached的基本命令(安装、卸载、启动、配置相关)
  2. 了解mysql的三种不同安装方式的区别
  3. WinSocket简单编程实验
  4. Scott Mitchell 的ASP.NET 2.0数据教程之十一: 基于数据的自定义格式化
  5. 说说JSON和JSONP,也许你会豁然开朗,含jQuery用例
  6. day16T2改错记
  7. 表单的增 删 改 查
  8. Java8 Time
  9. DedeCMS筛选简单实现方法不改后台源文件
  10. MapReduce with MongoDB and Python[ZT]