Accesing values of another program - c++

So, I've been wondering that how I access values of different program with my c++ code.
I understand that I have to know the memory location and access it somehow but I don't really know how.
Let's say that I have a game where I have a character that has a certain amount of health and I want to read that health with my c++ code (similar to how you can read different values with the cheat engine program).
How would I accomplish this?
For clarity: Operating system is windows

You can use the ReadProcessMemory/VirtualQuery (safer than ReadProcessMemory) and WriteProcessMemory functions.
If you are clever you can inject a DLL, then you can use pointers in your code
int * money = 0x00400000+0x00ABCDEF;//pointer to money address
*money = 5000;//set money to 5000.
if you need DLL examples, here are some:
Red Alert 3 Player Information Mod
Need for Speed: Underground 2 cheat mod
Sometimes pointers can change what they point to, this can be "dangerous" in terms of the application.
When you access a pointer which points to a protected memory area, inaccessible memory, not to the stuff you want or an invalid location your application may crash. I don't know how Cheat Engine prevents it but you have a few options, the ones I suggest:
Exit application gracefully and let the user know you couldn't handle it
Handle the problem with a try / catch block instead? (be sure to capture the correct error)
Hard exit the application
Do nothing and let the application behave weird / crash
... more and more
I also wrote pointer class myself which handles the dereferencing and stops when an error is encountered (returns null)
//null as last parameter automaticly "Dereferences"
template<class T = DWORD, class S = DWORD> struct Pointer
{
private:
std::vector<S> params;
S variable;
bool MoreThanOne;
public:
//null as last parameter automaticly "Dereferences"
template<class... Args>
Pointer(Args... args)
{
std::array<S, sizeof...(args)> list = {args...};
for( auto i : list)
params.push_back(i);
if(params.size() > 1)
MoreThanOne = true;
else
MoreThanOne = false;
}
T ResolvePointer()
{
variable = params[0];
if(!MoreThanOne)
return (T)variable;
try
{
auto it = params.begin();
++it;
for(; it != params.end(); ++it)
{
if(*reinterpret_cast<S*>(variable) == NULL)
return static_cast<T>(NULL);
variable = *reinterpret_cast<S*>(variable) + *it;
}
}
catch(...)
{
return static_cast<T>(NULL);
}
return (T)variable;
}
T operator()()
{
return ResolvePointer();
}
};
usage:
unsigned long ipaddr = htonl(Pointer<unsigned long>(0x00400000+0x008E3A74,0x04,0x38,NULL)());//pointer to players IP address
if(ipaddr != NULL)//....

You can't access variables in another process unless:
Your program uses "debug functions" to access the values.
You use some sort of IPC (shared memory, pipes, message queues) to share/transfer the data.
Each process has its own address space [1], and there is no way to access into another process's address space without some mechanism to access it.
[1] Assuming we're talking about a "real" OS that uses proper memory management. In some OS's such as traditional DOS, there is no memory protection between processes. But no sane person works with these OS's unless the system is running with a very feeble processor and small amounts of memory.

You should not write to another process's memory space without using specific IPC mechanisms. Operating systems typically prevent this for obvious reasons. Instead, you would need to use the target application's extension mechanisms, or decompile / modify / hex edit to effect the changes you want. That being said, doing so may be in violation of the terms of service for the software you are messing with.
To be clear, the code will compile just fine, letting you set a pointer to whatever arbitrary address you'd like, but once you try to read or write that address, the OS will step in and cause an error condition.
If you aren't violating the software's EULA by doing so, here are some pointers for finding things you might like to modify:
If the code can be decompiled into some readable source form, do so and make modifications there.
Edit the compiled binary with a hex editor, look for well-defined values and change them (does the max_health always start out at 25? That might be unique enough to locate and modify). A note about this: Make sure the values you intend to insert fit in the same space as the original values, otherwise you will break things and have undefined results.
Does the application provide an extension mechanism, such as a scripting API or mod support? If so, this can be a vector for causing the types of system changes you want.

