I want to catch SIGBUS, my code is shown below:
#include <stdlib.h>
#include <signal.h>
#include <iostream>
#include <stdio.h>
void catch_sigbus (int sig)
{
//std::cout << "SIGBUS" << std::endl;
printf("SIGBUS\n");
exit(-1);
}
int main(int argc, char **argv) {
signal (SIGBUS, catch_sigbus);
int *iptr;
char *cptr;
#if defined(__GNUC__)
# if defined(__i386__)
/* Enable Alignment Checking on x86 */
__asm__("pushf\norl $0x40000,(%esp)\npopf");
# elif defined(__x86_64__)
/* Enable Alignment Checking on x86_64 */
__asm__("pushf\norl $0x40000,(%rsp)\npopf");
# endif
#endif
/* malloc() always provides aligned memory */
cptr = (char*)malloc(sizeof(int) + 1);
/* Increment the pointer by one, making it misaligned */
iptr = (int *) ++cptr;
/* Dereference it as an int pointer, causing an unaligned access */
*iptr = 42;
return 0;
}
When I use printf, it can catch by calling catch_sigbus, but when I use cout, it cannot. So anybody could help me? I run on Ubuntu 12.04.
I have another question. When I catch SIGBUS, how can I get si_code? BUS_ADRALN/BUS_ADRERR/BUS_OBJERR
You can't use printf or cout in a signal handler. Nor can you call exit. You got lucky with printf this time, but you weren't as lucky with cout. If your program is in a different state maybe cout will work and printf won't. Or maybe neither, or both. Check the documentation of your operating system to see which functions are signal safe (if it exists, it's often very badly documented).
Your safest bet in this case is to call write to STDERR_FILENO directly and then call _exit (not exit, that one is unsafe in a signal handler). On some systems it's safe to call fprintf to stderr, but I'm not sure if glibc is one of them.
Edit: To answer your added question, you need to set up your signal handlers with sigaction to get the additional information. This example is as far as I'd go inside a signal handler, I included an alternative method if you want to go advanced. Notice that write is theoretically unsafe because it will break errno, but since we're doing _exit it will be safe in this particular case:
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
void
bus_handler(int sig, siginfo_t *si, void *vuctx)
{
char buf[2];
#if 1
/*
* I happen to know that si_code can only be 1, 2 or 3 on this
* particular system, so we only need to handle one digit.
*/
buf[0] = '0' + si->si_code;
buf[1] = '\n';
write(STDERR_FILENO, buf, sizeof(buf));
#else
/*
* This is a trick I sometimes use for debugging , this will
* be visible in strace while not messing with external state too
* much except breaking errno.
*/
write(-1, NULL, si->si_code);
#endif
_exit(1);
}
int
main(int argc, char **argv)
{
struct sigaction sa;
char *cptr;
int *iptr;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = bus_handler;
sa.sa_flags = SA_SIGINFO;
sigfillset(&sa.sa_mask);
sigaction(SIGBUS, &sa, NULL);
#if defined(__GNUC__)
# if defined(__i386__)
/* Enable Alignment Checking on x86 */
__asm__("pushf\norl $0x40000,(%esp)\npopf");
# elif defined(__x86_64__)
/* Enable Alignment Checking on x86_64 */
__asm__("pushf\norl $0x40000,(%rsp)\npopf");
# endif
#endif
/* malloc() always provides aligned memory */
cptr = (char*)malloc(sizeof(int) + 1);
/* Increment the pointer by one, making it misaligned */
iptr = (int *) ++cptr;
/* Dereference it as an int pointer, causing an unaligned access */
*iptr = 42;
return 0;
}
According to your comment, you're trying to debug SIGBUS, and there's existing question about that already:
Debugging SIGBUS on x86 Linux
That lists a number of possible causes. But probably the most likely reason for SIGBUS is, you have memory corruption and it messes things up so you get SIGBUS later... So debugging the signal might not be helpful at nailing the bug. That being said, use debugger to catch the point in code where signal is thrown, and see if it is a pointer. That's a good starting point for trying to find out the cause.
Related
I'm currently working on a project running on a heavily modified version of Linux patched to be able to access a VMEbus. Most of the bus-handling is done, I have a VMEAccess class that uses mmap to write at a specific address of /dev/mem so a driver can pull that data and push it onto the bus.
When the program starts, it has no idea where the slave board it's looking for is located on the bus so it must find it by poking around: it tries to read every address one by one, if a device is connected there the read method returns some data but if there isn't anything connected a SIGBUS signal will be sent to the program.
I tried several solutions (mostly using signal handling) but after some time, I decided on using jumps. The first longjmp() call works fine but the second call to VMEAccess::readWord() gives me a Bus Error even though my handler should prevent the program from crashing.
Here's my code:
#include <iostream>
#include <string>
#include <sstream>
#include <csignal>
#include <cstdlib>
#include <csignal>
#include <csetjmp>
#include "types.h"
#include "VME_access.h"
VMEAccess *busVME;
int main(int argc, char const *argv[]);
void catch_sigbus (int sig);
void exit_function(int sig);
volatile BOOL bus_error;
volatile UDWORD offset;
jmp_buf env;
int main(int argc, char const *argv[])
{
sigemptyset(&sigBusHandler.sa_mask);
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = exit_function;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
/* */
struct sigaction sigBusHandler;
sigBusHandler.sa_handler = catch_sigbus;
sigemptyset(&sigBusHandler.sa_mask);
sigBusHandler.sa_flags = 0;
sigaction(SIGBUS, &sigBusHandler, NULL);
busVME = new VMEAccess(VME_SHORT);
offset = 0x01FE;
setjmp(env);
printf("%d\n", sigismember(&sigBusHandler.sa_mask, SIGBUS));
busVME->readWord(offset);
sleep(1);
printf("%#08x\n", offset+0xC1000000);
return 0;
}
void catch_sigbus (int sig)
{
offset++;
printf("%#08x\n", offset);
longjmp(env, 1);
}
void exit_function(int sig)
{
delete busVME;
exit(0);
}
As mentioned in the comments, using longjmp in a signal handler is a bad idea. After doing the jump out of a signal handler your program is effectively still in the signal handler. So calling non-async-signal-safe functions leads to undefined behavior for example. Using siglongjmp won't really help here, quoting man signal-safety:
If a signal handler interrupts the execution of an unsafe function, and the handler terminates via a call to longjmp(3) or siglongjmp(3) and the program subsequently calls an unsafe function, then the behavior of the program is undefined.
And just for example, this (siglongjmp) did cause some problems in libcurl code in the past, see here: error: longjmp causes uninitialized stack frame
I'd suggest to use a regular loop and modify the exit condition in the signal handler (you modify the offset there anyway) instead. Something like the following (pseudo-code):
int had_sigbus = 0;
int main(int argc, char const *argv[])
{
...
for (offset = 0x01FE; offset is sane; ++offset) {
had_sigbus = 0;
probe(offset);
if (!had_sigbus) {
// found
break;
}
}
...
}
void catch_sigbus(int)
{
had_sigbus = 1;
}
This way it's immediately obvious that there is a loop, and the whole logic is much easier to follow. And there are no jumps, so it should work for more than one probe :) But obviously probe() must handle the failed call (the one interrupted with SIGBUS) internally too - and probably return an error. If it does return an error using the had_sigbus function might be not necessary at all.
I'm trying to make a Python program that interfaces with a different crashy process (that's out of my hands). Unfortunately the program I'm interfacing with doesn't even crash reliably! So I want to make a quick C++ program that crashes on purpose but I don't actually know the best and shortest way to do that, does anyone know what to put between my:
int main() {
crashyCodeGoesHere();
}
to make my C++ program crash reliably
The abort() function is probably your best bet. It's part of the C standard library, and is defined as "causing abnormal program termination" (e.g, a fatal error or crash).
Try:
raise(SIGSEGV); // simulates a standard crash when access invalid memory
// ie anything that can go wrong with pointers.
Found in:
#include <signal.h>
Dividing by zero will crash the application:
int main()
{
return 1 / 0;
}
*((unsigned int*)0) = 0xDEAD;
Well, are we on stackoverflow, or not?
for (long long int i = 0; ++i; (&i)[i] = i);
(Not guaranteed to crash by any standards, but neither are any of the suggested answers including the accepted one since SIGABRT could have been caught anyway. In practice, this will crash everywhere.)
throw 42;
Just the answer... :)
assert(false); is pretty good too.
According to ISO/IEC 9899:1999 it is guaranteed to crash when NDEBUG is not defined:
If NDEBUG is defined [...] the assert macro is defined simply as
#define assert(ignore) ((void)0)
The assert macro is redefined according to the current state of NDEBUG each time that is included.
[...]
The assert macro puts diagnostic tests into programs; [...] if expression (which shall have a scalar type) is false [...]. It
then calls the abort function.
Since a crash is a symptom of invoking undefined behaviour, and since invoking undefined behaviour can lead to anything, including a crash, I don't think you want to really crash your program, but just have it drop into a debugger. The most portable way to do so is probably abort().
While raise(SIGABRT) has the same effect, it is certainly more to write. Both ways however can be intercepted by installing a signal handler for SIGABRT. So depending on your situation, you might want/need to raise another signal. SIGFPE, SIGILL, SIGINT, SIGTERM or SIGSEGV might be the way to go, but they all can be intercepted.
When you can be unportable, your choices might be even broader, like using SIGBUS on linux.
The answer is platform specific and depends on your goals. But here's the Mozilla Javascript crash function, which I think illustrates a lot of the challenges to making this work:
static JS_NEVER_INLINE void
CrashInJS()
{
/*
* We write 123 here so that the machine code for this function is
* unique. Otherwise the linker, trying to be smart, might use the
* same code for CrashInJS and for some other function. That
* messes up the signature in minidumps.
*/
#if defined(WIN32)
/*
* We used to call DebugBreak() on Windows, but amazingly, it causes
* the MSVS 2010 debugger not to be able to recover a call stack.
*/
*((int *) NULL) = 123;
exit(3);
#elif defined(__APPLE__)
/*
* On Mac OS X, Breakpad ignores signals. Only real Mach exceptions are
* trapped.
*/
*((int *) NULL) = 123; /* To continue from here in GDB: "return" then "continue". */
raise(SIGABRT); /* In case above statement gets nixed by the optimizer. */
#else
raise(SIGABRT); /* To continue from here in GDB: "signal 0". */
#endif
}
The only flash I had is abort() function:
It aborts the process with an abnormal program termination.It generates the SIGABRT signal, which by default causes the program to terminate returning an unsuccessful termination error code to the host environment.The program is terminated without executing destructors for objects of automatic or static storage duration, and without calling any atexit( which is called by exit() before the program terminates)function. It never returns to its caller.
I see there are many answers posted here that will fall into lucky cases to get the job done, but none of them are 100% deterministic to crash. Some will crash on one hardware and OS, the others would not.
However, there is a standard way as per official C++ standard to make it crash.
Quoting from C++ Standard ISO/IEC 14882 §15.1-7:
If the exception handling mechanism, after completing the
initialization of the exception object but before the activation of a
handler for the exception, calls a function that exits via an
exception, std::terminate is called (15.5.1).
struct C {
C() { }
C(const C&) {
if (std::uncaught_exceptions()) {
throw 0; // throw during copy to handler’s exception-declaration object (15.3)
}
}
};
int main() {
try {
throw C(); // calls std::terminate() if construction of the handler’s
// exception-declaration object is not elided (12.8)
} catch(C) { }
}
I have written a small code to demonstrate this and can be found and tried on Ideone here.
class MyClass{
public:
~MyClass() throw(int) { throw 0;}
};
int main() {
try {
MyClass myobj; // its destructor will cause an exception
// This is another exception along with exception due to destructor of myobj and will cause app to terminate
throw 1; // It could be some function call which can result in exception.
}
catch(...)
{
std::cout<<"Exception catched"<<endl;
}
return 0;
}
ISO/IEC 14882 §15.1/9 mentions throw without try block resulting in implicit call to abort:
If no exception is presently being handled, executing a
throw-expression with no operand calls std::terminate()
Others include :
throw from destructor: ISO/IEC 14882 §15.2/3
*( ( char* ) NULL ) = 0;
This will produce a segmentation fault.
This one is missing:
int main = 42;
This crashes on my Linux system, because string literals are stored in read only memory:
0[""]--;
By the way, g++ refuses to compile this. Compilers are getting smarter and smarter :)
What about stack overflow by a dead loop recursive method call?
#include <windows.h>
#include <stdio.h>
void main()
{
StackOverflow(0);
}
void StackOverflow(int depth)
{
char blockdata[10000];
printf("Overflow: %d\n", depth);
StackOverflow(depth+1);
}
See Original example on Microsoft KB
This is a more guaranteed version of abort presented in above answers.It takes care of the situation when sigabrt is blocked.You can infact use any signal instead of abort that has the default action of crashing the program.
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
sigset_t act;
sigemptyset(&act);
sigfillset(&act);
sigprocmask(SIG_UNBLOCK,&act,NULL);
abort();
}
This is the snippet provided by Google in Breakpad.
volatile int* a = reinterpret_cast<volatile int*>(NULL);
*a = 1;
int i = 1 / 0;
Your compiler will probably warn you about this, but it compiles just fine under GCC 4.4.3
This will probably cause a SIGFPE (floating-point exception), which perhaps is not as likely in a real application as SIGSEGV (memory segmentation violation) as the other answers cause, but it's still a crash. In my opinion, this is much more readable.
Another way, if we're going to cheat and use signal.h, is:
#include <signal.h>
int main() {
raise(SIGKILL);
}
This is guaranteed to kill the subprocess, to contrast with SIGSEGV.
int* p=0;
*p=0;
This should crash too. On Windows it crashes with AccessViolation and it should do the same on all OS-es I guess.
Although this question already has an accepted answer...
void main(){
throw 1;
}
Or... void main(){throw 1;}
int main(int argc, char *argv[])
{
char *buf=NULL;buf[0]=0;
return 0;
}
Writing to a read-only memory will cause segmentation fault unless your system don't support read-only memory blocks.
int main() {
(int&)main = 0;
}
I have tested it with MingGW 5.3.0 on Windows 7 and GCC on Linux Mint. I suppose that other compilers and systems will give a similar effect.
Or another way since we're on the band wagon.
A lovely piece of infinite recursion. Guaranteed to blow your stack.
int main(int argv, char* argc)
{
return main(argv, argc)
}
Prints out:
Segmentation fault (core dumped)
void main()
{
int *aNumber = (int*) malloc(sizeof(int));
int j = 10;
for(int i = 2; i <= j; ++i)
{
aNumber = (int*) realloc(aNumber, sizeof(int) * i);
j += 10;
}
}
Hope this crashes. Cheers.
int main()
{
int *p=3;
int s;
while(1) {
s=*p;
p++;
}
}
A stylish way of doing this is a pure virtual function call:
class Base;
void func(Base*);
class Base
{
public:
virtual void f() = 0;
Base()
{
func(this);
}
};
class Derived : Base
{
virtual void f()
{
}
};
void func(Base* p)
{
p->f();
}
int main()
{
Derived d;
}
Compiled with gcc, this prints:
pure virtual method called
terminate called without an active exception
Aborted (core dumped)
You can use of assembly in your c++ code BUT INT 3 is only for x86 systems other systems may have other trap/breakpoint instructions.
int main()
{
__asm int 3;
return 0;
}
INT 3 causes an interrupt and calls an interrupt vector set up by the OS.
Use __builtin_trap() in GCC or clang, or __debugbreak() in MSVC. Not handling these breakpoints/traps will lead to an unhandled breakpoint exception/crash.
Other suggestions that use abort() or exit(): those may be handled by other threads, making it more difficult to see the stack of the thread that propagated the crash.
#include <thread>
void intentionalCrash()
{
auto noop = [](){return;};
// Thread t1 is in a joinable state.
// When program returns t1 will be out of scope.
// Destructing a joinable thread creates a crash.
std::thread t1(noop);
}
int main()
{
intentionalCrash();
return 0;
}
Simple buffer overflow code that will cause the program to crash
int main()
{
int n[0];
n[2] = 0;
}
I am trying to port some code using VC++'s try-except statement to MinGW:
bool success = true;
__try {
//...
} __except ((EXCEPTION_STACK_OVERFLOW == GetExceptionCode())
? EXCEPTION_EXECUTE_HANDLER
: EXCEPTION_CONTINUE_SEARCH) {
success = false;
_resetstkoflw();
}
return success;
Is it possible to write code that catches a stack overflow exception using MinGW g++?
You would need to manually call the Windows API functions which register exception handling; namely, AddVectoredExceptionHandler. Note that by using MinGW which does not respect SEH exceptions, throwing any SEH exception or attempting to catch any such exception will result in undefined behavior, because the normal C++ stack unwinding semantic isn't done. (How does Windows know to nuke all those std::strings on the stack?)
You would also need to call RemoveVectoredExceptionHandler at the end of the time you want that SEH exception handler to be called.
Generally MinGW is lacking in support of Windows features like SEH and COM. Any reason you're trying to use that instead of MSVC++ (given that both compilers are free?)
This isn't well known, but the header file <excpt.h> in MinGW and MinGW-w64 provides macros __try1 and __except1 to produce gcc inline assembly for handling exceptions. These macros are not documented and are not easy to use. It gets worse. The x86_64 editions of __try1 and __except1 aren't compatible with the 32-bit editions. They use different callbacks with different arguments and different return values.
After a few hours, I almost had working code on x86_64. I needed to declare a callback with the same prototype as _gnu_exception_handler in MinGW's runtime. My callback was
long CALLBACK
ehandler(EXCEPTION_POINTERS *pointers)
{
switch (pointers->ExceptionRecord->ExceptionCode) {
case EXCEPTION_STACK_OVERFLOW:
return EXCEPTION_EXECUTE_HANDLER;
default:
return EXCEPTION_CONTINUE_SEARCH;
}
}
And my try-except code was
__try1 (ehandler) {
sum = sum1to(n);
__asm__ goto ( "jmp %l[ok]\n" :::: ok);
} __except1 {
printf("Stack overflow!\n");
return 1;
}
ok:
printf("The sum from 1 to %u is %u\n", n, sum);
return 0;
It was working until I enabled optimization with gcc -O2. This caused assembler errors so my program no longer compiled. The __try1 and __except1 macros are broken by an optimization in gcc 5.0.2 that moves functions from .text to a different section.
When the macros did work, the control flow was stupid. If a stack overflow happened, the program jumped through __except1. If a stack overflow didn't happen, the program fell through __except1 to the same place. I needed my weird __asm__ goto to jump to ok: and prevent the fall-through. I can't use goto ok; because gcc would delete __except1 for being unreachable.
After a few more hours, I fixed my program. I copied and modified the assembly code to improve the control flow (no more jump to ok:) and to survive gcc -O2 optimization. This code is ugly, but it works for me:
/* gcc except-so.c -o except-so */
#include <windows.h>
#include <excpt.h>
#include <stdio.h>
#ifndef __x86_64__
#error This program requires x86_64
#endif
/* This function can overflow the call stack. */
unsigned int
sum1to(unsigned int n)
{
if (n == 0)
return 0;
else {
volatile unsigned int m = sum1to(n - 1);
return m + n;
}
}
long CALLBACK
ehandler(EXCEPTION_POINTERS *pointers)
{
switch (pointers->ExceptionRecord->ExceptionCode) {
case EXCEPTION_STACK_OVERFLOW:
return EXCEPTION_EXECUTE_HANDLER;
default:
return EXCEPTION_CONTINUE_SEARCH;
}
}
int main(int, char **) __attribute__ ((section (".text.startup")));
/*
* Sum the numbers from 1 to the argument.
*/
int
main(int argc, char **argv) {
unsigned int n, sum;
char c;
if (argc != 2 || sscanf(argv[1], "%u %c", &n, &c) != 1) {
printf("Argument must be a number!\n");
return 1;
}
__asm__ goto (
".seh_handler __C_specific_handler, #except\n\t"
".seh_handlerdata\n\t"
".long 1\n\t"
".rva .l_startw, .l_endw, ehandler, .l_exceptw\n\t"
".section .text.startup, \"x\"\n"
".l_startw:"
:::: except );
sum = sum1to(n);
__asm__ (".l_endw:");
printf("The sum from 1 to %u is %u\n", n, sum);
return 0;
except:
__asm__ (".l_exceptw:");
printf("Stack overflow!\n");
return 1;
}
You might wonder how Windows can call ehandler() on a full stack. All those recursive calls to sum1to() must remain on the stack until my handler decides what to do. There is some magic in the Windows kernel; when it reports a stack overflow, it also maps an extra page of stack so that ntdll.exe can call my handler. I can see this in gdb, if I put a breakpoint on my handler. The stack grows down to address 0x54000 on my machine. The stack frames from sum1to() stop at 0x54000, but the exception handler runs on an extra page of stack from 0x53000 to 0x54000. Unix signals have no such magic, which is why Unix programs need sigaltstack() to handle a stack overflow.
You might want to look into LibSEH for adding Structured Exception Handling compatibility for MinGW.
MinGW doesn't support the keywords for structured exceptions; but, as Billy O'Neal says in his answer, you can call certain native functions to get the same effect.
The question is whether you want the same effect. I strongly believe that structured exceptions are a mistake. The list of structured exceptions that the operating system will tell you about include things like "tried to divide an integer by 0," "couldn't use the HANDLE parameter passed to a function," "tried to execute an illegal machine code instruction," and "tried to access memory without permission to do so." You really can't do anything intelligent about these errors, but structured exceptions give you the opportunity to (1) claim that you have and (2) allow the program to hobble along a little longer. It's far better to find out why the code tried to divide by 0, passed an invalid HANDLE parameter, tried to access memory without permission to do so, etc. and fix the code to never do that.
There is an argument that you could use structured exceptions to detect problems, display a dialog box, and exit. I'm not sure how this is better than letting the operating system display a dialog box and exit the program (especially if the operating system sends you a minidump in the process), which is the default behavior for unhandled exceptions.
Some errors aren't recoverable.
On x86 (either 64-bit or 32-bit) Linux --
for example:
void signal_handler(int) {
// want to know where the program is interrupted ...
}
int main() {
...
signal(SIGALRM, signal_handler);
alarm(5);
...
printf(...); <------- at this point, we trigger signal_handler
...
}
In signal_handler, how can we know we are interrupted at printf in main()?
Use sigaction with SA_SIGINFO set in sa_flags.
Prototype code:
#define _GNU_SOURCE 1 /* To pick up REG_RIP */
#include <stdio.h>
#include <signal.h>
#include <assert.h>
static void
handler(int signo, siginfo_t *info, void *context)
{
const ucontext_t *con = (ucontext_t *)context;
/* I know, never call printf from a signal handler. Meh. */
printf("IP: %lx\n", con->uc_mcontext.gregs[REG_RIP]);
}
int
main(int argc, char *argv[])
{
struct sigaction sa = { };
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
assert(sigaction(SIGINT, &sa, NULL) == 0);
for (;;);
return 0;
}
Run it and hit Ctrl-C. (Use Ctrl-\ to terminate...)
This is for x86_64. For 32-bit x86, use REG_EIP instead of REG_RIP.
[edit]
Of course, if you are actually in a library function (like printf) or a system call (like write), the RIP/EIP register might point somewhere funny...
You might want to use libunwind to crawl the stack.
Depending on your OS / Platform, it could be in a variety of areas:
On the current stack a set number of registers deep
On an/the interrupt stack
Within some sort of callback associated with your signal routine...
Without having additional info, I don't think we can track this much further. Adding a C/C++ tag to your might generate more responses and views.
In signal_handler, how can we know we are interrupted at printf in main()?
You can't, at least not from a C, C++, or POSIX perspective. Your operating system may provide OS-specific calls that let you poke at the stack. That's more than a bit dubious, though.
With timer-based signals, which instruction triggered the signal is a toss of the coin.
Workaround idea: if there are only a small number of places which can trigger a signal handler or you are only interested in which bigger block it happened you could maintain that in a variable.
entered = 1; // or entered = ENTER_PRINTF1;
printf(....);
I've made this simple class to open a process and read memory from it:
The problem is when I call ReadDWORD with any memory address ReadProcessMemory fails with error code 6: ERROR_INVALID_HANDLE, The handle is invalid. And I can't figure out what I'm doing wrong.
If I put the OpenProcess part in the ReadDWORD function it works fine. Is there something wrong with how I store the handle? Why does it become invalid before I use it?
Memory.h
#ifndef MEMORY_H
#define MEMORY_H
#include <windows.h>
#include <psapi.h>
#pragma comment(lib, "psapi.lib")
#include <iostream>
class Memory
{
public:
Memory();
Memory(DWORD offset);
~Memory();
DWORD ReadDWORD(DWORD addr);
private:
HANDLE m_hProc;
DWORD m_Offset;
};
#endif
Memory.cpp
#include "Memory.h"
Memory::Memory()
{
Memory(0);
}
Memory::Memory(DWORD offset)
{
m_hProc = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, false, 5444); // 5444 is the PID of a process I'm testing this with
m_Offset = offset;
}
Memory::~Memory()
{
CloseHandle(m_hProc);
}
DWORD Memory::ReadDWORD(DWORD addr)
{
// Optional memory offset
addr += m_Offset;
DWORD value = -1;
int result = ReadProcessMemory(m_hProc, (LPVOID)addr, &value, sizeof(DWORD), NULL);
if (result == 0)
std::cout << "ReadProcessMemory error: " << GetLastError() << std::endl;
return value;
}
Memory::Memory()
{
Memory(0);
}
This isn't doing what you think its doing: it's not actually calling the other constructor, instead it's creating a temporary that gets discarded. So you are opening the process, but in a separate temporary object, while this object remains uninitialized.
Safer approach is to have a separate Initialize(offset) method that you call from both ctors.
(The advice in the other answers is also good; check your return values, and where you get a E_INVALID_HANDLE, check that the handle is something that looks like a handle. Or set a breakpoint at the OpenHandle and ReadProcessMemory and check that the same value is being used in both places. C++ is often full of surprises, and there's often no substitute for just stepping through the code to make sure it's doing what you think it's doing.)
To access other processes, you often need to enable certain privileges. SeDebugPrivilege comes to mind. See here. Otherwise see the suggestion from Hans Passant (i.e. GetLastError).
You can use RtlAdjustPrivilege function to get SeDebugPrivilege.
NTSTATUS NTAPI RtlAdjustPrivilege(ULONG,BOOLEAN,BOOLEAN,PBOOLEAN); /*This is the
protoype of RtlAdjustPrivilege function.*/