WEBVTT

1
00:00:00.080 --> 00:00:01.960
<v Speaker 1>Welcome back listener. Today we're going to be taking a

2
00:00:02.000 --> 00:00:06.440
<v Speaker 1>deep dive into into the world beneath the surface of

3
00:00:06.599 --> 00:00:10.240
<v Speaker 1>CC plus plus programs. Yeah, have you ever wondered what's

4
00:00:10.439 --> 00:00:12.199
<v Speaker 1>really going on when your code runs?

5
00:00:12.599 --> 00:00:15.359
<v Speaker 2>It's a great question. We're talking beyond the you know,

6
00:00:15.480 --> 00:00:18.600
<v Speaker 2>the the elegant syntax and the results you see on screen,

7
00:00:18.960 --> 00:00:23.519
<v Speaker 2>right down to the bare metal of how computers actually think. Yeah,

8
00:00:23.600 --> 00:00:25.879
<v Speaker 2>kind of like cracking open the hood of a high

9
00:00:25.920 --> 00:00:29.600
<v Speaker 2>performance engine, but except instead of pistons and gears, we're

10
00:00:29.600 --> 00:00:31.160
<v Speaker 2>going to be looking at bits and bytes and the

11
00:00:31.199 --> 00:00:35.000
<v Speaker 2>fascinating logic of assembly code exactly. And our guidebook for

12
00:00:35.039 --> 00:00:40.200
<v Speaker 2>this adventure is Dmitri Vostakov's Foundations of Linux, Debugging, disassembling,

13
00:00:40.320 --> 00:00:40.960
<v Speaker 2>and reversing.

14
00:00:42.200 --> 00:00:44.640
<v Speaker 1>And why should you care about this? Well, Understanding how

15
00:00:44.679 --> 00:00:47.079
<v Speaker 1>your code interacts with the hardware can help you write

16
00:00:47.079 --> 00:00:51.079
<v Speaker 1>more efficient programs, debug those tricky issues right, and even

17
00:00:51.079 --> 00:00:54.840
<v Speaker 1>give you like a new appreciation for the elegance of

18
00:00:54.880 --> 00:00:55.560
<v Speaker 1>software design.

19
00:00:55.759 --> 00:00:59.840
<v Speaker 2>It's really about gaining a deeper understanding of the tools

20
00:00:59.880 --> 00:01:02.759
<v Speaker 2>that you use every single day. Yeah, So imagine being

21
00:01:02.759 --> 00:01:06.319
<v Speaker 2>a carpenter who only knows how to use power tools. Okay, yeah,

22
00:01:06.359 --> 00:01:09.400
<v Speaker 2>but understanding the hand tools underneath gives you more control,

23
00:01:09.599 --> 00:01:12.840
<v Speaker 2>more precision, a deeper understanding of your craft.

24
00:01:12.959 --> 00:01:16.599
<v Speaker 1>That's a great analogy. Okay, so let's unpack this. The

25
00:01:16.719 --> 00:01:20.640
<v Speaker 1>book starts with kind of a simplified model of a computer, yes,

26
00:01:20.719 --> 00:01:23.400
<v Speaker 1>almost like a blueprint, and it uses this analogy of

27
00:01:23.439 --> 00:01:27.159
<v Speaker 1>a city, uh huh, with buildings representing memory cells exactly.

28
00:01:27.200 --> 00:01:30.000
<v Speaker 2>Each building or memory cell has a unique address, like

29
00:01:30.040 --> 00:01:34.159
<v Speaker 2>a street number, and these cells hold the data, the

30
00:01:34.280 --> 00:01:37.519
<v Speaker 2>raw numbers that your program works with. But imagine if

31
00:01:37.560 --> 00:01:40.120
<v Speaker 2>every time your program needed data it had to drive

32
00:01:40.159 --> 00:01:43.120
<v Speaker 2>across town to fetch it right from these buildings. It

33
00:01:43.159 --> 00:01:44.560
<v Speaker 2>would be incredibly inefficient.

34
00:01:44.640 --> 00:01:46.680
<v Speaker 1>Yeah. That's where registers come in, right. They're like having

35
00:01:46.680 --> 00:01:49.680
<v Speaker 1>a little backpack, yeah, to carry you the most frequently

36
00:01:49.799 --> 00:01:51.159
<v Speaker 1>used data precisely.

37
00:01:51.439 --> 00:01:56.640
<v Speaker 2>Registers are small, super fast storage locations right on the CPU, okay,

38
00:01:56.680 --> 00:02:00.200
<v Speaker 2>instead of driving across town for every little errand you

39
00:02:00.280 --> 00:02:03.280
<v Speaker 2>keep your most essential items like your wallet and keys

40
00:02:03.439 --> 00:02:04.640
<v Speaker 2>close at hand, so.

41
00:02:04.680 --> 00:02:08.159
<v Speaker 1>In like a real sixty four bit PC, these backpacks

42
00:02:08.319 --> 00:02:13.560
<v Speaker 1>are registers like RAX yes, and it's smaller counterpart, EAX.

43
00:02:13.319 --> 00:02:17.240
<v Speaker 2>Yes, and each register has its own specific purpose. Think

44
00:02:17.319 --> 00:02:20.520
<v Speaker 2>of RAX as kind of your main workhourse capable of

45
00:02:20.560 --> 00:02:23.560
<v Speaker 2>handling a variety of operations. We'll see how it's used

46
00:02:23.560 --> 00:02:24.800
<v Speaker 2>in our example a little bit later.

47
00:02:24.960 --> 00:02:27.080
<v Speaker 1>Now I'm curious to see this all in action. The

48
00:02:27.120 --> 00:02:30.639
<v Speaker 1>book walks through a simple program that adds two numbers yes,

49
00:02:31.000 --> 00:02:33.919
<v Speaker 1>and it really breaks down how that interplay of memory

50
00:02:34.080 --> 00:02:36.960
<v Speaker 1>registers and assembly instructions makes it happen.

51
00:02:37.080 --> 00:02:39.319
<v Speaker 2>It's a great illustration. So let's say we have two

