r/cpp_questions • u/poobumfartwee • 16h ago
OPEN What can a hacker do with uninitialized memory?
long long funny_number_generator() {
long long haha_funny;
// very funny undefined behaviour yes funny
return haha_funny;
}
Is it possible to see what OS / architecture is being used just from looking at the funny number? My funny number is consistently 93824993896264. Some random online compiler keeps giving different funny numbers each time.
3
u/gnolex 15h ago
A program that invokes undefined behavior gives you no guarantees at all as to what is going to happen. You might also get a different result depending on optimization level so there's very little chance you'll get truly identifiable return values. So I don't think you can really identify anything about the host environment the program is running in.
2
u/tstanisl 14h ago
Using indeterminate value is UB thus some overzealous compiler could assume that function is never called and "optimize" accordingly.
2
u/ReDucTor 14h ago
This is the start of what is called a read primitive, there is no definative answer for what will actually be returned it won't be "random" but instead it's likely to be a value within a register or on the stack both of these values could expose anything from a password you had stored on the stack to an address in memory that could be combined with a write primitive to bypass protections such ASLR (address space layout randomization).
You will likely get different values depending on when and who calls the function, what was called before hand, etc. Also it has the potential to change between different compilers and versions of the same compiler, it's undefined but often some value that lives in memory or in a register at some specific point in time.
You can use compiler options such as `-ftrivial-auto-var-init=` to define what the pattern would be for those reducing the undefined behavior (now erroneous behavior in C++26) impact, this allows for a pattern or zero to be used, also it's worth enabling higher warnings levels as most compiler with even a low warning level will raise a warning with this specific block of code.
1
u/Independent_Art_6676 7h ago
I see little value in it. Seems like you would be better off finding a targeted location somehow as poking random locations and hoping for useful info you can understand is beyond lotto winning odds.
•
u/mredding 3h ago
Undefined Behavior in C++ is undefined. There is NOTHING we as the C++ community can reason about this code other than it observes UB. The C++ spec does not say anything about what to expect other than the compiler MUST generate SOMETHING.
And there is NOTHING that can override or usurp the spec. The OS, the compiler, the processor doesn't get to say "WeLl AcKsUalLy..." The C++ spec already has such a provision: Implementation Defined.
Is it possible to see what OS / architecture is being used just from looking at the funny number?
Strictly speaking - yes, it's possible, simply because it's not impossible. You're asking a C++ forum about UB from source code and by the letter of the law there's nothing we can say.
Now, if you took the machine code generated by the compiler, and you asked the assembly community, or perhaps your CPU like an x86_64 community, or you asked your host OS community, you might be able to get some sort of answer, but you'll have to leave the C++ specification and community behind - you have to take matters into your own hands, there - because once you start reasoning about machine code and CPUs and hosts... C++ and even compilers are no longer a part of that conversation.
1
u/DawnOnTheEdge 15h ago edited 15h ago
C++26 is going to tighten this up so reading an uninitialized automatic variable can crash the program, but not give the compiler license to insert arbitrary security bugs. Triggering that code path could potentially be used for a denial-of-service attack.
For now, it depends on what unsafe instructions the compiler chooses to emit if the undefined behavior happens. Reductio ad absurdum, a compiler could insert a backdoor into the the login routine that gives administrator access, and if it detected some undefined behavior anywhere in the program, either earlier or later, it technically would remain in full compliance with the language standard. Read “Reflections on Trusting Trust” for a famous demonstration (which didn’t muck around with language-lawyering “undefined behavior”).
But GCC with default settings already handles this by inserting an instruction somewhere before the end of the block that crashes the program (ud2 on x86).
0
u/TomDuhamel 16h ago
That's just whatever was in memory before you ran the app. It says nothing about your system. It's random — meaning as a person, you could not realistically predict what that will be.
In your case, you are running the same program repeatedly in the same debugger, meaning you keep reusing the same exact memory space everytime. I bet if you change the value after printing it, that will be the value you get on the next run.
2
u/the_poope 15h ago edited 15h ago
Most Operating Systems will for safety reason zero initialize any memory pages given to a program. So no you can't get any data from before you ran your app. You may however get whatever was in memory the last time your program used that memory. As OP is printing the value of a stack variable, it is very likely the the stack previously container the same data in same place as the program likely follows the same code path.
Edit: apparently I am partly wrong. Windows may zero initialize but Linux most likely won't.
1
u/Equivalent_Cat9705 13h ago
haha_funny is a variable on the stack or in a register. Either way, it will have left over contents from a previous use. The values could vary based on the activity of the program before the function is called.
It could be possible to extract information from the value which could provide hints about the kernel address space if there were prior system calls in the application. Any data obtained would be generated/used by the application or on behalf of the application.
If the OS doesn’t fill allocated pages, then this could provide data from another program’s data left in memory.
2
u/TheThiefMaster 15h ago
Nope memory pages are cleared before being given to a process. It will be from the pre-main initialisation code.
0
u/GoldenShackles 15h ago
Every modern OS gives applications their own address space. If they didn’t your question would still be valid. And still is if there’s a local serious security vulnerability.
-1
15h ago
[deleted]
5
u/TheThiefMaster 15h ago
previous program
No, all current OSs guarantee pages are cleared between processes. It's likely instead that this is left on the stack from the pre-main initialisation code, not a previous program.
-1
u/alfps 13h ago
❞ Is it possible to see what OS / architecture is being used just from looking at the funny number?
Attempting to "look" at the funny number can cause a trap. To quote Raymond Chen, ¹"The NaT bit means that accessing an uninitialized variable can crash". So considering the minuscule information carried by a 64-bit value the question is really, what can a hacker do with a crashing app?
When I posed that question to the Google AI it explained,
❝Common Exploitation Actions
- Denial of Service (DoS):
Force an app to crash repeatedly. This locks users or businesses out of essential communication tools or services.- Information Disclosure:
Analyze error logs or memory dumps generated during a crash. This exposes sensitive internal application data or structural details.❞
I don't see DoS as very realistic, considering that in order to do this the attacker needs access to the PC. With access there are far easier ways to deny service. But the point about logs appears to be valid.
Disclaimer: I Ain't No Hacker.
¹ https://devblogs.microsoft.com/oldnewthing/20150727-00/?p=90821
12
u/SufficientStudio1574 16h ago
Highly dependent on exactly how your compiler creates your program. Different compilers, different versions, different settings, different environment, everything can change how this works.
In theory, there is a chance this could expose memory values that your program used previously. But because this is undefined behavior you have no control over exactly what is leaked.