You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
desc: '<b>Goal:</b> Understand how C stores variables in memory as raw bytes.',
8
+
source: {
9
+
c: [
10
+
{text: '#include <stdio.h>',cls: ''},
11
+
{text: '',cls: ''},
12
+
{text: 'int main() {',cls: ''},
13
+
{text: ' int x = 42;',cls: 'highlight'},
14
+
{text: ' char c = \'A\';',cls: 'highlight'},
15
+
{text: ' printf("%d %c\\n", x, c);',cls: ''},
16
+
{text: ' return 0;',cls: ''},
17
+
{text: '}',cls: ''},
18
+
],
19
+
},
20
+
mode: 'step',
21
+
vizMode: 'stack',
22
+
bufSize: 16,
23
+
steps: [
24
+
{
25
+
action: 'init',
26
+
log: ['info','In C, every variable is a named slot in memory. Unlike Python or JavaScript, you must tell the compiler how big each slot is by choosing a "type." Let\'s see how two different types get stored.'],
27
+
},
28
+
{
29
+
action: 'init',
30
+
srcLine: 3,
31
+
log: ['info','int x = 42 -- An "int" occupies 4 bytes (32 bits). The computer stores the value 42 in hexadecimal as 0x0000002A. Those 4 bytes sit at a specific address in memory.'],
32
+
},
33
+
{
34
+
action: 'init',
35
+
srcLine: 4,
36
+
log: ['info','char c = \'A\' -- A "char" occupies just 1 byte (8 bits). Characters are stored as numbers using the ASCII code. The letter A is 65 in decimal, or 0x41 in hex.'],
37
+
},
38
+
{
39
+
action: 'init',
40
+
log: ['info','The sizeof operator tells you how many bytes a type uses: sizeof(int) is 4, sizeof(char) is 1. Other common types: short (2 bytes), long (4-8 bytes), double (8 bytes).'],
41
+
},
42
+
{
43
+
action: 'done',
44
+
log: ['success','Variables in C map directly to bytes in memory. There is no hidden layer of abstraction. Understanding this is the foundation of everything that follows -- exploits work because attackers can read and manipulate these raw bytes.'],
45
+
},
46
+
],
47
+
check(){returnfalse;},
48
+
winTitle: 'Variables & Memory!',
49
+
winMsg: 'You learned how C stores data as raw bytes in memory.',
desc: '<b>Goal:</b> Learn what pointers are -- they are just numbers that hold memory addresses.',
8
+
source: {
9
+
c: [
10
+
{text: '#include <stdio.h>',cls: ''},
11
+
{text: '',cls: ''},
12
+
{text: 'int main() {',cls: ''},
13
+
{text: ' int x = 10;',cls: 'highlight'},
14
+
{text: ' int *p = &x;',cls: 'highlight'},
15
+
{text: ' printf("x = %d\\n", x);',cls: ''},
16
+
{text: ' *p = 20;',cls: 'highlight'},
17
+
{text: ' printf("x = %d\\n", x);',cls: ''},
18
+
{text: ' return 0;',cls: ''},
19
+
{text: '}',cls: ''},
20
+
],
21
+
},
22
+
mode: 'step',
23
+
vizMode: 'stack',
24
+
bufSize: 16,
25
+
steps: [
26
+
{
27
+
action: 'init',
28
+
srcLine: 3,
29
+
log: ['info','First we create an integer variable x with the value 10. It lives at some address in memory -- let\'s say address 0xBFFF0010. The 4 bytes at that address hold the value 10.'],
30
+
},
31
+
{
32
+
action: 'init',
33
+
srcLine: 4,
34
+
log: ['info','int *p = &x -- The & operator ("address-of") gives us the memory address where x lives. The variable p is a "pointer" -- it stores that address (0xBFFF0010). A pointer is just a number that happens to be an address.'],
35
+
},
36
+
{
37
+
action: 'init',
38
+
log: ['info','A pointer itself takes up 4 bytes on a 32-bit system (or 8 bytes on 64-bit). It holds the address of another variable. Think of it as a slip of paper with a house number written on it.'],
39
+
},
40
+
{
41
+
action: 'init',
42
+
srcLine: 6,
43
+
log: ['info','*p = 20 -- The * operator ("dereference") follows the address stored in p and modifies the value at that location. Since p points to x, this changes x from 10 to 20.'],
44
+
},
45
+
{
46
+
action: 'init',
47
+
log: ['warn','Here is the key insight: modifying *p and modifying x are the same operation. Both change the exact same bytes in memory. The pointer just gives us another way to reach them.'],
48
+
},
49
+
{
50
+
action: 'done',
51
+
log: ['success','Pointers are central to C -- and central to exploitation. If an attacker can control a pointer, they can read or write anywhere in memory. That ability to reach arbitrary addresses is what makes many attacks possible.'],
52
+
},
53
+
],
54
+
check(){returnfalse;},
55
+
winTitle: 'Pointers Demystified!',
56
+
winMsg: 'You learned that pointers are just addresses stored as numbers.',
{text: ' name[10] = \'!!\'; // out of bounds!',cls: 'highlight vuln'},
21
+
{text: ' return 0;',cls: ''},
22
+
{text: '}',cls: ''},
23
+
],
24
+
},
25
+
mode: 'step',
26
+
vizMode: 'stack',
27
+
bufSize: 32,
28
+
steps: [
29
+
{
30
+
action: 'init',
31
+
srcLine: 4,
32
+
log: ['info','char name[8] declares an array of 8 bytes. The string "Alice" fills the first 5 bytes with the ASCII values for A, l, i, c, e. The 6th byte is automatically set to 0x00 -- the "null terminator" -- which marks the end of the string.'],
33
+
},
34
+
{
35
+
action: 'init',
36
+
srcLine: 5,
37
+
log: ['info','char buf[8] creates another 8-byte block right next to name in memory. Arrays in C are laid out contiguously -- each element sits right after the previous one, with no gaps or fences between different arrays.'],
38
+
},
39
+
{
40
+
action: 'init',
41
+
log: ['info','The null terminator (0x00) is how C knows where a string ends. Functions like printf and strlen scan forward byte by byte until they hit 0x00. If that byte is missing or overwritten, the function will keep reading into whatever memory comes next.'],
42
+
},
43
+
{
44
+
action: 'init',
45
+
srcLine: 9,
46
+
log: ['info','name[7] = \'Z\' is fine -- index 7 is the last valid position in an 8-element array (indices 0 through 7). This writes one byte within bounds.'],
47
+
},
48
+
{
49
+
action: 'init',
50
+
srcLine: 10,
51
+
log: ['warn','name[10] = \'!\' is OUT OF BOUNDS. Index 10 is past the end of the 8-byte array. But C does not check! It happily writes to whatever memory is 10 bytes past the start of name. This could overwrite data belonging to buf or other variables.'],
52
+
},
53
+
{
54
+
action: 'done',
55
+
log: ['success','C arrays have no bounds checking. Writing past the end of an array overwrites whatever happens to be next in memory. This is the fundamental reason buffer overflows exist -- and it is exactly what attackers exploit.'],
56
+
},
57
+
],
58
+
check(){returnfalse;},
59
+
winTitle: 'Arrays & Strings!',
60
+
winMsg: 'You learned how C arrays work and why they are vulnerable to out-of-bounds access.',
0 commit comments