52
00:02:39.360 --> 00:02:43.759
<v Speaker 2>memory locations labeled A and B, each containing the number one.

53
00:02:44.120 --> 00:02:47.199
<v Speaker 2>The program first needs to load these values into registers

54
00:02:47.199 --> 00:02:49.000
<v Speaker 2>to work with them. It's kind of like bringing the

55
00:02:49.120 --> 00:02:53.599
<v Speaker 2>ingredients from the pantry with the countertop before you start cooking.

56
00:02:53.879 --> 00:02:56.520
<v Speaker 1>So we'd use instructions to move the value of A

57
00:02:57.080 --> 00:03:01.159
<v Speaker 1>into eax, yes, and the value of B into another register,

58
00:03:01.319 --> 00:03:02.960
<v Speaker 1>maybe edX exactly.

59
00:03:03.319 --> 00:03:06.520
<v Speaker 2>Now the magic happens. Okay, an assembly instruction called AD

60
00:03:06.840 --> 00:03:10.159
<v Speaker 2>comes into play. Okay, this instruction adds the value in

61
00:03:10.360 --> 00:03:13.599
<v Speaker 2>edX to the value in EAX, storing the result back

62
00:03:13.639 --> 00:03:16.479
<v Speaker 2>in EAX. It's like combining the contents of our containers.

63
00:03:16.719 --> 00:03:20.080
<v Speaker 1>So now EAX holds the sum which is two. But

64
00:03:20.080 --> 00:03:22.000
<v Speaker 1>we're not done yet, right, we need to store that

65
00:03:22.039 --> 00:03:23.240
<v Speaker 1>result back into memory.

66
00:03:23.319 --> 00:03:26.919
<v Speaker 2>The program uses another instruction to move the value from

67
00:03:26.960 --> 00:03:31.080
<v Speaker 2>eax back into memory, updating the value of b to two. Gotcha,

68
00:03:31.520 --> 00:03:34.879
<v Speaker 2>And that, in essence is how a computer executes. Wow,

69
00:03:34.919 --> 00:03:39.960
<v Speaker 2>even the simplest arithmetic operation, fetching the values, performing the calculation,

70
00:03:40.199 --> 00:03:41.400
<v Speaker 2>and storing the result.

71
00:03:41.560 --> 00:03:43.599
<v Speaker 1>It's amazing how much is happening under the hood for

72
00:03:43.599 --> 00:03:44.520
<v Speaker 1>such a basic task.

73
00:03:44.639 --> 00:03:45.360
<v Speaker 2>Yeah, it is.

74
00:03:45.599 --> 00:03:47.520
<v Speaker 1>But things get even more interesting when we start talking

75
00:03:47.560 --> 00:03:51.560
<v Speaker 1>about code optimization. The book shows how the compiler can

76
00:03:51.599 --> 00:03:56.240
<v Speaker 1>be surprisingly clever, sometimes taking shortcuts that produce drastically different

77
00:03:56.240 --> 00:03:58.199
<v Speaker 1>assembly code for the same outcome.

78
00:03:58.400 --> 00:04:01.280
<v Speaker 2>Compilers are like master chefs who can find the most

79
00:04:01.280 --> 00:04:04.080
<v Speaker 2>efficient way to prepare a dish. Let's say the compiler

80
00:04:04.120 --> 00:04:06.360
<v Speaker 2>knows the values of A and B at compile time,

81
00:04:06.520 --> 00:04:10.000
<v Speaker 2>even before the program runs. It can simply calculate the

82
00:04:10.000 --> 00:04:13.360
<v Speaker 2>sum directly and store the final result, skipping all of

83
00:04:13.360 --> 00:04:16.279
<v Speaker 2>those steps of moving values between memory and registers.

84
00:04:16.639 --> 00:04:19.480
<v Speaker 1>So the optimized code might be just a single instruction

85
00:04:19.879 --> 00:04:23.160
<v Speaker 1>that assigns the value too. To be directly exactly, It's

86
00:04:23.199 --> 00:04:25.759
<v Speaker 1>like the compiler did the addition for us before the

87
00:04:25.800 --> 00:04:27.160
<v Speaker 1>program even started running.

88
00:04:27.279 --> 00:04:30.600
<v Speaker 2>That's right, and that's why understanding assembly can be so valuable.

89
00:04:30.680 --> 00:04:33.720
<v Speaker 2>It gives you insight into the compiler's decision making process.

90
00:04:34.240 --> 00:04:36.480
<v Speaker 2>It can help you write more efficient code yourself.

91
00:04:36.759 --> 00:04:40.279
<v Speaker 1>This whole idea of efficiency reminds me of another crucial concept,

92
00:04:40.680 --> 00:04:45.120
<v Speaker 1>the way computers represent numbers using binary and hexadecimal. I

93
00:04:45.120 --> 00:04:47.199
<v Speaker 1>remember finding this a bit intimidating it first.

94
00:04:47.319 --> 00:04:50.439
<v Speaker 2>They can seem cryptic, but they're just different ways of

95
00:04:50.480 --> 00:04:54.759
<v Speaker 2>expressing the same information. Okay, Binary uses only two symbols

96
00:04:55.000 --> 00:04:57.360
<v Speaker 2>zero in one, like a light switch that can be

97
00:04:57.399 --> 00:05:00.519
<v Speaker 2>either on or off R. Hexodesimal, on the other hand,

98
00:05:00.639 --> 00:05:03.879
<v Speaker 2>uses sixteen symbols, making it a more compact way to

99
00:05:03.920 --> 00:05:05.160
<v Speaker 2>represent larger numbers.

100
00:05:05.399 --> 00:05:08.560
<v Speaker 1>So why is hexadesimal so important in this world of debugging.

101
00:05:09.199 --> 00:05:11.600
<v Speaker 1>It seems like we're constantly looking at memory addresses and

102
00:05:11.639 --> 00:05:13.240
<v Speaker 1>instructions represented in hes.

103
00:05:13.399 --> 00:05:16.079
<v Speaker 2>Imagine trying to debug a program by staring at a

