Anti-debugging - memory function for detecting 3 breakpoints

I look at some simple debugging measures listed in this article http://www.codeproject.com/Articles/30815/An-Anti-Reverse-Engineering-Guide#BpMem

I performed a simple check for int 3 breakpoints in the given function, so the testForInt3Breakpoints function returns true if the breakpoint is set somewhere inside thisIsADummyFunction .

int thisIsADummyFunction() { int i = rand(); ++i; return i; } bool testForInt3Breakpoints() { bool breakPointPresent = false; unsigned char* memPtr = reinterpret_cast<unsigned char*>( thisIsADummyFunction ); auto size = 0x16; //this value determined by manual inspection of compiled code for ( size_t i = 0; i < size; i++ ) { if ( memPtr[ i ] == 0xCC ) { //see if byte equals int 3 instruction breakPointPresent = true; break; } } return breakPointPresent; } 

The function above works fine for me for one specific function, but I would like to be able to control several functions without having to check the compiled code every time.

My question is, are there any methods for getting functional memory to find out which memory to monitor?

I understand that there is no general cross-platform way to do this at runtime: How do I get the length of a function in bytes?

but I work on windows x64 and visual studio 2015 and am very pleased with solutions for a specific platform or anything that can somehow automate the process.

+5
source share
1 answer

As noted in the above comments, there is no good solution for this specific description of the problem, especially not in conjunction with scanning for 0xCC, this is a valid byte that will happen sooner or later in your code, even if breakpoints are not set.

As also indicated, the best approach would be to hash the entire section of the code. However, this has the following disadvantages:

  • The problem with Hen-and-egg: you need to get the hashed value after compilation, but actually use it inside your code to compare the actual hash with the expected one.
  • Depending on how often you check and how large your section of code is (including library code), this can have a greater impact on performance. In addition, if you check while your application is not running, Windows will have to be on the page in all parts of the code, even if they are not currently running, effectively blocking your entire program in memory, even if it is not required.
  • You may have problems with security software and other tools that perform low-level modifications to other processes. Some tools like this overwrite / hook part of your code directly into memory to perform additional security functions.

If you still want to go this route, you can get the boundaries of your section of code using VirtualQuery with a pointer anywhere in the code (e.g. &main ), then read it all and use a hash algorithm like Murmurhash (which is pretty fast) to create a hash and compare it with the stored value.

To solve the chicken and egg problem, you can, for example, get a hash from the current copy of your program (either using some kind of "secret" command line key, or by reading memory using another program from which you use OpenProcess , VirtualQueryEx and ReadProcessMemory for the job) and save it in a place that is not part of the hash, for example, your data section or resources. If you use the latter, you can even set the correct hash in the file without recompiling it.

0
source

Source: https://habr.com/ru/post/1246961/


All Articles