Who is responsible for deleting FILE_NOTIFY_INFORMATION.FileName? - c++

Winapi's ReadDirectoryChanges uses FILE_NOTIFY_INFORMATION to present it's results. The struct looks like this:
typedef struct _FILE_NOTIFY_INFORMATION {
DWORD NextEntryOffset;
DWORD Action;
DWORD FileNameLength;
WCHAR FileName[1];
} FILE_NOTIFY_INFORMATION, *PFILE_NOTIFY_INFORMATION;
If I get this struct filled by winapi, how do I correctly delete the FileName WCHAR*? Do I have to delete it?
None of the examples (not that there are many examples) of the ReadDirectoryChanges mention deleting anything. Microsoft of course does not provide any examples at all.

If you use malloc you need call free after you finish using the object.
For example:
DWORD FileNameLength = 100;
PFILE_NOTIFY_INFORMATION file_notify_info = (PFILE_NOTIFY_INFORMATION)malloc(FIELD_OFFSET(FILE_NOTIFY_INFORMATION, FileName[FileNameLength]));
free(file_notify_info);
Refer to "Why do some structures end with an array of size 1?".

Related

How can I see the memory view of a DLL residing in a process? [duplicate]

I am trying to get the image base of my process once it is loaded in memory. From my understanding, you can call GetModuleHandle to get the image base. My question is, does the handle returned essentially point to the IMAGE_DOS_HEADER struct such that you could do the following:
PIMAGE_DOS_HEADER DosHeader;
DosHeader = (PIMAGE_DOS_HEADER)GetModuleHandle(NULL);
If this is not correct, what other method could you use?
This is correct, though if you want the module handle of of a dll you need to specify its path. Otherwise you will get the handle to the process exe. You should also check the returned HMODULE first to see that its valid.
An example of how to get the virtual size of the module:
std::size_t GetModuleSize(const char* szModule)
{
HMODULE hModule = GetModuleHandle(szModule);
if(hModule == NULL) return 0;
IMAGE_DOS_HEADER* pDOSHeader = (IMAGE_DOS_HEADER*)hModule;
IMAGE_NT_HEADERS* pNTHeaders =(IMAGE_NT_HEADERS*)((BYTE*)pDOSHeader + pDOSHeader->e_lfanew);
return pNTHeaders->OptionalHeader.SizeOfImage;
}
you'll notice I use IMAGE_DOS_HEADER* and not PIMAGE_DOS_HEADER as I find that more readable and clear.
With Microsoft's compiler and linker, you can use
extern "C" IMAGE_DOS_HEADER __ImageBase;

C++ How can i do read/writeprocess with a given address from CE that contains a float?

