multiple LD_REPLOAD sharing variables - c++

My purpose is quite simple: when I start the mongoose server, the server will initialize a variable which is defined by me. To do this, I hooked __libc_start_main. Then when the server receives a request, it will print out that initialized variable. To do this, I hooked recv. Below is my code.
#include <string>
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
#include "common-structure.h"
# define dprintf(fmt...)
data datainfo; //defined in common-structure.h
typedef int (*main_type)(int, char**, char**);
struct arg_type
{
char **argv;
int (*main_func) (int, char **, char **);
};
main_type saved_init_func = NULL;
void tern_init_func(int argc, char **argv, char **env){
dprintf("%04d: __tern_init_func() called.\n", (int) pthread_self());
if(saved_init_func)
saved_init_func(argc, argv, env);
datainfo.age = 10;
}
typedef void (*fini_type)(void*);
fini_type saved_fini_func = NULL;
extern "C" int my_main(int argc, char **pt, char **aa)
{
int ret;
arg_type *args = (arg_type*)pt;
dprintf("%04d: __libc_start_main() called.\n", (int) pthread_self());
ret = args->main_func(argc, args->argv, aa);
return ret;
}
extern "C" int __libc_start_main(
void *func_ptr,
int argc,
char* argv[],
void (*init_func)(void),
void (*fini_func)(void),
void (*rtld_fini_func)(void),
void *stack_end)
{
typedef void (*fnptr_type)(void);
typedef int (*orig_func_type)(void *, int, char *[], fnptr_type,
fnptr_type, fnptr_type, void*);
orig_func_type orig_func;
arg_type args;
void * handle;
int ret;
// Get lib path.
Dl_info dli;
dladdr((void *)dlsym, &dli);
std::string libPath = dli.dli_fname;
libPath = dli.dli_fname;
size_t lastSlash = libPath.find_last_of("/");
libPath = libPath.substr(0, lastSlash);
libPath += "/libc.so.6";
libPath = "/lib/x86_64-linux-gnu/libc.so.6";
if(!(handle=dlopen(libPath.c_str(), RTLD_LAZY))) {
puts("dlopen error");
abort();
}
orig_func = (orig_func_type) dlsym(handle, "__libc_start_main");
if(dlerror()) {
puts("dlerror");
abort();
}
dlclose(handle);
dprintf("%04d: __libc_start_main is hooked.\n", (int) pthread_self());
args.argv = argv;
args.main_func = (main_type)func_ptr;
saved_init_func = (main_type)init_func;
saved_fini_func = (fini_type)rtld_fini_func;
ret = orig_func((void*)my_main, argc, (char**)(&args),
(fnptr_type)tern_init_func, (fnptr_type)fini_func,
rtld_fini_func, stack_end);
return ret;
}
//hook recv
extern "C" ssize_t recv(int sockfd, void *buf, size_t len, int flags)
{
ssize_t (*orig_recv)(int sockfd, void *buf, size_t len, int flags);
orig_recv = dlsym(RTLD_NEXT, "recv");
orig_recv(sockfd, buf, len, flags);
printf("age is %d\n", datainfo.age);
}
However, when I makefile, I get the error: invalid conversion from ‘void*’ to ‘ssize_t (*)(int, void*, size_t, int) coming from dlsym(RTLD_NEXT, "recv");. My another question is can I achieve my goal in this way? If not, what is the correct way?

C++ is much more strongly typed than C, you need to explicitly cast void * to the correct type.
For example:
extern "C" ssize_t recv(int sockfd, void *buf, size_t len, int flags)
{
using orig_recv_t = ssize_t (*)(int, void *, size_t, int);
// Or for pre C++11 compilers: typedef ssize_t (*orig_recv_t)(int, void *, size_t, int);
orig_recv_t orig_recv;
orig_recv = reinterpret_cast<orig_recv_t>(dlsym(RTLD_NEXT, "recv"));
orig_recv(sockfd, buf, len, flags);
printf("age is %d\n", datainfo.age);
}

Related

how to encrypt and decrypt string with openssl?

