Skip to content
MPGHThe Dark Arts
/
RegisterLog in
Forum
Community
What's NewLatest posts across the boardTrendingHottest threads right nowSubscribedThreads you follow
Discussion
GeneralIntroductionsEntertainmentDebate FortFlaming & Rage
Board
News & AnnouncementsMPGH TimesSuggestions & HelpGiveaways
More Sections
Art & Graphic DesignProgrammingHackingCryptocurrency
Hacks & Cheats
Games
ValorantCS2 / CS:GOCall of Duty / WarzoneFortniteApex LegendsEscape From Tarkov
+14 moreLeague of LegendsGTA VMinecraftRustROTMGBattlefieldTroveBattleOnCombat ArmsCrossFireBlackshotRuneScapeDayZDead by Daylight
Resources
Game Hacking TutorialsReverse EngineeringGeneral Game HackingAnti-CheatConsole Game Hacking
Tools
Game Hacking ToolsTrainers & CheatsHack/Release NewsNew
Submit a release →Share your cheat, tool, or config with the community.
AINEW
AI Tools
General & DiscussionPrompt EngineeringLLM JailbreaksHotAI Agents & AutomationLocal / Open Models
AI × Gaming
AI Aimbots & VisionML Anti-CheatGame Bots & Automation
Create
AI Coding / Vibe CodingAI Art & MediaAI Voice & TTS
The AI frontier →Where game hacking meets modern machine learning. Jump in.
Marketplace
Buy & Sell
SellingBuyingTradingUser Services
Trust & Safety
Middleman LoungeMarketplace TalkVouch Copy Profiles
Money
Cryptocurrency TalkCurrency ExchangeWork & Job Offers
Start selling →List accounts, services, and goods. Use the middleman to trade safe.
MPGH The Dark Arts

A community for offensive security research, reverse engineering, and AI.

Community

ForumMarketplaceSearch

Account

RegisterLog in

Legal

Privacy PolicyForum RulesHelp & FAQ
© 2026 MPGH · All rights reserved.Built by the community, for the community. For educational purposes onlyContent is shared for security research and education — we don't condone illegal use. You're responsible for complying with applicable laws. Use at your own risk.
Home › Forum › MultiPlayer Game Hacks & Cheats › Steam Games Hacks & Cheats › Counter-Strike 2 Hacks › Counter-Strike 2 Coding & Resources › C/C++ Encrypt/Decrypt Functions & Memory At Runtime

PostC/C++ Encrypt/Decrypt Functions & Memory At Runtime

Posts 1–15 of 39 · Page 1 of 3
nullptr_t
nullptr_t
C/C++ Encrypt/Decrypt Functions & Memory At Runtime
In this Tutorial/Source Code Release I attempt to give you an introduction to self modifying / polymorphic code.
 
Will It Help To Prevent VAC From Detecting My Hacks?
There is no guarantee that this prevent anti-cheats from detecting your hacks, but nevertheless it can help.
Tested on MSVC 2015.

Our Dummy Function For Testing:
Code:
// Our testfunction that we are going to encrypt
void TestFunction()
{
	MessageBox(0, L"Hello From Testfunction!", L"Test", 0);
}
// Marks the end of testfunction()
void FunctionStub() { return; }
There is no official way of getting a size of a function in memory, but it can be done by subtracting the size of a stub function
from the original one. This requires the functions to be placed next to each other (as in code) by the compiler in the object
file when the program is built.

In order to achieve this, first do not place any code in between the two procedures, next disable all compiler optimizations
and last disable DEP (Data Execution Prevention) from advanced linker options (/NXCOMPAT:NO).