I am currently working on teleport feature for a game trainer. I found the right static addresses containing a float:
picture of addresses with offsets
This address points to my X-coordinate. Now I am now trying to change my X-coordinate (a float) with read/write processmemory . But whatever i do it doesnt work (I have no problems with changing normal ints). I want to replace the value with a float that i choose before.
Can somebody please give me a detailed example how i can do this ?
Thank you in advance
1) get process base address - Getting base address of a process
hprocess is handle, pass there openprocess returned value (https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx)
2) add 'teleport' offset to base address
3) write given value to memory of process
HANDLE hProcess = openProcess(processId); //you also need to pass desired mode, use read & write
DWORD dwBaseAddress = getBaseAddress(hProcess):
DWORD dwPositionAddress = dwBaseAddress + POSITION_OFFSET;
float newPosition = 123.5;
WriteProcessMemory(hProcess, dwPositionAddress, &newPosition, sizeof(float));
you need to check for errors, this is just pseudocode to give you idea what you need to do, also make sure you run your trainer as admin and have access to game's memory
You have to read pointer and add that pointers its relative offsets to get to teleport address.
You can use WriteProcessMemory() to write into process memory directly and ReadProcessMemory() to read from memory .
But in case if you are reading two-three level pointer it will become cumbersome approach to do so.
So i recommend using Game Trainer or memory hacking library to read/write pointer easily.
you could use GTLibc Game Trainer libray for C/C++.
GTLibc Game trainer library
or you could use Memory.dll game hacking library for C#.
Memory.dll
Doing it internally instead
Readprocessmemory and writeprocessmemory would be relatively simple, but a better option is to inject a DLL into the target process for speed and simplicity. You can either manually deference by using a *, or do the preferred method and set up classes with the proper sizes so you don't have to deal with offsets in the same way. Check out Reclass.NET for automating this.
class unk3{
public:
char pad_001[0x10];
float location;
}
class unk2{
public:
unk3* m_unk3;
}
class unk1{
public:
char pad_001[0x78];
unk2* m_unk2;
}
Then declare an instance at your static offset, and read/write to it like it is your own memory.
unk1* p_unk1 = (unk1*)(uintptr_t*)(OFFSET);
p_unk1->m_unk2->m_unk3->location = 300f;
Using RPM
If you want to go external, you'll need to first open a handle to the process.
void attach(LPCSTR WindowName) {
HWND hWindow = FindWindowA(NULL, WindowName);
if (hWindow)
{
GetWindowThreadProcessId(hWindow, &Proc_ID);
hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION/*PROCESS_ALL_ACCESS*/, FALSE, Proc_ID);
HANDLE hModule = INVALID_HANDLE_VALUE;
MODULEENTRY32 ePoint;
hModule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, Proc_ID);
ePoint.dwSize = sizeof(MODULEENTRY32);
Module32First(hModule, &ePoint);
base = (DWORD*)ePoint.modBaseAddr;
CloseHandle(hModule);
}
}
Then I'd recommend setting up templates for doing the reading/writing for you.
template <class T>
T read(DWORD_PTR Address){
T buffer;
ReadProcessMemory(this->hProcess, (LPCVOID)Address, &buffer, sizeof(buffer), NULL);
return buffer;
}
Then pretty much the same method for writing. Then execution would be:
DWORD_PTR p_unk1 = mem.read<DWORD_PTR>(OFFSET);
DWORD_PTR p_unk2 = mem.read<DWORD_PTR>(p_unk1 + 0x78);
DWORD_PTR p_unk3 = mem.read<DWORD_PTR>(p_unk2);
float location = mem.read<float>(p_unk3 + 0x10);
Externally efficiency
Rather than just ready sizeof(DWORD_PTR) and reading every element in the class, its better if you do something like this:
class unk3{
public:
char pad_001[0x10];
float location;
}
class unk2{
public:
DWORD_PTR m_unk3;
}
class unk1{
public:
char pad_001[0x78];
DWORD_PTR m_unk2;
}
Replace every class* with a DWORD_PTR
Then execute it with
unk1 p_unk1 = mem.read<unk1>(OFFSET);
unk2 p_unk2 = mem.read<unk2>(p_unk1.m_unk2);
unk3 p_unk3 = mem.read<unk3>(p_unk2.m_unk3);
float location = p_unk3.Location;
For those who are wondering, writing that way is done:
mem.write<float>(p_unk2 + offsetof(unk3, location), value);
Wrap up
Internally doing this is significantly better, less hassle. Note on your question, writeprocessmemory just shoves bytes, it doesn't care about type. You're probably passing the address of an integer as the buffer to write, when ints and floats are encoded differently with little endian. Make sure you declare it as a float, or better yet, use a template. Or even better, just write a dll :)

Hooked NtOpenFile fails when std::wstring is defined on the stack

