C++ passing a lambda from a data structure - c++

I have 2 data structures both in my injector and dll:
struct SubData_t
{
int SubTest;
};
struct DataHolder_t
{
int Test;
SubData_t SubData;
};
This is how I assign the data structure values:
DataHolder_t *DataHolder = new DataHolder_t();
DataHolder->Test = 123;
DataHolder->SubData.SubTest = 456;
int ResponseCode = Inject(4321, "test.dll", DataHolder);
And this is a custom LoadLibrary function that passes the data to dll export:
int Inject(DWORD ProcessId, char *DLLFile, DataHolder_t *Data)
{
// ...
LoadRemoteLibraryR(hProcess, lpBuffer, dwLength, NULL, 0xd13f5171 /* dllexport EntryPoint hash */, (LPVOID)Data, (DWORD)(sizeof(struct DataHolder_t) + 1));
// ...
}
Then I get the data in the dll export and assign the values from lpUserdata to the data structure:
DLLEXPORT BOOL EntryPoint(LPVOID lpUserdata, DWORD nUserdataLen)
{
DataHolder_t *DataHolder = (struct DataHolder_t *)lpUserdata;
char buffer[100];
sprintf(buffer, "%d | %d", DataHolder->Test, DataHolder->SubData.SubTest);
MessageBox(NULL, buffer, "Test", MB_OK);
return TRUE;
}
However I'm new to lambdas and can't figure out how (if it's even possible) to pass lambda (functions) the same way to the dll export. Or is there any other way to pass functions/logic to the dll export, so that they can be called from the target process that the dll was injected to?

Use type erasure, like std::function, or a reasonable facsimile, and pass the type-erased parameter as a reference, instead of passing by value, for best results.

Related

How to wrap a function call C++ to assign variables

Is there a way to have a function that executes a different function but carries out the same steps independent of the function?
This example would better portray what I mean:
ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
if (!SQL_SUCCEEDED(ret)) {
printf("SQL Failed\n");
DisplayError(SQL_HANDLE_STMT, stmt);
}
ret = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
if (!SQL_SUCCEEDED(ret)) {
printf("SQL Failed\n");
DisplayError(SQL_HANDLE_STMT, stmt);
}
I can't think of a more general example other than my specific needs, but the common part here is that I am always checking if the return variable from an SQL function is an error, and then if it is, printing said error. I feel this would be better if it was possible to wrap the error checking in a debug mode, and strip it off in a release mode, but I don't know how to do it. I am hoping that there is an answer along the lines of
SQL(ret, SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env));
Where wrapping the entire call in a defined SQL function would call any sql function passed in, as well as assigning it to the variable so long as the return types are the same.
I have tried to come up with something such as
#define SQL(a, x) (a = x; if (!SQL_SUCCEEDED(a)) { printf("SQL Failed\n"); DisplayError(SQL_HANDLE_STMT, stmt);})
but this doesn't work.
You can pass functions by copying or by const reference...
int MyFunction( const std::function<int(void)> & fn )
{
return fn();
}
int MyFunction2( std::function<int(int)> fn )
{
return fn(7);
}
and either pass a Lambda
MyFunction([]{ return SomeIntFunction(); });
or a reference to a static function
MyFunction(&StaticIntFunction);
or bind the function
MyFunction(std::bind(&Class::SomeIntFunction, classInstance));

How to check the "type" of a Win32 handle at runtime