Trying to encrypt and decrypt strings with evp functions of openssl.
I tried the following source code but I got unexpected results (garbege output).
What I am missing?
#include <stdio.h>
#include <unistd.h>
#if 1
#include <openssl/evp.h>
char *se_evp_encrypt(char *ssid, char *data, int inl, char *ret, int *rb)
{
int i, tmp, ol;
EVP_CIPHER_CTX evpctx;
char key[EVP_MAX_KEY_LENGTH] = {0};
char iv[EVP_MAX_IV_LENGTH] = {0};
*ret = '\0';
strncpy(key, ssid, EVP_MAX_KEY_LENGTH);
strncpy(iv, ssid, EVP_MAX_IV_LENGTH);
EVP_EncryptInit(&evpctx, EVP_bf_cbc(), key, iv);
EVP_EncryptUpdate(&evpctx, ret, &ol, data, inl);
*rb = ol;
EVP_EncryptFinal(&evpctx, ret, &ol);
return ret;
}
char *se_evp_decrypt(char *ssid, char *ct, int inl, char *pt)
{
int ol;
EVP_CIPHER_CTX evpctx;
char key[EVP_MAX_KEY_LENGTH] = {0};
char iv[EVP_MAX_IV_LENGTH] = {0};
char final[EVP_MAX_BLOCK_LENGTH];
*pt = '\0';
strncpy(key, ssid, EVP_MAX_KEY_LENGTH);
strncpy(iv, ssid, EVP_MAX_IV_LENGTH);
EVP_DecryptInit(&evpctx, EVP_bf_cbc(), key, iv);
EVP_DecryptUpdate(&evpctx, pt, &ol, ct, inl);
if (!ol) /* there's no block to decrypt */
{
return "";
}
pt[ol] = 0;
EVP_DecryptFinal(&evpctx, final, &inl);
return pt;
}
int main(int argc, char *argv[])
{
char str[] = "abcdef123456789";
char buf[256] = "", buf2[256] = "";
int i;
se_evp_encrypt("anyssid", str, strlen(str), buf, &i);
printf("Ciphertext is %d bytes. %d\n", i, strlen(str));
se_evp_decrypt("anyssid", buf, i, buf2);
printf("Decrypted: >>%s<<\n", buf2);
}
#endif
fixed the source code in this way
#include <stdio.h>
#include <unistd.h>
#if 1
#include <openssl/evp.h>
char *se_evp_encrypt(char *ssid, char *data, int inl, char *ret, int *rb)
{
int i, tmp, ol;
EVP_CIPHER_CTX evpctx = {0};
char key[EVP_MAX_KEY_LENGTH] = {0};
char iv[EVP_MAX_IV_LENGTH] = {0};
*ret = '\0';
strncpy(key, ssid, EVP_MAX_KEY_LENGTH);
strncpy(iv, ssid, EVP_MAX_IV_LENGTH);
EVP_EncryptInit(&evpctx, EVP_bf_cbc(), key, iv);
EVP_EncryptUpdate(&evpctx, ret, &ol, data, inl);
EVP_EncryptFinal(&evpctx, ret + ol, &tmp);
*rb = ol + tmp;
return ret;
}
char *se_evp_decrypt(char *ssid, char *ct, int inl, char *pt)
{
int ol, tmp;
EVP_CIPHER_CTX evpctx;
char key[EVP_MAX_KEY_LENGTH] = {0};
char iv[EVP_MAX_IV_LENGTH] = {0};
char final[EVP_MAX_BLOCK_LENGTH];
*pt = '\0';
strncpy(key, ssid, EVP_MAX_KEY_LENGTH);
strncpy(iv, ssid, EVP_MAX_IV_LENGTH);
EVP_DecryptInit(&evpctx, EVP_bf_cbc(), key, iv);
EVP_DecryptUpdate(&evpctx, pt, &ol, ct, inl);
EVP_DecryptFinal(&evpctx, pt+ol , &tmp);
pt[ol+tmp] = 0;
return pt;
}
int main(int argc, char *argv[])
{
char str[] = "abcdef123456789";
char buf[256] = "", buf2[256] = "";
int i;
se_evp_encrypt("anyssid", str, strlen(str), buf, &i);
printf("Ciphertext is %d bytes. %d\n", i, strlen(str));
se_evp_decrypt("anyssid", buf, i, buf2);
printf("Decrypted: >>%s<<\n", buf2);
}
#endif

ERROR : ‘fuse_operations_compat2’ has no non-static data member named ‘readdir’