I have written a hooking dll using the mhook library. In a spezial case the NtOpenFile() fails when a std::wstring is defined as stack var. Defining it on the heap the code is working.
The code is working without problems except when a certain win32 application (lets call it nuisance.exe) tries to open an existing testfile (like c:\temp\anyfile.log) the access fails. Mostly STATUS_INVALID_ACL (0xC0000077) is returned then.
I have reduced my code line by line and finally found that the error happens when in a called function a std::wstring is defined (this example below). The error happens every time an on different OS's
NTSTATUS NtOpenFileApiHook::NtOpenFileHook(PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
ULONG ShareAccess,
ULONG OpenOptions
)
{
NTSTATUS Status = STATUS_SUCCESS;
// using this function the call will fail
AfterThis_NtOpenFile_WillFail();
// using this function INSTEAD the call will work
AfterThis_NtOpenFile_WillWork();
// calling the real NtOpenFile using a pointer
// nothing was changed hier, the original parameters are passed
Status = RealNtOpenFile(FileHandle, ...);
return Status;
}
int AfterThis_NtOpenFile_WillFail()
{
std::wstring String = L"";
return 0;
}
int AfterThis_NtOpenFile_WillWork()
{
std::wstring * pString = new std::wstring();
pString->assign(L"");
delete pString;
return 0;
}
I have fixed it this way for this call. But I'm afraid that other functions in other circumstainces could fail so I'm looking for the reason and (probably) for a solution.
Nuisance.exe is a C# application with default stacksize callling a win32 dll about which I know nothing.
If Nuisance.exe was a C++ application, I would imagine that it calls NtOpenFile in a way similar to this, allocating one of pointer parameters on overwritten stack:
POBJECT_ATTRIBUTES MakeObjectAttributes()
{
POBJECT_ATTRIBUTES oa = {...};
return &oa; // Pointer to stack variable - UB
}
...
NtOpenFile(..., MakeObjectAttributes(), ...)
STATUS_INVALID_ACL (0xC0000077) error might suggest that SecurityDescriptor within OBJECT_ATTRIBUTES is allocated this way.
Then it matters how much stack is used by AfterThis_NtOpenFile_WillFail, and it is more than AfterThis_NtOpenFile_WillWork, since std::wstring would be larger than just a couple of pointers due to small string optimization.
If the call chain is always the same, the corruption may be deterministic.
I don't know if code equivalent of returning address of temporary is possible in C#. But the DLL may be in C/C++ or similar language that allows dandling pointers.
To prove/disprove the role of stack, try to allocate other data on stack that has std::wstring size. More precise proof could be checking passed pointer to see if they point to stack area that is about to be overwritten.

System Error 122 - ERROR_INSUFFICIENT_BUFFER when calling WriteMsgQueue()

'm new to C++ so still trying to get my head around the code so sorry for sounding stupid!
I'm making changes to some existing code.
The old code is calling the below function where the cbDataSize is being determined by sizeof(MyStruct)
BOOL WINAPI WriteMsgQueue(HANDLE hMsgQ, LPVOID lpBuffer, DWORD cbDataSize, DWORD dwTimeout, DWORD dwFlags);
The change I made was to add another Struct within the Struct MyStruct so that it now looks like:
struct MyInnerStruct {
char myarray[20][256];
long mycount;
};
struct MyStruct {
long value1;
long value2;
MyInnerStruct inner;
};
Below is the call to WriteMsgQueue:
HANDLE requestQueue;
MyStruct myData;
DWORD timeout = 12000;
WriteMsgQueue(requestQueue, &myData, sizeof(myData), timeout, 0);
I am now receiving the System Error 122 - ERROR_INSUFFICIENT_BUFFER when the WriteMsgQueue() is being called.
Any help appreciated on how I calculate the correct size?
The queue probably wasn't allocated with enough space to hold your larger structure. You may need to find where the old code creates the queue (via CreateMsgQueue()) and look at the MSGQUEUEOPTIONS struct being passed in. This struct has a cbMaxMessage field which determines the maximum size of a single message. You may need to increase this. Also check the other fields like cbSize, dwMaxMessages etc.

COM Passing C++ struct from C++ client to to C++ server by pointer