Now let's write our XOR Function (in inline asm)
Code:
void XorBlock(DWORD dwStartAddress, DWORD dwSize)
{
    __asm
	{
        push eax
        push ecx
        mov ecx, dwStartAddress          // Move Start Address to ECX
        add ecx, dwSize                  // Add the size of the function to ECX
        mov eax, dwStartAddress          // Copy the Start Address to EAX

        crypt_loop:                         // Start of the loop
            xor byte ptr ds:[eax], 0x4D     // XOR The current byte with 0x4D
            inc eax                         // Increment EAX with dwStartAddress++
            cmp eax,ecx                     // Check if every byte is XORed
        jl crypt_loop;                      // Else jump back to the start label

        pop ecx // pop ECX from stack
        pop eax // pop EAX from stack
    }
}
Next we'll write our function to get the size of a certain function:
Code:
DWORD GetFuncSize(DWORD* Function, DWORD* StubFunction)
{
	DWORD dwFunctionSize = 0, dwOldProtect;
	DWORD *fnA = NULL, *fnB = NULL;

	fnA = (DWORD *)Function;
	fnB = (DWORD *)StubFunction;
	dwFunctionSize = (fnB - fnA);
	VirtualProtect(fnA, dwFunctionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect); // Need to modify our privileges to the memory
	return dwFunctionSize;
}
Memory Hex Dumper (just to see the differences):
(credits to domnikl for: C function to dump memory)

Code:
void HexDumpMemory(void *addr, int len)
{
	int i;
	unsigned char buff[17];
	unsigned char *pc = (unsigned char*)addr;

	// Process every byte in the data.
	for (i = 0; i < len; i++) {
		// Multiple of 16 means new line (with line offset).

		if ((i % 16) == 0) {
			// Just don't print ASCII for the zeroth line.
			if (i != 0)
				printf("  %s\n", buff);

			// Output the offset.
			printf("  %04X ", i);
		}

		// Now the hex code for the specific character.
		printf(" %02X", pc[i]);
		// And store a printable ASCII character for later.
		if ((pc[i] < 0x20) || (pc[i] > 0x7e)) {
			buff[i % 16] = '.';
		}
		else {
			buff[i % 16] = pc[i];
		}

		buff[(i % 16) + 1] = '\0';
	}

	// Pad out last line if not exactly 16 characters.
	while ((i % 16) != 0) {
		printf("   ");
		i++;
	}

	// And print the final ASCII bit.
	printf("  %s\n", buff);
}
And lastly a little test:
Code:
int main()
{
	DWORD dwFuncSize = GetFuncSize((DWORD*)&TestFunction, (DWORD*)&FunctionStub);
	
	printf("\n\nEncrypted:\n");
	XorBlock((DWORD)&TestFunction, dwFuncSize); // XOR encrypt the function
	HexDumpMemory(&TestFunction, dwFuncSize);

	//TestFunction(); // If you try to run the encrypted function you will get Access Violation Exception.

	printf("\n\nDecrypted:\n");
	XorBlock((DWORD)&TestFunction, dwFuncSize); // XOR decrypt the function   
	HexDumpMemory(&TestFunction, dwFuncSize);

	TestFunction(); // Fine here

	getchar();
    return 0;
}

Q: How to use this to (potentially) prevent from VAC detecting my cheats?
A: Encrypt each function of your cheat at main() and when needed, just decrypt the function
and after used just encrypt it again.
#1 · 10y ago
4N
4nuoFZf9aE
.. @nullptr_t This provides no protection what so ever. What???
#2 · edited 10y ago · 10y ago
OH
OhStarQ
I am guessing it would protect the function from getting read by VAC when it is not being used? If it's in memory they could get the function but if it's encrypted it would be much more difficult.
@rwby
#3 · edited 10y ago · 10y ago
nullptr_t
nullptr_t
Quote Originally Posted by OhStarQ View Post
I am guessing it would protect the function from getting read by VAC when it is not being used? If it's in memory they could get the function but if it's encrypted it would be much more difficult.
@rwby
"size" is a reserved word in inline assembly, you cannot use it. Use dwSize instead.

- - - Updated - - -

Quote Originally Posted by rwby View Post
.. @nullptr_t This provides no protection what so ever. What???
This can be used to battle signature scanning & heuristics. If VAC scans/dumps the memory of your program/module while executing, and some functions are encrypted, signatures differ from the real memory. Hence making detection by signature
impossible
#4 · edited 10y ago · 10y ago
4N
4nuoFZf9aE
Quote Originally Posted by nullptr_t View Post
"size" is a reserved word in inline assembly, you cannot use it. Use dwSize instead.

