0

I have a .so lib, that holds 1 function i want to call from my own code.
I have decompiled a function that uses the same function, with IDA and it looks like :

ns::fw::SessionIf *v6
ns::fw::SessionIf::Send(v6, 0x1813u, 8u, &v15, 1, 0);

How can i make this same call from my code?

arnold
  • 455
  • 1
  • 8
  • 19
  • 1
    Does this answer your question? [Linking library without a header file?](https://stackoverflow.com/questions/11852329/linking-library-without-a-header-file) – Odysseus Feb 18 '22 at 14:57
  • That would probably work for the function call, but i would not know how to make the class initializer work this way. – arnold Feb 18 '22 at 15:48
  • You must first find how much memory you should allocate for SessionIf object, then you need to find .ctor function to initialize that block of memory by passing the pointer of the memory you allocated (any subsequent member function want that pointer as its first parameter), only after you can correctly call Send function. By the way all of the function declaration in ELF will be looked different. For example you can simply get a pointer for printf (which is _printf) by calling dlsym(lib, "printf"); but cpp functions will be looked ugly as hell like _NSFWSessionIf_Send32 (even worse :D) – Gurhan Polat Feb 27 '22 at 14:13

1 Answers1

0

As long as you compile your program so that shared data structures are binary-equivalent in both the .so lib and your executable, then it should be rather straightforward.

The tutorial linked by Odysseus shows how to do it in Windows.

It seems like you want to initialize an object in your program using the .so lib, with no shared header file.

This is no problem as long as you define the same data structure in the exact same way in your .cpp file. I don't have a Linux machine handy, but I can give you a working example in Windows:

#include <Windows.h>
#include <iostream>
#include <string>

struct ComplexStruct {
    std::string m_str;
    int m_int;
};

typedef ComplexStruct* (__stdcall* func_complex_ptr)(void);
typedef void(__stdcall* func_complex_ptr2)(ComplexStruct&);

int main() {
    HINSTANCE procDll = LoadLibrary(L"C:/temp/test/DllTest.dll");

    func_complex_ptr dllComplexFunc = (func_complex_ptr)GetProcAddress(procDll, "getComplex");
    ComplexStruct* pComplex = dllComplexFunc();
    std::cout << "output1: " << pComplex->m_str << std::endl;

    func_complex_ptr2 dllComplexFunc2 = (func_complex_ptr2)GetProcAddress(procDll, "initComplex");
    ComplexStruct complexInst;
    dllComplexFunc2(complexInst);
    std::cout << "output2: " << complexInst.m_str << std::endl;

    return 0;
}

(I didn't include the code for the DLL file but I can if you want.)

The only situations that can be problematic are if the object has a complex destructor, depending on what exactly it does, or if the object interacts with hidden state inside of the .so library. You might wish to avoid deleting the object in your program and instead call some form of specialized free function in the .so if it has one. Or if you're dealing with simple objects, then there's no problem.

If you want an example that works on Linux, with .so files, I can craft one as well.

Alex
  • 877
  • 5
  • 10