I've been researching passing a struct as a parameter from a C++ client to a C++ server using COM. I've found many examples but none that really explained it to me like I'm five nor any that really provided a firm understanding of how to do what I want, which is simply pass a C++ struct through a COM interface where both sides are C++. Should be easy, right?
I have established my struct as follows in the IDL file on server-side:
[
uuid(7F0C9A48-3C41-425B-B4E6-8156B61D5355),
version(1.0)
]
typedef struct xxxData
{
int iWidth;
int iHeight;
SafeArray(short) pxxxData;
} xxxData;
// Fix for UUID DECLARATION FOR _uuidof() functionality
// From http://go4answers.webhost4life.com/Example/error-c2787-no-guid-been-associated-158947.aspx
cpp_quote("struct __declspec(uuid(\"{7F0C9A48-3C41-425B-B4E6-8156B61D5355}\")) xxxData;")
Which works, so far as I can tell.
Now my client calls GetImageData which is shown as follows:
[id(16)] HRESULT GetImageData([in,out] VARIANT* pData);
Now my client call is as follows with this function:
VARIANT* pData = new VARIANT;
VariantInit( pData );
xxxData* data = new xxxxData;
HRESULT hr = mpCOMEvents->GetImageData(pData);
data = (FBIS_ImageData*)(pData->pvRecord);
int length = data->iWidth * data->iHeight;
However, length is giving me an incorrect address location. This makes me wonder if my use of pvRecord is incorrect and if I can really typecast it?
Here is my COM server side:
xxxData data;
//SAFEARRAY *psa;
IRecordInfo *pRI;
HRESULT hr;
/* Pass in Structure Information */
data.iHeight = 100;
data.iWidth = 100;
// Used http://vcfaq.mvps.org/com/4.htm as reference
hr = GetRecordInfoFromGuids(LIBID_xxxLib, 1, 0, 0x409, _uuidof(xxxData), &pRI);
VariantInit(pData);
pData->vt = VT_RECORD;
pData->pvRecord = &data;
pData->pRecInfo = pRI;
pRI = NULL;
There's some confusion here.
If you're not aiming to be automation friendly, change your IDL to:
[size_is=iWidth*iHeight] unsigned short* pxxxData;
and don't use SAFEARRAY API on this. For marshalling, you'll have to compile a proxy/stub DLL and register it.
If you're aiming to be automation friendly, change your IDL to:
SAFEARRAY(short) pxxxData;
and do use the SAFEARRAY API on this. For marshalling, you'll have to compile a typelib (optionally, embed it) and register it. This also enables early-binding (e.g. VB6, tlbimp).
This will work for languages/environments that support user-defined types. For the ones that don't (e.g. scripting languages), you'll have to use an oleautomation/dual/IDispatch-based interface instead of a struct (and implement in in the server).
EDIT: Based on the changes you made to your question.
You should declare the pData parameter as out only, GetImageData will populate it, not use it and possibly replace it. It also only requires marshaling on return, not on the call. Here's a suggestion:
[id(16)] HRESULT GetImageData([out] VARIANT* pData);
Your client code has a memory leak, it always creates an xxxData. Here's a suggestion:
// If pData is in-out, this is not safe, use CoTaskMemAlloc(sizeof(VARIANT)) instead.
// The callee may override the buffer by assuming it was CoTaskMemAlloc'ed, thus
// assuming it can CoTaskMemFree the original location and set the pointer to a new
// CoTaskMemAlloc'ed location.
// The callee may be a proxy.
// Assuming it's out only, we can provide any location with enough space for a VARIANT.
VARIANT vData;
VariantInit( &vData );
xxxData* data; // remove memory leak
HRESULT hr = mpCOMEvents->GetImageData(&vData);
// error handling removed for clarity (I hope)
data = (xxxData*)(vData.pvRecord);
int length = data->iWidth * data->iHeight;
// ... use data ...
// Don't forget to clear the variant, or there'll be a memory leak
// It implies:
// vData.pRecInfo->RecordDestroy(vData.pvRecord);
// This should recursively release memory allocated in each field
// and finally release the memory allocated for the struct itself.
// vData.pRecInfo->Release();
VariantClear( &vData );
// don't use data past this point
Your server code is setting pData->pvRecord to point to the stack, which means that it will potentially be overwritten by a caller or some other invoked function. Here's a suggestion:
xxxData* data; // Changed to pointer
IRecordInfo *pRI;
HRESULT hr;
// data.iHeight = 100; // removed
// data.iWidth = 100; // removed
hr = GetRecordInfoFromGuids(LIBID_xxxLib, 1, 0, 0x409, _uuidof(xxxData), &pRI);
// error handling removed for clarity (I hope)
VariantInit(pData);
// This will allocate memory for the struct itself
// For fields that require memory allocation, follow "normal" COM rules,
// such as using CoTaskMemAlloc for buffers, SysAllocString or similar for BSTRs,
// etc.
// For each inner (pointed to) structure, you should call RecordCreate on the
// respective IRecordInfo instance for that type.
data = (xxxData*)pRI->RecordCreate();
data->iHeight = 100; // new
data->iWidth = 100; // new
// If pData is in-out, this will leak, use VariantClear instead.
// Assuming it's out only, use VariantInit as it points to (allocated) garbage.
VariantInit(pData);
pData->vt = VT_RECORD;
pData->pvRecord = data; // data is already a pointer
pData->pRecInfo = pRI;
pRI = NULL;
// This won't (normally) leak, the caller must call VariantClear on the out VARIANT.
// The caller may be a stub.