# 0x0 start

首先导入 Python.h, 并添加 python37_d.lib 依赖

# 0x1 遇到的问题

刚开始跟着教程走,结果总是提示缺少 python37_d.lib 依赖,后来根据下面的找到的教程才发现库目录才是有依赖搜索的目录

image-20220920190610497

~~ 看教程里是从上往下数第四个改成了 C:\environment\Python37\libs 结果被骗了…~~QAQ

https://blog.csdn.net/bandaoyu/article/details/105102945

image-20220920185252138


于是 vs 的 VC++ 目录的配置可以如图所示

image-20220920185347392

并且在链接器输入子目录内添加 python python37_d.lib 依赖

image-20220920185516666

这样修改 Python.h 头文件可以正确的包含进来

# 0x2 试用网上的 c 调用 python 的代码

#include<stdio.h>
#include <Python.h>
int main()
{
	PyObject *pName, *pModule, *pDict, *pFunc;
	PyObject *pArgs, *pValue;
	// 待传参数
	int time[6]={1,2,3,4,5,6};
	// 初始化 python
	Py_Initialize();
	// 检查初始化是否成功  
	if (!Py_IsInitialized())
	{
		printf("初始化失败\n");
		Py_Finalize();
	}
	// 设置 python 模块,搜寻位置,文件放在.c 文件一起
	PyRun_SimpleString("import sys");
	PyRun_SimpleString("sys.path.append('./')");
	// 获取 python 文件名,导入模块(我这里的 py 文件是 graph.py) 
	pModule = PyImport_ImportModule("graph");
	if (!pModule) {
		printf("py文件导入失败\n");
		Py_Finalize();
	}
	else {
		// 直接获取模块中的函数
		pFunc = PyObject_GetAttrString(pModule, "create_graph");
		// 验证函数是否获取成功
		if (!pFunc) {
			printf("函数导入失败\n");
			Py_Finalize();
		}
		// 将 c/c++ 类型数据转换为 python 类型,利用元组传递
		pArgs = PyTuple_New(6);
		pValue = PyLong_FromLong(time[0]);
		PyTuple_SetItem(pArgs, 0, pValue);
		pValue = PyLong_FromLong(time[1]);
		PyTuple_SetItem(pArgs, 1, pValue);
		pValue = PyLong_FromLong(time[2]);
		PyTuple_SetItem(pArgs, 2, pValue);
		pValue = PyLong_FromLong(time[3]);
		PyTuple_SetItem(pArgs, 3, pValue);
		pValue = PyLong_FromLong(time[4]);
		PyTuple_SetItem(pArgs, 4, pValue);
		pValue = PyLong_FromLong(time[5]);
		PyTuple_SetItem(pArgs, 5, pValue);
		
		// 调用直接获得的函数,并传递参数
		pValue = PyObject_CallObject(pFunc, pArgs);
		// 释放 python
		Py_Finalize();
		
		printf("success");
		return 0;
	}
}

graph.py 的代码

# -*- coding:utf-8 -*-
import xlsxwriter
def create_graph(a,b,c,d,e,f):
	# 创建一个 excel
	workbook = xlsxwriter.Workbook("排序算法比较结果.xlsx")
	# 创建一个 sheet
	worksheet = workbook.add_worksheet()
	# worksheet = workbook.add_worksheet("bug_analysis")
	# 自定义样式,加粗
	bold = workbook.add_format({'bold': 1})
	# --------1、准备数据并写入 excel---------------
	# 向 excel 中写入数据,建立图标时要用到
	headings = ["排序方法", "排序时间"]
	data = [["简单选择排序", "直接插入排序", "冒泡排序", "快速排序", "两路合并排序", "堆排序"],[a,b,c,d,e,f]]
	
	# 写入表头
	worksheet.write_row('A1', headings, bold)
 
	# 写入数据
	worksheet.write_column('A2', data[0])
	worksheet.write_column('B2', data[1])
 
	# --------2、生成图表并插入到 excel---------------
	# 创建一个柱状图 (column chart)
	chart_col = workbook.add_chart({'type': 'column'})
 
	# 配置第一个系列数据
	chart_col.add_series({'name': '=Sheet1!$B$1','categories': '=Sheet1!$A$2:$A$7','values':   '=Sheet1!$B$2:$B$7','line': {'color': 'red'},})
	# 这里的 sheet1 是默认的值,因为我们在新建 sheet 时没有指定 sheet 名
	# 如果我们新建 sheet 时设置了 sheet 名,这里就要设置成相应的值
 
	# 设置图表的 title 和 x,y 轴信息
	chart_col.set_title({'name': "排序算法结果"})
	chart_col.set_x_axis({'name': "排序方法"})
	chart_col.set_y_axis({'name':  "花费时间(ms)"})
 
	# 设置图表的风格
	chart_col.set_style(1)
 
	# 把图表插入到 worksheet 以及偏移
	worksheet.insert_chart('A10', chart_col, {'x_offset': 25, 'y_offset': 10})
	
	workbook.close()
	return 0