I am trying to build a simple filesystem using fuse 2.9.7 to store an avifile in it. But i am having trouble in finding the solution for these error.
‘fuse_operations_compat2’ has no non-static data member named ‘readdir’
I have this main.cpp
#include<iostream>
#include<fuse.h>
#include "include/AVIContainer.h"
#include "include/Fuse.h"
using namespace std;
int main(int argc, char* argv[])
{
AVIContainer *avi = new AVIContainer(320, 240, 30, 90);
avi->WriteToFile("test.avi");
struct fuse_operations oper = {
.getattr = getattr_callback,
.readdir = readdir_callback,
.open = open_callback,
.read = read_callback,
};
return fuse_main(argc, argv , &oper);
}
and these are the header file(.cpp)
#define FUSE_USE_VERSION 30
#include<fuse.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<time.h>
#include<string.h>
#include<stdlib.h>
#include "Fuse.h"
char filename[30] = "/avifile";
char filename2[30] = "avifile";
int getattr_callback(const char *path, struct stat *st)
{
st->st_uid = getuid();
st->st_gid = getgid();
st->st_atime = time(NULL);
st->st_mtime = time(NULL);
if(strcmp(path, "/") == 0)
{
st->st_mode = S_IFDIR | 0755;
st->st_nlink = 2;
}
if(strcmp(path,filename) == 0)
{
st->st_mode = S_IFREG | 0644;
st->st_nlink = 1;
st->st_size = datasize;
}
return 0;
}
int readdir_callback(const char *path, void *buffer, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
{
filler(buffer, ".", NULL, 0);
filler(buffer, "..", NULL, 0);
if(strcmp(path, "/") == 0)
{
filler(buffer, filename2, NULL, 0);
}
return 0;
}
int read_callback(const char *path, char *buffer, size_t size, off_t offset, struct fuse_file_info *fi)
{
unsigned int SizetoRead = size;
if( (offset + size) > datasize)
{
SizetoRead = datasize - offset;
}
memcpy(buffer, databuffer + offset, SizetoRead);
return SizetoRead;
}
int open_callback(const char *path, fuse_file_info *fi)
{
return 0;
}
and this is .h file
#ifndef FUSE
#define FUSE
#include <fuse.h>
uint8_t* get_data();
unsigned int get_size();
int getattr_callback(const char *path, struct stat *st);
int read_callback(const char *path, char *buffer, size_t size, off_t offset, struct fuse_file_info *fi);
int readdir_callback(const char *path, void *buffer, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi);
int open_callback(const char *path, fuse_file_info *fi);
#endif
I think the problem is with version of fuse , though not sure.
please help, thanks in advance
Edit:
You are using the high level fuse ops (vs the low level ones).
here is what you can do with it (fuse_compat.h)
struct fuse_operations_compat2 {
int (*getattr) (const char *, struct stat *);
int (*readlink) (const char *, char *, size_t);
int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t_compat);
int (*mknod) (const char *, mode_t, dev_t);
int (*mkdir) (const char *, mode_t);
int (*unlink) (const char *);
int (*rmdir) (const char *);
int (*symlink) (const char *, const char *);
int (*rename) (const char *, const char *);
int (*link) (const char *, const char *);
int (*chmod) (const char *, mode_t);
int (*chown) (const char *, uid_t, gid_t);
int (*truncate) (const char *, off_t);
int (*utime) (const char *, struct utimbuf *);
int (*open) (const char *, int);
int (*read) (const char *, char *, size_t, off_t);
int (*write) (const char *, const char *, size_t, off_t);
int (*statfs) (const char *, struct statfs *);
int (*flush) (const char *);
int (*release) (const char *, int);
int (*fsync) (const char *, int);
int (*setxattr) (const char *, const char *, const char *, size_t, int);
int (*getxattr) (const char *, const char *, char *, size_t);
int (*listxattr) (const char *, char *, size_t);
int (*removexattr) (const char *, const char *);
};
try having the version as 32
In your main.cpp, the fuse.h Header is included before the version is set, so when your main file is compiled (where the readdir is supposed to be set), FUSE is loaded in compatibility mode. Removing the #include<fuse.h> from your main file should solve the problem as FUSE is then included via your header file, which sets the correct version.

Play a memory buffer with libvlc

