'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.
Related
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?".
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 :)
I'm using GetProcAddress to gain access to a standard Isapi Filter DLL method - the GetFilterVersion method which takes a pointer to a HTTP_FILTER_VERSION structure.
https://msdn.microsoft.com/en-us/library/ms525822(v=vs.90).aspx
https://msdn.microsoft.com/en-us/library/ms525465(v=vs.90).aspx
I've tested the code against a working Isapi filter that I've written and it works fine. I debug the code against an Isapi filter from a vendor (I don't have access to the source code or anything beyond the dll itself) and I get the exception, "access violation writing location". What could be the issue? (Both Isapi filters work in IIS.)
//Attempted to define function ptr several ways
typedef BOOL(__cdecl * TRIRIGAISAPIV)(PHTTP_FILTER_VERSION);
//typedef BOOL( * TRIRIGAISAPIV)(PHTTP_FILTER_VERSION);
//typedef BOOL(WINAPI * TRIRIGAISAPIV)(PHTTP_FILTER_VERSION);
void arbitraryMethod()
{
HINSTANCE hDLL; // Handle to DLL
TRIRIGAISAPIV lpfnDllFunc2; // Function pointer
DWORD lastError;
BOOL uReturnVal2;
hDLL = LoadLibrary(L"iisWASPlugin_http.dll"); //vendor's dll
//hDLL = LoadLibrary(L"KLTWebIsapi.dll //my dll
if (hDLL != NULL)
{
lpfnDllFunc2 = (TRIRIGAISAPIV)GetProcAddress(hDLL, "GetFilterVersion");
if (!lpfnDllFunc2)
{
lastError = GetLastError();
// handle the error
FreeLibrary(hDLL);
//return 1;
}
else
{
HTTP_FILTER_VERSION pVer = { 6 };
//Call the function via pointer; Works with my dll, fails with vendor's
uReturnVal2 = lpfnDllFunc2(&pVer);
//................ HELP!!!!!!!!!!!!!
}
}
}
One issue that I see is that your function pointer declaration is incorrect.
According to the Microsoft documentation, GetFilterVersion is prototyped as:
BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer);
The WINAPI is a Windows macro that is actually defined as __stdcall, thus you are declaring the function pointer incorrectly when you used __cdecl.
What does WINAPI mean?
Thus, your declaration should be:
typedef BOOL(__stdcall * TRIRIGAISAPIV)(PHTTP_FILTER_VERSION);
It could be that there are actually some additional structure fields filled by the custom filter.
You can try to increase the size of the structure to see if that will work, like for example:
struct HTTP_FILTER_VERSION_EXTRA {
HTTP_FILTER_VERSION v;
char[1024] extra;
};
HTTP_FILTER_VERSION_EXTRA ver;
ver.v.dwServerFilterVersion = 6;
uReturnVal2 = lpfnDllFunc2(&ver.v);
It is sometimes the case with the WinAPI structures that they allow versioning, so adding fields is possible. If the function doesn't then check (or doesn't know) the actual structure version, it might try to use an extended one which might be different than the one supplied - if the size of the supplied struct is then lesser than the structure version the func tries to use, bad things can happen.
Also check if the DLL is 64-bit or 32-bit. You cannot use 64-bit DLL by 32-bit app and vice versa (but I expect that would already fail during the LoadLibrary call).
I was very surprized to see that in the version of Visual C++ that comes with VS2013 the data members of a newly created class seem to be automatically initialized to 0 or null depending on their type. This is new - and very useful! - behaviour in my experience. I have previously only used VC++ Version 4 when writing serious apps and way back in the middle 1990's the initial values were explicitly stated as being undefined/random.
Is this perhaps some helpful attribute of using the debug libraries, or is it possible to rely on null initialization all the time?
As requested, some example code - nothing very exciting I am afraid:
class CData
{
public:
CData();
CData(const CData ©);
~Data();
const CData& operator=(const CData ©);
//Accessors/Mutators follow...
private:
bool Initialize_Data();
//Just giving a couple of examples of data member sets.
char *input_script_name;
int size_input_script_name;
int size_input_script_name_buffer;
char *interpreter_name;
int size_interpreter_name;
int size_interpreter_name_buffer;
};
CData::CData()
{
Initialize_Data();
}
CData::~CData()
{
//Code to store relevent data in registry
//and then free dynamically allocated memory follows...
}
bool CData::Initialize_Data()
{
//Code to retrieve data from registry stored at end of last run follows
//along with routines to check bounds.
//
//At this point, without executing any further a breakpoint is triggered
//and on inspecting data members in a Watch on 'this' I find them
//to be already initialized to either 0 or null respectively.
}
...
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
//Application entry point;
CData application_data; //and away it goes!
//Usual name mutex to prevent multiple instances and message loop follow...
}
As I said VERY basic and I am not illustrating all the code. However, at the point the breakpoint in 'Initialize_Data' is reached - which is immediately on creating the class and BEFORE anything else is executed - all the data members show up as either 0 or null in a Watch. Which is rather surprising!
This is just a coincidence. What you probably observe is that something clears a lot of memory just before your object is initialized, and then your object is placed in that zero-initialized memory. There is no guarantee that this will remain the case, nor will you be able to rely on this on other platforms/compilers. In Debug mode, Visual C++ actually tries to clear to a non-zero bit-pattern, for example.
If you want to zero initialize, you can use the C++ 11 non-static member initializers like this:
char *input_script_name = nullptr;
int size_input_script_name = 0;
int size_input_script_name_buffer = 0;
char *interpreter_name = nullptr;
int size_interpreter_name = 0;
int size_interpreter_name_buffer = 0;
I'm not sure if the current compilers optimize this to a memset if everything is set to 0, but this is the way to go if you have access to a C++11 compiler.
Update
Just checked with Clang 3.4, it does emit a memset if everything is set to 0. GCC initializes using registers, but I suspect that's because my small test case only had ~10 member variables.
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.