Related

How can calling a function pointer saved from a previous execution fail?

I was curious if function pointers could be stored in a file and used at some future point in time when the program had exited and started again. For example, my first test program looked something like this pseudocode:
void f(){}
typedef void(*Fptr)();
int main() {
int i;
cin >> i;
if (i == 1) {
std::ofstream out(/**/);
out << &f;
}
else {
std::ifstream in(/**/);
Fptr fp;
in >> fp;
fp();
}
}
That is just the logic of what I wanted to do. I would launch it with input 1, let it exit, and run it again with input 2. Don't consider that to be my real code, as I erased the original test because...
That only worked if I don't change the directory that the executable is in!
Adding a new file to the directory (presumably removing a file too) and moving the executable somewhere new would all cause fp(); to crash. The new function address would be a different value.
So I made a new test which calculates the difference between an old function pointer and a current function address. Applying that offset to an old function pointer and calling it yields the correct function call, regardless of what I do to the directory.
I am confident this is UB. However, like de-referencing a null pointer will cause a segfault, the UB is pretty consistent.
Aside from rewriting the data with garbage, and assuming that the functions aren't loaded in a DLL, how likely is this method to succeed? In what ways will it still fail to work?
As others mentioned, this problem is caused by the "Address Space Layout Randomization" (ASLR). This randomization is done for each module (i.e, each executable image). This means that if all your functions are contained in your .exe, they are guaranteed to to always have the same offset from the base of the module. If some function are in a DLL, the same apply, but from the base of the DLL module. It is important that the relative module addresses stay the same, because otherwise it wouldn't be possible to locate entry points and DLL functions.
On a Windows environment :
In Visual Studio (and MSVC), ASLR is ON by default, but you can disable it in the "Linker > Advanced > Randomized Base Address" option (/DYNAMICBASE:NO in command line). By disabling this option, the functions will always be at the same address.
You can also determine the offset at runtime. The module base address can be obtained with GetModuleHandle() (the module handle is in fact the base address). With this, you can work with relative addresses for your pointers.
uintptr_t base_address = (uintptr_t)GetModuleHandle(NULL);
uintptr_t offset = (uintptr_t)&f - base_address;
out << offset;
in >> offset;
fp = (Fptr)(offset + base_address);
fp();
The function pointer will ONLY work if the program is loaded at the same address each time. Modern OS's have "address space randomization", which causes the actual address of code, data and stack to be moved around at random - to avoid stack overflow attacks that modify the return address - since it's not possible to know the address to "return to" if it is picked at random.
There are settings to disable the random changes.
Obviously, it also won't work if code is changed that is between the start of the code-section that the callee function in.
The pointer is converted to a void *, which should be possible - obviously, the file content won't work on another OS or processor architecture, but I don't see a particular reason for this not working.
However, a more portable way would be to store a sequence number of the operation you are using, rather than a function pointer. And then doing something like this:
for(;;)
switch(sequence)
{
case 1:
f();
sequence++;
break;
case 2:
g();
sequence++;
break;
}
...
}
On failure, store sequence (or sequence - 1).
The above assumes the f and g functions are throwing an exception or using longjmp to exit [or that ... is checking for errors].
Beyond that, I can't see a technical reason why

Side effects of exit() without exiting?

