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
Related
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.
Suppose I have a function foo (in C/C++) that is called from a given software tool.
Function foo is only allowed to write memory that has been allocated by foo or one of the functions called by foo, but not to write to memory that has been allocated by the functions that have been executed before calling foo.
I have the strong suspicion that at some place foo writes to memory it is not allowed to.
Is there a way to systematically debug this behavior? Maybe some fancy flag to valgrind?
The Valgrind manual has some Valgrind functions that your program can call.
It looks like VALGRIND_MAKE_MEM_NOACCESS may be what you want.
You could use a custom allocator (Boost Pool comes to mind) to make sure all your memory that you want to 'protect' is contiguously allocated.
Next, set a hardware breakpoint when any data in that memory region is changed.
I'd write a GDB script that sets a breakpoint on your function, then sets a hardware watch on the memory you suspect is being altered, then continues.
If function foo is modifying that memory the hardware watch will trigger on that instruction doing it.
The GDB script might look like:
break foo
commands
up
watch array
down
continue
end
I didn't test that and it may need tweaking, especially the watch expression. You might be limited to watching only one array element. I believe hardware watchpoints can actually watch only one integer size block: 4 bytes on 32 bit or 8 bytes on 64 bit.
The only way foo() can write to the memory outside its scope is if that memory is global, i.e. extern variable, or if foo() had one or more arguments which were meant to be read only but somehow they got modified.
To verify if the calling arguments are getting modified, you can create a structure to hold the arguments and just before returning compare original with saved arguments.
struct foo_args {
int a;
char *b;
};
void
foo(int a, char *b)
{
struct foo_args args;
args.a = a
args.b = strdup(b);
/* The rest of the foo() code. */
if (args.a != a || strcmp(args.b, b) != 0) {
printf("error - args got modified\n");
}
free(args.b);
}
If the above doesn't catch it, then the likely scenario is that either global, stack or heap memory is getting corrupted.
To have valgrind run the tool may not be practical, in which case you will need to create a 'wrapper' for foo() and ensure using valgrind or something similar that it is not doing what it is not supposed to do. The other option is to use a debugging library that tracks/monitors memory usage and flags memory errors as they occur.
I have a program which prompts me the error in VS2010, in debug :
Error: Stack around the variable 'x' was corrupted
This gives me the function where a stack overflow likely occurs, but I can't visually see where the problem is.
Is there a general way to debug this error with VS2010? Would it be possible to indentify which write operation is overwritting the incorrect stack memory?
thanks
Is there a general way to debug this error with VS2010?
No, there isn't. What you have done is to somehow invoke undefined behavior. The reason these behaviors are undefined is that the general case is very hard to detect/diagnose. Sometimes it is provably impossible to do so.
There are however, a somewhat smallish number of things that typically cause your problem:
Improper handling of memory:
Deleting something twice,
Using the wrong type of deletion (free for something allocated with new, etc.),
Accessing something after it's memory has been deleted.
Returning a pointer or reference to a local.
Reading or writing past the end of an array.
This can be caused by several issues, that are generally hard to see:
double deletes
delete a variable allocated with new[] or delete[] a variable allocated with new
delete something allocated with malloc
delete an automatic storage variable
returning a local by reference
If it's not immediately clear, I'd get my hands on a memory debugger (I can think of Rational Purify for windows).
This message can also be due to an array bounds violation. Make sure that your function (and every function it calls, especially member functions for stack-based objects) is obeying the bounds of any arrays that may be used.
Actually what you see is quite informative, you should check in near x variable location for any activity that might cause this error.
Below is how you can reproduce such exception:
int main() {
char buffer1[10];
char buffer2[20];
memset(buffer1, 0, sizeof(buffer1) + 1);
return 0;
}
will generate (VS2010):
Run-Time Check Failure #2 - Stack around the variable 'buffer1' was corrupted.
obviously memset has written 1 char more than it should. VS with option \GS allows to detect such buffer overflows (which you have enabled), for more on that read here: http://msdn.microsoft.com/en-us/library/Aa290051.
You can for example use debuger and step throught you code, each time watch at contents of your variable, how they change. You can also try luck with data breakpoints, you set breakpoint when some memory location changes and debugger stops at that moment,possibly showing you callstack where problem is located. But this actually might not work with \GS flag.
For detecting heap overflows you can use gflags tool.
I was puzzled by this error for hours, I know the possible causes, and they are already mentioned in the previous answers, but I don't allocate memory, don't access array elements, don't return pointers to local variables...
Then finally found the source of the problem:
*x++;
The intent was to increment the pointed value. But due to the precedence ++ comes first, moving the x pointer forward then * does nothing, then writing to *x will be corrupt the stack canary if the parameter comes from the stack, making VS complain.
Changing it to (*x)++ solves the problem.
Hope this helps.
Here is what I do in this situation:
Set a breakpoint at a location where you can see the (correct) value of the variable in question, but before the error happens. You will need the memory address of the variable whose stack is being corrupted. Sometimes I have to add a line of code in order for the debugger to give me the address easily (int *x = &y)
At this point you can set a memory breakpoint (Debug->New Breakpoint->New Data Breakpoint)
Hit Play and the debugger should stop when the memory is written to. Look up the stack (mine usually breaks in some assembly code) to see whats being called.
I usually follow the variable before the complaining variable which usually helps me get the problem. But this can sometime be very complex with no clue as you have seen it. You could enable Debug menu >> Exceptions and tick the 'Win32 exceptions" to catch all exceptions. This will still not catch this exceptions but it could catch something else which could indirectly point to the problem.
In my case it was caused by library I was using. It turnout the header file I was including in my project didn't quite match the actual header file in that library (by one line).
There is a different error which is also related:
0xC015000F: The activation context being deactivated is not the most
recently activated one.
When I got tired of getting the mysterious stack corrupted message on my computer with no debugging information, I tried my project on another computer and it was giving me the above message instead. With the new exception I was able to work my way out.
I encountered this when I made a pointer array of 13 items, then trying to set the 14th item. Changing the array to 14 items solved the problem. Hope this helps some people ^_^
One relatively common source of "Stack around the variable 'x' was corrupted" problem is wrong casting. It is sometimes hard to spot. Here is an example of a function where such problem occurs and the fix. In the function assignValue I want to assign some value to a variable. The variable is located at the memory address passed as argument to the function:
using namespace std;
template<typename T>
void assignValue(uint64_t address, T value)
{
int8_t* begin_object = reinterpret_cast<int8_t*>(std::addressof(value));
// wrongly casted to (int*), produces the error (sizeof(int) == 4)
//std::copy(begin_object, begin_object + sizeof(T), (int*)address);
// correct cast to (int8_t*), assignment byte by byte, (sizeof(int8_t) == 1)
std::copy(begin_object, begin_object + sizeof(T), (int8_t*)address);
}
int main()
{
int x = 1;
int x2 = 22;
assignValue<int>((uint64_t)&x, x2);
assert(x == x2);
}
I have the following code (some code removed to strip it to the essentials; the couple methods/attributes used should be self explanatory):
void testApp::togglePalette(){
GraphicalEntity* palette= this->getEntityByName("palette-picker");
cerr << palette << endl;
}
GraphicalEntity* testApp::getEntityByName(string name){
list<GraphicalEntity*>::iterator j;
for(j=screenEntities.begin(); j!=screenEntities.end();++j){
if ((*j)->getTypetag() == name){
cerr << *j << endl;
return *j;
}
}
}
Which outputs the following:
0x54bda0
0
I'm confused- why isn't palette in togglePalette() equal to the address returned from getEntityByName (so 0x54bda0 in the current case), but to 0?
Thanks!
EDIT: As Fred pointed out in one of his comments, it was indeed an issue of the compiler being confused by the code reaching the end of the function without returning anything.
Adding:
return (GraphicalEntity*) NULL;
at the end of my getEntityByName method solved the problem. Thanks a lot!
I'm still confused by why the method would return 0 even if the object is found (as in the way I implement my code, it is known that there will always be something found) though- any explanation on that would be more than welcome!
Following on my comment, here's a more complete answer.
There is a path in your testApp::getEntityByName() method where control exits the method without returning a value. Depending on your compiler, architecture and calling convention, this could result in machine code that doesn't work even if your flow never goes through the erroneous path.
Depending on the calling convention, it is either the caller or the called method's responsibility to clean up the stack before or after the method returns. The return value, and where it is allocated in memory, is part of that convention, and a compiler expects a function to always return the same type no matter what the control flow within the function is. Because of that, it can optimize some methods by rearranging some stuff and generating specific clean-up code to clean restore the stack according to the calling convention. In any case, the missing return value can mess up that optimization or clean-up because it violates what the compiler took for granted when it processed your code, i.e. that every path returned a pointer to a GraphicalEntity object. Failing that assumption corrupted the stack or its content, and you ended up with a NULL pointer (it might as well have crashed or done just about anything else, it's all part of undefined behavior).
It could happened if screenEntities is accessed via another thread so the "pallette-picker" has been removed or modified. Then getEntityByName function will return NULL in debug mode.
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.