如何使用Python获取PE文件的指令?

Asa*_*unt 2 python portable-executable capstone

所以我正在尝试使用 Python 为学校项目编写一个基本的反汇编程序。我正在使用 pydasm 和 capstone 库。我不明白的是如何使用 Python 实际访问程序的汇编指令。这些库允许我反汇编指令,但我不知道如何在 Python 中访问程序的指令。有人能给我一些指导吗?

谢谢。

Nei*_*tsa 5

您应该谨慎对待代码部分,因为代码部分的基础可能不仅仅包含代码(导入或只读数据可能存在于此位置)。

开始反汇编的最佳方法是查看指示 PE 文件中第一个执行字节的AddressOfEntryPoint字段IMAGE_OPTIONAL_HEADER(除非存在 TLS,但那是另一个主题)。

在 python 中浏览 PE 文件的一个非常好的库是pefile

下面是在程序入口点获取前 10 个字节的示例:

#!/usr/local/bin/python2
# -*- coding: utf8 -*-
from __future__ import print_function
import sys
import os.path
import pefile


def find_entry_point_section(pe, eop_rva):
    for section in pe.sections:
        if section.contains_rva(eop_rva):
            return section

    return None


def main(file_path):
    print("Opening {}".format(file_path))

    try:
        pe = pefile.PE(file_path, fast_load=True)
        # AddressOfEntryPoint if guaranteed to be the first byte executed.
        eop = pe.OPTIONAL_HEADER.AddressOfEntryPoint
        code_section = find_entry_point_section(pe, eop)
        if not code_section:
            return

        print("[+] Code section found at offset: "
              "{:#x} [size: {:#x}]".format(code_section.PointerToRawData,
                                          code_section.SizeOfRawData))

        # get first 10 bytes at entry point and dump them
        code_at_oep = code_section.get_data(eop, 10)
        print("[*] Code at EOP:\n{}".
              format(" ".join("{:02x}".format(ord(c)) for c in code_at_oep)))

    except pefile.PEFormatError as pe_err:
        print("[-] error while parsing file {}:\n\t{}".format(file_path,
                                                              pe_err))

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("[*] {} <PE_Filename>".format(sys.argv[0]))
    else:
        file_path = sys.argv[1]
        if os.path.isfile(file_path):
            main(file_path)
        else:
            print("[-] {} is not a file".format(file_path))
Run Code Online (Sandbox Code Playgroud)

只需将 PE 文件的名称作为第一个参数传递即可。

在上面的代码中,code_at_oep变量保存入口点的前几个字节。从那里您可以将此字节传递给 capstone 引擎。

请注意,这些第一个字节可能只是一个jmporcall指令,因此您必须遵循代码执行才能正确反汇编。正确反汇编程序仍然是计算机科学中的一个悬而未决的问题......