If my application runs out of memory, I would like to re-run it with changed parameters. I have malloc / new in various parts of the application, the sizes of which are not known in advance. I see two options:
Track all memory allocations and write a restarting procedure which deallocates all before re-running with changed parameters. (Of course, I free memory at the appropriate places if no errors occur)
Restarting the application (e.g., with WinExec() on Windows) and exiting
I am not thrilled by either solution. Did I miss an alternative maybe.
Thanks
You could embedd all the application functionality in a class. Then let it throw an expection when it runs out of memory. This exception would be catched by your application and then you could simply destroy the class, construct a new one and try again. All in one application in one run, no need for restarts. Of course this might not be so easy, depending on what your application does...
There is another option, one I have used in the past, however it requires having planned for it from the beginning, and it's not for the library-dependent programmer:
Create your own heap. It's a lot simpler to destroy a heap than to cleanup after yourself.
Doing so requires that your application is heap-aware. That means that all memory allocations have to go to that heap and not the default one. In C++ you can simply override the static new/delete operators which takes care of everything your code allocates, but you have to be VERY aware of how your libraries, even the standard library, use memory. It's not as simple as "never call a library method that allocates memory". You have to consider each library method on a case-by-case basis.
It sounds like you've already built your app and are looking for a shortcut to memory wiping. If that is the case, this will not help as you could never tack this kind of thing onto an already built application.
The wrapper-program (as proposed before) does not need to be a seperate executable. You could just fork, run your program and then test the return code of the child. This would have the additional benefit, that the operating system automatically reclaims the child's memory when it dies. (at least I think so)
Anyway, I imagined something like this (this is C, you might have to change the includes for C++):
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define OUT_OF_MEMORY 99999 /* or whatever */
int main(void)
{
int pid, status;
fork_entry:
pid = fork();
if (pid == 0) {
/* child - call the main function of your program here */
} else if (pid > 0) {
/* parent (supervisor) */
wait(&status); /* waiting for the child to terminate */
/* see if child exited normally
(i.e. by calling exit(), _exit() or by returning from main()) */
if (WIFEXITED(status)) {
/* if so, we can get the status code */
if (WEXITSTATUS(status) == OUT_OF_MEMORY) {
/* change parameters */
goto fork_entry; /* forking again */
}
}
} else {
/* fork() error */
return 1;
}
return 0;
}
This might not be the most elegant solution/workaround/hack, but it's easy to do.
A way to accomplish this:
Define an exit status, perhaps like this:
static const int OUT_OF_MEMORY=9999;
Set up a new handler and have it do this:
exit(OUT_OF_MEMORY);
Then just wrap your program with another program that detects this
exit status. When it does then it can rerun the program.
Granted this is more of a workaround than a solution...
The wrapper program I mentioned above could be something like this:
static int special_code = 9999;
int main()
{
const char* command = "whatever";
int status = system(command);
while ( status == 9999 )
{
command = ...;
status = system(command);
}
return 0;
}
That's the basicness of it. I would use std::string instead of char* in production. I'd probably also have another condition for breaking out of the while loop, some maximum number of tries perhaps.
Whatever the case, I think the fork/exec route mentioned below is pretty solid, and I'm pretty sure a solution like it could be created for Windows using spawn and its brethren.
simplicity rules: just restart your app with different parameters.
it is very hard to either track down all allocs/deallocs and clean up the memory (just forget some minor blocks inside bigger chunks [fragmentation] and you still have problems to rerun the class), or to do introduce your own heap-management (very clever people have invested years to bring nedmalloc etc to live, do not fool yourself into the illusion this is an easy task).
so:
catch "out of memory" somehow (signals, or std::bad_alloc, or whatever)
create a new process of your app:
windows: CreateProcess() (you can just exit() your program after this, which cleans up all allocated resources for you)
unix: exec() (replaces the current process completely, so it "cleans up all the memory" for you)
done.
Be warned that on Linux, by default, your program can request more memory than the system has available. (This is done for a number of reasons, e.g. avoiding memory duplication when fork()ing a program into two with identical data, when most of the data will remain untouched.) Memory pages for this data won't be reserved by the system until you try to write in every page you've allocated.
Since there's no good way to report this (since any memory write can cause your system to run out memory), your process will be terminated by the out of memory process killer, and you won't have the information or opportunity for your process to restart itself with different parameters.
You can change the default by using the setrlimit system call, to to limit the RLIMIT_RSS which limits the total amount of memory your process can request. Only after you have done this will malloc return NULL or new throw a std::bad_alloc exception when you reach the limit that you have set.
Be aware that on a heavily loaded system, other processes can still contribute to a systemwide out of memory condition that could cause your program to be killed without malloc or new raising an error, but if you manage the system well, this can be avoided.

