I have succesfully using dyld -macosx- to interpose standard C functions to a third party application, getting important information about the workarounds it does. But what I really need is to replace a certain function of a certain class.
The function I want to override is QString::append(..., ..., ...), so each time a string is appended to another -the whole application uses qstring-, i find out.
Is there a way? Here's the code I already have.
// libinterposers.c
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdarg.h>
#include <dlfcn.h>
#include <stdlib.h>
typedef struct interpose_s {
void *new_func;
void *orig_func;
} interpose_t;
int my_open(const char *, int, mode_t);
int my_close(int);
void* my_malloc(size_t);
static const interpose_t interposers[] \
__attribute__ ((section("__DATA, __interpose"))) = {
{ (void *)my_open, (void *)open },
{ (void *)my_close, (void *)close },
{ (void *)my_malloc, (void *)malloc },
};
int
my_open(const char *path, int flags, mode_t mode)
{
int ret = open(path, flags, mode);
printf("--> %d = open(%s, %x, %x)\n", ret, path, flags, mode);
return ret;
}
int
my_close(int d)
{
int ret = close(d);
printf("--> %d = close(%d)\n", ret, d);
return ret;
}
void*
my_malloc(size_t size)
{
void *ret = malloc(size);
//fprintf(stderr, "Reserva de memoria");
return ret;
}
Thank you very much
C++ does name mangling. This means member function QString::mid() looks something like __ZNK7QString3midEii to the linker. Run the nm(1) command on the library you are interposing on to see the symbols.
It is going to be much easier that this. QString uses memcpy to concatenate and work with Strings, and I can easily override memcpy, and apply a regular expression to the result, logging only the strings I want. Piece of cake. No need for magic voodo-hoodo :)
Related
I have a C++ code that links two shared libraries (let's say, foo1.so and foo2.so). In both libraries I have a class called "Mesh", and the compiler cannot know which one I am trying to use when I try to instantiate the class Mesh (obviously I know which one I want to instantiate). I get the "error: reference to ‘Mesh’ is ambiguous"
Of course I could alter the source code of one of the libraries, wrapping the Mesh class around a namespace and that would solve the problem. I would like to avoid changing the library's code, though. Is there a way to remove this ambiguity in the source file which uses the libraries?
Thank you,
Rafael.
By using dynamic libs (.so in linux), you can load each one and use each handle to differentiate call.
See Dynamically Loaded (DL) Libraries
For example :
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
class Meshib
{
void * _handle;
double (*_cosine)(double);
public:
Meshib( const char * libraryPath)
{
char *error;
_handle = dlopen (libraryPath, RTLD_LAZY);
if (!_handle) {
fputs (dlerror(), stderr);
exit(1);
}
_cosine = reinterpret_cast<decltype(_cosine)>( dlsym(_handle, "cosine") );
if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(1);
}
}
~Meshib() {
dlclose(_handle);
}
double cosine(double v) { return (*_cosine)(v); }
};
int main(int argc, char **argv)
{
Meshib meshLib1( "foo1.so" );
Meshib meshLib2( "foo2.so" );
printf("%f\n", meshLib1.cosine(2.0));
printf("%f\n", meshLib2.cosine(2.0));
}
See this article for C++ class dynamic load.
I have a largish code base that does log_msg("Here comes %s", "the text"), where log_message is a macro that adds function name and line numbers to the log message.
GCC/G++ warn about errors when the format string doesn't match the supplied arguments. Unfortunately sometimes the code calls log_msg(get_the_text()). The return value of get_the_text() is unknown at compile time, so if it contains some printf formatting sequences, the code will fall flat on its face.
What I'm looking for is a way to route the single argument usages through a different code path that doesn't interpret the formatting codes. I tried something like this hoping that the non-variadic case is more specific than the variadic one:
void log_the_message_implementation(const char *filename, const char *funcname, const char *msg);
void log_the_message_implementation(const char *filename, const char *funcname, const char *msg, ...);
I was hoping that the compiler would pick the single argument function when there are no variable args, but it complains about ambiguous calls.
Any ideas how to fix this without changing thousands of calls from
log_msg(get_the_text()) to log_msg("%s", get_the_text())?
Thanks to #SamVarshavchik this is what I came up with:
#include <iostream>
#include <cstdio>
#include <tuple>
template<typename ... Args>
void log(Args ... args) {
if (sizeof...(args) == 1) {
auto t = std::make_tuple(args...);
std::puts(std::get<0>(t));
} else {
std::printf(args...);
}
}
int
main() {
log("Test %d");
log("%s %d\n", "Test", 1);
log([]{ return "%s";}());
return 0;
}
I'm currently working on I2C between a Raspberry Pi 3 and a PsoC 4. I'm using the I2C-dev library to handle the I2C communication. So the I2C bus is up and running, and the read and write function has been implemented correctly. I want however to make functions pointer the read and write functions hence the to functions uses the same types of arguments (atleast it looks like) I have the following main code called I
2Ctest-tools.cpp:
#include <unistd.h> //Needed for I2C port
#include <fcntl.h> //Needed for I2C port
#include <sys/ioctl.h> //Needed for I2C port
#include <linux/i2c-dev.h> //Needed for I2C port
#include <stdio.h>
#include "i2c.h"
#include "functions.h"
int main() {
int addr = 0x49;
int cmd = 2; //Write
int length = 5;
int file_i2c = 0;
I2C myI2C;
unsigned char buffer[5];
buffer[0] = 0x01;
buffer[1] = 0x02;
buffer[2] = 0x20;
buffer[3] = 0x00;
buffer[4] = 0x17;
i2c_init(&myI2C, cmd, addr, &file_i2c);
i2c_exe(&myI2C, file_i2c, buffer, length);
return 0;
}
As shown in the code, im using a object of the struct called myI2C which is passed in the two functions i2c_init, i2c_exe. The source code for functions.cpp is in the following:
#include <unistd.h> //Needed for I2C port
#include <fcntl.h> //Needed for I2C port
#include <sys/ioctl.h> //Needed for I2C port
#include <linux/i2c-dev.h> //Needed for I2C port
#include <stdio.h>
#include "i2c.h"
#include "functions.h"
int i2c_init(I2C *cthis, int cmd, int addr, int *ptrFile_i2c ) {
char *filename = (char*)"/dev/i2c-1";
if ((*ptrFile_i2c = open(filename, O_RDWR)) < 0)
{
//ERROR HANDLING: you can check errno to see what went wrong
printf("Failed to open the i2c bus");
return 0;
}
if (ioctl(*ptrFile_i2c, I2C_SLAVE, addr) < 0)
{
printf("Failed to acquire bus access and/or talk to slave.\n");
//ERROR HANDLING; you can check errno to see what went wrong
return 0;
}
switch(cmd) {
case 1:
//cthis->WR = write;
break;
case 2:
cthis->WR = read;
break;
}
return 0;
}
int i2c_exe(I2C *cthis, int file_i2c, unsigned char *buffer, size_t length) {
cthis->WR(file_i2c, buffer, length);
return 0;
}
So the important thing to note here is that in the function i2c_init im switching on the varialbe cmd, which dictates whether the function pointer will point on the write or read function. Now the failure part comes in. The functions pointer is declared in its own .h file called i2c.h and looks like this:
struct I2C {
ssize_t (*WR)(int, const void *, size_t);
};
As you can see the function pointer has to point on a function with the parameters (int, const void*, size_t) this works like a charm when the function points on the write function BUT when it points on the read function im getting and error, the error says:
functions.cpp: In function ‘int i2c_init(I2C*, int, int, int*)’:
functions.cpp:30:14: error: invalid conversion from ‘ssize_t ()(int, void, size_t) {aka int ()(int, void, unsigned int)}’ to ‘ssize_t ()(int, const void, size_t) {aka int ()(int, const void, unsigned int)}’ [-fpermissive]
cthis->WR = read;
I have studied the error and concluded that it's because the read and write function somehow does not take the same arguments, which is weird because im passing the same arguments in them (int i2s_file, int buffer, int length) so if i change the function pointer to
ssize_t (*WR)(int, void *, size_t);
the function works with read but not with write.. So my question is: can i somehow change the write or read function to take the same argument by changing the i2c-dev library or is there anything else i could do to solve this problem?
here's a link to the i2c-dev library, which i have completely giving up to understand http://textuploader.com/5yioi
thanks in advanced
You can cast the functions explicitly to the correct type:
typedef ssize_t (*I2CCMD)(int, void *, size_t);
cthis->WR = (I2CCMD)write;
cthis->WR = (I2CCMD)read;
This should eliminate the error.
Obviously the read function cannot take a pointer to const since, unlike the write function, it has to modify that parameter.
So you cannot switch functionality with a function pointer, because the function pointers are of different types.
The best work-arounds seem to be either moving the "cmd" parameter to the i2c_exe function, or alternatively create a private variable containing cmd (inside struct I2C would be ideal). And then in i2c_exe either call read or write.
A worse solution is to change the struct to a union, like:
union I2C {
ssize_t (*WR)(int, const void *, size_t);
ssize_t (*read)(int, void*, size_t);
};
Then in case of reads, use the read member to assign to the struct. But please note that this is kind of a "dirty hack", it is poorly-specified behavior in theory. In practice, it will most likely work on any given system. (It is very unlikely that const correctness would ever affect calling convention.)
With the Visual C++ compiler, it is possible to create a DLL file, that can imitate another DLL file and redirect all function calls to the original DLL. Here is an article with a tool that can generate Visual C++ code automatically.
The generated function-stubs work (tested) and look like this:
extern "C" __declspec(naked) void __stdcall __E__0__()
{
__asm
{
jmp p[0]; // p[0] = GetProcAddress(hL,"AcceptEx");
}
}
Now I want to do the same thing with MinGW/GCC instead of MSVC.
__declspec(naked) isn't supported by GCC on i386, so we need another way.
As suggested here, I could override functions by writing assembly code in the global scope. Here's my code that should do the trick:
__asm__
(
"jmp *%0"
: /* empty output list */
: "r" (pointer_to_original_function) /* p[0] in the example above */
);
My snippet uses GCC's extended ASM. But unfortunatelly this is only allowed inside of functions, not in the global scope!
So... how do I do that? My next approach would be to try it without extended ASM, but how do I get the pointer address in assembly then?
Here i'm trying to get it from a global variable, but it segfaults at repace_this_stub():
#include <stdio.h>
void try_to_jump_to_me()
{
printf("you made the jump\n");
}
void* target_pointer = try_to_jump_to_me;
__asm__ (
"replace_this_stub:"
"jmp target_pointer"
);
void replace_this_stub();
int main(int argc, char** argv)
{
printf("starting in main. \n");
replace_this_stub();
printf("back in main?\n");
}
If the pointer is in a global variable, you can just use its name. Be sure to apply any name mangling. Also put your code in the applicable code section and give it a name. Sample code:
#include <stdio.h>
void* p = printf;
asm(
".section .text\n\t"
"proxy: jmp *p\n\t"
".previous\n\t");
extern void proxy();
int main()
{
proxy("Hello world!\n");
return 0;
}
If you want to use an array, just add the appropriate displacement. Extended sample:
#include <stdio.h>
#include <string.h>
void* p[] = { printf, strcpy };
#define str(x) #x
#define PROXY(name, index) asm( \
".section .text\n\t" \
str(proxy_##name) ": jmp *p + " str(index) " * 4\n\t" \
".previous\n\t"); \
extern void proxy_##name()
PROXY(printf, 0);
PROXY(strcpy, 1);
int main()
{
char buf[128];
proxy_strcpy(buf, "Hello world!\n");
proxy_printf(buf);
return 0;
}
I'm using CUnit for my project unit testing.
I need to test whether I call libc functions with the right parameters & whether I treat their return values the right way.
for example: if I call the bind(...) function - I would like to check which af param I pass & assert if this is the wrong one, and also I would like to emulate it's return value & assert if I check it the right way.
For these purposes I would expect the CUnit environment to have a built-in mechanism to let me call a 'mocked' bind() function while testing and a real bind() function when running the code - but I can't find anything like this.
Can you please tell me if I'm missing something in CUnit, or maybe suggest a way to implement this.
Thanks,
Jo.
Unfortunately, you can't mock functions in C with CUnit.
But you can implement your own mock functions by using and abusing of defines :
Assuming you define UNITTEST when compiling for tests, you can in the tested file (or in a include) define something like this :
#ifdef UNITTEST
#define bind mock_bind
#endif
In a mock_helper.c file that you will compile in test mode :
static int mock_bind_return; // maybe a more complete struct would be usefull here
static int mock_bind_sockfd;
int mock_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
CU_ASSERT_EQUAL(sockfd, mock_bind_sockfd);
return mock_bind_return;
}
Then, in your test file :
extern int mock_bind_return;
extern int mock_bind_sockfd;
void test_function_with_bind(void)
{
mock_bind_return = 0;
mock_bind_sockfd = 5;
function_using_bind(mock_bind_sockfd);
}
glibcmock is a solution of mocking libc function with Google Test. for example:
#include "got_hook.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <sys/socket.h>
#include <mutex>
#include <memory>
struct MockBind {
MOCK_METHOD3(Bind, int(int, const struct sockaddr*, socklen_t));
};
static MockBind *g_mock{nullptr};
static int Bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
return g_mock->Bind(sockfd, addr, addrlen);
}
static std::mutex g_test_mutex;
TEST(BindTest, MockSample) {
std::lock_guard<std::mutex> lock(g_test_mutex);
std::unique_ptr<MockBind> mock(g_mock = new MockBind());
testing::GotHook got_hook;
ASSERT_NO_FATAL_FAILURE(got_hook.MockFunction("bind", (void*)&Bind));
// ... do your test here, for example:
struct sockaddr* addr = nullptr;
EXPECT_CALL(*g_mock, Bind(1, addr, 20)).WillOnce(testing::Return(0));
EXPECT_EQ(0, bind(1, addr, 20));
}