104
00:05:16.160 --> 00:05:19.399
<v Speaker 2>giant wall of zeros and ones. Hexadesimal makes things more

105
00:05:19.439 --> 00:05:23.560
<v Speaker 2>manageable by grouping those bits into chunks, each represented by

106
00:05:23.560 --> 00:05:27.839
<v Speaker 2>a single hexodesimal symbol. It's like breaking that wall into

107
00:05:27.879 --> 00:05:29.360
<v Speaker 2>smaller and more readable sections.

108
00:05:29.399 --> 00:05:31.839
<v Speaker 1>It's all about making the information more digestible for us

109
00:05:31.920 --> 00:05:35.680
<v Speaker 1>humans exactly right now, I know we can't avoid talking

110
00:05:35.720 --> 00:05:40.160
<v Speaker 1>about one of the most powerful and sometimes misunderstood features

111
00:05:40.199 --> 00:05:42.360
<v Speaker 1>of CC plus plus. Pointers.

112
00:05:42.519 --> 00:05:45.560
<v Speaker 2>Pointers are the key yes to unlocking the true power

113
00:05:46.040 --> 00:05:50.920
<v Speaker 2>and potential pitfalls of these languages. But to understand pointers,

114
00:05:50.920 --> 00:05:52.639
<v Speaker 2>we need to go back to our city analogy.

115
00:05:53.000 --> 00:05:55.879
<v Speaker 1>All right, let's go back to our city. How do

116
00:05:56.000 --> 00:05:57.439
<v Speaker 1>pointers fit into this picture?

117
00:05:57.800 --> 00:06:00.879
<v Speaker 2>We'll imagine instead of carrying around bulky packages of data,

118
00:06:01.040 --> 00:06:03.680
<v Speaker 2>you could simply share their locations. Okay, that's what a

119
00:06:03.720 --> 00:06:06.399
<v Speaker 2>pointer does. It holds the address of a memory location,

120
00:06:06.920 --> 00:06:09.680
<v Speaker 2>like a street address in our city. Instead of copying

121
00:06:09.720 --> 00:06:12.000
<v Speaker 2>an entire file, you can just use a pointer to

122
00:06:12.000 --> 00:06:13.519
<v Speaker 2>tell the program where to find it.

123
00:06:13.600 --> 00:06:15.360
<v Speaker 1>So a pointer is like a map that tells us

124
00:06:15.399 --> 00:06:18.120
<v Speaker 1>where to find the actual data. That makes sense, But

125
00:06:18.160 --> 00:06:22.720
<v Speaker 1>I also hear horror stories about pointers causing programs to

126
00:06:22.759 --> 00:06:25.720
<v Speaker 1>crash and burn. What's the deal with that?

127
00:06:25.959 --> 00:06:28.680
<v Speaker 2>Pointers are powerful, Yeah, but they can be dangerous if

128
00:06:28.680 --> 00:06:31.279
<v Speaker 2>they're misused. Right, If you have the wrong address, you'll

129
00:06:31.360 --> 00:06:34.920
<v Speaker 2>end up at the wrong place, maybe somewhere you shouldn't be. Similarly,

130
00:06:35.360 --> 00:06:38.680
<v Speaker 2>an invalid pointer, one that points to a protected or

131
00:06:38.759 --> 00:06:42.519
<v Speaker 2>non existent memory location, can cause your program to crash.

132
00:06:42.639 --> 00:06:44.439
<v Speaker 1>It sounds like we need to tread carefully in this

133
00:06:44.519 --> 00:06:47.959
<v Speaker 1>world of pointers. Yes, they're like a double edged sword exactly.

134
00:06:48.680 --> 00:06:52.720
<v Speaker 1>The book also mentions different types of addressing, like white word,

135
00:06:52.879 --> 00:06:55.759
<v Speaker 1>double word, and quad word. And there are these suffixes

136
00:06:55.959 --> 00:07:00.279
<v Speaker 1>used in assembly code b wl and Q. That's all

137
00:07:00.319 --> 00:07:01.120
<v Speaker 1>that about.

138
00:07:01.279 --> 00:07:03.360
<v Speaker 2>Those refer to the size of the data that we're

139
00:07:03.360 --> 00:07:06.639
<v Speaker 2>working with. Think back to our city analogy. A byte

140
00:07:07.040 --> 00:07:10.160
<v Speaker 2>is the smallest unit, like a single apartment. A quadword

141
00:07:10.240 --> 00:07:14.639
<v Speaker 2>is the largest, like a massive skyscraper. Those suffixes in

142
00:07:14.720 --> 00:07:18.120
<v Speaker 2>assembly code tell the computer how much data to load, store,

143
00:07:18.279 --> 00:07:19.560
<v Speaker 2>or manipulate at a time.

144
00:07:19.839 --> 00:07:23.040
<v Speaker 1>So move would move a single bite, while mufkq would

145
00:07:23.040 --> 00:07:25.959
<v Speaker 1>move a whole quadward. It's like specifying whether we're moving

146
00:07:26.000 --> 00:07:28.199
<v Speaker 1>a single box or an entire truckload of stuff.

147
00:07:28.240 --> 00:07:31.399
<v Speaker 2>Precisely and using the correct addressing mode is crucial for

148
00:07:31.439 --> 00:07:34.879
<v Speaker 2>avoiding errors. Imagine trying to cram the contents of a

149
00:07:34.920 --> 00:07:38.360
<v Speaker 2>skyscraper into a tiny apartment. It just wouldn't work.

150
00:07:38.639 --> 00:07:42.680
<v Speaker 1>Now, to really see how pointers work in practice, let's

151
00:07:42.680 --> 00:07:45.120
<v Speaker 1>look at a slightly more complex example from the book.

152
00:07:45.160 --> 00:07:49.279
<v Speaker 2>This program actually manipulates memory using poinkers okay, and the

153
00:07:49.279 --> 00:07:52.600
<v Speaker 2>book uses GDB. The doughbugger to show us exactly how

