SAFEARRAY on linux - c++

I'm using a proprietary library on linux that uses SAFEARRAY type in a callback function:
HRESULT Write(SAFEARRAY *Data)
SAFEARRAY is defined in a header file as typedef void SAFEARRAY.
I must define a callback function that will get the data (eg. as *unsigned char) and it's length (eg. as int or size_t) and write the data somewhere.
Something like:
HRESULT MyWrite(SAFEARRAY *Data) {
unsigned char *data = SafeArrayGetData(Data);
size_t length = SafeArrayGetLength(Data);
write_data_somewhere(data, length);
}
And then use it with the library:
ProprietaryLib::ExportThing(thing, MyWrite);
So my question is: How to get the data and it's length on linux, where I have no oaidl.h or oleauto.h header file.

Two thoughts on the matter:
Maybe you've seen it already, but Wine implements SAFEARRAY. Thus you may have a look at
https://github.com/wine-mirror/wine/blob/master/dlls/oleaut32/safearray.c
https://github.com/wine-mirror/wine/blob/master/include/oaidl.idl
https://github.com/wine-mirror/wine/blob/master/include/oleauto.h
It seems to me that to get length and data of the array, it should be fine to just access the members of the struct. For instance, in safearray.c they simply read cbElements at various places, and the method SafeArrayAccessData basically only returns pvData. (In addition, it "locks" the array. The "locking" seems to be a reference counter that is checked when a SAFEARRAY is resized or freed.)
One idea why your MYSAFEARRAY (mentioned in comments) does not work is
that struct packing might interfere. In https://learn.microsoft.com/en-us/cpp/build/reference/zp-struct-member-alignment they say that Windows SDK presupposes that structs are packed on 8-byte boundaries. So perhaps you could output the raw bytes and see if you detect a pattern. If that turns out to be the problem, try to change your compiler settings.

Related

How to copy a struct from a pointer-to-void?

Say I have a DLL contains a struct, but I don't know the details of this struct. But I have a void pointer which points to address of the struct.
Can anybody tell me how can I get the details of the struct? Such as output the struct to a text file.
Thank you!
You cannot know the details of the struct without the type definition. Copying a region starting with the void pointer without a type definition will give you the raw binary data, but you wont know where it ends, or which pieces represent which variables. Some of the values could be integer values or they could be pointer addresses. There are all sorts of possibilities.
You should try to obtain the header file.
You might be able to glean some information from the debug / symbol file if you have it (example .pdb files on Windows), or debugging the program with GDB on Linux, this will only work if you have a debug build of the program. Refer to the "whatis" and "ptype" commands in GDB.
You never know this without structure definition. Also there can be "holes" between the user's variables in the real memory placement because of the alignment and padding.
Say if you have,
struct mystr {
char x;
int y;
};
by default such structure most likely will have size 8, and after one byte of char x there will be three bytes of padding (in theory random values), and then 4 bytes of int y, but it depends on compiler and its directives.

How to use DetourAttach() for a pointer to a function in hex?

I am trying to make a tutorial using the detour library.
In older version of the detour library v1.5 the function DetourFunction was used to define the address so the DLL knows where to look for the function.
It could for example be used as follows:
InsertDateTime = (int (__stdcall*)(int))DetourFunction((PBYTE)0x01006F10, (PBYTE)MyInsertDateTime)
see http://www.moddb.com/groups/ibepex/tutorials/function-hooking
However in newer versions the function is changed to
LONG DetourAttach(
PVOID * ppPointer,
PVOID pDetour
);
where ppPointer is a pointer to the target pointer to which the detour will be attached.
Now since I know the adress of the target function in hex format, 0x01006F10, I want to somehow use that as an argument for ppPointer. I tried to just write:
InsertDateTime = (int (__stdcall*)(int))DetourAttach((PVOID*)0x01006F10, MyInsertDateTime);
and it compiles fine but my program does not work as I thought. It seems that the program never catches the function from that adress.
So basically my question is, did I use the pointer to the hex adress correctly and second, do I have some fundamental mistakes in the way I use DetourAttach()?
You are using DetourAttach incorrectly. The correct usage in your case would be:
int(__stdcall* InsertDateTime)(int) = (int(__stdcall*)(int))(0x01006F10);
LONG errorCode = DetourAttach((PVOID*)(&InsertDateTime), (PVOID)MyInsertDateTime);
if(!errorCode) {
//Detour successful
}
Note that in the presence of technologies like ASLR; You should use something like GetProcAddress to retrieve the address of the function at runtime otherwise you are likely to cause corruption or crashes.