Get specific process memory space

I have a pointer (void *) to a function and I want to know which process this function belongs to. I have no idea which way to go about it, but I think it's possible by using some form of VirtualQuery trickery. Any help would be appreciated.
Thanks in advance,
CLARIFICATION: By "belong to process" I mean what process the function is in. For example:
say there was an executable (test.exe) loaded in memory. This executable contains a function named SayHello, which is located at 0xDEADBEEF in memory. In an entirely different process, how would I know 0xDEADBEEF is in test.exe's memory space.
Hope that clears things up.
CLARIFICATION 2: I'm sure you're familiar with "VTable hooking", where an external module changes a VTable pointer in a seperate process to point to a different function. Thereby whenever the hooked member is called, it is passed to the external module.
To prevent this (anti-cheat), I want to be able to check whether all methods of a VTable point to the module they reside in.
SOLUTION CODE:
template<class T>
inline void **GetVTableArray(T *pClass, int *pSize)
{
void **ppVTable = *(void ***)pClass;
if(pSize)
{
*pSize = 0;
while(!IsBadReadPtr(ppVTable[*pSize], sizeof(UINT_PTR)))
(*pSize)++;
}
return ppVTable;
}
bool AllVTableMembersPointToCurrentModule(void *pClass)
{
DWORD dwOldProtect;
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 moduleEntry;
// Take a snapshot of all modules in the specified process
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
if(hModuleSnap == INVALID_HANDLE_VALUE)
return false;
// Set the size of the structure before using it
moduleEntry.dwSize = sizeof(MODULEENTRY32);
// Retrieve information about the first module (current process)
if(!Module32First(hModuleSnap, &moduleEntry))
{
CloseHandle(hModuleSnap);
return false;
}
// Grab the base address and size of our module (the address range where
// the VTable can validly point to)
UINT_PTR ulBaseAddress = reinterpret_cast<UINT_PTR>(moduleEntry.modBaseAddr);
UINT_PTR ulBaseSize = moduleEntry.modBaseSize;
// Get the VTable array and VTable member count
int nMethods;
void **ppVTable = GetVTableArray(pClass, &nMethods);
#ifdef VTABLE_FAKING
// Allow patching
VirtualProtect(ppVTable, nMethods * sizeof(UINT_PTR), PAGE_EXECUTE_READWRITE, &dwOldProtect);
// Now take the next module and set the first VTable pointer to point to an
// invalid address, outside of the current module's address range
Module32Next(hModuleSnap, &moduleEntry);
ppVTable[0] = moduleEntry.modBaseAddr;
#endif
// Don't allow people to overwrite VTables (can easily be bypassed, so make
// sure you check the VirtualProtect status of the VTable regularly with
// VirtualQuery)
VirtualProtect(ppVTable, nMethods * sizeof(UINT_PTR), PAGE_EXECUTE, &dwOldProtect);
// Clean up the snapshot object
CloseHandle(hModuleSnap);
// Ensure all VTable pointers are in our current module's address range
for(int i = 0; i < nMethods; ++i)
{
// Get address of the method this VTable pointer points to
UINT_PTR ulFuncAddress = reinterpret_cast<UINT_PTR>(ppVTable[i]);
// Check the address is within our current module range
if(ulFuncAddress < ulBaseAddress || ulFuncAddress > ulBaseAddress + ulBaseSize)
return false;
}
return true;
}
Each process has its own address space. This means that the same address will contain different things for different processes, so there is no way to do what you're asking.
If this pointer is to a function in the current program (i.e. a function that you can currently call), then the answer is simple: it belongs to the current process.
To further clarify: A pointer by itself is meaningless unless you already know which process it belongs to. Process #1001 may have a function sayHello at address 0x12345678, while process #1002 has the function sayGoodbye at address 0x12345678, and process #1003 contains some data at the same address. There is no way to know which process the pointer came from.
The hijacked function pointer in the VTable can only be inside your process, as the other folks have already answered. The memory address only makes sense for your process. If someone is going to overwrite one of your VTable spots, then they would first have to hook something your process, which means running code inside your process. There exists plenty of win API that provides hooking.
See EnumProcessModule to go through all of the modules in your process. See this about modules info including base address of your module. You would then have to check your VTables to make sure those addressed exist inside of your module's address range.
To prevent VTable hijacking in the first place? I don't know how to do this, other than trying Microsoft's Detours library, which can in theory be used to detour any hook API call inside your process.
If you have the module handle, you can inspect the image header to ensure that the vtable pointers are in that module's virtual address space.
In any of the Windows operating systems that are descended from Windows NT (so, for all intents and purposes anything including and after XP, and before that NT 4 and NT 3.51) each process has it's own address space. Within reason, any pointer address can be different in every process in the system as they all have an 0xDEADBEEF address and it may, or may not contain the same thing as other processes. This was not the same with Windows 3.0, 3.1, 95, 98 and ME (they had one address space which all processes shared) where your question MAY have made more sense.
So, without a handle to a process to go with your pointer address the address is pretty much useless to you. With a handle to a process you can (possibly) work out what you want by walking the import tables for the DLLs that you import... If the function isn't an imported function then it's unlikely that you could work out what you want to know.
Note that if the address is to a function which is from a 'standard' system DLL then you MAY be able to work out where it lives by finding out what function it represents in the address space of your process as there is a strong chance that the DLL will be mapped to the same base address in your process as it is in every other process.
Why not tell us a little more about what it is, exactly, that you're actually trying to do?
Edit:
Well, as I described above, what you're suggesting is not possible except on very old versions of Windows. What IS possible is that you can inject code into a process to replace that code that should be executed. The address of this injected code is valid in the target process's address space and contains code that you (the hacking process) have created. You do this by a combination of allocating memory in the remote process with VirtualAllocEx() (1) and then writing your code to it with WriteProcessMemory() (2). You now have code that you wrote in the target process. You can then patch it in so that it's called instead of the code that should be called.
The common way to do this is IAT hooking (Import Address Table hooking) and this lets you replace imported functions from DLLs. To detect this you need to scan the DLL's Import Address Table from the DLL image on disk, work out where the functions are in memory and then scan the in memory IAT to check that the functions are where they should be; if they're not then they've likely been patched.
You're suggesting that someone is replacing an arbitrary C++ vTable entry. This is possible with the same technique but it's harder as there's no convenient table of names to addresses that you can use to work out where to patch. Anyway, assuming the bad guy can find the correct address to patch he can use the same technique as above to create his own function in your process.
Detecting the vTable problem is made more complex by the lack of name to address lookup, but if you're in the process that's being hacked you can simply have written code that takes the address of the function in question at start up. Store that somewhere and compare it later. However, you'd probably best take a copy of the whole function itself in memory and compare with that as you might find that the bad guys simply look for some recognisable function signature bytes and patch a jump into them somewhere to their own code or simply to skip yours.
Good luck and grab yourself a good book, such as one by Jeffrey Richter which will explain much of this far better than I can.
I don't really understand your question, so I'm going to take a stab in the dark and answer what I think you're asking.
You're asking how you can find out, from a function pointer, to which module it belongs.
The solution is rather simple in theory, scan backwards in memory to find the header, and then enjoy using this function GetModuleFileName.
Since your question isn't well worded, you don't get a well worded answer.

Is it possible to use function pointers across processes?

I'm aware that each process creates it's own memory address space, however I was wondering,
If Process A was to have a function like :
int DoStuff() { return 1; }
and a pointer typedef like :
typedef int(DoStuff_f*)();
and a getter function like :
DoStuff_f * getDoStuff() { return DoStuff; }
and a magical way to communicate with Process B via... say boost::interprocess
would it be possible to pass the function pointer to process B and call
Process A's DoStuff from Process B directly?
No. All a function pointer is is an address in your process's address space. It has no intrinsic marker that is unique to different processes. So, even if your function pointer just happened to still be valid once you've moved it over to B, it would call that function on behalf of process B.
For example, if you had
////PROCESS A////
int processA_myfun() { return 3; }
// get a pointer to pA_mf and pass it to process B
////PROCESS B////
int processB_myfun() { return 4; } // This happens to be at the same virtual address as pA_myfun
// get address from process A
int x = call_myfun(); // call via the pointer
x == 4; // x is 4, because we called process B's version!
If process A and B are running the same code, you might end up with identical functions at identical addresses - but you'll still be working with B's data structures and global memory! So the short answer is, no, this is not how you want to do this!
Also, security measures such as address space layout randomization could prevent these sort of "tricks" from ever working.
You're confusing IPC and RPC. IPC is for communicating data, such as your objects or a blob of text. RPC is for causing code to be executed in a remote process.
In short, you cannot use function pointer that passed to another process.
Codes of function are located in protected pages of memory, you cannot write to them. And each process has isolated virtual address space, so address of function is not valid in another process. In Windows you could use technique described in this article to inject your code in another process, but latest version of Windows rejects it.
Instead of passing function pointer, you should consider creating a library which will be used in both processes. In this case you could send message to another process when you need to call that function.
If you tried to use process A's function pointer from process B, you wouldn't be calling process A - you'd call whatever is at the same address in process B. If they are the same program you might get lucky and it will be the same code, but it won't have access to any of the data contained in process A.
A function pointer won't work for this, because it only contains the starting address for the code; if the code in question doesn't exist in the other process, or (due to something like address space randomization) is at a different location, the function pointer will be useless; in the second process, it will point to something, or nothing, but almost certainly not where you want it to.
You could, if you were insane^Wdaring, copy the actual instruction sequence onto the shared memory and then have the second process jump directly to it - but even if you could get this to work, the function would still run in Process B, not Process A.
It sounds like what you want is actually some sort of message-passing or RPC system.
This is why people have invented things like COM, RPC and CORBA. Each of them gives this general kind of capability. As you'd guess, each does so the job a bit differently from the others.
Boost IPC doesn't really support remote procedure calls. It will enable putting a variable in shared memory so its accessible to two processes, but if you want to use a getter/setter to access that variable, you'll have to do that yourself.
Those are all basically wrappers to produce a "palatable" version of something you can do without them though. In Windows, for example, you can put a variable in shared memory on your own. You can do the same in Linux. The Boost library is a fairly "thin" library around those, that lets you write the same code for Windows or Linux, but doesn't try to build a lot on top of that. CORBA (for one example) is a much thicker layer, providing a relatively complete distributed environment.
If both processes are in the same application, then this should work. If you are trying to send function pointers between applications then you are out of luck.
My original answer was correct if you assume a process and a thread are the same thing, which they're not. The other answers are correct - different processes cannot share function pointers (or any other kind of pointers, for that matter).

