我正在寻找一种在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一样。
答案 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)