How to transmit a function to anonymous pipe WinAPI?

I need to write to anonymous pipe something like double (*fun)(double), but the following WriteFile(pipe, fun, 4, written_bytes, 0) causes an error in a pipe-receiver while ReadFile(read_pipe, fun, 4, written_bytes, 0). Are there any methods to do this?
I have an idea. I can create a struct with field of same type:
struct Foo
{
double (*f)(double);
};
And then I write it WriteFile(hWritePipe_StdIN, &to_process, sizeof(Foo), &bytes, 0);
But I have problem, that pipe-receiver never ends to read data:
ReadFile(hReadPipe, &to_process, sizeof(Foo), &bytes, 0);
There are some problems with it:
First, you should know the size of function.
If you do, you just call WriteFile(pipe, funcPtr, funcSize, ...) to transfer it.
Second, the function should contain only position-independent code, and don't address any data.
E.g. a function like this won't work:
double fun(double x)
{
int arr[10000]; // implicit function call (alloca or something like this)
printf("some");
static int some = 1;
return globalVal + (++some);
}
because function printf will have a different address and there will be no static variable and string in another process.
(Well, maybe you can transfer data as well, but there is no way you'll generate PI code.)
So, with all that limitations, you can send a function:
__declspec(naked) double fun(double x) { __asm ret }
const auto funcSize = 1;
WriteFile(pipe, &fun, funcSize, ...);
In native code you can not send function (the code) itself, neither to the same nor to different process. (You could try low-level hacking like the one #Abyx suggests, but it seriously limits functionality that the code can perform, and will probably make you resort to writing it all in assembler by hand.)
You also can't send function's address to another process, because each process has its own isolated address space; in another process, that address will contain different data.
The solution will be to create a shared library (preferably dynamic) that will contain all functions that could possibly be sent this way. Assign each function some tag (e.g. number or name), let DLL maintain a mapping between tags and addresses. Then send tags instead.
What are you trying to achieve, here? Are you really trying to write the function itself? Why? That's not something you can easily do in C++, for instance because the size of a function is not well-defined.
You should probably write the data, i.e. the number returned by fun() instead:
const double value = fun(input);
DWORD numberOfBytesWritten;
WriteFile(pipe, &value, sizeof value, &numberOfBytesWritten, NULL);
You should of course add code to check the output. Note that writing binary data like this can be brittle.
Since you're using WinAPI, the native way to send a function is via COM. In particular, expose the function as a method on a COM object, obtain a COM moniker, and send the moniker. Monikers can be serialized and sent over pipes. The other side can deserialize the moniker and get access to your object.
Under water, this works by looking up the object in the COM Running Object Table
Seeing how this is excessively complicated and error-prone to do in C++ (and only works with a very limited set of functions at all), I recommend you use a scripting language for this. Instruction caches and DEP are another two things you'd have to consider in addition to the already mentioned ones.
Really. Transmit the function as script, and run it on the other end. Save yourself that pain.
Angelscript looks and feels almost like C++, so that might be a possible candidate.
Now, if you object to this because you need something that a script cannot trivially do, knoweth: C++ will not be able to do it either, in this scenario.
Apart from the above mentioned PIC code issue (#Abyx) and the fact that you cannot safely or portably know a function's size, the only C++ functions that you could conceivably send via a pipe and execute in a meaningful manner are strictly const functions. Here, const is in the sense of e.g. GCC's __attribute__((const)), not the C++ const keyword.
That is, any such function may not examine any values except its arguments, and have no effects except the return value. The reason is obvious: A different process lives in a different address space, so anything you reference is meaningless. Anything you change is meaningless.
Now, this is just what a script can do, in a safe, straightforward manner, and reliably. The overhead is, considering you already send code through a pipe, neglegible.

LoadString with nBufferMax equal 0

i am working on making my applications international. After two days digging on msdn i came up with a test, which loads language-specific library containing resources. This is also my first attempt at loading library as a resource, loading strings from it and so on.
Next, according to msdn example at http://msdn.microsoft.com/en-us/library/windows/desktop/dd319071%28v=VS.85%29.aspx, i'm trying the LoadString.
Since string loading for entire application equals a lot of text copying, i thought i would use the - what i think is - memory efficient feature of LoadString, which is setting nBufferMax parameter to zero. According LoadString documentation, it should return a pointer to string resource. I thought i'd make a struct or a class of string pointers and do something along these lines (i extracted only the important bits):
wchar_t textBuf[SOMEVALUE]; // <-- this is how id DOES work
wchar_t *myString; // <-- this is how i would like it
HMODULE resContainer=LoadLibraryEx(L"MUILibENU.dll",NULL, LOAD_LIBRARY_AS_DATAFILE);
if(0!=resContainer){
// this works OK
int copied=LoadStringW(resContainer,IDS_APP_TITLE,textBuf,SOMEVALUE);
// this fails, also gives a warning at compile time about uninitialized variable used.
int copied=LoadStringW(resContainer,IDS_APP_TITLE,myString,0);
}
As you can see i am trying to get myString to become a pointer to loaded resource library's string without actually copying anything.
My question is: am i misunderstanding msdn documentation? Can i or can i not get a pointer to the string directly within loaded library, and simply use it later, e.g. to show a messagebox, without actually copying anything? Until i unload said library?
MSDN says:
[...] If this parameter is 0, then lpBuffer receives a read-only pointer to the resource itself.
It means that a) the pointer must be of type const wchar_t*:
const wchar_t *myString;
and b) you must pass a pointer to the pointer and use an ugly cast:
int copied=LoadStringW(resContainer,IDS_APP_TITLE,(LPWSTR)&myString,0);

C++ Saving/Loading a function as bytes. Getting the size of a function

Ok so I've used function pointers for some time. I was trying to figure out if this was possible.
First. It IS possible to convert a function pointer into an array of bytes.
It is also possible to reconstruct that function with the bytes in that array.
I would like to save a function into an array of bytes, and lets say save it to a text file (func.dat). Then later read that text file and execute the particular function...
Is it possible? It seems it should be possible the only problem I run across is finding the size of the array that makes up the function.
Is there any way to do this?
int func()
{
return 1+1;
}
int main()
{
int (*foo)() = func;
char* data = (char*)func;
// write all the data
char* copyFunc = new char[sizeof(func)];
for(int i = 0; i < sizeof(func); i++)
copyFunc[i] = data[i];
int (*constructedFoo)() = (int (*)())copyFunc;
return 0;
}
of course this code won't compile because sizeof does not work for functions, does anyone know how to get the size of a function? Or the size of the function header/footer.
I have tried things like
int func()
{
1+1;
new char('}');
}
Then searched for the } char (as the end of the function) but that size doesn't work.
If your wondering why I need it, it could be used for lets say, sending a function to a remote computer to execute (thinking of parallel processing) Or even saving a function in a file like in my first example to later be used, this can be helpful.
Any help is greatly appreciated.
What you're trying to do is not possible in C/C++. First of all, functions may not be contiguous in memory in the binary. So there's no definite "size".
Secondly, you can't just load it into another program and execute it because it will violate memory protection (among other things, like address space).
Lastly (if you managed to get this far), all non-relative jumps and references in the function will likely be broken.
EDIT:
The way to go about sending code to remote computers is to send entire (compiled) binaries. Then have the local and remote machines communicate.
Well there is actually a way how to save and load bytes of code and even run them. This is a great arcicle about that:
http://www.codeproject.com/KB/tips/Self-generating-code.aspx?msg=2633508#xx2633508xx
One thing you can do if you want dynamically loaded functions:
Create a dynamic library containing your functions (.dll or .so)
Export those symbols with extern "C" and if necessary declspec(dllexport)
Load the library at runtime with LoadLibrary() or dlopen()
Extract a particular symbol with GetProcAddress() or dlsym()
Execute it with libffi.
Clean up after yourself with FreeLibrary() or dlclose()