Most efficient replacement for IsBadReadPtr?

I have some Visual C++ code that receives a pointer to a buffer with data that needs to be processed by my code and the length of that buffer. Due to a bug outside my control, sometimes this pointer comes into my code uninitialized or otherwise unsuitable for reading (i.e. it causes a crash when I try to access the data in the buffer.)
So, I need to verify this pointer before I use it. I don't want to use IsBadReadPtr or IsBadWritePtr because everyone agrees that they're buggy. (Google them for examples.) They're also not thread-safe -- that's probably not a concern in this case, though a thread-safe solution would be nice.
I've seen suggestions on the net of accomplishing this by using VirtualQuery, or by just doing a memcpy inside an exception handler. However, the code where this check needs to be done is time sensitive so I need the most efficient check possible that is also 100% effective. Any ideas would be appreciated.
Just to be clear: I know that the best practice would be to just read the bad pointer, let it cause an exception, then trace that back to the source and fix the actual problem. However, in this case the bad pointers are coming from Microsoft code that I don't have control over so I have to verify them.
Note also that I don't care if the data pointed at is valid. My code is looking for specific data patterns and will ignore the data if it doesn't find them. I'm just trying to prevent the crash that occurs when running memcpy on this data, and handling the exception at the point memcpy is attempted would require changing a dozen places in legacy code (but if I had something like IsBadReadPtr to call I would only have to change code in one place).
bool IsBadReadPtr(void* p)
{
MEMORY_BASIC_INFORMATION mbi = {0};
if (::VirtualQuery(p, &mbi, sizeof(mbi)))
{
DWORD mask = (PAGE_READONLY|PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY);
bool b = !(mbi.Protect & mask);
// check the page is not a guard page
if (mbi.Protect & (PAGE_GUARD|PAGE_NOACCESS)) b = true;
return b;
}
return true;
}
a thread-safe solution would be nice
I'm guessing it's only IsBadWritePtr that isn't thread-safe.
just doing a memcpy inside an exception handler
This is effectively what IsBadReadPtr is doing ... and if you did it in your code, then your code would have the same bug as the IsBadReadPtr implementation: http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx
--Edit:--
The only problem with IsBadReadPtr that I've read about is that the bad pointer might be pointing to (and so you might accidentally touch) a stack's guard page. Perhaps you could avoid this problem (and therefore use IsBadReadPtr safely), by:
Know what threads are running in your process
Know where the threads' stacks are, and how big they are
Walk down each stack, delberately touching each page of the stack at least once, before you begin to call isBadReadPtr
Also, the some of the comments associated with the URL above also suggest using VirtualQuery.
The reason these functions are bad to use is that the problem can't be solved reliably.
What if the function you're calling returns a pointer to memory that is allocated, so it looks valid, but it's pointing to other, unrelated data, and will corrupt your application if you use it.
Most likely, the function you're calling actually behaves correctly, and you are misusing it. (Not guaranteed, but that is often the case.)
Which function is it?
The fastest solution I can think of is to consult the virtual memory manager using VirtualQuery to see if there is a readable page at the given address, and cache the results (however any caching will reduce the accuracy of the check).
Example (without caching):
BOOL CanRead(LPVOID p)
{
MEMORY_BASIC_INFORMATION mbi;
mbi.Protect = 0;
::VirtualQuery(((LPCSTR)p) + len - 1, &mbi, sizeof(mbi));
return ((mbi.Protect & 0xE6) != 0 && (mbi.Protect & PAGE_GUARD) == 0);
}
Why can't you call the api
AfxIsValidAddress((p), sizeof(type), FALSE));
If the variable is uninitialized you are hosed. Sooner or later it's going to be an address for something you don't want to play with (like your own stack).
If you think you need this, and (uintptr_t)var < 65536 does not suffice (Windows does not allow allocating the bottom 64k), there is no real solution. VirtualQuery, etc. appear to "work" but sooner or later will burn you.
I am afraid you are out of luck - there is no way to reliably check the validity of a pointer. What Microsoft code is giving you bad pointers?
Any implementation of checking the validity of memory is subject to the same constriants that make IsBadReadPtr fail. Can you post an example callstack of where you want to check the validity of memory of a pointer passed to you from Windows? That might help other people (including me) diagnose why you need to do this in the first place.
If you have to resort to checking patterns in data, here are a few tips:
If you mention using IsBadReadPtr, you are probably developing for Windows x86 or x64.
You may be able to range check the pointer. Pointers to objects will be word aligned. In 32-bit windows, user-space pointers are in the range of 0x00401000-0x7FFFFFFF, or for large-address-aware applications, 0x00401000-0xBFFFFFFF instead (edit: 0x00401000-0xFFFF0000 for a 32-bit program on 64-bit windows). The upper 2GB/1GB is reserved for kernel-space pointers.
The object itself will live in Read/Write memory which is not executable. It may live in the heap, or it may be a global variable. If it is a global variable, you can validate that it lives in the correct module.
If your object has a VTable, and you are not using other classes, compare its VTable pointer with another VTable pointer from a known good object.
Range check the variables to see if they are possibly valid. For example, bools can only be 1 or 0, so if you see one with a value of 242, that's obviously wrong. Pointers can also be range checked and checked for alignment as well.
If there are objects contained within, check their VTables and data as well.
If there are pointers to other objects, you can check that the object lives in memory that is Read/Write and not executable, check the VTable if applicable, and range check the data as well.
If you do not have a good object with a known VTable address, you can use these rules to check if a VTable is valid:
While the object lives in Read/Write memory, and the VTable pointer is part of the object, the VTable itself will live in memory that is Read Only and not executable, and will be aligned to a word boundary. It will also belong to the module.
The entries of the VTable are pointers to code, which will be Read Only and Executable, and not writable. There is no alignment restrictions for code addresses. Code will belong to the module.
Here is what I use this just replaces the official microsoft ones by using #define's this way you can use the microsoft ones and not worry about them failing you.
// Check memory address access
const DWORD dwForbiddenArea = PAGE_GUARD | PAGE_NOACCESS;
const DWORD dwReadRights = PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY;
const DWORD dwWriteRights = PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY;
template<DWORD dwAccessRights>
bool CheckAccess(void* pAddress, size_t nSize)
{
if (!pAddress || !nSize)
{
return false;
}
MEMORY_BASIC_INFORMATION sMBI;
bool bRet = false;
UINT_PTR pCurrentAddress = UINT_PTR(pAddress);
UINT_PTR pEndAdress = pCurrentAddress + (nSize - 1);
do
{
ZeroMemory(&sMBI, sizeof(sMBI));
VirtualQuery(LPCVOID(pCurrentAddress), &sMBI, sizeof(sMBI));
bRet = (sMBI.State & MEM_COMMIT) // memory allocated and
&& !(sMBI.Protect & dwForbiddenArea) // access to page allowed and
&& (sMBI.Protect & dwAccessRights); // the required rights
pCurrentAddress = (UINT_PTR(sMBI.BaseAddress) + sMBI.RegionSize);
} while (bRet && pCurrentAddress <= pEndAdress);
return bRet;
}
#define IsBadWritePtr(p,n) (!CheckAccess<dwWriteRights>(p,n))
#define IsBadReadPtr(p,n) (!CheckAccess<dwReadRights>(p,n))
#define IsBadStringPtrW(p,n) (!CheckAccess<dwReadRights>(p,n*2))
This approach is based on my understanding of Raymond Chen's blog post, If I'm not supposed to call IsBadXxxPtr, how can I check if a pointer is bad?
This is an old question but this part:
the code where this check needs to be done is time sensitive so I need
the most efficient check possible that is also 100% effective
VirtualQuery() takes a kernel call, so the simple memcpy() in an exception handler will be faster for the case where the memory is okay to read most of the time.
__try
{
memcpy(dest, src, size);
}__except(1){}
All stays in user mode when there is no exception. Maybe a bit slower for the use case where the memory is bad to read more than it is good (since it fires off a exception which is a round trip through the kernel and back).
You could also extend it with a custom memcpy loop and *size so you could return exactly how many bytes were actually read.
if you are using VC++ then I suggest to use microsoft specific keywords __try __except
to and catch HW exceptions