I have to write a reference counted wrapper class in C++11 for Win32 handles like HFONT, HWND, HMODULE and so on. I want to use a single WinHandle class that implicitly casts to all handle types (which are all a void* typedef). Unfortunately all handles have different functions to destroy the underlying object for example DestroyWindow(), CloseHandle(), DeleteObject() and so forth, thus i'd need a different class for every handle-type to implement the appropriate destroy-function. (that would be 47 classes + base class including user objects, gdi objects and kernel objects)
So is there a way to determine at runtime of which "type" the handle is or rather which function needs to be called? (In the documentation I only found the isWindow() function)
I already thought about using RTTI or calling all delete-functions until one of them succeeds. RTTI won't work because all HANDLE types are typedefs of void* and thus the same. The latter might work, but all handles must be unique for it to work properly (no GDI handle can ever have the same value as a user handle or kernel handle) otherwise it might cause bugs and memory leaks
If the only thing you're looking for is a reference counted handle, why not just use shared_ptr ?
E.g :
shared_ptr<void> file( CreateFile(L"la.txt", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL), CloseHandle);
DWORD written;
WriteFile(file.get(), //get handle
"ABC\r\n",
5,
&written,
NULL);
It doesn't have a big foot print int your code and you won't have to write 40 classes.
You can avoid passing the relevant close function each time by defining some function for each type of closing e.g :
auto make_handle_CloseHandle = [](HANDLE h){ return (shared_ptr<void>(h,CloseHandle)); };
auto file = make_handle_CloseHandle(CreateFile(L"la.txt", /*same ...*/));
DWORD written;
WriteFile( file.get(), //get handle
"ABC\r\n",
5,
&written,
NULL);
And put it in some header file under a relevant namespace that way you won't have to type the close function's name each time and users of those functions will know which function is called (according to the make_handle_* name) which might make thing safer than trying to automagically identify the handle's type just by the handle.
Since the failure result for CreateFile is INVALID_HANDLE_VALUE (-1) I'm not certain this is a good solution all in all.
https://learn.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilea
Rather than use something intended to refer to a memory address, implementing some sort of shared_resource or unique_resource type, which accepts template arguments or a single argument that encapsulates the characteristics of the wrapped type is probably the way to go.
Mine looks something like this:
template <typename TRAITS>
struct SharedHandle
{
....
}
and is used like this:
struct TestTraits
{
using HandleType = int;
static constexpr HandleType INVALID = 0;
static void Close(HandleType& h)
{
h = INVALID;
}
};
using SharedHandleTestType = SharedHandle<TestTraits>;
TEST(ClvLib_SharedHandle_Tests, SharedHandle_default)
{
auto tt = SharedHandleTestType();
EXPECT_FALSE(tt);
}
TEST(ClvLib_SharedHandle_Tests, SharedHandle_good)
{
auto tt = SharedHandleTestType(1);
EXPECT_TRUE(tt);
}
TEST(ClvLib_SharedHandle_Tests, SharedHandle_use)
{
auto tt = SharedHandleTestType(1);
auto result = [](int t)->int {return t + 1; }(tt);
auto expected = tt.Get() + 1;
EXPECT_EQ(expected, result);
}
TEST(ClvLib_SharedHandle_Tests, SharedHandle_copy1)
{
auto tt = SharedHandleTestType(1);
auto t2 = tt;
EXPECT_TRUE(tt);
EXPECT_TRUE(t2);
tt = 0;
EXPECT_FALSE(tt);
EXPECT_TRUE(t2);
}
TEST(ClvLib_SharedHandle_Tests, SharedHandle_copy2)
{
auto tt = SharedHandleTestType(1);
auto t2 = tt;
EXPECT_TRUE(tt);
EXPECT_TRUE(t2);
tt = 0;
EXPECT_FALSE(tt);
EXPECT_TRUE(t2);
t2.Release();
EXPECT_FALSE(tt);
EXPECT_FALSE(t2);
}
For Windows file handles:
struct WinHandleTraits_IHV
{
using HandleType = HANDLE;
static constexpr HandleType INVALID = INVALID_HANDLE_VALUE;
static void Close(HandleType& h)
{
CloseHandle(h);
}
};
using WinFileHandle = SharedHandle<WinHandleTraits_IHV>;

Win32 C++ DLL function gets garbage values in parameters