I want to play a buffer in libvlc which is filled by a signal/slot from another thread. I've used read_callbacks of libvlc but it can be compiled with mingw and compiling it for msvc is a hard process (see here).(I want to compile my program in msvc2012). so I want to use imem option and I wrote the following code but it crashed and do not show anything.
#include <QMainWindow>
#include <QFile>
#include <vlc/vlc.h>
#include <vlc/libvlc_media_player.h>
#include <vlc/libvlc_media.h>
using namespace std ;
const int len = (820 * 600 * 4) + 31;
int imemGetCallback (void *data, const char *cookie,int64_t *dts, int64_t *pts,unsigned *flags, size_t * bufferSize, void ** buffer);
int imemReleaseCallback (void *data, const char *cookie, size_t bufferSize, void * buffer);
int main(){
char smem_options1[2000];
char venc_options[1000];
sprintf(venc_options,"bframes=6,ref=6");
char str_imem_get[100], str_imem_release[100],str_imem_data[100];
sprintf(str_imem_get, "--imem-get=%ld", imemGetCallback);
sprintf(str_imem_release, "--imem-release=%ld", imemReleaseCallback);
const char * const vlc_args[] = {
"-I","dummy",
"--ignore-config",
"--demux","rawvideo",
"--rawvid-fps","30",
"--rawvid-width","820",
"--rawvid-height","600",
"--rawvid-chroma","RV24",
"--imem-channels=1",
"--imem-data=0",
"--imem-cat=4",
"--imem-fps=30",
"--imem-codec=none",
str_imem_get,
str_imem_release
};
libvlc_instance_t * inst_broadcast =libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);;// libvlc_new(vlc_argc, vlc_argv);
libvlc_media_t * m = libvlc_media_new_location(inst_broadcast, "imem://");
auto _vlcmp = libvlc_media_player_new_from_media(m);
libvlc_media_player_play(_vlcmp);
}
int imemGetCallback (void *data, const char *cookie,int64_t *dts, int64_t *pts,unsigned *flags, size_t * bufferSize, void ** buffer)
{
int64_t uS = 33333; // 30 fps
static int index=0;
*bufferSize = len;
*buffer = buf;
*dts = *pts = 33333;
return 1;
}
int imemReleaseCallback (void *data, const char *cookie, size_t bufferSize, void * buffer)
{
return 0;
}
how can I use imem option to do the job?

Visual C++ - get() - redefinition different type modifiers c2373

I've been at this for some time now. I need a basic IRC Ping Pong function to return the the proper response when the IRC server pings. I changed the name of the function get() to something else and I'm still getting the error. I thought perhaps the function name get() was already defined in one of the includes or something else.
#include "stdafx.h"
#include "Ping_Pong.h"
#include <iostream>
#include <ws2tcpip.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CWinApp theApp;
#define MT4_EXPFUNC __declspec(dllexport)
#pragma comment(lib, "Ws2_32.lib")
class MT4_EXPFUNC IRC {
private:
char buf[513];
char rbuf[513];
char sbuf[513];
char *tok;
int recv_bytes;
int irc_socket;
struct addrinfo hints;
struct addrinfo *results;
public:
char *nick, *user, *host, *chan, *type, *mesg;
int irc_connect(const char *host, const char *port, const char *nick);
void socket_err(const char* err_string);
//int join(const char *channel);
This is the name of the function in question
int __stdcall get();
char *check(const char* test_str);
char *pop_arg(char **save_ptr);
int init_comarg();
int say(const char *channel, const char *message);
int sayf(const char *channel, const char *message, ...);
int mode(const char *channel, const char *mode, char *target);
//void die();
};
And this is the function I'm having a problem with.
MT4_EXPFUNC int __stdcall IRC::get()
{
memset(rbuf, 0, 513);
recv_bytes = recv(irc_socket, rbuf, sizeof(rbuf), 0);
if (recv_bytes <= 0) {
return -1;
}
std::cout << rbuf;
// Auto-Respond to PING messages.
if (rbuf[0] == 'P' && rbuf[1] == 'I') {
tok = strtok(rbuf, "PING :");
sprintf(buf, "PONG %s", tok-1 );
send(irc_socket, buf, strlen(buf), 0);
std::cout << buf;
memset(buf, 0, 513);
}
if ( strstr(rbuf, "PRIVMSG")) {
memcpy(sbuf, rbuf, 513);
nick = strtok(sbuf, "!") + 1;
user = strtok(NULL, "#");
host = strtok(NULL, " ");
type = strtok(NULL, " ") - 1;
chan = strtok(NULL, " ");
mesg = strtok(NULL, ":");
}
return 1;
}
In the tutorial linked below, a .def file was suggested with the following code:
Library "Ping_Pong"
Export get
I removed the .def and it worked.
http://www.xpworx.com/metatrader-mql-articles/mql4-articles/create-your-own-metatrader-extension-dll.php

overloading new and delete in c++