154
00:07:52.600 --> 00:07:56.000
<v Speaker 2>the memory layout changes step by step. It's like watching

155
00:07:56.000 --> 00:07:57.800
<v Speaker 2>a slow motion replay of the action.

156
00:07:58.079 --> 00:08:00.759
<v Speaker 1>This is getting exciting. Before before we dive into that,

157
00:08:00.879 --> 00:08:03.399
<v Speaker 1>let's take a quick break to let all this information

158
00:08:03.480 --> 00:08:06.240
<v Speaker 1>sync in. When we come back, we'll explore this example

159
00:08:06.279 --> 00:08:09.439
<v Speaker 1>in detail and see the power of pointers in action.

160
00:08:10.199 --> 00:08:14.600
<v Speaker 1>Stay tuned, Welcome back. Now let's get our hands dirty

161
00:08:14.639 --> 00:08:16.959
<v Speaker 1>with this pointer example. Okay, the book sets up a

162
00:08:17.000 --> 00:08:19.519
<v Speaker 1>program that assigns the address of a variable let's call

163
00:08:19.560 --> 00:08:22.079
<v Speaker 1>it A, to a pointer called PAW. Then he uses

164
00:08:22.120 --> 00:08:24.759
<v Speaker 1>PAW to store the value one at the memory location

165
00:08:24.879 --> 00:08:25.720
<v Speaker 1>pointed two by PA.

166
00:08:26.079 --> 00:08:29.160
<v Speaker 2>It's like we're creating a treasure map okay, where PA

167
00:08:29.399 --> 00:08:32.000
<v Speaker 2>holds the coordinates to the treasure chest, which is the

168
00:08:32.039 --> 00:08:34.879
<v Speaker 2>memory location of A, and then we use that map

169
00:08:34.960 --> 00:08:38.080
<v Speaker 2>to put a gold coin or value of one into

170
00:08:38.159 --> 00:08:38.639
<v Speaker 2>the jest.

171
00:08:39.000 --> 00:08:42.279
<v Speaker 1>So the assembly code first needs to figure out the

172
00:08:42.320 --> 00:08:46.559
<v Speaker 1>address of A and store it in PA. How does

173
00:08:46.600 --> 00:08:48.159
<v Speaker 1>that happen? At this low level?

174
00:08:48.679 --> 00:08:51.360
<v Speaker 2>That's where an instruction called LEE, which stands for a

175
00:08:51.360 --> 00:08:54.440
<v Speaker 2>load effective address comes in. It figures out the address

176
00:08:54.440 --> 00:08:56.679
<v Speaker 2>of A and puts it into a register. Let's say

177
00:08:56.919 --> 00:08:57.679
<v Speaker 2>our ax.

178
00:08:57.879 --> 00:08:58.240
<v Speaker 1>Okay.

179
00:08:58.360 --> 00:09:02.279
<v Speaker 2>Then another instruction move move copies that address from RAX

180
00:09:02.320 --> 00:09:04.480
<v Speaker 2>into the memory location of our pointer PAW.

181
00:09:05.120 --> 00:09:07.720
<v Speaker 1>Got it. So now PAW is holding the address of

182
00:09:07.840 --> 00:09:10.639
<v Speaker 1>A like our treasure map pointing to the right spot. Yes,

183
00:09:10.960 --> 00:09:13.000
<v Speaker 1>but how do we actually use PAW to change the

184
00:09:13.039 --> 00:09:15.960
<v Speaker 1>value of A right? It seems indirect.

185
00:09:15.480 --> 00:09:17.799
<v Speaker 2>That's the beauty of pointers. We can use PAW to

186
00:09:17.879 --> 00:09:20.879
<v Speaker 2>indirectly access and modify the value at the memory location

187
00:09:20.960 --> 00:09:21.519
<v Speaker 2>it points to.

188
00:09:21.679 --> 00:09:21.960
<v Speaker 1>Okay.

189
00:09:22.039 --> 00:09:25.000
<v Speaker 2>The assembly code would use another move instruction, but this

190
00:09:25.080 --> 00:09:28.360
<v Speaker 2>time it uses RAX, which holds the address stored in PAW,

191
00:09:28.799 --> 00:09:30.679
<v Speaker 2>to figure out where to put the new value.

192
00:09:30.879 --> 00:09:34.440
<v Speaker 1>So we're essentially using RAX as a temporary go between

193
00:09:34.840 --> 00:09:38.320
<v Speaker 1>holding the address from PAW while the move instruction puts

194
00:09:38.320 --> 00:09:41.000
<v Speaker 1>the value one into the correct memory spot.

195
00:09:40.720 --> 00:09:42.799
<v Speaker 2>Which is where A lives precisely.

196
00:09:43.000 --> 00:09:43.360
<v Speaker 1>Okay.

197
00:09:43.759 --> 00:09:47.159
<v Speaker 2>This indirect access is what makes pointers so versatile. You

198
00:09:47.159 --> 00:09:49.559
<v Speaker 2>can change the value of PAW to point to a

199
00:09:49.559 --> 00:09:53.440
<v Speaker 2>different memory location, and suddenly you're manipulating a different variable

200
00:09:53.440 --> 00:09:55.039
<v Speaker 2>altogether just by changing the map.

201
00:09:55.519 --> 00:09:58.799
<v Speaker 1>That's incredibly powerful, But as we talked about before, it

202
00:09:58.840 --> 00:10:02.639
<v Speaker 1>also comes with risks. What happens if our treasure map

203
00:10:02.720 --> 00:10:06.000
<v Speaker 1>our pointer is wrong or worse, what if it points

204
00:10:06.039 --> 00:10:06.960
<v Speaker 1>to nowhere at all.

205
00:10:07.080 --> 00:10:10.799
<v Speaker 2>That's when we run into the dreaded segmentation faults and

206
00:10:10.840 --> 00:10:14.559
<v Speaker 2>program crashes. If we try to use a NL pointer

207
00:10:14.879 --> 00:10:17.720
<v Speaker 2>which essentially points to nothing, or an invalid pointer that

