I'm trying to create a basic program that has memory tampering protection, however it always says it's correct, even if I nop the whole license check function in Ollydbg or change and rebuild the code.

I'm following the Surreptitious Software book, and wrote the following program:

#include "stdafx.h"

#define CORRECTHASH 5131241

void BEGIN() {}

const std::string correctlicense("ABC");

bool licenseCheck() {

    std::cout << "Enter license: ";

    std::string license;
    std::cin >> license;

    volatile DWORD d;

    // Fingerprint
    __asm {
        lea ebx, d
        mov ebx, 0x050b072b

    return license.compare(correctlicense) == 0;

UINT hash(UINT *beginAddress, UINT *endAddress) {

    UINT h = *beginAddress;

    for (; beginAddress <= endAddress; beginAddress++) {
        h ^= *beginAddress;

    return h;
void END() {}

int main()

    UINT uHash = hash((UINT*)BEGIN, (UINT*)END);

    std::cout << "[Protection checks]" << std::endl;
    std::cout << "Tampering: ";

    if (uHash != CORRECTHASH) {
        std::cout << "Failed ( " << uHash << " )" << std::endl;
        return 0;
    else {
        std::cout << "Correct" << std::endl;

    if (licenseCheck()) {
        std::cout << "Correct!" << std::endl;
    else {
        std::cout << "Failed!" << std::endl;

    return 0;

The program basically 'hashes' the code between the BEGIN function and END function, but it doesn't seem to work. The hash is always correct even after tampering.

I'm using Windows 7 and Visual studio 2017 the build/run the program.


Does the book actually use this as an example? This is not going to work in general.

The theory behind the snippet is that the code will be compiled in such a way where all of the functions are situated in the assembly language output in the same order in which they were situated in the C code. That is a broken assumption in general. The compiler is under no obligation to layout the functions in the binary in the same order in which they were laid out in the source code.

In this case I would expect that the functions BEGIN and END will be merged together into the same function via a compiler optimization known as clone detection, that it would compile to a single RETN instruction, and that the hash value would be the UINT corresponding to a RETN followed by padding bytes prior to the next function (if there is one).

You could figure out exactly what's going on by looking at the disassembly listing for the compiled code (or passing a flag to the compiler that caused it to emit the assembly language version).


I took the code and compiled and ran it as is i get a failed result
modified the CORRECTHASH to the result of first failure and i get a correct result

why would you nop the license check it simply compares xyz with ABC prints and discards it doesn't seem to have any impact on the hash function

you would either need to create a CORRECTHASH or tamper the existing hash it seems from looking at it a few minutes (you can tamper the ABC to some other string too to make the correct hash)

here is the output of tampered and compiled exe

bogus key with tampered hash

Enter license: abc
[Protection checks]
Tampering: Correct
Press any key to continue . . .

correct key with tampered hash
Enter license: ABC
[Protection checks]
Tampering: Correct
Press any key to continue . . .

comaprison of unmodified and modified source code 

>fc licchk.cpp unmodlicchk.cpp
Comparing files licchk.cpp and UNMODLICCHK.CPP
***** licchk.cpp

#define CORRECTHASH 9480169  <<<<<<<<<<<< modified


#define CORRECTHASH 5364713 <<<<<<<<<< original

  • Yes, but the goal is to detect tampering with the license check function. That's why I nopped the license check function to check if the protection is working. By nopping this function, it has changed so I would expect that the hash is different, but it isn't. – JeffreyZ Jan 8 '18 at 9:27
  • I edited the code to make it a bit more clear what I mean. – JeffreyZ Jan 8 '18 at 9:41
  • this question nor my answer appears to have any relation to reverse engineering your edited code appears to have logic errors (it will never reach license check nor will it ask for a cin << but always print fail) please consider asking at code review or SO – blabb Jan 8 '18 at 10:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.