I created a structure like that:
struct Options {
double bindableKeys = 567;
double graphicLocation = 150;
double textures = 300;
};
Options options;
Right after this declaration, in another process, I open the process which contains the structure and search for a byte array with the struct's doubles but nothing gets found.
To obtain a result, I need to add something like std::cout << options.bindableKeys;after the declaration. Then I get a result from my pattern search.
Why is this behaving like that? Is there any fix?
Minimal reproducible example:
struct Options {
double bindableKeys = 567;
double graphicLocation = 150;
double textures = 300;
};
Options options;
while(true) {
double val = options.bindableKeys;
if(val > 10)
std::cout << "test" << std::endl;
}
You can search the array with CheatEngine or another pattern finder
Contrary to popular belief, C++ source code is not a sequence of instructions provided to the executing computer. It is not a list of things that the executable will contain.
It is merely a description of a program.
Your compiler is responsible for creating an executable program, that follows the same semantics and logical narrative as you've described in your source code.
Creating an Options instance is all well and good, but if creating it does not do anything (has no side effects) and you never use any of its data, then it may as well not exist, and therefore is not a part of the logical narrative of your program.
Consequently, there is no reason for the compiler to put it into the executable program. So, it doesn't.
Some people call this "optimisation". That the instance is "optimised away". I prefer to call it common sense: the instance was never truly a part of your program.
And even if you do use the data in the instance, it may be possible for an executable program to be created that more directly uses that data. In your case, nothing changes the default values of Option's members, so there is no reason to include them into the program: the if statement can just have 567 baked into it. Then, since it's baked in, the whole condition becomes the constant expression 567 > 10 which must always be true; you'll likely find that the resulting executable program consequently contains no branching logic at all. It just starts up, then outputs "test" over and over again until you force-terminate it.
That all being said, because we live in a world governed by physical laws, and because compilers are imperfect, there is always going to be some slight leakage of this abstraction. For this reason, you can trick the compiler into thinking that the instance is "used" in a way that requires its presence to be represented more formally in the executable, even if this isn't necessary to implement the described program. This is common in benchmarking code.
Related
Is it possible to have a function like this:
const char* load(const char* filename_){
return
#include filename_
;
};
so you wouldn't have to hardcode the #include file?
Maybe with a some macro?
I'm drawing a blank, guys. I can't tell if it's flat out not possible or if it just has a weird solution.
EDIT:
Also, the ideal is to have this as a compile time operation, otherwise I know there's more standard ways to read a file. Hence thinking about #include in the first place.
This is absolutely impossible.
The reason is - as Justin already said in a comment - that #include is evaluated at compile time.
To include files during run time would require a complete compiler "on board" of the program. A lot of script languages support things like that, but C++ is a compiled language and works different: Compile and run time are strictly separated.
You cannot use #include to do what you want to do.
The C++ way of implementing such a function is:
Find out the size of the file.
Allocate memory for the contents of the file.
Read the contents of the file into the allocated memory.
Return the contents of the file to the calling function.
It will better to change the return type to std::string to ease the burden of dealing with dynamically allocated memory.
std::string load(const char* filename)
{
std::string contents;
// Open the file
std::ifstream in(filename);
// If there is a problem in opening the file, deal with it.
if ( !in )
{
// Problem. Figure out what to do with it.
}
// Move to the end of the file.
in.seekg(0, std::ifstream::end);
auto size = in.tellg();
// Allocate memory for the contents.
// Add an additional character for the terminating null character.
contents.resize(size+1);
// Rewind the file.
in.seekg(0);
// Read the contents
auto n = in.read(contents.data(), size);
if ( n != size )
{
// Problem. Figure out what to do with it.
}
contents[size] = '\0';
return contents;
};
PS
Using a terminating null character in the returned object is necessary only if you need to treat the contents of the returned object as a null terminated string for some reason. Otherwise, it maybe omitted.
I can't tell if it's flat out not possible
I can. It's flat out not possible.
Contents of the filename_ string are not determined until runtime - the content is unknown when the pre processor is run. Pre-processor macros are processed before compilation (or as first step of compilation depending on your perspective).
When the choice of the filename is determined at runtime, the file must also be read at runtime (for example using a fstream).
Also, the ideal is to have this as a compile time operation
The latest time you can affect the choice of included file is when the preprocessor runs. What you can use to affect the file is a pre-processor macro:
#define filename_ "path/to/file"
// ...
return
#include filename_
;
it is theoretically possible.
In practice, you're asking to write a PHP construct using C++. It can be done, as too many things can, but you need some awkward prerequisites.
a compiler has to be linked into your executable. Because the operation you call "hardcoding" is essential for the code to be executed.
a (probably very fussy) linker again into your executable, to merge the new code and resolve any function calls etc. in both directions.
Also, the newly imported code would not be reachable by the rest of the program which was not written (and certainly not compiled!) with that information in mind. So you would need an entry point and a means of exchanging information. Then in this block of information you could even put pointers to code to be called.
Not all architectures and OSes will support this, because "data" and "code" are two concerns best left separate. Code is potentially harmful; think of it as nitric acid. External data is fluid and slippery, like glycerine. And handling nitroglycerine is, as I said, possible. Practical and safe are something completely different.
Once the prerequisites were met, you would have two or three nice extra functions and could write:
void *load(const char* filename, void *data) {
// some "don't load twice" functionality is probably needed
void *code = compile_source(filename);
if (NULL == code) {
// a get_last_compiler_error() would be useful
return NULL;
}
if (EXIT_SUCCESS != invoke_code(code, data)) {
// a get_last_runtime_error() would also be useful
release_code(code);
return NULL;
}
// it is now the caller's responsibility to release the code.
return code;
}
And of course it would be a security nightmare, with source code left lying around and being imported into a running application.
Maintaining the code would be a different, but equally scary nightmare, because you'd be needing two toolchains - one to build the executable, one embedded inside said executable - and they wouldn't necessarily be automatically compatible. You'd be crying loud for all the bugs of the realm to come and rejoice.
What problem would be solved?
Implementing require_once in C++ might be fun, but you thought it could answer a problem you have. Which is it exactly? Maybe it can be solved in a more C++ish way.
A better alternative, considering also performances etc., to compile a loadable module beforehand, and load it at runtime.
If you need to perform small tunings to the executable, place parameters into an external configuration file and provide a mechanism to reload it. Once the modules conform to a fixed specification, you can even provide "plugins" that weren't available when the executable was first developed.
At the very first, apologies in advance for the very indistinct presentation of the question - if I knew what to ask for, I would probably know how to fix it.
... But I do not even have a faint theory, seven years of C++ experience notwithstanding. Any helpful pointers (hè) will be most appreciated.
Possibly related to this question. (same symptoms)
Not related to that one. (no explicit function pointers here)
Problem: A count of objects with certain properties, which themselves are checked by a member function of their class shows incorrect results. The source is that the check happens with gibberish values. The source of that is that the pointer "this" changes between calling the function and entering its body. Once the body is left, the pointer is again correct.
Sadly, the solution for the related question does not work here.
I am not able to produce a minimal example of the problem.
Furthermore, literally hundreds of member functions are being called correctly in the same program, as far as I know without exhibiting this behaviour.
What can I do?
As a bandaid, replacing the function call with a copy of its body works, but this is no proper solution.
I am at a complete loss as to how to proceed with my diagnosis.
Concise: What steps can I follow to attain greater insight into the nature of the problem?
A short checklist of things already taken care of:
The objects in question are properly initialised at the time of the call.
All optimisations are off. No inlining. This is a debug build with the appropriate settings in effect.
Cleaning and rebuilding the project has not yielded a different result.
Recompiling with the original (but retyped) function call after the bandaid solution had been tested successfully led to a return of the problem.
There are no compiler warnings in the compilation unit involved (warning level 3), specifically disabled project-wide are:
C4005 (macro redefinition, due to using a custom/hacked Windows SDK for compatibility reasons - this was originally a Win95 program)
C4244 (implicit cast to smaller type, due to legacy code waiting to be refactored - those are all float-to-int conversions that lack an explicit cast, all 800+ instances of them)
C4995 (calling function marked with #pragma deprecated, due to C-lib functions being called without preceding underscore - hoping to eventually switch to GCC)
"control flow guard" and "basic runtime checks" are enabled, but do not trigger.
And a hint that may or may not be relevant, but which I cannot interpret at the moment:
For the very first hex, IsSea is called normally, that is: "this" inside is identical to "this" outside
Only in all hexes that follow does the bug happen.
The altered "this" pointer does not point to the first hex though, it seems to hit unallocated space.
Here is an extract of how it looks like:
Header:
// These three are actually included from other files.
constexpr unsigned int AREA_none = 0u;
constexpr unsigned int AREA_Lake = 1u;
enum Terrain
{
OCEAN = 8,
TERRA_INCOGNITA = 10
};
class CHex
{
public:
CHex(); // initialises ALL members with defined error values
bool ReadHex(); // Init-type function calling the problematic one
bool IsSea() const // problematic function
{ return this->_Area != AREA_none && this->_Area != AREA_LAKE && this->_nTerrain == Terrain::OCEAN; }
// The body does the right thing - just WITH the wrong thing.
protected:
unsigned int _Area;
int _nNavalIndex;
Terrain _nTerrain;
static int _nNavalCount = 0;
// There are a lot more functions in here, both public and protected.
// The class also inherits a bunch from three other classes, but no virtual functions and no overlaps are involved.
}
Source:
CHex::CHex() : _Area{0u}, _nNavalIndex{0}, _nTerrain{Terrain::TERRA_INCOGNITA}
{}
bool CHex::ReadHex()
{
// Calls a lexer/parser pair to procure values from several files.
// _Area and _nTerrain are being initialised in this process.
// All functions called here work as expected and produce data matching the source files.
// _Area and _nTerrain have the correct values seen in the source files at this point.
if(this->IsSea()) // but inside that it looks as if they were uninitialised
// This ALWAYS happens because the function always returns true.
_nNavalIndex = _nNavalCount++;
// Stopping at the next instruction, all values are again correct
// - with the notable exception of the two modified by the instruction that should not have happened.
// If I replace that with the following, I receive the correct result:
/*
// direct copy of the function's body
if(this->_Area != AREA_none && this->_Area != AREA_Lake && this->_nTerrain == Terrain::OCEAN)
_nNavalIndex = _nNavalCount++; // only happens when it should; at the end, the count is correct
*/
// Sanity checks follow here.
// They too work correctly and produce results appropriate for the data.
return true; // earlier returns exist in the commented-out parts
}
Sorry again for this big mess, but well, right now I am a mess. It's like seeing fundamental laws of physics change.
--
On advice from #Ben Voigt I hacked in a diagnostic that dumps the pointers into a file. Behold:
Before ReadHex: 20A30050 (direct array access) On ReadHex: 20A30050 On IsSea: 20A30050 (with members: 0, 8) After ReadHex: 20A30050
Before ReadHex: 20A33EAC (direct array access) On ReadHex: 20A33EAC On IsSea: 20A33EAC (with members: 2, 0) After ReadHex: 20A33EAC
Before ReadHex: 20A37D08 (direct array access) On ReadHex: 20A37D08 On IsSea: 20A37D08 (with members: 2, 0) After ReadHex: 20A37D08
Before ReadHex: 20A3BB64 (direct array access) On ReadHex: 20A3BB64 On IsSea: 20A3BB64 (with members: 3, 0) After ReadHex: 20A3BB64
Before ReadHex: 20A3F9C0 (direct array access) On ReadHex: 20A3F9C0 On IsSea: 20A3F9C0 (with members: 4, 3) After ReadHex: 20A3F9C0
Before ReadHex: 20A4381C (direct array access) On ReadHex: 20A4381C On IsSea: 20A4381C (with members: 3, 0) After ReadHex: 20A4381C
[...]
They are all correct. Every single one of them. And even better: The function now evaluates correctly!
Here is the changed source (I am omitting the comments this time):
Header:
// These three are actually included from other files.
constexpr unsigned int AREA_none = 0u;
constexpr unsigned int AREA_Lake = 1u;
enum Terrain
{
OCEAN = 8,
TERRA_INCOGNITA = 10
};
extern FILE * dump;
class CHex
{
public:
CHex();
bool ReadHex();
bool IsSea() const {
fprintf(dump, "\tOn IsSea:\t%p (with members: %u, %i) ", (void*)this, this->_Area, this->_nTerrain);
return this->_Area != AREA_none && this->_Area != AREA_LAKE && this->_nTerrain == Terrain::OCEAN; }
protected:
unsigned int _Area;
int _nNavalIndex;
Terrain _nTerrain;
static int _nNavalCount = 0;
// lots more functions and attributes
}
Source:
CHex::CHex() : _Area{0u}, _nNavalIndex{0}, _nTerrain{Terrain::TERRA_INCOGNITA}
{}
bool CHex::ReadHex()
{
fprintf(dump, "On ReadHex:\t%p ", (void*)this);
// Calls a lexer/parser pair to procure values from several files.
// _Area and _nTerrain are being initialised in this process.
if(this->IsSea()) // Suddenly works!?
_nNavalIndex = _nNavalCount++;
// Sanity checks follow here.
fprintf(dump, "After ReadHex:\t%p ", (void*)this);
return true;
}
The additional outputs (as well as the initialisation and closing of dump) come from the next higher level in the control flow, another function in another class, where the loop over all hexes resides. I omitted that for now, but will add it if someone thinks it's important.
And apropos that. It now looks to me as if this fault were a result of bugs in the tools, not in the code. As a matter of fact, even though the function now evaluates correctly, the debugger still shows the wrong pointer from before and its nonsensical members.
EDIT for OP edit:
This now smells even more like a ODR violation. Changing an inline function, and having that change program behavior is exactly what could happen with the undefined behavior induced from ODR violations. Do you use templates anywhere? Also, try de-inlining IsSea() in the original version to see if that helps.
(original answer):
This smells like one of three things to me.
First, it could be a one-definition-rule violation for the function in question. Make absolutely certain there aren't multiple versions in different translation units, or different compilation settings in different units.
Secondly the compiler could be doing something because of your use of the reserved name _Area. Regardless of anything else you should fix this problem.
Thirdly, VC++ can utilize different mechanisms for member function pointers, and possibly one of those is affecting your case here (even given that you don't show use of member function pointers). See https://msdn.microsoft.com/en-us/library/83cch5a6.aspx?f=255&MSPPError=-2147217396 for some information. Another possibility is that the compiler options for such pointers are different across translation units.
This is a very sad answer, but alas, sometimes a sad answer is nevertheless correct.
Let us start with the smaller but at least somewhat useful part:
The values VS2015's debugger displays for the this pointer - and in extension all members of the object pointed to - are indeed incorrect and in a very reproducable way:
If a breakpoint is set on a member function defined in a header file, "this" displayed in the debugger will display - the entry point of this function. It will still have the type of the object in question and display all the members... but as those values are populated as offsets from the entry point of said function, their displayed contents are of course nonsensical.
All of this is purely a UI issue and does not affect the actual program execution.
And now the useless and depressing part:
The fault which originally prompted me to open this topic, which persisted through several compilations with different build settings - is gone and can no longer be reproduced after I put in the fprinf commands to dump the pointer addresses to a file in order to discover the bug described above.
Even though the code is letter by letter identical to the formerly faulty code, it now works flawlessly. Further alterations have done nothing to change this. I cannot bring it back, try as I might.
This whole dastard thing - was a fluke. Somehow. Which means that it may happen again, at any time, for no apparent reason, without any means of prevention whatsoever. Great, is it not?
...
In any case, heartfelt thanks to #Ben Voigt for raising the notion that mayhap those debugger outputs may not be related to reality in the first place.
Similarly, thanks to #dyp for pointing out and explaining an unrelated potential issue (names prefixed by '_' followed by a capital letter being reserved expressions) I was not aware of before.
Thanks to #Mark-B for actually providing hypotheses about the problem, even if none of them proved to be correct. At least there were some and one might have been.
Can we understand if there is a variable mentioned/created/exists ?
I mean something like that:
//..Some codes
int main(){
int var1;
float var2;
char var3;
cout << isExist("var1") << endl;//Or isExist(/*Something related with var1*/)
cout << isExist("var2") << endl;
cout << isExist("var3") << endl;
cout << isExist("var456") << endl;//There is no variable named with var456
return 0;
}
Output:
true
true
true
false
No. C and C++ do not support reflection.
Not in C/C++. But you could have a look at boost reflect library. http://bytemaster.bitshares.org/boost_reflect/
In C/C++, accessing a variable not defined will generate a compiler error. So, in a sense, that is inherent to how it works. You cannot do that at runtime, at least not as you are trying to do, and should not have need to - because you can't name new variables at runtime in the first place, so you should already know the variables there.
The only way to do this would be indirectly with macros. Macros can't check if a variable itself is defined, but a define could be paired with a variable definition and you could check for the define token.
#define A_VARIABLE 1
int a_variable = 60;
And later:
#ifdef A_VARIABLE
...
#endif
Like most macros, it is probably best to avoid this sort of behavior - however, I have seen it used to deal with platform-dependence of certain variables.
Dynamic memory is a different matter. Since you did not mention it, I will not go into it, but suffice to say it is a more complicated problem which proves the bane of many programmers and the source of many runtime errors.
The 'programming language C' is a human readable form of providing instructions to a computer. All names in the program have only meaning within the program text.
Upon compilation, the names are replaced with a symbolic reference to a storage location or function (execution starting point). Any symbol not found in the current complilation unit (object module) is marked for future resolution.
The object modules are combined (linked) into an executable, where all references to symbols not in an object module are resolved with locations in other object modules; otherwise the creation of the executable fails.
Since now any names have been replaced with references to storage locations and execution starting points, the executable doesn't know anymore about the names used in the program text to refer to its storage locations and functions.
Any ability to do so (the 'reflection' as user #Bill-Lynch calls it) would be 'bolted on' to the language/environment as a separate layer, for example provided by the debugging/development envionment.
My question now is if I've declared a constant using const, I read that it's possible for it to be modified externally (maybe by a device connected to the system). I want to know if it's possible to check if my constant has been modified or not. Naturally, I would try something like this:
const double PI = 3.1412 //blah blah blah
// ...
if (PI == 3.1412) {
// do something with PI
}
which clearly will not compile since a constant cannot be an lvalue.
How do I go about this? Or is it impossible (I don't want to waste my time if it cannot be done)?
Thanks.
First of all, why won't your example compile? If you couldn't compare constants, they would be kind of useless.
I would classify this as a waste of time. If something external to your program is modifying your memory, then what's to stop it from also modifying the memory you store your comparison at? In your example, that test could fail not because PI changed, but because 3.1415 did... that number is stored somewhere, after all.
If your program changes the value of PI, then it is broken, and you can't be sure the test works reliably anyhow. That's firmly undefined behavior, so anything goes. Its a lot like testing if a reference parameter references null... a well defined program can not possibly result in the test failing, and if it could pass you can't be sure the program is in a functioning state anyhow, so the test itself is a waste of time.
In either case, the compiler will probably decide that the test is a waste of time, and remove it all together.
Now, there is one situation that is slightly different from what you originally stated, which might be what your source was refering to. Consider the following code:
void external_function();
void internal_function(const int& i) {
cout << i << "...";
external_function();
cout << i;
}
Within internal_function, the compiler can not assume that both outputs are identical. i could be a reference to an integer that is not actually const, and external_function could change it. The key difference here is that i is a reference, whereas in your original question PI is a constant value.
int pi = 3;
void external_function() { pi = 4; }
void internal_function(const int&);
int main() {
internal_function(pi);
}
That will result in 3...4 being printed. Even though i is a constant reference, the compiler has to assume it might change because something it can't see might change it.
In that case, such a test might be useful under certain circumstances.
void internal_function(const int& i) {
const int original_i = i;
cout << i << "...";
external_function();
cout << i << endl;
if(i != original_i) cout << "lol wut?" << endl;
}
In this case, the test is useful. original_i is guarenteed to have not changed [and if it has, see the first half of this answer], and if i has changed the assertion will fail.
const folding is important here. With your sample code, the
const double PI = 3.1412; //blah blah blah
if (PI == 3.1412) {
}
the literal might actually share the storage space for the constant.
It seems you want to have 'insurance' or 'tamper-detection' of some kind.
For this purpose, you'd have to self-sign the binary with some kind of certificate. However, with sufficient reverse engineering, the verification of the signature can be subverted.
So, you'd actually need a trusted kernel function to verify the binary before execution. Open source kernels would appear to have the benefit of proper peer review and cross-examination. That kernel would really need TPM hardware to assist. You'd then be down to physical security (you have to trust the hardware vendor and the physical security of your hosting location).
Also, you'd need NX kernel features (or like the Win32 DEP), to prevent execution of writable memory. Inversely, you'd need kernel protection of the executable segments (this is usually the case anyway, to allow sharing of memory maps, IIRC).
All of which just begs the question: what do you need this kind of security for. Depending on the answer, implementing the above, and more, might even be reasonable.
$0.02
The point of const is that the identifier is a constant. If someone is using const_cast or other tricks to subvert your constant then their program will have undefined behavior. I wouldn't worry about this in practice.
I believe, once you compile your code with some optimizations, the compiler emits the machine code with the constant literal (such as 3.1412), instead of the variable name (such as PI). So the machine code most likely will not have symbols (i.e PI) which you use in your code.
static const double PI = 3.14;
prevents modifying this constant from other modules compiled with this one. OTOH, it doesn't saves from changing this constant using HEX editor or in-memory.
The other solution (not recommended but possible) is to use
#define PI 3.14
And, yes, you can use
M_PI
constant. See this question
I would assume that the actual memory space that the const resides in would have to be modified for it to be modified. Unless you have a clear reason/issue to do a check like this, I would say that it is not required. I have never known anything to require a check of the value of a constant.
If you have a declared non-volatile const variable, there is no legal way for it to be modified externally.
Writing to a const variable is undefined behavior. And declaring a extern double PI; in another translation unit will declare a different variable than what you declared, because yours has internal linkage, which means it can only be redeclared in the same translation unit.
And even if it were to declare the same variable, then behavior would be undefined (because of a const / non-const mismatch in type identity).
Constant variables cannot be changed without invoking undefined behavior. There is no point in defending against that.
first time posting here after having so many of my Google results come up from this wonderful site.
Basically, I'd like to find the name of the variable stored at a particular memory address. I have a memory editing application I wrote that edits a single value, the problem being that every time the application holding this value is patched, I have to hardcode in the new memory address into my application, and recompile, which takes so much time to upkeep that its almost not worthwhile to do.
What I'd like to do is grab the name of the variable stored at a certain memory address, that way I can then find its address at runtime and use that as the memory address to edit.
This is all being written in C++.
Thanks in advance!
Edit:
Well I've decided I'd like to stream the data from a .txt file, but I'm not sure how to convert the string into an LPVOID for use as the memory address in WriteProcessMemory(). This is what I've tried:
string fileContents;
ifstream memFile("mem_address.txt");
getline(memFile, fileContents);
memFile.close();
LPVOID memAddress = (LPVOID)fileContents.c_str();
//Lots of code..
WriteProcessMemory(WindowsProcessHandle, memAddress, &BytesToBeWrote, sizeof(BytesToBeWrote), &NumBytesWrote);
The code is all correct in terms of syntax, it compiles and runs, but the WriteProcessMemory errors and I can only imagine it has to do with my faulty LPVOID variable. I apologize if extending the use of my question is against the rules, I'll remove my edit if it is.
Compile and generate a so called map file. This can be done easily with Visual-C++ (/MAP linker option). There you'll see the symbols (functions, ...) with their starting address. Using this map file (Caution: has to be updated each time you recompile) you can match the addresses to names.
This is actually not so easy because the addresses are relative to the preferred load address, and probably will (randomization) be different from the actual load address.
Some old hints on retrieving the right address can be found here: http://home.hiwaay.net/~georgech/WhitePapers/MapFiles/MapFiles.htm
In general, the names of variables are not kept around when the program is compiled. If you are in control of the compilation process, you can usually configure the linker and compiler to produce a map-file listing the locations in memory of all global variables. However, if this is the case, you can probably acheive your goals more easily by not using direct memory accesses, but rather creating a proper command protocol that your external program can call into.
If you do not have control of the compilation process of the other program, you're probably out of luck, unless the program shipped with a map file or debugging symbols, either of which can be used to derive the names of variables from their addresses.
Note that for stack variables, deriving their names will require full debugging symbols and is a very non-trivial process. Heap variables have no names, so you will have no luck there, naturally. Further, as mentioned in #jdehaan's answer, map files can be a bit tricky to work with in the best of times. All in all, it's best to have a proper control protocol you can use to avoid any dependence on the contents of the other program's memory at all.
Finally, if you have no control over the other program, then I would recommend putting the variable location into a separate datafile. This way you would no longer need to recompile each time, and could even support multiple versions of the program being poked at. You could also have some kind of auto-update service pulling new versions of this datafile from a server of yours if you like.
Unless you actually own the application in question, there is no standard way to do this. If you do own the application, you can follow #jdehaan answer.
In any case, instead of hardcoding the memory address into your application, why not host a simple feed somewhere that you can update at any time with the memory address you need to change for each version of the target application? This way, instead of recompiling your app every time, you can just update that feed when you need to be able to manipulate a new version.
You cannot directly do this; variable names do not actually exist in the compiled binary. You might be able to do that if the program was written, in say, Java or C#, which do store information about variables in the compiled binary.
Further, this wouldn't in general be possible, because it's always possible that the most up to date copy of a value inside the target program is located inside of a CPU register rather than in memory. This is more likely if the program in question is compiled in release mode, with optimizations turned on.
If you can ensure the target program is compiled in debug mode you should be able to use the debugging symbols emitted by the compiler (the .pdb file) in order to map addresses to variables, but in that case you would need to launch the target process as if it were being debugged -- the plain Read Process Memory and Write Process Memory methods would not work.
Finally, your question ignores a very important consideration -- there need not be a variable corresponding to a particular address even if such information is stored.
If you have the source to the app in question and optimal memory usage is not a concern, then you can declare the interesting variables inside a debugging-friendly structure similar to:
typedef struct {
const char head_tag[15] = "VARIABLE_START";
char var_name[32];
int value;
const char tail_tag[13] = "VARIABLE_END";
} debuggable_int;
Now, your app should be able to search through the memory space for the program and look for the head and tail tags. Once it locates one of your debuggable variables, it can use the var_name and value members to identify and modify it.
If you are going to go to this length, however, you'd probably be better off building with debugging symbols enabled and using a regular debugger.
Billy O'Neal started to head in the right direction, but didn't (IMO) quite get to the real target. Assuming your target is Windows, a much simpler way would be to use the Windows Symbol handler functions, particularly SymFromName, which will let you supply the symbol's name, and it will return (among other things) the address for that symbol.
Of course, to do any of this you will have to run under an account that's allowed to do debugging. At least for global variables, however, you don't necessarily have to stop the target process to find symbols, addresses, etc. In fact, it works just fine for a process to use these on itself, if it so chooses (quite a few of my early experiments getting to know these functions did exactly that). Here's a bit of demo code I wrote years ago that gives at least a general idea (though it's old enough that it uses SymGetSymbolFromName, which is a couple of generations behind SymFromName). Compile it with debugging information and stand back -- it produces quite a lot of output.
#define UNICODE
#define _UNICODE
#define DBGHELP_TRANSLATE_TCHAR
#include <windows.h>
#include <imagehlp.h>
#include <iostream>
#include <ctype.h>
#include <iomanip>
#pragma comment(lib, "dbghelp.lib")
int y;
int junk() {
return 0;
}
struct XXX {
int a;
int b;
} xxx;
BOOL CALLBACK
sym_handler(wchar_t const *name, ULONG_PTR address, ULONG size, void *) {
if (name[0] != L'_')
std::wcout << std::setw(40) << name
<< std::setw(15) << std::hex << address
<< std::setw(10) << std::dec << size << L"\n";
return TRUE;
}
int
main() {
char const *names[] = { "y", "xxx"};
IMAGEHLP_SYMBOL info;
SymInitializeW(GetCurrentProcess(), NULL, TRUE);
SymSetOptions(SYMOPT_UNDNAME);
SymEnumerateSymbolsW(GetCurrentProcess(),
(ULONG64)GetModuleHandle(NULL),
sym_handler,
NULL);
info.SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
for (int i=0; i<sizeof(names)/sizeof(names[0]); i++) {
if ( !SymGetSymFromName(GetCurrentProcess(), names[i], &info)) {
std::wcerr << L"Couldn't find symbol 'y'";
return 1;
}
std::wcout << names[i] << L" is at: " << std::hex << info.Address << L"\n";
}
SymCleanup(GetCurrentProcess());
return 0;
}
WinDBG has a particularly useful command
ln
here
Given a memory location, it will give the name of the symbol at that location. With right debug information, it is a debugger's (I mean person doing debugging :)) boon!.
Here is a sample output on my system (XP SP3)
0:000> ln 7c90e514 (7c90e514)
ntdll!KiFastSystemCallRet |
(7c90e520) ntdll!KiIntSystemCall
Exact matches:
ntdll!KiFastSystemCallRet ()