208
00:10:17.720 --> 00:10:20.720
<v Speaker 2>points to a protected area of memory, the operating system

209
00:10:20.720 --> 00:10:22.759
<v Speaker 2>steps in and says, Nope, not allowed.

210
00:10:22.840 --> 00:10:24.480
<v Speaker 1>It's like trying to dig for treasure in the middle

211
00:10:24.480 --> 00:10:28.919
<v Speaker 1>of a busy street. You're bound to hit something important cause.

212
00:10:28.799 --> 00:10:32.720
<v Speaker 2>Chaos, exactly, And that's why understanding how pointers work and

213
00:10:32.799 --> 00:10:36.480
<v Speaker 2>using them carefully is crucial. They can unlock tremendous power

214
00:10:36.519 --> 00:10:40.440
<v Speaker 2>and efficiency, but require a deep respect for their potential consequences.

215
00:10:41.159 --> 00:10:44.519
<v Speaker 1>Speaking of understanding how things work, let's shift gears a

216
00:10:44.519 --> 00:10:48.279
<v Speaker 1>bit and talk about reverse engineering. Okay, the book dedicates

217
00:10:48.279 --> 00:10:51.960
<v Speaker 1>a significant section to this, and I must admit it

218
00:10:52.039 --> 00:10:54.639
<v Speaker 1>feels a bit like stepping into the shoes of a detective.

219
00:10:55.320 --> 00:10:58.759
<v Speaker 2>Reverse engineering is like being handed a disassembled puzzle, a

220
00:10:58.879 --> 00:11:02.440
<v Speaker 2>jumbled mess of ambly instructions, and your task is to

221
00:11:02.480 --> 00:11:07.120
<v Speaker 2>figure out what the original picture the program's purpose looked like.

222
00:11:07.240 --> 00:11:09.960
<v Speaker 1>So we're not looking at nicely formatted CC plus plus

223
00:11:09.960 --> 00:11:12.879
<v Speaker 1>code anymore. No, we're scaring at the raw output the

224
00:11:12.919 --> 00:11:16.639
<v Speaker 1>compiler generates. Right where do you even begin to make

225
00:11:16.679 --> 00:11:17.200
<v Speaker 1>sense of that?

226
00:11:17.440 --> 00:11:20.600
<v Speaker 2>It's all about pattern recognition and connecting the dots. You

227
00:11:20.679 --> 00:11:24.000
<v Speaker 2>start by identifying familiar landmarks in the assembly code.

228
00:11:24.120 --> 00:11:24.519
<v Speaker 1>Okay.

229
00:11:24.559 --> 00:11:27.919
<v Speaker 2>For example, function prologs and epilogues, which mark the beginning

230
00:11:27.919 --> 00:11:30.919
<v Speaker 2>and end of a function, are like signposts telling you

231
00:11:30.919 --> 00:11:32.799
<v Speaker 2>where one function ends and another begins.

232
00:11:33.080 --> 00:11:36.720
<v Speaker 1>Wait back up a second, what exactly are these prologs

233
00:11:36.720 --> 00:11:37.799
<v Speaker 1>and epilogus you mentioned?

234
00:11:38.320 --> 00:11:41.399
<v Speaker 2>Think of them as the setup and cleanup crew for

235
00:11:41.480 --> 00:11:45.799
<v Speaker 2>a function. The prologue sets up the stack frame, reserving

236
00:11:45.840 --> 00:11:49.679
<v Speaker 2>space for local variables. Okay, well, the epilogue cleans up

237
00:11:49.679 --> 00:11:52.759
<v Speaker 2>the stack and restores the previous state. They ensure that

238
00:11:52.840 --> 00:11:56.279
<v Speaker 2>functions can operate in their own little sandboxes without interfering

239
00:11:56.320 --> 00:11:56.799
<v Speaker 2>with each other.

240
00:11:57.120 --> 00:11:59.960
<v Speaker 1>Ah. So they're like the stage hands setting up into

241
00:12:00.000 --> 00:12:02.799
<v Speaker 1>taking down the scenery for each act in a play. Yeah,

242
00:12:02.919 --> 00:12:06.360
<v Speaker 1>that makes sense, But how do we go from recognizing

243
00:12:06.399 --> 00:12:10.080
<v Speaker 1>these sign posts to actually understanding what the code is doing?

244
00:12:10.679 --> 00:12:14.279
<v Speaker 2>From there, you look for instructions that load and store values,

245
00:12:14.399 --> 00:12:17.440
<v Speaker 2>perform calculations, jump to different parts of the code, and

246
00:12:17.480 --> 00:12:20.720
<v Speaker 2>so on. Right, you gradually piece together the puzzle by

247
00:12:20.799 --> 00:12:24.080
<v Speaker 2>understanding the role of each instruction and how they fit together.

248
00:12:24.320 --> 00:12:26.919
<v Speaker 1>It sounds like you're tracing the flow of data through

249
00:12:26.919 --> 00:12:30.799
<v Speaker 1>the program, figuring out where it comes from, how it's manipulated,

250
00:12:30.840 --> 00:12:31.679
<v Speaker 1>and where it ends up.

251
00:12:31.720 --> 00:12:34.480
<v Speaker 2>Precisely, It's like following a trail of breadcrumbs, only in

252
00:12:34.480 --> 00:12:38.559
<v Speaker 2>this case, the bread crumbs are assembly instructions, and with practice,

253
00:12:38.639 --> 00:12:42.480
<v Speaker 2>you start to develop an intuition for how CC plus

254
00:12:42.519 --> 00:12:46.519
<v Speaker 2>constructs are translated into assembly language, making it easier to

255
00:12:46.559 --> 00:12:48.840
<v Speaker 2>reverse engineer even complex programs.

256
00:12:48.919 --> 00:12:51.960
<v Speaker 1>So by understanding assembly code, we can not only appreciate

257
00:12:52.039 --> 00:12:55.720
<v Speaker 1>how computers think, but also delve into the inner workings

258
00:12:55.759 --> 00:13:01.200
<v Speaker 1>of existing programs, potentially uncovering vulnerabilities or optimize performance. It's