- - - Updated - - -



This can be used to battle signature scanning & heuristics. If VAC scans/dumps the memory of your program/module while executing, and some functions are encrypted, signatures differ from the real memory. Hence making detection by signature
impossible
Its not impossible, even @WasserEsser will agree, that this does not help in any way possible. The encrypted code can still be scanned. lol.
#5 · 10y ago
OH
OhStarQ
Quote Originally Posted by rwby View Post


Its not impossible, even @WasserEsser will agree, that this does not help in any way possible. The encrypted code can still be scanned. lol.
At least it is making it harder, which is what he said in the post. The comment he made about it being impossible is false however.
#6 · 10y ago
4N
4nuoFZf9aE
Quote Originally Posted by OhStarQ View Post
At least it is making it harder, which is what he said in the post. The comment he made about it being impossible is false however.
It doesnt.
#7 · 10y ago
WA
WasserEsser
1. This has nothing to do with Polymorphic code, don't call it polymorphic code if it ain't polymorphic code. Polymorphic code is code that changes each time it's getting executed, but remains the same functionality. For instance, you've got a cmp instruction pared with a jnz instruction. Now on the next run it would change the entire code above the cmp instruction to result in a 0, and replace the jnz instruction with a jz instruction. The code would have the same functionality, it would just get tested differently. On the next run however this wold again completely change to have a completely different set of instructions used but with the same functionality of the code. A really naive example could also be 5 + 5 - 5. Lets say the compiler generates an add instruction followed by a sub instruction. On the next execution, it could result in a sub instruction followed by an add instruction. The signature changes, the result is the same. On the next run, it would change completely again.

Your example provided above is encrypting it statically aswell as decrypting it statically. You aren't changing your code on each execution, hence it's not polymorphic.

2. Your example doesn't help against VAC's signature scanning techniques.

  1. VAC can gather a signature out of your encrypted code
  2. VAC can gather a signature out of your decrypted code
  3. VAC can combine those together
  4. VAC isn't gathering a signature out of your entire code, it's a really really small signature compared to how big the binary actually is, which makes it very very hard to be lucky that VAC is scanning in the exact moment when the function that you're using and which is used in their signature is getting called; even then, VAC is repeatingly scanning
  5. If you dump the VAC modules and reverse it, you can see that they can load files into memory, this means that your entire code is not going to be decrypted at all, meaning they can just compare it to a signature gathered out of your encrypted code
  6. They can just use your decrypt / encrypt function together with signature scanning to make sure it's the right binary




EDIT: RIP format

However, thanks for taking the effort to experience a little bit with this.
#8 · edited 10y ago · 10y ago
nullptr_t
nullptr_t
Quote Originally Posted by WasserEsser View Post
1. This has nothing to do with Polymorphic code, don't call it polymorphic code if it ain't polymorphic code. Polymorphic code is code that changes each time it's getting executed, but remains the same functionality. For instance, you've got a cmp instruction pared with a jnz instruction. Now on the next run it would change the entire code above the cmp instruction to result in a 0, and replace the jnz instruction with a jz instruction. The code would have the same functionality, it would just get tested differently. On the next run however this wold again completely change to have a completely different set of instructions used but with the same functionality of the code. A really naive example could also be 5 + 5 - 5. Lets say the compiler generates an add instruction followed by a sub instruction. On the next execution, it could result in a sub instruction followed by an add instruction. The signature changes, the result is the same. On the next run, it would change completely again.

Your example provided above is encrypting it statically aswell as decrypting it statically. You aren't changing your code on each execution, hence it's not polymorphic.

2. Your example doesn't help against VAC's signature scanning techniques.

  1. VAC can gather a signature out of your encrypted code
  2. VAC can gather a signature out of your decrypted code
  3. VAC can combine those together
  4. VAC isn't gathering a signature out of your entire code, it's a really really small signature compared to how big the binary actually is, which makes it very very hard to be lucky that VAC is scanning in the exact moment when the function that you're using and which is used in their signature is getting called; even then, VAC is repeatingly scanning
  5. If you dump the VAC modules and reverse it, you can see that they can load files into memory, this means that your entire code is not going to be decrypted at all, meaning they can just compare it to a signature gathered out of your decrypted code
  6. They can just use your decrypt / encrypt function together with signature scanning to make sure it's the right binary