I have a Win32 C++ dll (A) that calls another Win32 C++ dll (B). (B) is loaded using LoadLibrary and contains a method:
Draw(HDC hDC, LPRECT lpRect, LPBUFFER buffer, LPOPTIONS options)
Buffer structure is defined as:
struct Buffer
{
char* pData;
long Length;
TCHAR FileName[MAX_PATH];
Extension Extension;
};
typedef Buffer BUFFER, *LPBUFFER;
(A) fills BUFFER with filename, length etc and calls the Draw function. The Draw function then uses the values from BUFFER. It all works fine when DLLs are compiled as 64-bit but if I compile them as 32-bit then I start getting garbage values in BUFFER fields in (B). Logs shows that the values are good in (A) but turn into garbage when they reach (B).
I tried changing the Structure Alignment Option /ZpX and calling convention for Draw method (__cdecl, __stdcall) but none helped. I think it is related to calling convention because if I change Draw function syntax and put BUFFER as first param then (B) gets correct values. What's going on here?
Function pointer type:
typedef bool (__cdecl *DrawFunc)(HDC hDC, LPRECT lpRect, LPBUFFER buffer, LPOPTIONS options);
Then in InitInstance:
pDrawFunc = (DrawFunc)GetProcAddress(dllHandle, "Draw");
UPDATE
1. As mentioned above, if I put BUFFER as first param then it receives correct values.
2. HDC being a single numeric value always receives correct value
3. RECT gets incorrect values, very large ones
I believe the problem has something to do with structs. Only structs get incorrect values.
UPDATE 2
OK I found out my own silly mistake, the declaration for Draw method had LPRECT whereas the implementation had RECT. My bad, sorry about that.
But I am still not sure why:
1. Other parameters were showing garbage values?
2. Why it worked in 64-bit?
Ok, I create a solution with 3 projects: library B, that contains Draw(), library A, that has Test(), that loads library B and call Draw() with some Buffer* and application test, that links with library A and calls Test(). Everything works fine, both for 32 bit and 64. Small snippet of Test():
#include "stdafx.h"
#include "A.h"
#include "../B/B.h"
namespace {
LPBUFFER CreateBuffer(const char* const data, LPCTSTR const name)
{
if(!data || !name)
return NULL;
LPBUFFER buffer = new BUFFER();
buffer->Length = static_cast<long>(strlen(data) + 1);
buffer->pData = new char[buffer->Length];
strcpy_s(buffer->pData, buffer->Length * sizeof(char), data);
buffer->Extension = 0;
::ZeroMemory(buffer->FileName, _countof(buffer->FileName) * sizeof(TCHAR));
_tcscpy_s(buffer->FileName, name);
return buffer;
}
void DestroyBuffer(LPBUFFER buffer)
{
delete [] buffer->pData;
buffer->Length = 0;
buffer->pData = NULL;
buffer->Extension = 0;
::ZeroMemory(buffer->FileName, _countof(buffer->FileName) * sizeof(TCHAR));
delete buffer;
}
} // namespace
A_API void Test()
{
HMODULE b_lib = ::LoadLibrary(_T("B.dll"));
if(!b_lib)
{
::OutputDebugString(_T("Can't load library\n"));
return;
}
typedef bool (*DrawFunction)(HDC hDC, LPRECT lpRect, LPBUFFER buffer, LPOPTIONS options);
DrawFunction draw = reinterpret_cast<DrawFunction>(::GetProcAddress(b_lib, "Draw"));
if(!draw)
{
::OutputDebugString(_T("Can't get address of Draw()"));
goto FINISH_LABEL;
}
LPBUFFER buffer = CreateBuffer("test", _T("path"));
draw(NULL, NULL, buffer, NULL);
DestroyBuffer(buffer);
FINISH_LABEL:
::FreeLibrary(b_lib);
b_lib = NULL;
}
And a whole solution: https://www.dropbox.com/s/5ei6ros9e8s94e2/B.zip

casting issue with linked list item

This is my PER_IO_CONTEXT structure (i stored them in singly linked list):
typedef struct _PER_IO_CONTEXT
{
SLIST_ENTRY ItemEntry;
WSAOVERLAPPED Overlapped;
WSABUF wsabuf;
/* some other data*/
} PER_IO_CONTEXT, *PPER_IO_CONTEXT;
and below is WSAsend , that use the list for getting WSAOVERLAPPED structure:
...
PSLIST_HEADER pListHead;
...
PSLIST_ENTRY pListEntry = InterlockedPopEntrySList(pListHead);
PPER_IO_CONTEXT ovl = (PPER_IO_CONTEXT)pListEntry;
WSASend(pTmp1->Socket,..., &(ovl->Overlapped), NULL);
and the last part when GQCS gets notification:
LPWSAOVERLAPPED lpOverlapped = NULL;
PPER_IO_CONTEXT lpIOContext = NULL;
....
GetQueuedCompletionStatus(..... (LPOVERLAPPED *)&lpOverlapped, INFINITE);
lpIOContext = (PPER_IO_CONTEXT)lpOverlapped;
lpIOContext->wsabuf // this fail
As you can see following cast lpIOContext =(PPER_IO_CONTEXT)lpOverlapped doesn't work because WSAsend was provided with wsaoverlapped - the second member of PER_IO_CONTEXT structure, so dereferences such as lpIOContext-> can't be used in this case.
There is a way to deal with this situation?
To get the address of the corresponding PER_IO_CONTEXT struct you can use this:
lpIOContext = CONTAINING_RECORD(lpOverlapped, PER_IO_CONTEXT, Overlapped);
CONTAINING_RECORD is a macro defined in VC\crt\src\collections.h in such a way:
#define CONTAINING_RECORD(address, type, field) \
((type *)((char *)(address) - (ULONG_PTR)(&((type *)0)->field)))
More information: http://msdn.microsoft.com/en-us/library/windows/hardware/ff542043%28v=vs.85%29.aspx
I'm not sure whether there's a supported mechanism to convert a pointer to a member of a struct to a pointer to the struct. You could cast everything to BYTE * and do the arithmetic, which would work in practice, but depending on your needs it might be cleaner to reorganize to avoid the necessity:
typedef struct _PER_IO_CONTEXT
{
WSAOVERLAPPED Overlapped;
WSABUF wsabuf;
/* some other data*/
} PER_IO_CONTEXT, *PPER_IO_CONTEXT;
typedef struct _PER_IO_CONTEXT_LIST_ITEM
{
SLIST_ENTRY ItemEntry;
PER_IO_CONTEXT Item;
} PER_IO_CONTEXT_LIST_ITEM, *PPER_IO_CONTEXT_LIST_ITEM;