259
00:13:01.240 --> 00:13:04.440
<v Speaker 1>like having a secret decoder ring for the digital world exactly.

260
00:13:04.679 --> 00:13:08.799
<v Speaker 2>Reverse engineering isn't just an academic exercise. It has practical

261
00:13:08.840 --> 00:13:14.000
<v Speaker 2>applications in security analysis, software development, and even understanding legacy

262
00:13:14.000 --> 00:13:18.240
<v Speaker 2>code that might lack proper documentation. It's a powerful skill

263
00:13:18.279 --> 00:13:21.039
<v Speaker 2>that opens up a whole new layer of understanding.

264
00:13:21.279 --> 00:13:23.840
<v Speaker 1>Now, as we delve deeper into this low level world,

265
00:13:23.879 --> 00:13:27.480
<v Speaker 1>we keep encountering this concept of the stack. The book

266
00:13:27.559 --> 00:13:30.200
<v Speaker 1>uses the analogy of a stack of plates and I'm

267
00:13:30.240 --> 00:13:32.639
<v Speaker 1>starting to grasp how it works. But why is this

268
00:13:32.759 --> 00:13:35.519
<v Speaker 1>stack structure so important in the grand scheme of things?

269
00:13:35.879 --> 00:13:39.919
<v Speaker 2>The stack is crucial for managing memory efficiently, especially when

270
00:13:39.960 --> 00:13:43.360
<v Speaker 2>dealing with function calls. Imagine you're hosting a dinner party

271
00:13:43.679 --> 00:13:47.000
<v Speaker 2>and each guest needs their own set of plates and cutlery.

272
00:13:47.399 --> 00:13:50.000
<v Speaker 1>Okay, I can picture that. Everyone gets their own space

273
00:13:50.080 --> 00:13:51.360
<v Speaker 1>on the table exactly.

274
00:13:51.559 --> 00:13:54.559
<v Speaker 2>In a computer program, each function gets its own section

275
00:13:54.600 --> 00:13:57.480
<v Speaker 2>of memory on the stack, called a stack frame. The

276
00:13:57.559 --> 00:14:01.279
<v Speaker 2>stack frame holds the function's local variables, parameters pass to

277
00:14:01.320 --> 00:14:03.240
<v Speaker 2>the function, and some bookkeeping information.

278
00:14:03.639 --> 00:14:07.080
<v Speaker 1>So it's like each guest having their own designated area

279
00:14:07.159 --> 00:14:08.840
<v Speaker 1>to keep their belongings organized.

280
00:14:09.080 --> 00:14:09.200
<v Speaker 2>Right.

281
00:14:09.399 --> 00:14:12.399
<v Speaker 1>But what happens if we invite too many guests, or

282
00:14:12.440 --> 00:14:15.600
<v Speaker 1>in our case, make too many function calls? What we

283
00:14:15.679 --> 00:14:18.720
<v Speaker 1>run out of table space or in this case, stack space.

284
00:14:18.919 --> 00:14:21.919
<v Speaker 2>That's a great analogy, and you're right. We can indeed

285
00:14:22.000 --> 00:14:24.600
<v Speaker 2>run out of stack space. It's called a stack overflow,

286
00:14:25.120 --> 00:14:27.840
<v Speaker 2>and it's a common programming error, especially when you have

287
00:14:27.879 --> 00:14:31.840
<v Speaker 2>functions calling themselves recursively, or when dealing with large data

288
00:14:31.840 --> 00:14:33.120
<v Speaker 2>structures on the stack.

289
00:14:33.240 --> 00:14:35.480
<v Speaker 1>It's like piling on more and more plates until the

290
00:14:35.480 --> 00:14:39.080
<v Speaker 1>whole stack topples over not a good scenario. So how

291
00:14:39.120 --> 00:14:41.840
<v Speaker 1>do we avoid these stack overflows in our programs?

292
00:14:42.240 --> 00:14:45.480
<v Speaker 2>Careful memory management is key. We need to be mindful

293
00:14:45.559 --> 00:14:48.000
<v Speaker 2>of how much data we're putting on the stack and

294
00:14:48.120 --> 00:14:51.639
<v Speaker 2>make sure functions clean up after themselves, removing their data

295
00:14:51.679 --> 00:14:54.759
<v Speaker 2>when they're done, just like responsible dinner guests clearing their

296
00:14:54.759 --> 00:14:55.360
<v Speaker 2>own plates.

297
00:14:55.480 --> 00:14:58.080
<v Speaker 1>That makes sense now. The book also mentions something called

298
00:14:58.080 --> 00:15:01.159
<v Speaker 1>the frame pointer. What role does this play in our

299
00:15:01.200 --> 00:15:02.720
<v Speaker 1>stack of plates analogy?

300
00:15:02.919 --> 00:15:05.200
<v Speaker 2>The frame pointer is like a place card that marks

301
00:15:05.240 --> 00:15:08.039
<v Speaker 2>the beginning of each guest space on the table. Okay,

302
00:15:08.240 --> 00:15:10.840
<v Speaker 2>it provides a stable reference point for the function to

303
00:15:10.879 --> 00:15:14.399
<v Speaker 2>find its local variables and parameters, even as the stack

304
00:15:14.480 --> 00:15:16.960
<v Speaker 2>grows and shrinks with each function call in return.

305
00:15:17.159 --> 00:15:19.799
<v Speaker 1>Ah, so it's like having a map of the table

306
00:15:20.080 --> 00:15:23.639
<v Speaker 1>so that each guest can easily find their belongings. Yeah,

307
00:15:23.759 --> 00:15:26.159
<v Speaker 1>this is getting quite technical, but I'm really starting to

308
00:15:26.200 --> 00:15:30.759
<v Speaker 1>appreciate the intricate mechanisms at play behind the scenes of

309
00:15:30.799 --> 00:15:31.759
<v Speaker 1>a running program.

310
00:15:31.919 --> 00:15:34.639
<v Speaker 2>It is fascinating, isn't it. And there's still more to explore.

