简体   繁体   中英

Is it possible to check if a memory address is valid?

A client came to me with an application that they lost the source code to. This application is crashing seemingly at random, when loading some files. I suspect that the issue is due to a race condition in which a pointer is deleted and then either not set to NULL or not checked for validity.

When stepping through the assembly using OllyDBG, I found that the crash ALWAYS happens at the same location, so this is kind of re-enforcing my theory. This is the assembly line it sometimes crashes on, keyword sometimes.

MOV EDI,DWORD PTR DS:[EAX]

Is it possible to validate a memory address is valid and exists either through native assembly or through C++ that pulls an address through an inline assembly call (or something like this)?

There is no general standard way in C++ to validate a memory address. Nor is there such assembly instruction that I know of.

On a memory mapped system (such as any modern operating system), you may be able to check whether an address has been mapped for the process using a system specific API. An address being mapped to the process doesn't guarantee that the address is valid from the C++ point of view, but an unmapped address is definitely invalid.

Furthermore, even if could find that an address is valid, that doesn't tell you whether the object you are expecting is in that address or something else.


There are tools for validating memory accesses outside of the C++ language 1 . There's for example Valgrind and also compiles provide address sanitisers and memory sanitisers. Mostly, these help detect invalid accesses that wouldn't have crashed the program otherwise. But they also often can provide additional information regarding that memory.

1 If you had access to the source.

I suspect that the issue is due to a race condition

Being able to validate a memory address won't solve this problem. What you should do 1 , is to use a debugger to find out what object is being accessed, find all places where that object is accessed. If any of those places is not holding a mutex that is common to all other places potentially accessing the object at the same time, then there's your bug.

1 If you had access to the source.

lost the source code

If you have a massive budget, then you could try reverse-engineering it and try to figure out what it's doing. I wouldn't hold my breath; it may be best to declare this as a lost cause.

Everyone provided some great responses. Unfortunately, in this situation, the client wasn't willing to pay to have the software re-developed entirely.

I managed to kind of negate the crash... After identifying exactly where the crash occurred I used used code injection to JMP to a custom C++ function. The C++ function employs a __try __except block. Inside of the Try I placed the problem assembly code, and if the problem code causes a crash, the __except catches it. After that, it was just a matter of analyzing what the problem code was doing and when it started doing something else and then jumping to the start of that "something else" part of the problem function when an exception is caught.

It's not exactly detecting if a memory location is valid or not, but rather it's just skipping code if it causes an exception. Hope this helps someone eventually...

Yes, validating a pointer's content is possible. However, verifying that the target is the correct one is more difficult.

In order to validate a pointer you'll need:

  1. Table of valid address ranges (addresses that are implemented and their ranges).
    For example, on embedded systems addresses that are decoded may not have memory or devices at all locations.
  2. For OS's that support paging or virtual memory, you'll need to figure out the limits of your program's memory area (as given by the OS). The OS may take portions of your executable and swap them out with code on a hard drive.
  3. For OS's that support virtual memory, you'll have to figure out where in the "virtual" memory that your pointer is allowed to access. Read about memory mapped files.
  4. On some platforms, the address 0x0000 is a valid address. Verify if this is the case on your target platform.

IMHO, pointer content can be validated, but the validation may be very compilicated.

Prefer to use references.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM