If I have source code like this
#include <stdio.h> //test
int main(void)
{
int tmp;
scanf("%d", &tmp);
printf("%d\n", tmp);
}
I know I can give parameter with python like (python -c 'print "1234"';cat) | ./test
But I have problem with other case. For example if program get integer with scanf and string with read.
#include <stdio.h> //test
#include <unistd.h>
int main(void)
{
int tmp1=0;
char tmp2[100]={0};
scanf("%d", &tmp1);
read(0, tmp2, 100);
printf("%d %s\n", tmp1, tmp2);
}
I tried like this (python -c 'print "134\n"+"Hello World\n"';cat) | ./test I think result may be 134 Hello World However result was just 134. I can't input string with this method.
I can't find other way to solve this problem. Is there any method to solve this problem?
I'm using x64 Ubuntu 16.04 LTS and compile option was -o test -m32 test.c
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)
li = list(map(int,input().split()))
I am pretty new to c++ . I essentialy want the easiest verison of this code which takes in the input I pass in via terminal and push back the output to a vector.
I've tried:
#include <iostream>
#include<vector>
#include<string>
using namespace std;
int main()
{
string input;
vector<int> numbers;
while(getline(cin,input,' ')){
numbers.push_back(stoi(input));
}
for(int i : numbers){
cout << i << endl;
}
return 0;
}
I am using g++ 9.2.0.
The same code works fine on an online ide. I am not sure if it's an issue with the g++ compiler or not.
Weird Stuff!
Your example runs fine for me: https://ideone.com/bFLjB1
You could clean this up a bit by using the default type deduction and whitespace-splitting behavior of cin's operator>>:
std::vector<int> numbers;
int temp = 0;
while (std::cin >> temp) {
numbers.push_back(temp);
}
You can construct a container directly from whitespace delimited input.
#include <iostream>
#include <vector>
#include <iterator>
int main() {
std::vector<int> numbers(std::istream_iterator<int>(std::cin), {});
for(int i : numbers){
std::cout << i << std::endl;
}
return 0;
}
I'm trying to call a C++ function from my Python code, if I pass a Boolean or an int it works perfectly, but if I send a string, it only prints the first character.
I am compiling with:
g++ -c -fPIC foo.cpp -Wextra -Wall -o foo.o
g++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o
python3 fooWrapper.py
Here is the C++ and Python code:
Python:
from ctypes import cdll
lib = cdll.LoadLibrary("./libfoo.so")
lib.Foo_bar("hello")
c++:
#include <iostream>
#include <string>
#include <unistd.h>
void bar(char* string){
printf("%s", string);
}
extern "C" {
void Foo_bar(char* aString){
bar(aString);
}
}
I'm aware of the Boost Library, but i couldn't manage to download it, and this way works well excepts for strings.
Thank you for your help
The problem is that strings are passed as pointers to wchar_t wide characters in Python 3. And in little-endian system your string can be coded in binary as
"h\0\0\0e\0\0\0l\0\0\0l\0\0\0o\0\0\0\0\0\0\0"
Which, when printed with %s will stop at the first null terminator.
For UTF-8-encoded byte strings (char *) you need a bytes object. For example:
lib.Foo_bar("hello".encode())
or use bytes literals:
lib.Foo_bar(b"hello")
Even better if you had specified the correct argument types:
from ctypes import cdll, c_char_p
foo_bar = cdll.LoadLibrary("./libfoo.so").Foo_bar
foo_bar.argtypes = [c_char_p]
foo_bar(b"hello\n")
foo_bar("hello\n")
when run will output the following:
hello
Traceback (most recent call last):
File "foo.py", line 5, in <module>
foo_bar("hello\n")
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type
i.e. the latter call that uses a string instead of bytes would throw.
You may also process Python3 strings in C++ directly using the wchar_t type. In that case, you need to do any necessary conversions in C++ like this:
#include <iostream>
#include <locale>
#include <codecvt>
void bar(wchar_t const* aString)
{
// Kudos: https://stackoverflow.com/a/18374698
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> convert;
std::cout << convert.to_bytes(aString) << std::endl;
}
extern "C" {
void Foo_bar(wchar_t const* aString)
{
bar(aString);
}
}
You will lose Python2 compatibility, however.
I have recently bumped into a swig limitation related to the size of C++ std::string.
I have some C++ code returning a pair. I noticed that when the size of the string in the pair is smaller that 2*1024*1024*1024-64 (2GB) the pair properly returns and the string is mapped to a python native string. However if the string is greater than 2GB, then in python the string is not mapped anymore to a native python string. For example using the code below, and mapping through swig to python you can reproduce my error.
Environment:: SWIG Version 3.0.8, Ubuntu 16.04.3 LTS, g++ 5.4.0; Python 2.7.12
/////////// bridge.h
#include <vector>
#include <utility>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
pair<int, string> large_string(long sz);
long size_pstring(pair<int,string>& p);
void print_pstring(pair<int,string>& p);
string save_pstring(pair<int,string>& p);
//////////bridge.cc
#include "bridge.h"
pair<int, string> large_string(long sz){
pair<int, string> pis;
pis.first=20;
pis.second=string(sz,'A');
return pis;
}
long size_pstring(pair<int,string>& p){
return p.second.size();
}
void print_pstring(pair<int,string>& p){
cout<<"PSTRING: first="<<p.first<<" second.SZ="<<p.second.size()<<"\n";
cout<<"First 100 chars: \n"<<p.second.substr(0,100)<<"\n";
}
string save_pstring(pair<int,string>& p){
string fname="aloe.txt";
std::ofstream ofile(fname.c_str());
ofile<<p.second;
ofile.close();
return fname;
}
////////// bridge.i
%module graphdb
%include stl.i
%include "std_vector.i"
%{
#include "bridge.h"
%}
%include "bridge.h"
namespace std {
%template(p_string) pair<int,string>;
};
//////// makefile
all:
swig -c++ -python bridge.i
g++ -std=c++11 -fpic -c bridge.cc bridge_wrap.cxx -I/usr/include/python2.7/
g++ -shared *.o -o _graphdb.so
Bellow I include a session in python showing that it is probably just a matter of how string is mapped and that most probably an int rather long is used to represent the size of string in swig bridge code.
>>> s=graphdb.large_string(12)
>>> print s
(20, 'AAAAAAAAAAAA')
>>> s=graphdb.large_string(2*1024*1024*1024)
>>> print s
(20, <Swig Object of type 'char *' at 0x7fd4205a6090>)
>>> l=graphdb.size_pstring(s)
>>> print l
2147483648
>>> fname = graphdb.save_pstring(s)
Saving the string to a file is correct and next I can load the file to a python string correctly.
So my question: does anybody know what swig config option I should change to allow large strings to be properly mapped to native python ?
--Thx
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);