311
00:15:34.639 --> 00:15:38.879
<v Speaker 2>We haven't even touched upon the CPU flags register, which

312
00:15:38.919 --> 00:15:41.559
<v Speaker 2>acts like a hidden dashboard revealing the state of the

313
00:15:41.600 --> 00:15:43.240
<v Speaker 2>processor after each operation.

314
00:15:43.679 --> 00:15:50.519
<v Speaker 1>Okay, now you've peaked my curiosity. CPU flags register sounds

315
00:15:50.559 --> 00:15:52.960
<v Speaker 1>like something out of a spy movie. What secrets does

316
00:15:53.000 --> 00:15:53.360
<v Speaker 1>it hold?

317
00:15:54.039 --> 00:15:56.120
<v Speaker 2>Well? For that, we'll need to continue our deep dive

318
00:15:56.120 --> 00:15:57.799
<v Speaker 2>in the next part. Stay tuned.

319
00:15:58.320 --> 00:16:00.600
<v Speaker 1>Welcome back to the final part of our deep dive.

320
00:16:01.200 --> 00:16:05.080
<v Speaker 1>We've journeyed through memory and registers and pointers, and even

321
00:16:05.240 --> 00:16:07.279
<v Speaker 1>dabbled in the art of reverse engineering.

322
00:16:07.440 --> 00:16:08.759
<v Speaker 2>Yeah, it's been quite a journey.

323
00:16:08.879 --> 00:16:12.039
<v Speaker 1>Now it's time to unveil the secrets of this CPU

324
00:16:12.080 --> 00:16:16.559
<v Speaker 1>flags register right, and uncover how function parameters work at

325
00:16:16.559 --> 00:16:17.799
<v Speaker 1>this granular level.

326
00:16:17.960 --> 00:16:21.399
<v Speaker 2>Let's start with function parameters. They're like the specialized tools

327
00:16:21.399 --> 00:16:23.720
<v Speaker 2>a function needs to do its job. So when you

328
00:16:23.759 --> 00:16:26.799
<v Speaker 2>call a function, you're essentially handing it these tools, these

329
00:16:26.799 --> 00:16:29.679
<v Speaker 2>pieces of data, so it can perform that specific task.

330
00:16:29.879 --> 00:16:32.080
<v Speaker 1>So, if we call a function to calculate the area

331
00:16:32.080 --> 00:16:35.080
<v Speaker 1>of a rectangle, we'd pass at the lengthen with those parameters,

332
00:16:35.159 --> 00:16:38.039
<v Speaker 1>right exactly, But how does the function actually receive and

333
00:16:38.159 --> 00:16:40.480
<v Speaker 1>organize these parameters down at the assembly level.

334
00:16:40.759 --> 00:16:43.279
<v Speaker 2>Imagine you're a chef and someone hands you a basket

335
00:16:43.279 --> 00:16:47.279
<v Speaker 2>of ingredients. You wouldn't just start cooking without first organizing

336
00:16:47.279 --> 00:16:48.639
<v Speaker 2>those ingredients on your countertop.

337
00:16:48.720 --> 00:16:52.720
<v Speaker 1>Right, of course, not a well organized workspace is essential

338
00:16:52.840 --> 00:16:53.720
<v Speaker 1>for any chef.

339
00:16:54.080 --> 00:16:58.039
<v Speaker 2>Exactly, the stack, our trustee stack of plates acts like

340
00:16:58.080 --> 00:17:02.519
<v Speaker 2>that countertoption is called its parameters are carefully placed on

341
00:17:02.559 --> 00:17:06.440
<v Speaker 2>the stack in a specific order. This organized placement allows

342
00:17:06.480 --> 00:17:11.079
<v Speaker 2>the function to know precisely where to find each parameter.

343
00:17:10.960 --> 00:17:13.440
<v Speaker 1>So it's not just a random jumble of data on

344
00:17:13.480 --> 00:17:16.759
<v Speaker 1>the stack. There's a method to the madness, right, But

345
00:17:16.920 --> 00:17:20.279
<v Speaker 1>how does the function actually locate and access these neatly

346
00:17:20.400 --> 00:17:21.440
<v Speaker 1>arranged parameters.

347
00:17:21.759 --> 00:17:24.839
<v Speaker 2>Remember our trustee frame pointer are placecard that marks the

348
00:17:24.839 --> 00:17:27.720
<v Speaker 2>beginning of the function stack frame. Yes, well, the function

349
00:17:27.920 --> 00:17:30.720
<v Speaker 2>uses the frame pointer as a reference to calculate the

350
00:17:30.759 --> 00:17:34.480
<v Speaker 2>location of each parameter relative to its own stack frame.

351
00:17:34.880 --> 00:17:37.319
<v Speaker 1>It's like having a seating chart that tells each guest

352
00:17:37.359 --> 00:17:40.559
<v Speaker 1>each parameter exactly where their place is at the table. Yeah,

353
00:17:40.640 --> 00:17:43.759
<v Speaker 1>and this process happens seamlessly every time a function is called,

354
00:17:44.079 --> 00:17:46.799
<v Speaker 1>ensuring that everything is in its right place precisely.

355
00:17:47.319 --> 00:17:51.240
<v Speaker 2>And this mechanism is crucial for making programs modular and reusable.

356
00:17:51.599 --> 00:17:54.480
<v Speaker 2>We can call the same function with different parameters, just

357
00:17:54.519 --> 00:17:57.200
<v Speaker 2>like a chef can use the same recipe with different ingredients.

358
00:17:57.200 --> 00:17:58.519
<v Speaker 2>To create a variety of dishes.

359
00:17:58.640 --> 00:18:01.319
<v Speaker 1>Okay, that makes sense. Now let's move on to this

360
00:18:01.400 --> 00:18:05.400
<v Speaker 1>mysterious CPU flags register you mentioned earlier. What kind of

361
00:18:05.480 --> 00:18:07.039
<v Speaker 1>dashboard are we talking about here?