if __name__=="__main__":
	create_graph(10, 40, 50, 20, 10, 50)

image-20220920191141530

芜湖运行成功!

没想到第一次运行就如此顺利

在看看源文件下的目录有没有生成 .xlsx 文件

image-20230904005044622

确实多了一个,不错不错.

# 0x3 自己写一个 helloworld!

不过这个 helloworld 是调用 python 的函数打印的

image-20220920191757251

可恶新开了一个解决方案,又得重新配置包含目录了, 心累

#include<Python.h>
#include<stdio.h>
int main()
{
	PyObject* pName, * pModule, * pDict, * pFunc;
	PyObject* pArgs, * pValue;// 经典复制粘贴变量(这玩意儿自己一个一个打也太麻烦了而且也记不住呀)
	Py_Initialize();// 初始化一下~
	if (!Py_IsInitialized())// 看看初始化有没有成功
	{
		printf("初始化失败\n");
		Py_Finalize();
	}
	PyRun_SimpleString("import sys");// 设置 python 模块,搜寻位置,文件放在.c 文件一起
	PyRun_SimpleString("sys.path.append(./)");
	pModule = PyImport_ImportModule("hello");// 导入 hello.py
	if (!pModule) 
	{
		printf("py文件导入失败\n");
		Py_Finalize();
	}
	else//hello.py 如果打开成功,直接获取模块的函数
	{
		pFunc = PyObject_GetAttrString(pModule, "printhello");
		if (!pFunc) {
			printf("函数导入失败\n");
			Py_Finalize();
		}
	}
	// 没参数,就不用 demo0 里面那么麻烦啊吧啊吧了~
	pValue = PyObject_CallObject(pFunc, pArgs);// 调用函数
	Py_Finalize();// 释放 python
	return 0;
}
def printhello()
    print("hello,world!")
printhello()

写好啦~运行看看

image-20220920194206019

pFunc 可能未初始化都不让运行,真 gou!

#include<Python.h>
#include<stdio.h>
int main()
{
	PyObject* pName, * pModule, * pDict, * pFunc;
	PyObject* pArgs,* pValue;// 经典复制粘贴变量(这玩意儿自己一个一个打也太麻烦了而且也记不住呀)
	Py_Initialize();// 初始化一下~
	if (!Py_IsInitialized())// 看看初始化有没有成功
	{
		printf("初始化失败\n");
		Py_Finalize();
	}
	PyRun_SimpleString("import sys");// 设置 python 模块,搜寻位置,文件放在.c 文件一起
	PyRun_SimpleString("sys.path.append('./')");
	pModule = PyImport_ImportModule("hello");// 导入 hello.py
	if (!pModule) 
	{
		printf("py文件导入失败\n");
		Py_Finalize();
		return 1;
	}
	pFunc = PyObject_GetAttrString(pModule, "printhello");
	if (!pFunc) {
		printf("函数导入失败\n");
		Py_Finalize();
	}
	pArgs = NULL;
	pValue = PyObject_CallObject(pFunc, pArgs);// 调用函数
	Py_Finalize();// 释放 python
	return 0;
}

代码改好可以运行咯

image-20220920194510930

为啥这个 hello,world! 输出两次嘞

看来 c 调用 python 也是先把 main 函数运行一遍的哈

# 0x4 接下来,开始逆向的工作~

单独运行一下 can can

image-20220920194925163

晕!还得 py 文件才能让你老老实实运行吗!?

hello.py 拖进去一份,image-20220920195303159, 正常运行

IDA 进去看看

# 参考资料

  • https://www.jb51.net/article/212125.htm
更新于 阅读次数