C++ *LPCSTR weird scope error

I currently have a class called TextureObject. In the creation function I create the texture, and assign a LPCSTR in the class to a parameter given in the function. When I return that LPCSTR later, it returns in an unexpected manner.
Some type names and functions are from DirectX 11, just ignore them.
Code:
The h File:
class TextureObject
{
public:
ID3D11ShaderResourceView *pTexture;
LPCSTR GetFilename() const { return *FFilename; }
bool IsNotNull;
void CreateTexture(ID3D11Device &dev,LPCSTR Filename);
void ReCreate(ID3D11Device &dev);
void Release();
int relativeId;
private:
LPCSTR *FFilename;
};
The cpp file:
void TextureObject::CreateTexture(ID3D11Device &dev,LPCSTR Filename)
{
D3DX11CreateShaderResourceViewFromFile(
&dev, // the Direct3D device
Filename, // load Wood.png in the local folder
NULL, // no additional information
NULL, // no multithreading
&pTexture, // address of the shader-resource-view
NULL); // no multithreading
FFilename = new LPCSTR(Filename);
IsNotNull = true;
}
void TextureObject::ReCreate(ID3D11Device &dev)
{
CreateTexture(dev, *FFilename);
}
When using vs 2012 debugger in the CreateTexture function, the Filename debugger values are:
0x0a06fed0 "C:\Users\Utilizador\Desktop\particle.png"
Which is perfect for me! When i assign the class's FFilename:
FFilename = new LPCSTR(Filename);
It's ok. When I check the value of FFilename within the scope of this function, it's the same value of the Filename. But when i use GetFilename, things start getting crazy:
= 0x0a06fed0 "îþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþü =I.C"
Mmm, I just met you, and this is crazy, but... Here's my value. mKay?
Well, please help me. Thank You
You are not copying the string. You are copying the pointer. I think you probably wanted to copy the string, because you cannot guarantee the caller's pointer will still reference valid data at a later time.
LPCSTR is just a const char*. There's probably a corresponding windows call, but I would just use strdup to copy the string.
Define FFilename as LPCSTR:
LPCSTR FFilename;
And then:
void TextureObject::CreateTexture(ID3D11Device &dev,LPCSTR Filename)
{
D3DX11CreateShaderResourceViewFromFile(
&dev, // the Direct3D device
Filename, // load Wood.png in the local folder
NULL, // no additional information
NULL, // no multithreading
&pTexture, // address of the shader-resource-view
NULL); // no multithreading
FFilename = strdup(Filename);
IsNotNull = true;
}
void TextureObject::ReCreate(ID3D11Device &dev)
{
CreateTexture(dev, FFilename);
}
Since you are using C++, you are free to use std::string instead, which will be cleaned up automatically when the object is destroyed.
When you create your pointer FFilename, you're initializing it with another pointer. That's not going to make a copy of the string, now you have two pointers pointing to the same thing. Presumably that thing is a temporary object, and when you go to look at it later it's no longer valid.
I'd suggest using std::string for this instead, it's much less error prone. The c_str method can get a LPCSTR at any time.
As marcin_j said, use std::[w]string. As for the line:
FFilename = new LPCSTR(Filename);
It just allocates 4 bytes for a pointer and initializes it to the filename string. It doesn't actually copy the string. So you can still use the string, but it is owned by whoever calls TextureObject::CreateTexture, and may be released while TextureObject is still referencing it.
Change the class to:
class TextureObject
{
public:
// ...all the same stuff as before...
private:
wstring FFilename; // it's better to store filenames as Unicode
};
And the methods to:
void TextureObject::CreateTexture(ID3D11Device* dev, const wstring& Filename)
{
D3DX11CreateShaderResourceViewFromFile(
dev, // the Direct3D device
Filename.c_str(), // load Wood.png in the local folder
NULL, // no additional information
NULL, // no multithreading
&pTexture, // address of the shader-resource-view
NULL); // no multithreading
FFilename = Filename;
IsNotNull = true;
}
void TextureObject::ReCreate(ID3D11Device* dev)
{
CreateTexture(dev, FFilename.c_str());
}