362
00:18:07.279 --> 00:18:10.640
<v Speaker 2>Imagine a control panel with a series of lights, each

363
00:18:10.680 --> 00:18:14.839
<v Speaker 2>representing a specific condition inside the CPU. Okay, These lights

364
00:18:14.960 --> 00:18:18.960
<v Speaker 2>or flags are individual bits within the CPU flags register,

365
00:18:19.440 --> 00:18:21.680
<v Speaker 2>and they get flipped on or off based on the

366
00:18:21.720 --> 00:18:23.359
<v Speaker 2>outcome of various operations.

367
00:18:23.880 --> 00:18:26.359
<v Speaker 1>So some flags might indicate whether the result of an

368
00:18:26.359 --> 00:18:30.680
<v Speaker 1>arithmetic operation was zero, negative, or caused and overflow. Its

369
00:18:30.759 --> 00:18:32.680
<v Speaker 1>like the CPU is sending us signals about what.

370
00:18:32.720 --> 00:18:35.920
<v Speaker 2>Just happened exactly. Other flags track things like whether a

371
00:18:35.960 --> 00:18:39.519
<v Speaker 2>comparison resulted in equality, or if a carry occurred during

372
00:18:39.559 --> 00:18:42.519
<v Speaker 2>an addition. It's a treasure trove of information about the

373
00:18:42.559 --> 00:18:44.000
<v Speaker 2>CPU's internal state.

374
00:18:44.279 --> 00:18:47.559
<v Speaker 1>But why should we as programmers care about these kind

375
00:18:47.599 --> 00:18:51.359
<v Speaker 1>of cryptic CPU signals? How do they actually impact our programs?

376
00:18:51.640 --> 00:18:55.000
<v Speaker 2>They play a crucial role in conditional branching, where the

377
00:18:55.039 --> 00:18:59.960
<v Speaker 2>program's flow can change based on certain conditions. Right For instance,

378
00:19:00.319 --> 00:19:03.319
<v Speaker 2>if a flag indicating a zero result to set, the

379
00:19:03.359 --> 00:19:06.880
<v Speaker 2>program might jump to a specific section of code. If

380
00:19:06.920 --> 00:19:10.119
<v Speaker 2>it's not set, it might take a different path I see.

381
00:19:10.519 --> 00:19:14.839
<v Speaker 1>So the CPU flags act like signposts, guiding the program's

382
00:19:14.880 --> 00:19:18.680
<v Speaker 1>execution based on the outcome of previous operations. Exactly, it's

383
00:19:18.680 --> 00:19:21.079
<v Speaker 1>like having to choose your own adventure story, where the

384
00:19:21.119 --> 00:19:23.359
<v Speaker 1>flags determine which page to turn to next.

385
00:19:23.559 --> 00:19:27.319
<v Speaker 2>Precisely, this ability to make decisions based on conditions gives

386
00:19:27.359 --> 00:19:31.200
<v Speaker 2>programs incredible flexibility and power to handle a wide range

387
00:19:31.200 --> 00:19:32.039
<v Speaker 2>of situations.

388
00:19:32.240 --> 00:19:35.240
<v Speaker 1>So understanding these flags can help us decipher the CPU's

389
00:19:35.240 --> 00:19:38.960
<v Speaker 1>internal logic and even anticipate how our programs will behave

390
00:19:39.079 --> 00:19:40.319
<v Speaker 1>under different circumstances.

391
00:19:40.359 --> 00:19:43.240
<v Speaker 2>Exactly, it's like learning the secret language of the processor,

392
00:19:43.759 --> 00:19:47.400
<v Speaker 2>allowing us to trace the execution flow and potentially even

393
00:19:47.400 --> 00:19:49.279
<v Speaker 2>optimize our code for better performance.

394
00:19:49.640 --> 00:19:52.519
<v Speaker 1>Wow, we've covered so much ground in this deep dive,

395
00:19:52.920 --> 00:19:56.519
<v Speaker 1>from memory layouts and registers to pointers in reverse engineering,

396
00:19:56.839 --> 00:20:00.240
<v Speaker 1>and even the CPU's internal flags. It feels like we've

397
00:20:00.279 --> 00:20:03.720
<v Speaker 1>peeled back the layers of this complex machine and glimpsed

398
00:20:03.759 --> 00:20:04.640
<v Speaker 1>its inner workings.

399
00:20:05.000 --> 00:20:06.920
<v Speaker 2>And while this might seem like a lot to absorb,

400
00:20:07.119 --> 00:20:10.000
<v Speaker 2>remember it's just the tip of the iceberg. The world

401
00:20:10.000 --> 00:20:13.720
<v Speaker 2>of programming is vast and ever evolving, but the fundamental

402
00:20:13.720 --> 00:20:16.400
<v Speaker 2>principles that we've explored here will serve you well as

403
00:20:16.400 --> 00:20:17.480
<v Speaker 2>you continue your journey.

404
00:20:17.599 --> 00:20:20.720
<v Speaker 1>Absolutely, this deep dive has given me a whole new

405
00:20:20.759 --> 00:20:23.960
<v Speaker 1>appreciation for the intricate dance of bits and bites and

406
00:20:24.000 --> 00:20:26.880
<v Speaker 1>instructions that make the magic of computing possible.

407
00:20:26.960 --> 00:20:29.400
<v Speaker 2>And who knows, maybe someday you'll be writing your own

408
00:20:29.400 --> 00:20:32.640
<v Speaker 2>assembly code, or even diving into the fascinating world of

409
00:20:32.680 --> 00:20:36.000
<v Speaker 2>low level security research. The possibilities are endless.

410
00:20:36.119 --> 00:20:38.839
<v Speaker 1>To our listener, we encourage you to keep exploring, keep

411
00:20:38.880 --> 00:20:42.160
<v Speaker 1>asking questions, and never stop learning. The deeper you dive,

412
00:20:42.240 --> 00:20:44.960
<v Speaker 1>the more you'll discover about the power and elegance of

413
00:20:45.000 --> 00:20:48.680
<v Speaker 1>the digital world. Until next time, happy coding.