EDIT: RIP format

However, thanks for taking the effort to experience a little bit with this.
Thanks for pointing it out, well I am sure someone will figure out some use for this code. For example in reverse engineering.
Have a nice day
#9 · 10y ago
JA
javalover
Quote Originally Posted by nullptr_t View Post
This can be used to battle signature scanning & heuristics. If VAC scans/dumps the memory of your program/module while executing, and some functions are encrypted, signatures differ from the real memory. Hence making detection by signature
impossible
polymorphic/metamorphic code can be signature-scanned, but not conventionally (this means if you try to scan, you would not have success at all a next time, as there would be many mutations) (by definition, poly = many, morphic = forms - this is not what your code actually does). sometimes signature-scanning could bypass small mutations byte strings using some wildcards, which would not be correct at all.
I would suggest you trying with metamorphism, which is sometimes used more than polymorphic codes to make something more unrecognizable.
#10 · edited 10y ago · 10y ago
nullptr_t
nullptr_t
Quote Originally Posted by javalover View Post
polymorphic/metamorphic code can be signature-scanned, but not conventionally (this means if you try to scan, you would not have success at all a next time, as there would be many mutations) (by definition, poly = many, morphic = forms - this is not what your code actually does). sometimes signature-scanning could bypass small mutations byte strings using some wildcards, which would not be correct at all.
I would suggest you trying with metamorphism, which is sometimes used more than polymorphic codes to make something more unrecognizable.
Well you can just encrypt the block with a random key every time of execution, that way it will be more efficient.
#11 · 10y ago
WA
WasserEsser
Quote Originally Posted by nullptr_t View Post
Well you can just encrypt the block with a random key every time of execution, that way it will be more efficient.
But can still be countered. You need to save the key since you have to decrypt it with the same key again. You can just grab the key and decrypt it with this key.
#12 · 10y ago
JA
javalover
Quote Originally Posted by nullptr_t View Post
Well you can just encrypt the block with a random key every time of execution, that way it will be more efficient.
More efficient compared to which method? Metamorphism, or polymorphism?
#13 · 10y ago
nullptr_t
nullptr_t
Quote Originally Posted by WasserEsser View Post
But can still be countered. You need to save the key since you have to decrypt it with the same key again. You can just grab the key and decrypt it with this key.
Well obviously you have to, generate a random key for each execution.

- - - Updated - - -

Quote Originally Posted by javalover View Post
More efficient compared to which method? Metamorphism, or polymorphism?
More efficient compared to using only the same key.
#14 · 10y ago
WA
WasserEsser
Quote Originally Posted by nullptr_t View Post
Well obviously you have to, generate a random key for each execution.

- - - Updated - - -



More efficient compared to using only the same key.
The main problem persists, the signature is easily scannable ( without ANY problems at all ) if the file is just loaded from disk into memory.
#15 · 10y ago
Posts 1–15 of 39 · Page 1 of 3

Post a Reply

Similar Threads

  • C/C++ Polymorphic Code (Encrypt/Decrypt Functions & Memory At Runtime)By nullptr_t in C++/C Programming
    30Last post 9y ago
  • Encrypt/Decrypt FunctionsBy CodeDemon in Combat Arms Hack Coding / Programming / Source Code
    7Last post 16y ago
  • Mods Encrypt/Decrypt???By SPA777174 in Call of Duty Modern Warfare 2 Help
    0Last post 16y ago
  • [TUT]Basic Encrypter\DecrypterBy Bombsaway707 in Visual Basic Programming
    30Last post 16y ago
  • Encrypt/Decrypt vb.Net?By o0OpurezO0o in Visual Basic Programming
    24Last post 15y ago

Tags for this Thread

#c++#crypter#polymorphism#runtime#self-modyfying code