HI All,
I was trying to overload new and delete to fix a memory leak problem in my project. But got stuck with some compilation error.
Currently this code is bit shabby
Here is my hdr file
#include <cstddef>
#include <iostream>
#include <list>
#include <stdarg.h>
#include <stdio.h>
using namespace std;
typedef unsigned int DWORD;
void AddTrack(DWORD addr, DWORD asize, const char *fname, DWORD lnum);
char *OutputDebugString (const char *fmt, ...);
void RemoveTrack(DWORD addr);
void DumpUnfreed();
#ifdef _DEBUG
#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW
void * operator new (unsigned int size, const char *file, int line)
{
void *ptr = (void *)malloc(size);
AddTrack((DWORD)ptr, size, file, line);
return(ptr);
}
/*inline void * operator new(unsigned int size)
{
void *ptr = (void *)malloc(size);
AddTrack((DWORD)ptr, size, _FILE_,_LINE_);
return(ptr);
}*/
void operator delete(void *p)
{
RemoveTrack((DWORD)p);
free(p);
}
#endif
char *OutputDebugString (const char *fmt, ...)
{
char *p = NULL;
size_t size = 1024;
int n = 0;
va_list ap;
if((p = (char*) malloc(size)) == NULL)
return NULL;
while(1) {
va_start(ap, fmt);
n = vsnprintf(p, size, fmt, ap);
va_end(ap);
if(n > -1 && n < size)
return p;
/* failed: have to try again, alloc more mem. */
if(n > -1) /* glibc 2.1 */
size = n + 1;
else /* glibc 2.0 */
size *= 2; /* twice the old size */
if((p = (char *)realloc (p, size)) == NULL)
return NULL;
}
}
typedef struct information {
DWORD address;
DWORD size;
char file[64];
DWORD line;
} ALLOC_INFO;
typedef list < ALLOC_INFO* > AllocList;
AllocList *allocList;
void AddTrack(DWORD addr, DWORD asize, const char *fname, DWORD lnum)
{
ALLOC_INFO *info;
if(!allocList) {
//allocList = new AllocList;
allocList = (AllocList*)malloc (sizeof (AllocList));
}
//info = new(ALLOC_INFO);
info = (ALLOC_INFO*) malloc (sizeof (ALLOC_INFO));
info->address = addr;
strncpy(info->file, fname, 63);
info->line = lnum;
info->size = asize;
allocList->insert(allocList->begin(), info);
}
void RemoveTrack(DWORD addr)
{
AllocList::iterator i;
if(!allocList)
if(!allocList)
return;
for(i = allocList->begin(); i != allocList->end(); i++)
{
if((*i)->address == addr)
{
allocList->remove((*i));
break;
}
}
}
void DumpUnfreed()
{
AllocList::iterator i;
DWORD totalSize = 0;
char buf[1024];
if(!allocList)
return;
for(i = allocList->begin(); i != allocList->end(); i++) {
sprintf(buf, "%-50s:\t\tLINE %d,\t\tADDRESS %d\t%d unfreed\n",
(*i)->file, (*i)->line, (*i)->address, (*i)->size);
OutputDebugString("%s",buf);
totalSize += (*i)->size;
}
sprintf(buf, "-----------------------------------------------------------\n");
OutputDebugString("%s",buf);
sprintf(buf, "Total Unfreed: %d bytes\n", totalSize);
OutputDebugString("%s",buf);
}
And my main.cpp is
#include "mynew.h"
int main()
{
char *ptr = new char;
DumpUnfreed();
return 0;
}
When i try to compile i get the following error
[root#dhcppc0 new]# !g
g++ main.cpp -D_DEBUG
mynew.h:25: error: declaration of ‘operator new’ as non-function
main.cpp: In function ‘int main()’:
main.cpp:9: error: no matching function for call to ‘operator new(unsigned int, const char [9], int)’
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/new:84: note: candidates are: void* operator new(size_t)
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/new:88: note: void* operator new(size_t, const std::nothrow_t&)
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/new:94: note: void* operator new(size_t, void*)
I know there is some thing wrong with my #defines, but I am not sure what is wrong.
Can any one please bale me out of this
You've defined your new macro before your functions. Your code ends up looking like:
void *
operator new(__FILE__, __LINE__)(unsigned int size, const char *file, int line)
Which is obviously wrong. Your should move the macro definitions underneath the functions (or better is to keep those functions in a .cpp file you link with.) For what it's worth, new is a keyword and cannot be an identifier, so your program is, strictly speaking, ill-formed.
I recently posted my global memory operators framework. It might help you a bit.
the signature don't match it sould be void* operator new (size_t size).
overriding single object new signature is
static void * operator new(site_t size),
roni