-
Notifications
You must be signed in to change notification settings - Fork 238
Expand file tree
/
Copy pathNOPExample.cpp
More file actions
85 lines (73 loc) · 2.43 KB
/
Copy pathNOPExample.cpp
File metadata and controls
85 lines (73 loc) · 2.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include "main.h"
// this is the simulated list of creatures in the game
std::vector<_creature> creatures;
int creaturesDrawn = 0;
// this is the simulated function to draw creature names
void drawHealthBar(int healthbar)
{
creaturesDrawn++; // make a note that we drew it
Sleep(healthbar); // just an example, we're not really doing anything
}
// this is the function where we place the NOP.
void drawCreatureHealthBarExample()
{
for (int i = 0; i < creatures.size(); i++) {
auto c = creatures[i];
if (c.isEnemy && c.isCloaked)
{
// our NOP is esentially going to remove this continue statement,
// which will be a JUMP that evades the drawHealthBar car
continue;
}
drawHealthBar(c.healthBar);
}
}
// this is the function that actually does the NOP
template<int SIZE>
void writeNop(DWORD address)
{
auto oldProtection = protectMemory<BYTE[SIZE]>(address, PAGE_EXECUTE_READWRITE);
for (int i = 0; i < SIZE; i++)
writeMemory<BYTE>(address + i, 0x90);
protectMemory<BYTE[SIZE]>(address, oldProtection);
}
// I cannot hard-code any addresses from within this application,
// as they may change upon re-compile. For this reason, I'll locate
// the address of the JMP that I want to replace programatically
// by scanning for the 'JMP -67' statement (bytes 0xEB 0xBD)
// somewhere within 1000 bytes of the start of the function
DWORD getAddressForNOP(DWORD functionStart)
{
auto oldProtection = protectMemory<BYTE[1000]>(functionStart, PAGE_EXECUTE_READ); // make sure memory is readable, just incase
auto mem = pointMemory<BYTE>(functionStart);
DWORD ret = 0;
for (int i = 0; i < 999; i++) {
if (mem[i] == 0xEB && mem[i+1] == 0xBD) {
ret = functionStart + i;
break;
}
}
protectMemory<BYTE[1000]>(functionStart, oldProtection); // restore old memory protection
return ret;
}
// This ties the entire example together
void NOPExample()
{
creaturesDrawn = 0;
// nop it
auto address = getAddressForNOP((DWORD)&drawCreatureHealthBarExample);
if (address)
writeNop<2>(address);
// add some make creatures
creatures.push_back(_creature(0, true, true));
creatures.push_back(_creature(0, true, false));
creatures.push_back(_creature(0, false, true));
creatures.push_back(_creature(0, false, false));
//call the function
drawCreatureHealthBarExample();
//check if NOP worked
if (creaturesDrawn == 4)
printf("NOP worked! Drew all creatures!\n");
else
printf("NOP failed! :( Only drew %d/4 creatures.\n", creaturesDrawn);
}