使用python从c源代码文件中提取功能代码

时间:2019-03-09 15:09:55

标签: python c parsing

我正在寻找一种在Python中解析c源文件的方法。

我知道有一个像pycparse这样的库可以解析c文件,但似乎它取决于gcc编译器。

我正在使用类似readelf的工具,该工具读取ELF文件,从函数中提取操作码。我需要读取c源文件,才能从文件中获取函数的相应c代码。

因此,如果我们在拆分屏幕上进行思考,我想在左侧看到汇编器/操作码,在右侧看到相应的C代码。

例如,当我打开用c语言编写的基本计算器时,我的二进制文件中就有一个名为“ add”的函数。我提取操作码/汇编器,并将其显示在窗口的左侧。现在,我需要一个python函数,该函数会打开目录中的所有c文件,以查找该函数的相应c代码。

有人知道如何解决这一挑战吗?

这是我现在拥有的东西的示例输出:

|==================================================================|
| Adress             | Function                       | Size       |
|====================|================================|============|
| 0x000000000000065a | sub                            | 31         |
|==================================================================|
| 55 48 89 e5 89 7d ec 89 75 e8 c7 45 fc 00 00 00 00 8b 45 ec 2b   |
| 45 e8 89 45 fc 8b 45 fc 5d c3                                    |
|==================================================================|
| int sub(int a, int b)                                            |
| {                                                                |
|   int c = 0;                                                     |
|   c = a - b;                                                     |
|   return c;                                                      |
| }                                                                |
|==================================================================|

但是我的代码当前只能与pycparse和basic-c文件一起使用,因为如果我必须在不同的c文件中搜索该函数,则pycparse会失败。我认为它使用编译器来编译代码,就像充当包装器gcc一样。

1 个答案:

答案 0 :(得分:0)

我写了一个小函数,现在我使用ctags和python从c源中提取函数体。

也许可以帮助某人...

import subprocess
import glob


def get_line_number(filename, funcname):
    found = False
    cmd = "ctags -x --c-kinds=fp " + filename + " | grep " + funcname

    output = subprocess.getoutput(cmd)
    lines = output.splitlines()

    for line in lines:
        if line.startswith(funcname + " "):    
            found = True

            if output.strip() is not "":
                output = output.split(" ")
                lines = list(filter(None, output))
                line_num = lines[2]

                print("Function found in file " + filename + " on line: " + line_num)
                return int(line_num)

    if found == False:
        #print("Function not found")
        return 0


def process_file(filename, line_num):
    print("opening " + filename + " on line " + str(line_num))

    code = ""
    cnt_braket = 0
    found_start = False
    found_end = False

    with open(filename, "r") as f:
        for i, line in enumerate(f):
            if(i >= (line_num - 1)):
                code += line

                if line.count("{") > 0:
                    found_start = True
                    cnt_braket += line.count("{")

                if line.count("}") > 0:
                    cnt_braket -= line.count("}")

                if cnt_braket == 0 and found_start == True:
                    found_end = True
                    return code


folder = "/usr/src/bash-4.4.18"
funcname = "add_alias"

for filename in glob.iglob(folder + "/*.c", recursive=True):
    line_num = get_line_number(filename, funcname)

    if line_num > 0:
        process_file(filename, line_num)
相关问题