I have created a c program which requires an input (through scanf). Then I created the .so file and called that in a python script, so that when I run the script, input will be asked in the terminal. But when I run the python program, the terminal hangs.
Please note:
1. My c code
#include <stdio.h>
#include <string.h>
int open(void)
{
char input[20];
scanf("input = %s\n",&input);
printf("\n%s\n","input");
}
2. Command I used for compiling the code
gcc -c usb_comm.c
3.Creating .so file
gcc -shared -o libhello.so usb_comm.o
4.Relevant section of python program
Loading the .so file
from ctypes import cdll
mydll = cdll.LoadLibrary('/home/vineeshvs/Dropbox/wel/workspace/Atmel/libhello.so')
Calling the function defined in the c program
mydll.scanf("%c",mydll.open())
Thanks for listening :)
mydll.open() call scanf. Why do you call scanf in Python?
Just call mydll.open() only:
mydll.open()
UPDATE
#include <stdio.h>
void open(void)
{
char input[20];
printf("input = "); // If you want prompt
scanf("%s", input);
printf("\n%s\n", input);
}
Related
I have this little exploitable file:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
// gcc -z execstack -z norelro -fno-stack-protector -o format0 format0.c
int target;
void vuln(char *string)
{
printf(string);
if (target){
printf("Tyes yes eys");
}
}
int main(int argc, char **argv)
{
vuln(argv[1]);
return 0;
}
It's very simple, I compile like this:
gcc file.c -o file -no-pie
and then I run it like this get it to leak some values:
./file %x
38b3fda8
Which works prefectly.
But I want to automate this a bit, using python. So I try the following:
$ ./form &(python -c "print('%x'*3)")
[1] 30633
%x%x%x
[1]+ Done ./form
and this looks super weird. Firstly, the string format error is not triggered. Then it prints it's own name and some other random stuff.
I also tried doing this in gdb, with the same result.
How do I give input with python like every other tutorial online?
I think you meant:
./form $(python -c "print('%x'*3)")
What ./form &(python -c "print('%x'*3)")
does is:
/form &
(python -c "print('%x'*3)")
i.e. form is run in the background. (Process 30633) in your example.
Python is run in the foreground in a subshell. (And prints out %x%x%x to your terminal)
Creating a python module with swig is the easy part.
But what if this module has to interact with my C++ application that imports it from its embedded python instance?
For example #Flexo has made a pretty good example on how to expose the python module to the application here: How can I implement a C++ class in Python, to be called by C++?
All I want is that the application and the module are able to interact with each other like sharing variables and calling callbacks and so on so I found this answer a bit too complex for the task.
I couldn't really find much else on how to achieve this and the swig documentation doesn't explain this either ( I guess it has more to do with python and not with SWIG in particular that's why it is not mentioned in the SWIG documentation ).
I then found out that I can also just include the *_wrap.cxx file created by SWIG in my C++ application and achieve the same results (see code below)
I just started with SWIG and Python thats why my question now is, is there a better way than mine or an official way to achieve the same result? Have I overlooked something?
Can I import my swig module before initializing the python instance without having to include the Swigtest_wrap.cxx file?
That's how I made it:
1. Files
following three files contain everything needed for my python module. Containing only a class which I later want to use a as base class for a new python class.
Swigtest.h - header for python module
#ifndef SWIGTEST_H
#define SWIGTEST_H
class Callback
{
public:
Callback(){}
virtual ~Callback() {}
// we want to override this function in python
virtual void Exec() {}
static void callFunc();
static void setCallback(Callback* callback);
private:
static Callback* m_callback;
};
#endif // SWIGTEST_H
Swigtest.cpp - for python module
Callback* Callback::m_callback = nullptr;
void Callback::callFunc()
{
if(m_callback != nullptr)
{
m_callback->Exec();
return;
}
std::cout << "callback not set" << std::endl;
}
void Callback::setCallback(Callback* callback)
{
m_callback = callback;
}
Swigtest.i - interface file for SWIG
the only thing to note here is the activation of the "director" feature
%module(directors="1") mymodule
// We need to include Swigtest.h in the SWIG generated C++ file
%{
#include <iostream>
#include "Swigtest.h"
%}
// Enable cross-language polymorphism in the SWIG wrapper.
%feature("director") Callback;
// Tell swig to wrap everything in Swigtest.h
%include "Swigtest.h"
Switest.py
this python script creates a new Class derived from our Callback class and sets the callback to
this class.
import mymodule
# lets create a new class derived from callback
class MyPyCallbackFromC(mymodule.Callback):
def Exec(self):
print("this class was created in python - It worked!")
callback = mymodule.Callback()
mycallback = MyPyCallbackFromC()
# set callback to this new class
callback.setCallback(mycallback)
# now lets call it from our c++ application
main.cpp
#include <Python.h>
#include <iostream>
#include "Swigtest.h"
// we include this file to be able to append the python
// module table with our own swig wrapped module
#include "Swigtest_wrap.cxx"
int main()
{
// *_wrap.cxx has to be included for PyInit__mymodule;
// must be added before the Python instance is initialized!
PyImport_AppendInittab("_mymodule", PyInit__mymodule);
Py_Initialize();
// create Callback class
Callback* callback = new Callback();
// call Exec() function of linked class
// should return error because no class is set as Callback yet
callback->callFunc();
// execute our script which sets a new class as our callback
FILE* fp;
const char* filename;
filename = "Swigtest.py";
fp = _Py_fopen(filename, "r");
PyRun_SimpleFile(fp, filename);
// if we now call the callback from our application
// the Exec function that was defined in our python script should be executed
callback->callFunc();
delete callback;
Py_Finalize();
}
2. Building
Building the module
#swig
swig -c++ -python Swigtest.i
#compile
g++ -fpic -c Swigtest.cpp Swigtest_wrap.cxx -I/pathTo/python
#build
g++ -Wall -Wextra -shared Swigtest.o Swigtest_wrap.o -o _mymodule.so
Building the application
#compile
g++ -fpic -c Swigtest.cpp
g++ -fpic -c main.cpp -I/pathTo/python
#build
g++ main.o Swigtest.o -o libmyapp.so -I/pathTo/python -lpython3
3. Execution:
starting the application from the terminal
$ ./libmyapp.so
output
callback not set
this class was created in python - It worked!
That's it.
I have a C++ project that I would like to add an embedded python interpreter to. I've actually succeeded in this with simple scripts, but when I try doing something with Tkinter, it opens a blank window and never draws any frame or contents. I'm pretty sure it has to do with the GIL, but have been unsuccessful in finding some combination of calls that work. I've made a simple example that illustrates this with a C++ file and a python script that the compiled program runs. If you uncomment the MyPythonThread line and comment out the two that run it in a thread, then it works as expected.
It seems python knows whether it is in the "main" thread or not, regardless of which thread I Py_Initialize from.
Other info.: I'm testing this on Mac OS X 10.13.6 with homebrew installed python 2.7.15.
//
// Compile with: g++ `python-config --cflags --libs` --std=c++11 test.cc
//
#include <cstdio>
#include <Python.h>
#include <thread>
void MyPythonThread(void)
{
PyEval_InitThreads();
Py_Initialize();
const char *fname = "test.py";
PySys_SetArgv( 1, (char**)&fname );
auto fil = std::fopen(fname, "r");
PyRun_AnyFileEx( fil, NULL, 1 );
}
int main(int narg, char * argv[])
{
// This works
// MyPythonThread();
// This does not
std::thread thr(MyPythonThread);
thr.join();
return 0;
}
Here is the python script that it runs:
#!/usr/bin/env python
import Tkinter as tk
window = tk.Tk()
top_frame = tk.Frame(window).pack()
b1 = tk.Button(top_frame, text = "Button").pack()
window.mainloop()
I have the following:
/* execute_py.c */
#include <stdio.h>
#include <stdlib.h>
#include "postgres.h"
#include "fmgr.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
int
call_py()
{
printf("Executing your Python script...");
return system("python36 absolute/path/to/example.py");
}
and:
# example.py
with open("absolute/path/to/test.txt", "w") as f:
f.write("hello world")
I compiled the c script into execute_py.o and execute_py.so then created a function in the PostgreSQL server:
CREATE OR REPLACE FUNCTION call_py() RETURNS integer
AS 'absolute/path/to/execute_py', 'call_py'
LANGUAGE C STRICT;
and tried to run the function like this:
SELECT call_py();
The function returned 0. But when I checked the folder, there is no test.txt being generated.
I'm new to C and not sure what had happened. Seeking for help.
Thanks ahead!
Sorry, I was being stupid and forgot to add execution permission to example.py.
I am building a R extension which has an embedded python in it.
Everything goes well now, except that the python cannot find the encoding I needed. It keeps throwing LookupError when I do something involving 'big5'. However, if I build a stand alone c++ application, the python interpreter does find the encoding and stop throwing errors.
test.cpp for normal stand alone example in c:
#include <Python.h>
int main(int argc, char* argv[]) {
Py_SetProgramName("test"); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString(
"import codecs\n"
"f = codecs.open('big5_encoded_file', encoding='big5', mode='r')"
);
Py_Finalize();
return 0;
}
testr.cpp for R extension:
#include <R.h>
#include <Rdefines.h>
#include <Python.h>
extern "C" SEXP testpy();
SEXP testpy() {
Py_SetProgramName("test"); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString(
"import codecs\n"
"f = codecs.open('big5_encoded_file', encoding='big5', mode='r')"
);
Py_Finalize();
return R_NilValue;
}
A Makefile on ubuntu 12.10:
all: test testr.so
test: test.cpp
g++ test.cpp -o test -I/usr/include/python2.7 -lpython2.7
testr.so: testr.cpp
R CMD SHLIB testr.cpp
The ./test runs normally, but Rscript -e "dyn.load('testr.so');.Call('testpy')" produces a "LookupError: unknown encoding: big5"
Thanks
-- edit --
To build the testr.so, please set:
export PKG_CXXFLAGS=-I/usr/include/python2.7
export PKG_LIBS=-lpython2.7
I notice that it is a linking issue.
I tried to import encodings.big5 in the embedded python, but the error of undefined reference occurred. The solution in http://bugs.python.org/issue4434 works for me:
before PyInitialize() I can call dlopen("libpython2.7.so", RTLD_LAZY | RTLD_GLOBAL);