WEBVTT

1
00:00:00.040 --> 00:00:04.639
<v Speaker 1>All right, jumping right into this deep dive Windows kernel programming.

2
00:00:04.759 --> 00:00:09.119
<v Speaker 1>Oh yeah, you handed me some excerpts from Pavel Yosefovic's book,

3
00:00:10.080 --> 00:00:13.679
<v Speaker 1>and I gotta say, some of this stuff intense. Yeah,

4
00:00:13.720 --> 00:00:15.439
<v Speaker 1>it's intense. It's a little over my head. Yeh, that's

5
00:00:15.480 --> 00:00:18.559
<v Speaker 1>why you're here, thankfully. But I'm ready to learn, ready

6
00:00:18.600 --> 00:00:20.960
<v Speaker 1>to uncover the secrets of the kernel some most people

7
00:00:21.000 --> 00:00:22.800
<v Speaker 1>never even you know, think about.

8
00:00:23.120 --> 00:00:28.920
<v Speaker 2>Well, Yusefavich definitely doesn't shy away from the complexity of it.

9
00:00:29.079 --> 00:00:35.159
<v Speaker 2>We're talking processes, threads, virtual memory system calls, object managers, handles,

10
00:00:35.200 --> 00:00:38.759
<v Speaker 2>I mean, the whole nine yards, and even getting into

11
00:00:38.799 --> 00:00:41.679
<v Speaker 2>like setting up a kernel development environment, and you know,

12
00:00:41.719 --> 00:00:43.759
<v Speaker 2>the nuances of programming at the kernel level.

13
00:00:43.840 --> 00:00:46.200
<v Speaker 1>Yeah, I skim those sections, and let's just say, I'm

14
00:00:46.200 --> 00:00:49.079
<v Speaker 1>glad you're the one fluent in kernels. But before we

15
00:00:49.119 --> 00:00:51.000
<v Speaker 1>get too lost in the weeds, here something that caught

16
00:00:51.039 --> 00:00:55.479
<v Speaker 1>my eye. File system minifilters. Yeah, Yusefovich talks about them

17
00:00:55.479 --> 00:00:57.840
<v Speaker 1>like there's some kind of secret weapon for developers.

18
00:00:58.039 --> 00:01:01.200
<v Speaker 2>They kind of are. You know, it's amazing what you

19
00:01:01.200 --> 00:01:02.920
<v Speaker 2>can do with a minifilter. I mean, think about it

20
00:01:02.960 --> 00:01:05.920
<v Speaker 2>this way, like a minifilter can actually step in and

21
00:01:06.040 --> 00:01:09.560
<v Speaker 2>intercept filesystem operations, yeah, before they even get to the

22
00:01:09.560 --> 00:01:10.719
<v Speaker 2>file system itself.

23
00:01:10.799 --> 00:01:13.040
<v Speaker 1>So like, if I'm an anti virus program, I can

24
00:01:13.120 --> 00:01:15.480
<v Speaker 1>use a minifilter to scan a file before it even

25
00:01:15.480 --> 00:01:16.480
<v Speaker 1>gets written to the disc.

26
00:01:16.640 --> 00:01:20.000
<v Speaker 2>That's one example. Yeah, yeah, but it goes way beyond that, right, Like,

27
00:01:20.159 --> 00:01:22.359
<v Speaker 2>you can use it for everything from real time backups

28
00:01:22.680 --> 00:01:26.920
<v Speaker 2>to like really granular access control. Yasufovich even gives an

29
00:01:26.959 --> 00:01:30.079
<v Speaker 2>example of a minifilter that encrypts files on the fly,

30
00:01:30.719 --> 00:01:32.439
<v Speaker 2>completely transparent to the user.

31
00:01:32.799 --> 00:01:34.840
<v Speaker 1>Wow. Yeah, that's pretty mind blowing.

32
00:01:34.920 --> 00:01:35.280
<v Speaker 2>Yeah.

33
00:01:35.280 --> 00:01:37.439
<v Speaker 1>Okay, so before we get too far ahead of ourselves,

34
00:01:37.519 --> 00:01:40.439
<v Speaker 1>let's rewind a bit. Yu Seefavitch spends a good chunk

35
00:01:40.480 --> 00:01:44.079
<v Speaker 1>of the book talking about processes and threads, you know,

36
00:01:44.159 --> 00:01:46.480
<v Speaker 1>the building blocks of everything that happens in the kernel.

37
00:01:46.599 --> 00:01:48.280
<v Speaker 1>It's been a while since I've had to think about

38
00:01:48.280 --> 00:01:51.079
<v Speaker 1>that stuff. Remind me, why are they so important?

39
00:01:51.400 --> 00:01:54.519
<v Speaker 2>Well, think of a process like a container, right, Like

40
00:01:54.719 --> 00:01:57.599
<v Speaker 2>it's a little world into itself. It has its own

41
00:01:57.640 --> 00:02:00.760
<v Speaker 2>memory space, it has its own security set, it has

42
00:02:00.799 --> 00:02:03.599
<v Speaker 2>its own set of resources. And then the threads are

43
00:02:03.640 --> 00:02:06.519
<v Speaker 2>like the workers within that container that actually carry out

44
00:02:06.519 --> 00:02:07.200
<v Speaker 2>the instructions.

45
00:02:07.280 --> 00:02:11.680
<v Speaker 1>Okay, that makes sense. But Yusifavich mentioned something kind of interesting.

46
00:02:11.759 --> 00:02:15.960
<v Speaker 1>He says that a process without any threads is basically useless.

47
00:02:16.960 --> 00:02:18.759
<v Speaker 1>Why is that, Well.

48
00:02:18.560 --> 00:02:20.960
<v Speaker 2>It's like having you know, all the equipment in a factory,

49
00:02:21.000 --> 00:02:24.080
<v Speaker 2>but no workers to run the equipment. Right, Like, without threads,

50
00:02:24.120 --> 00:02:27.280
<v Speaker 2>a process can actually do anything. It's just taking up space.

51
00:02:27.800 --> 00:02:31.159
<v Speaker 2>So the kernel, being you know, the efficient manager it is,

52
00:02:31.439 --> 00:02:32.520
<v Speaker 2>it'll eventually destroy it.

53
00:02:32.919 --> 00:02:35.159
<v Speaker 1>Ah. So it's all about making sure resources are being

54
00:02:35.240 --> 00:02:35.960
<v Speaker 1>used effectively.

55
00:02:36.120 --> 00:02:36.840
<v Speaker 2>Yeah, okay.

56
00:02:37.280 --> 00:02:38.960
<v Speaker 1>Now another thing that always kind of trips me up

57
00:02:39.039 --> 00:02:41.919
<v Speaker 1>is virtual memory. You know, it's like this magical realm

58
00:02:41.960 --> 00:02:44.199
<v Speaker 1>where every process thinks it has all the memory in

59
00:02:44.240 --> 00:02:46.919
<v Speaker 1>the world, even if it's sharing a physical machine with

60
00:02:46.919 --> 00:02:49.240
<v Speaker 1>a bunch of other processes. How does that even work?

61
00:02:49.439 --> 00:02:53.280
<v Speaker 2>Well, Yussefhavich describes it as, you know, like each process

62
00:02:53.319 --> 00:02:56.680
<v Speaker 2>gets its own map to a vast territory, but only

63
00:02:56.719 --> 00:02:59.639
<v Speaker 2>the areas that they actually use get real Okay, Right.

64
00:02:59.840 --> 00:03:03.479
<v Speaker 2>The kernel is like the master cartographers, right, it's managing

65
00:03:03.479 --> 00:03:05.560
<v Speaker 2>all these maps making sure that they don't overlap.

66
00:03:05.719 --> 00:03:08.240
<v Speaker 1>Okay, that's a helpful way to think about it. So

67
00:03:08.319 --> 00:03:12.199
<v Speaker 1>the kernel is constantly juggling all these virtual maps, making

68
00:03:12.199 --> 00:03:15.120
<v Speaker 1>sure that each process has the illusion of its own

69
00:03:15.240 --> 00:03:19.759
<v Speaker 1>private memory space. But what happens when a process needs

70
00:03:19.800 --> 00:03:23.560
<v Speaker 1>to do something that requires like kernel privileges, you know,

71
00:03:23.639 --> 00:03:28.280
<v Speaker 1>like access hardware, modify systems settings. That's where system calls.

72
00:03:27.960 --> 00:03:30.479
<v Speaker 2>Come in, right, Yeah, exactly. So it's like needing to

73
00:03:30.520 --> 00:03:33.199
<v Speaker 2>go through customs, you know, to cross a border. Like

74
00:03:33.280 --> 00:03:36.080
<v Speaker 2>a process can't just waltz into kernel mode whenever it wants.

75
00:03:36.439 --> 00:03:39.439
<v Speaker 2>It needs to present the right credentials, follow the protocol.

76
00:03:39.360 --> 00:03:41.280
<v Speaker 1>And you see, Fitch gets into a really in depth

77
00:03:41.319 --> 00:03:43.280
<v Speaker 1>detail about how this works at like the low level.

78
00:03:43.360 --> 00:03:46.199
<v Speaker 1>He talks about system call numbers and the system service

79
00:03:46.240 --> 00:03:49.400
<v Speaker 1>dispatch table and all sorts of other kind of intricate mechanisms.

80
00:03:50.000 --> 00:03:53.240
<v Speaker 1>Is there anything in particular about system calls that stood

81
00:03:53.240 --> 00:03:55.800
<v Speaker 1>out to you, you know, anything that surprised you or

82
00:03:55.800 --> 00:03:57.479
<v Speaker 1>made you think differently about how they work?

83
00:03:57.840 --> 00:04:00.960
<v Speaker 2>You Know what really struck me is just the level

84
00:04:01.000 --> 00:04:03.759
<v Speaker 2>of indirection involved. Yeah, you know what I mean. Like,

85
00:04:03.759 --> 00:04:07.439
<v Speaker 2>it's not just a simple matter of a user mode

86
00:04:07.439 --> 00:04:11.120
<v Speaker 2>function calling a kernel mode function directly, right. There are

87
00:04:11.319 --> 00:04:14.840
<v Speaker 2>layers upon layers of abstraction, like checks and balances to

88
00:04:15.039 --> 00:04:16.920
<v Speaker 2>ensure security and stability.

89
00:04:17.000 --> 00:04:20.199
<v Speaker 1>So even something as seemingly straightforward as a system call

90
00:04:20.319 --> 00:04:23.839
<v Speaker 1>is actually this really intricate dance between user mode and

91
00:04:23.959 --> 00:04:27.720
<v Speaker 1>kernel mode. It's fascinating but also a little daunting, to

92
00:04:27.759 --> 00:04:28.240
<v Speaker 1>be honest.

93
00:04:28.439 --> 00:04:30.519
<v Speaker 2>Well, yeah, I mean that's the kernel for you, right,

94
00:04:30.560 --> 00:04:33.639
<v Speaker 2>It's a world of complexity and power, and you know

95
00:04:33.720 --> 00:04:38.639
<v Speaker 2>where even small mistakes can have huge consequences. But you know,

96
00:04:38.720 --> 00:04:40.680
<v Speaker 2>that's also what makes it so intriguing. There's always more

97
00:04:40.720 --> 00:04:42.199
<v Speaker 2>to learn, there's always more to discover.

98
00:04:42.439 --> 00:04:44.600
<v Speaker 1>I'm starting to feel like an explorer setting off into

99
00:04:44.680 --> 00:04:49.439
<v Speaker 1>uncharted territory. Speaking of territory, Yosefovich mentions this thing called

100
00:04:49.480 --> 00:04:53.040
<v Speaker 1>the object manager, which he describes as like the kernel's

101
00:04:53.199 --> 00:04:55.720
<v Speaker 1>internal librarian. What's that all about?

102
00:04:56.160 --> 00:04:59.160
<v Speaker 2>Yeah, so the object manager is essentially the kernel's way

103
00:04:59.199 --> 00:05:03.399
<v Speaker 2>of keeping track of air everything, files, processes, threads, devices,

104
00:05:03.439 --> 00:05:07.079
<v Speaker 2>you name it. It's like this vast library, with every

105
00:05:07.120 --> 00:05:09.680
<v Speaker 2>resource neatly cataloged and organized.

106
00:05:09.920 --> 00:05:12.560
<v Speaker 1>So even the kernel needs a good filing system, that's right,

107
00:05:13.079 --> 00:05:15.639
<v Speaker 1>But what's the point of having this object manager? Why

108
00:05:15.680 --> 00:05:18.480
<v Speaker 1>not just let each component manage its own resources.

109
00:05:18.639 --> 00:05:21.759
<v Speaker 2>Well, centralizing resource management this way through the object manager

110
00:05:22.199 --> 00:05:25.920
<v Speaker 2>has a lot of benefits, right. It enforces consistency, it

111
00:05:25.959 --> 00:05:28.839
<v Speaker 2>prevents conflicts, it makes it much easier to track an

112
00:05:28.839 --> 00:05:32.480
<v Speaker 2>audit resource usage, and plus it provides kind of this

113
00:05:32.639 --> 00:05:37.680
<v Speaker 2>uniform interface for accessing and manipulating resources regardless of their type.

114
00:05:37.879 --> 00:05:40.040
<v Speaker 1>That makes sense. It's like having a single point of

115
00:05:40.079 --> 00:05:42.399
<v Speaker 1>contact for all your resource needs rather than having to

116
00:05:42.439 --> 00:05:44.759
<v Speaker 1>deal with a bunch of different departments. Right, But how

117
00:05:44.759 --> 00:05:48.279
<v Speaker 1>do user mode processes actually interact with these objects that

118
00:05:48.319 --> 00:05:49.519
<v Speaker 1>are managed by the kernel.

119
00:05:49.600 --> 00:05:53.120
<v Speaker 2>Ah, that's where handles come in. Okay, so Yosipovic describes

120
00:05:53.160 --> 00:05:57.160
<v Speaker 2>these handles as like tickets that user mode programs use

121
00:05:57.240 --> 00:06:00.879
<v Speaker 2>to access those kernel objects. It's like getting a claim

122
00:06:01.000 --> 00:06:03.480
<v Speaker 2>ticket at a coat check, right, Yeah, you present your

123
00:06:03.519 --> 00:06:05.199
<v Speaker 2>ticket to retrieve your coat.

124
00:06:05.480 --> 00:06:08.399
<v Speaker 1>So a handle is basically a reference to an object

125
00:06:08.480 --> 00:06:11.759
<v Speaker 1>that's being managed by the kernel. Yes, but Yusufhovich also

126
00:06:11.839 --> 00:06:14.759
<v Speaker 1>mentions that each process has its own private handle table.

127
00:06:14.839 --> 00:06:17.879
<v Speaker 2>Why is that, Well, it's all about security and isolation, right.

128
00:06:18.199 --> 00:06:21.240
<v Speaker 2>By giving each process its own handle table, the kernel

129
00:06:21.279 --> 00:06:25.800
<v Speaker 2>can control exactly which processes have access to which objects,

130
00:06:26.680 --> 00:06:28.920
<v Speaker 2>and it can also prevent one process from messing with

131
00:06:28.959 --> 00:06:32.160
<v Speaker 2>another processes objects, even if they happen to have the

132
00:06:32.160 --> 00:06:33.160
<v Speaker 2>same handle value.

133
00:06:33.240 --> 00:06:35.120
<v Speaker 1>Right, So it's like each process gets its own set

134
00:06:35.120 --> 00:06:38.199
<v Speaker 1>of keys to access the kernel's resources, and those keys

135
00:06:38.199 --> 00:06:41.720
<v Speaker 1>don't work for any other process exactly. But Yusufhovich also

136
00:06:41.759 --> 00:06:43.959
<v Speaker 1>points out something kind of interesting. He says that the

137
00:06:44.040 --> 00:06:46.600
<v Speaker 1>name that's displayed for a handle can have different meanings

138
00:06:46.639 --> 00:06:49.040
<v Speaker 1>depending on the object type. What's that all about.

139
00:06:49.519 --> 00:06:51.360
<v Speaker 2>It can be a little confusing at first, but it

140
00:06:51.360 --> 00:06:53.360
<v Speaker 2>actually makes a lot of sense when you think about it.

141
00:06:54.639 --> 00:06:57.639
<v Speaker 2>You know, for some object types like mutex is, the

142
00:06:57.680 --> 00:07:00.800
<v Speaker 2>handle name is simply the name of the objects. Yeah,

143
00:07:00.839 --> 00:07:04.000
<v Speaker 2>But for other object types like files and directories, the

144
00:07:04.040 --> 00:07:07.560
<v Speaker 2>handle name is actually the path to that object in

145
00:07:07.600 --> 00:07:08.319
<v Speaker 2>the file system.

146
00:07:08.639 --> 00:07:11.439
<v Speaker 1>Okay, so the handle name isn't always a literal name.

147
00:07:11.480 --> 00:07:15.399
<v Speaker 1>It can also be like a path or some other

148
00:07:15.480 --> 00:07:19.199
<v Speaker 1>kind of identifier that's meaningful for that specific object type.

149
00:07:19.240 --> 00:07:19.639
<v Speaker 2>That's right.

150
00:07:19.879 --> 00:07:23.120
<v Speaker 1>But all this talk about handles and objects in kernel

151
00:07:23.120 --> 00:07:25.680
<v Speaker 1>mode is making me really curious about what it actually

152
00:07:25.759 --> 00:07:28.519
<v Speaker 1>takes to write code that runs in this kind of

153
00:07:28.600 --> 00:07:32.279
<v Speaker 1>privileged realm. Yusifovich has a whole section on setting up

154
00:07:32.319 --> 00:07:34.879
<v Speaker 1>a kernel development environment, and let's just say it looks

155
00:07:34.879 --> 00:07:37.920
<v Speaker 1>a lot different from my usual user mode coding setup.

156
00:07:37.959 --> 00:07:40.439
<v Speaker 1>Oh yeah, it's a whole different world down there, it is.

157
00:07:40.439 --> 00:07:43.079
<v Speaker 2>You need special tools like the Windows Driver kit. You

158
00:07:43.120 --> 00:07:45.120
<v Speaker 2>need a debugger they can understand what's going on in

159
00:07:45.160 --> 00:07:48.079
<v Speaker 2>the kernel, and you need a healthy dase of patients.

160
00:07:48.399 --> 00:07:52.879
<v Speaker 1>Yusifovich mentions the importance of error handling in Kernal development.

161
00:07:53.240 --> 00:07:57.000
<v Speaker 1>He says, even small mistakes can bring down the entire system.

162
00:07:58.000 --> 00:08:01.519
<v Speaker 1>Why is that what makes kernel development so much more

163
00:08:01.600 --> 00:08:04.079
<v Speaker 1>unforgiving than user mode programming. Yeah.

164
00:08:04.079 --> 00:08:06.319
<v Speaker 2>Well, in user mode, if your code crashes, it usually

165
00:08:06.360 --> 00:08:08.480
<v Speaker 2>only affects the current process, right, the rest of the

166
00:08:08.480 --> 00:08:11.439
<v Speaker 2>system kind of keeps humming along. But in kernel mode,

167
00:08:11.879 --> 00:08:14.720
<v Speaker 2>your code's running in the same address space as the

168
00:08:14.759 --> 00:08:18.079
<v Speaker 2>operating system itself, So a bug in your driver can

169
00:08:18.120 --> 00:08:22.360
<v Speaker 2>actually corrupt critical data structures, you know, leading to system

170
00:08:22.399 --> 00:08:24.639
<v Speaker 2>instability or even a complete crash.

171
00:08:24.720 --> 00:08:27.040
<v Speaker 1>So it's like playing with live wires.

172
00:08:27.399 --> 00:08:28.199
<v Speaker 2>Yeah, pretty much.

173
00:08:28.279 --> 00:08:30.439
<v Speaker 1>One wrong move and the whole house goes dark.

174
00:08:30.519 --> 00:08:34.480
<v Speaker 2>Yeah, exactly. And to make things even more challenging, kernel

175
00:08:34.480 --> 00:08:39.519
<v Speaker 2>development often involves like working with undocumented features reverse engineering

176
00:08:39.600 --> 00:08:40.360
<v Speaker 2>existing drivers.

177
00:08:40.480 --> 00:08:41.000
<v Speaker 1>Oh wow.

178
00:08:41.240 --> 00:08:42.720
<v Speaker 2>Yeah, so it's not for the faint of heart.

179
00:08:42.799 --> 00:08:45.120
<v Speaker 1>Yeah, I'm sarrying to understand why kernel developers are often

180
00:08:45.120 --> 00:08:48.759
<v Speaker 1>seen as like wizards or gurus. But let's dive into

181
00:08:48.799 --> 00:08:52.559
<v Speaker 1>some of the specifics of kernel programming. Here. Yasifavich talks

182
00:08:52.559 --> 00:08:55.960
<v Speaker 1>about different memory pools that drivers can use, paged and

183
00:08:56.039 --> 00:08:58.919
<v Speaker 1>non paged. What's the difference between these pools and why

184
00:08:58.919 --> 00:08:59.519
<v Speaker 1>does it matter?

185
00:09:00.000 --> 00:09:03.159
<v Speaker 2>Okay, so think about it this way. Page pool memory

186
00:09:03.279 --> 00:09:06.759
<v Speaker 2>is kind of like this, you know, flexible workspace that

187
00:09:06.840 --> 00:09:09.799
<v Speaker 2>can be moved around as needed. Okay, right, So it

188
00:09:09.840 --> 00:09:12.120
<v Speaker 2>could be swapped out to disk if the system is

189
00:09:12.200 --> 00:09:14.879
<v Speaker 2>running low on physical memory and brought back in when

190
00:09:14.879 --> 00:09:18.679
<v Speaker 2>it's needed again. But non paged pool memory, on the

191
00:09:18.679 --> 00:09:22.639
<v Speaker 2>other hand, that's like your you know, dedicated office space.

192
00:09:22.679 --> 00:09:23.759
<v Speaker 2>It's always available.

193
00:09:23.919 --> 00:09:27.120
<v Speaker 1>So nontage memory is like the VIP section. Yes, always

194
00:09:27.120 --> 00:09:29.960
<v Speaker 1>guarantee it a spot in RAM exactly. But wouldn't having

195
00:09:30.080 --> 00:09:32.919
<v Speaker 1>everything be non paged be a recipe for disaster?

196
00:09:33.360 --> 00:09:35.480
<v Speaker 2>You're right, You're absolutely right, and that's why drivers have

197
00:09:35.519 --> 00:09:37.600
<v Speaker 2>to be really, really careful about how they use non

198
00:09:37.600 --> 00:09:40.600
<v Speaker 2>paged memory. It's a precious resource that should only be

199
00:09:40.679 --> 00:09:43.440
<v Speaker 2>used for you know, code or data that absolutely cannot

200
00:09:43.480 --> 00:09:46.600
<v Speaker 2>be paged out, things like interrupt handlers or data structures

201
00:09:46.600 --> 00:09:48.519
<v Speaker 2>that need to be accessed very quickly and reliably.

202
00:09:48.759 --> 00:09:54.360
<v Speaker 1>It's all about striking that balance between performance and resource utilization. Yeah, okay,

203
00:09:54.480 --> 00:09:58.399
<v Speaker 1>so how does a driver actually tell the operating system

204
00:09:58.480 --> 00:10:01.559
<v Speaker 1>what it can do? Is there some kind of registration process?

205
00:10:01.840 --> 00:10:05.159
<v Speaker 2>There is? Yeah, So each driver has this special data

206
00:10:05.159 --> 00:10:08.120
<v Speaker 2>structure called a driver object. It's kind of like the

207
00:10:08.200 --> 00:10:11.440
<v Speaker 2>driver's resume right outlining its capabilities, and now it interfaces

208
00:10:11.440 --> 00:10:12.320
<v Speaker 2>with the rest of the system.

209
00:10:12.399 --> 00:10:15.519
<v Speaker 1>Interesting, So what kind of information is stored in this

210
00:10:15.679 --> 00:10:18.919
<v Speaker 1>driver object? What does the kernel need to know about

211
00:10:18.919 --> 00:10:21.360
<v Speaker 1>a driver in order for it to function properly.

212
00:10:21.519 --> 00:10:26.639
<v Speaker 2>Well, it's packed with important details. The driver object includes

213
00:10:26.679 --> 00:10:29.759
<v Speaker 2>things like the driver's name, the device object that it's

214
00:10:29.759 --> 00:10:33.399
<v Speaker 2>associated with, and probably most importantly, a list of function

215
00:10:33.480 --> 00:10:37.039
<v Speaker 2>pointers called the major function array. Okay, and this array

216
00:10:37.240 --> 00:10:41.360
<v Speaker 2>tells the operating system what IO requests the driver can handle.

217
00:10:41.480 --> 00:10:43.480
<v Speaker 1>So it's kind of like a menu of services that

218
00:10:43.519 --> 00:10:46.000
<v Speaker 1>the driver offers, like I can create files, I can

219
00:10:46.039 --> 00:10:47.440
<v Speaker 1>read files, I can delete files.

220
00:10:47.720 --> 00:10:50.720
<v Speaker 2>That's exactly right. Yeah. Each entry in that major function

221
00:10:50.840 --> 00:10:55.799
<v Speaker 2>array points to a specific function within the driver that's

222
00:10:55.879 --> 00:11:00.159
<v Speaker 2>responsible for handling a particular type of IO request. So,

223
00:11:00.200 --> 00:11:02.879
<v Speaker 2>for example, if the operating system needs to create a

224
00:11:02.879 --> 00:11:06.639
<v Speaker 2>new file, It'll check the driver's major function array for

225
00:11:06.720 --> 00:11:09.879
<v Speaker 2>an entry that corresponds to file creation.

226
00:11:09.679 --> 00:11:12.559
<v Speaker 1>Requests, and if the driver has registered a handler for

227
00:11:12.600 --> 00:11:15.919
<v Speaker 1>that request type, then the operating system will call that function,

228
00:11:16.080 --> 00:11:18.799
<v Speaker 1>passing along all the necessary information about the requests.

229
00:11:18.840 --> 00:11:21.480
<v Speaker 2>You got it. And that's where things get really interesting, right, Okay,

230
00:11:21.480 --> 00:11:24.200
<v Speaker 2>because those io requests are packaged up in these things

231
00:11:24.240 --> 00:11:30.240
<v Speaker 2>called IRPs iorequest packets, and Yosefovich really gets into the

232
00:11:30.320 --> 00:11:32.600
<v Speaker 2>nitty gritty of how these IRPs work.

233
00:11:33.080 --> 00:11:36.519
<v Speaker 1>Yeah, I remember him describing IRPs as like the language

234
00:11:36.559 --> 00:11:38.720
<v Speaker 1>of the kernel, the way that all the different components

235
00:11:38.759 --> 00:11:41.600
<v Speaker 1>communicate with each other. Right, But if I'm being honest,

236
00:11:41.639 --> 00:11:44.320
<v Speaker 1>the whole concept of IRP still feels a bit abstract

237
00:11:44.320 --> 00:11:46.879
<v Speaker 1>to me. Can you break it down for me? What

238
00:11:46.919 --> 00:11:50.639
<v Speaker 1>do these IRPs actually look like and how do they

239
00:11:50.720 --> 00:11:51.720
<v Speaker 1>flow through the system?

240
00:11:52.080 --> 00:11:56.720
<v Speaker 2>Okay? So imagine an IRP as an envelope, okay, right,

241
00:11:56.840 --> 00:12:00.360
<v Speaker 2>and inside this envelope is all sorts of information about

242
00:12:00.399 --> 00:12:03.720
<v Speaker 2>the request and what type of operation it is, what

243
00:12:03.799 --> 00:12:06.720
<v Speaker 2>file or device it's targeting, any data that needs to

244
00:12:06.720 --> 00:12:07.799
<v Speaker 2>be transferred, and so on.

245
00:12:07.919 --> 00:12:10.159
<v Speaker 1>So it's like a standardized form that everyone agrees on

246
00:12:10.320 --> 00:12:13.399
<v Speaker 1>just making sure that all the necessary information is included.

247
00:12:12.960 --> 00:12:15.600
<v Speaker 2>Precisely, and these IRPs, they get passed around from one

248
00:12:15.600 --> 00:12:19.559
<v Speaker 2>component to another as the request is processed. So, for example,

249
00:12:19.799 --> 00:12:22.720
<v Speaker 2>if a user mode application wants to write to a file,

250
00:12:23.559 --> 00:12:26.039
<v Speaker 2>it'll make a system call, which will eventually result in

251
00:12:26.240 --> 00:12:29.360
<v Speaker 2>an IRP being created in the kernel, and that IRP

252
00:12:29.559 --> 00:12:32.679
<v Speaker 2>might be passed through several layers of drivers, each one

253
00:12:32.720 --> 00:12:37.120
<v Speaker 2>potentially examining or modifying the request before it finally reaches

254
00:12:37.159 --> 00:12:40.320
<v Speaker 2>the filesystem driver that's responsible for actually writing the data

255
00:12:40.360 --> 00:12:40.679
<v Speaker 2>to disk.

256
00:12:40.799 --> 00:12:42.639
<v Speaker 1>So it's kind of like a relay race, with the

257
00:12:42.720 --> 00:12:45.200
<v Speaker 1>IRP being passed from one runner to the next until

258
00:12:45.200 --> 00:12:47.480
<v Speaker 1>it reaches the finish nine exactly. But with all these

259
00:12:47.480 --> 00:12:51.559
<v Speaker 1>different components potentially handling the IRP, how does the system

260
00:12:51.759 --> 00:12:54.279
<v Speaker 1>make sure that everything happens in the right order and

261
00:12:54.320 --> 00:12:57.039
<v Speaker 1>that nothing gets lost or corrupted along the way.

262
00:12:57.240 --> 00:12:59.320
<v Speaker 2>Well that's where the io manager comes in, okay, right,

263
00:12:59.320 --> 00:13:01.639
<v Speaker 2>It's like the racecord making sure all the runners are

264
00:13:01.639 --> 00:13:04.240
<v Speaker 2>in their lanes and the baton gets passed smoothly. So

265
00:13:04.279 --> 00:13:06.559
<v Speaker 2>the iron manager keeps track of all the IRPs in

266
00:13:06.600 --> 00:13:11.200
<v Speaker 2>the system, it routes them to the appropriate drivers. Yeah,

267
00:13:11.240 --> 00:13:14.519
<v Speaker 2>and it manages things like buffering and completion routines.

268
00:13:14.960 --> 00:13:17.960
<v Speaker 1>It's a complex system, but it's pretty amazing how it

269
00:13:18.000 --> 00:13:21.440
<v Speaker 1>all works together to handle, you know, potentially millions of

270
00:13:21.480 --> 00:13:23.200
<v Speaker 1>these io requests every second.

271
00:13:23.399 --> 00:13:24.159
<v Speaker 2>Yeah.

272
00:13:24.200 --> 00:13:26.279
<v Speaker 1>But let's go back to those mini filters we talked

273
00:13:26.279 --> 00:13:29.440
<v Speaker 1>about earlier. Where do they fit into this whole IRP

274
00:13:29.679 --> 00:13:30.960
<v Speaker 1>processing pipeline.

275
00:13:31.080 --> 00:13:34.360
<v Speaker 2>Ah? Yes, So mini filters are like secret agents that

276
00:13:34.440 --> 00:13:38.840
<v Speaker 2>can intercept those IRPs at various points along their journey.

277
00:13:38.600 --> 00:13:41.039
<v Speaker 1>So they can kind of peek inside the envelope. Yeah,

278
00:13:41.080 --> 00:13:44.159
<v Speaker 1>maybe even slip in a little something extra before passing

279
00:13:44.200 --> 00:13:45.399
<v Speaker 1>it along to the next component.

280
00:13:45.679 --> 00:13:47.600
<v Speaker 2>That's a great way to think about it. And that

281
00:13:47.720 --> 00:13:51.960
<v Speaker 2>ability to intercept and manipulate those IRPs is really what

282
00:13:52.039 --> 00:13:54.720
<v Speaker 2>makes minifilters so incredible powerful. They can, you know, they

283
00:13:54.720 --> 00:13:57.120
<v Speaker 2>can filter, they can modify, redirect, they can even block

284
00:13:57.159 --> 00:14:01.080
<v Speaker 2>IOA requests, all without the user even knowing it's happening.

285
00:14:01.399 --> 00:14:06.519
<v Speaker 1>Right. We talked earlier about antivirus programs using minifilters to

286
00:14:06.600 --> 00:14:10.240
<v Speaker 1>scan files before they're written to the disc, but Yosefavic

287
00:14:10.440 --> 00:14:13.279
<v Speaker 1>mentions a whole range of other applications like back up

288
00:14:13.320 --> 00:14:17.759
<v Speaker 1>and restore data encryption, even performance optimization. It seems like

289
00:14:17.840 --> 00:14:19.519
<v Speaker 1>there's a lot you can do with these things.

290
00:14:19.759 --> 00:14:22.159
<v Speaker 2>The possibilities are really endless, you know. For example, you

291
00:14:22.240 --> 00:14:26.159
<v Speaker 2>could use a mini filter to create a shadow copy

292
00:14:26.200 --> 00:14:28.720
<v Speaker 2>of every file that's written to a specific directory, right, Yeah,

293
00:14:28.840 --> 00:14:30.480
<v Speaker 2>essentially creating a real time backup.

294
00:14:30.600 --> 00:14:35.200
<v Speaker 1>That's impressive. And I remember Yusufovich mentioning something about minifilters

295
00:14:35.240 --> 00:14:39.120
<v Speaker 1>being able to enforce like really granular access control. Yes,

296
00:14:39.240 --> 00:14:40.080
<v Speaker 1>how does that work?

297
00:14:40.279 --> 00:14:43.399
<v Speaker 2>So imagine you want to restrict access to certain files

298
00:14:43.440 --> 00:14:46.480
<v Speaker 2>based on the user's identity, you know, or group membership.

299
00:14:46.879 --> 00:14:50.519
<v Speaker 2>A mini filter can actually examine the IERP for every

300
00:14:50.679 --> 00:14:54.600
<v Speaker 2>file access request, check the user's credentials, and if the

301
00:14:54.679 --> 00:14:58.440
<v Speaker 2>user doesn't have the necessary permissions, the minifilter can simply

302
00:14:58.519 --> 00:14:59.919
<v Speaker 2>block the requests.

303
00:15:00.000 --> 00:15:02.360
<v Speaker 1>So like having a bouncer at the door of every

304
00:15:02.399 --> 00:15:06.080
<v Speaker 1>file checking IDs and making sure that only authorized personnel

305
00:15:06.080 --> 00:15:06.480
<v Speaker 1>get through.

306
00:15:06.559 --> 00:15:07.600
<v Speaker 2>That's a great way to put it.

307
00:15:07.799 --> 00:15:10.480
<v Speaker 1>But with so much power at their disposal, isn't there

308
00:15:10.519 --> 00:15:13.720
<v Speaker 1>a risk that many filters could interfere with each other, right,

309
00:15:13.960 --> 00:15:16.320
<v Speaker 1>or even with the normal operation of the system.

310
00:15:16.480 --> 00:15:19.600
<v Speaker 2>Yeah, that's a valid concern, but the kernel's designed to

311
00:15:19.679 --> 00:15:23.720
<v Speaker 2>manage these interactions very carefully. So MANI filters are assigned

312
00:15:23.720 --> 00:15:27.919
<v Speaker 2>in altitude, which determines their order in the filtering chain altitude.

313
00:15:27.960 --> 00:15:30.200
<v Speaker 1>So it's like stacking them on top of each other, Yes,

314
00:15:30.320 --> 00:15:33.279
<v Speaker 1>with the higher altitude filters getting to see the IERP first.

315
00:15:33.399 --> 00:15:37.720
<v Speaker 2>That's exactly right. And this altitude system is carefully managed

316
00:15:38.000 --> 00:15:42.080
<v Speaker 2>to prevent those kinds of conflicts. In fact, Yosiphovich emphasizes it,

317
00:15:42.080 --> 00:15:45.320
<v Speaker 2>if you want to develop a production grade minifilter, you

318
00:15:45.360 --> 00:15:47.759
<v Speaker 2>actually need to a pain of proper altitude allocation for

319
00:15:47.840 --> 00:15:48.960
<v Speaker 2>Microsoft really, so.

320
00:15:48.919 --> 00:15:51.600
<v Speaker 1>It's not just a free for all where any developer

321
00:15:51.600 --> 00:15:53.879
<v Speaker 1>can choose any altitude they want, not at all.

322
00:15:53.919 --> 00:15:59.399
<v Speaker 2>No, Microsoft has these established ranges of altitudes for different purposes. Right,

323
00:16:00.120 --> 00:16:04.639
<v Speaker 2>Virus filters might occupy one altitude range while backup filters

324
00:16:04.679 --> 00:16:05.440
<v Speaker 2>occupy another.

325
00:16:05.519 --> 00:16:07.639
<v Speaker 1>Okay, that makes sense. It's like air traffic control, right,

326
00:16:07.720 --> 00:16:09.759
<v Speaker 1>making sure that all the planes are flying at the

327
00:16:09.799 --> 00:16:13.919
<v Speaker 1>right altitudes to prevent collisions. But this whole altitude allocation

328
00:16:14.039 --> 00:16:17.000
<v Speaker 1>process sounds pretty involved. Why is it so important?

329
00:16:17.399 --> 00:16:20.759
<v Speaker 2>Well, imagine what could happen if two minifilters with like

330
00:16:20.840 --> 00:16:24.279
<v Speaker 2>incompatible goals were operating at the same altitude.

331
00:16:24.720 --> 00:16:27.879
<v Speaker 1>Let me guess chaos chaos exactly.

332
00:16:28.120 --> 00:16:30.720
<v Speaker 2>You know, one minifilter might be trying to block access

333
00:16:30.720 --> 00:16:33.039
<v Speaker 2>to a file while the other one's trying to allow access.

334
00:16:33.759 --> 00:16:36.320
<v Speaker 2>Or one minifilter might be modifying the data in an

335
00:16:36.360 --> 00:16:39.720
<v Speaker 2>IRP while the other is expecting that data to be unchanged.

336
00:16:40.000 --> 00:16:41.840
<v Speaker 1>It sounds like a recipe for disaster.

337
00:16:42.080 --> 00:16:45.440
<v Speaker 2>Yeah, So this altitude allocation process is really all about

338
00:16:45.519 --> 00:16:48.759
<v Speaker 2>ensuring that mini filters can coexist peacefully and that the

339
00:16:48.799 --> 00:16:50.600
<v Speaker 2>system remains stable and predictable.

340
00:16:50.919 --> 00:16:54.000
<v Speaker 1>So this altitude allocation process is all about ensuring that

341
00:16:54.080 --> 00:16:57.519
<v Speaker 1>mani filters can coexist peacefully and that the system remains

342
00:16:57.519 --> 00:17:00.720
<v Speaker 1>stable and predictable. But let's dive a bit deeper into

343
00:17:00.720 --> 00:17:04.359
<v Speaker 1>the actual structure of a minifilter. How are they implemented

344
00:17:04.799 --> 00:17:08.279
<v Speaker 1>and what are the key components that developers need to understand? Okay,

345
00:17:08.720 --> 00:17:12.200
<v Speaker 1>from what I gathered from Yosifovic, a minifilter is essentially

346
00:17:12.279 --> 00:17:15.799
<v Speaker 1>a driver that registers a set of callback functions with

347
00:17:15.920 --> 00:17:17.279
<v Speaker 1>the filter manager.

348
00:17:17.160 --> 00:17:21.240
<v Speaker 2>Right, and those callback functions are the minifilter's eyes and ears, right, Okay,

349
00:17:21.480 --> 00:17:24.920
<v Speaker 2>allowing you to to observe and interact with IRPs as

350
00:17:24.920 --> 00:17:26.039
<v Speaker 2>they flow through the system.

351
00:17:26.359 --> 00:17:29.759
<v Speaker 1>He mentions two main types of callbacks, pre operation and

352
00:17:29.839 --> 00:17:33.119
<v Speaker 1>post operation. What's the difference between those and why are

353
00:17:33.119 --> 00:17:33.720
<v Speaker 1>they important?

354
00:17:33.839 --> 00:17:36.680
<v Speaker 2>Okay, so imagine you're standing at a checkpoint on a road,

355
00:17:37.079 --> 00:17:40.000
<v Speaker 2>right right, A pre operation callback is like checking the

356
00:17:40.079 --> 00:17:42.720
<v Speaker 2>driver's license and registration before the car is allowed to

357
00:17:42.759 --> 00:17:45.480
<v Speaker 2>pass through, and then a post operation callback is like

358
00:17:45.599 --> 00:17:48.160
<v Speaker 2>checking the trunk after the cars pass through, just to

359
00:17:48.200 --> 00:17:49.480
<v Speaker 2>make sure everything's in order.

360
00:17:49.720 --> 00:17:52.839
<v Speaker 1>So a pre operation callback gives the minifilter a chance

361
00:17:52.880 --> 00:17:57.200
<v Speaker 1>to examine and potentially modify the IRP before the operation

362
00:17:57.319 --> 00:18:00.920
<v Speaker 1>is actually performed, right, while a post operation callback gives

363
00:18:00.920 --> 00:18:03.720
<v Speaker 1>it a chance to inspect the results of the operation

364
00:18:04.240 --> 00:18:06.359
<v Speaker 1>and take any necessary actions based on.

365
00:18:06.359 --> 00:18:10.359
<v Speaker 2>Those results exactly. And those callbacks give mini filters just

366
00:18:10.400 --> 00:18:13.559
<v Speaker 2>this incredible amount of flexibility, right. They can use pre

367
00:18:13.680 --> 00:18:17.680
<v Speaker 2>operation callbacks to block requests, to modify data, to even

368
00:18:17.720 --> 00:18:20.519
<v Speaker 2>redirect the IRP to a different device or file. And

369
00:18:20.599 --> 00:18:23.960
<v Speaker 2>they can use post operation callbacks to log events, to

370
00:18:24.039 --> 00:18:27.880
<v Speaker 2>clean up resources, or even to initiate new io requests.

371
00:18:28.279 --> 00:18:31.079
<v Speaker 1>It's like having checkpoints at every stage of the journey,

372
00:18:31.200 --> 00:18:33.559
<v Speaker 1>allowing the mini filter to kind of control the flow

373
00:18:33.599 --> 00:18:35.960
<v Speaker 1>of traffic and make sure that everything is running smoothly,

374
00:18:36.200 --> 00:18:39.839
<v Speaker 1>that's right. But Yasifovich also mentioned something called contexts in

375
00:18:39.880 --> 00:18:42.079
<v Speaker 1>the context of mini filters. What are those?

376
00:18:42.359 --> 00:18:45.960
<v Speaker 2>Okay? So, contexts are kind of like little sticky notes

377
00:18:46.000 --> 00:18:49.680
<v Speaker 2>that a minifilter can attach to to various objects in

378
00:18:49.720 --> 00:18:54.559
<v Speaker 2>the kernel, you know, yeah, like files, streams, or even volumes.

379
00:18:55.319 --> 00:18:58.400
<v Speaker 2>They're a way for the mini filter to store information

380
00:18:58.519 --> 00:19:01.839
<v Speaker 2>that's specific to that object, you know, like flags or

381
00:19:01.920 --> 00:19:03.960
<v Speaker 2>counters or even cash data.

382
00:19:04.039 --> 00:19:06.559
<v Speaker 1>So it's like adding a little bit of extra information

383
00:19:07.160 --> 00:19:10.680
<v Speaker 1>to the object. Yeah, information that's only visible to the minifilter,

384
00:19:10.839 --> 00:19:11.319
<v Speaker 1>that's right.

385
00:19:11.640 --> 00:19:15.160
<v Speaker 2>And those context can be incredibly useful for managing state

386
00:19:15.480 --> 00:19:19.359
<v Speaker 2>and sharing information between different callback functions within the minifilter.

387
00:19:19.519 --> 00:19:21.240
<v Speaker 1>It sounds like a clever way to kind of keep

388
00:19:21.319 --> 00:19:24.599
<v Speaker 1>track of things right and avoid having to store state

389
00:19:24.640 --> 00:19:28.359
<v Speaker 1>information globally, which could potentially lead to you know, conflicts

390
00:19:28.440 --> 00:19:31.240
<v Speaker 1>or race conditions exactly. But let's talk about something that's

391
00:19:31.400 --> 00:19:33.640
<v Speaker 1>that's always on my mind when it comes to kernel development,

392
00:19:33.920 --> 00:19:38.119
<v Speaker 1>error handling. Yusuphovic stresses the importance of failing fast and

393
00:19:38.160 --> 00:19:41.599
<v Speaker 1>failing safely in kernel mode. Yes, why is that so crucial?

394
00:19:41.920 --> 00:19:45.440
<v Speaker 2>Well, remember, in kernel mode you're operating in the same

395
00:19:45.599 --> 00:19:49.240
<v Speaker 2>address space as the operating system itself. Ah Right, So

396
00:19:49.359 --> 00:19:52.599
<v Speaker 2>even a seemingly minor error in your driver can have

397
00:19:52.720 --> 00:19:54.160
<v Speaker 2>catastrophic consequences.

398
00:19:54.240 --> 00:19:56.880
<v Speaker 1>Right, It's like playing with live wires. One wrong move

399
00:19:57.039 --> 00:19:59.599
<v Speaker 1>and the whole house goes dart exactly.

400
00:19:59.480 --> 00:20:03.359
<v Speaker 2>So if you're driver encounters an unexpected condition, it's essential

401
00:20:03.400 --> 00:20:07.319
<v Speaker 2>to stop processing their request immediately and return an appropriate

402
00:20:07.400 --> 00:20:07.839
<v Speaker 2>error code.

403
00:20:07.960 --> 00:20:11.200
<v Speaker 1>So it's better to abort the mission than to risk

404
00:20:11.319 --> 00:20:12.240
<v Speaker 1>causing more damage.

405
00:20:12.279 --> 00:20:17.599
<v Speaker 2>Absolutely, and just as important as failing fast is failing safely.

406
00:20:18.319 --> 00:20:21.160
<v Speaker 2>So this means ensuring that your driver doesn't leave the

407
00:20:21.240 --> 00:20:24.640
<v Speaker 2>system in an inconsistent state even if an error does occur.

408
00:20:25.240 --> 00:20:28.359
<v Speaker 2>All resources need to be properly released, all data structures

409
00:20:28.359 --> 00:20:29.160
<v Speaker 2>need to be cleaned.

410
00:20:28.960 --> 00:20:30.960
<v Speaker 1>Up, so it's like making sure you lock the doors

411
00:20:31.000 --> 00:20:32.920
<v Speaker 1>and turn off the lights before you leave the house,

412
00:20:33.000 --> 00:20:34.880
<v Speaker 1>even if you're rushing out in an emergency.

413
00:20:34.920 --> 00:20:39.200
<v Speaker 2>Precisely, and Yosefovich highlights several techniques that drivers can use

414
00:20:39.200 --> 00:20:42.720
<v Speaker 2>to ensure safe air handling, like using tri finally blocks

415
00:20:42.720 --> 00:20:45.240
<v Speaker 2>to guarantee that cleanup code is executed even if an

416
00:20:45.240 --> 00:20:46.119
<v Speaker 2>exception is thrown.

417
00:20:46.440 --> 00:20:50.119
<v Speaker 1>It sounds like AerR handling is serious business. In kernel development,

418
00:20:50.240 --> 00:20:51.960
<v Speaker 1>it is. But let's move on to another kind of

419
00:20:52.079 --> 00:20:56.640
<v Speaker 1>challenging aspect here, debugging. We talked earlier about how kernel

420
00:20:56.680 --> 00:21:00.440
<v Speaker 1>debugging requires these specialized tools and techniques, right, but is

421
00:21:00.440 --> 00:21:04.000
<v Speaker 1>there anything specific to mini filter debugging that developers should

422
00:21:04.000 --> 00:21:04.519
<v Speaker 1>be aware of.

423
00:21:05.079 --> 00:21:08.640
<v Speaker 2>Yeah. So one of the biggest challenges is that minifilters

424
00:21:08.680 --> 00:21:12.319
<v Speaker 2>often operate at a very low level, right, Yeah, interacting

425
00:21:12.319 --> 00:21:14.759
<v Speaker 2>with the filesystem and other kernel components in ways that

426
00:21:14.839 --> 00:21:17.759
<v Speaker 2>can be difficult to observe from user mode.

427
00:21:17.920 --> 00:21:20.960
<v Speaker 1>So it's like trying to debug a program that's running

428
00:21:20.960 --> 00:21:22.400
<v Speaker 1>on a different planet.

429
00:21:22.200 --> 00:21:24.920
<v Speaker 2>In a way. Yeah, But fortunately there are tools that

430
00:21:25.000 --> 00:21:29.599
<v Speaker 2>can help Yasifovich mentions a special debugger expression called fltkd

431
00:21:29.720 --> 00:21:33.200
<v Speaker 2>dot dll, which provides commands that are specifically designed for

432
00:21:33.279 --> 00:21:36.400
<v Speaker 2>debugging minifilters, so you can use it to display information

433
00:21:36.440 --> 00:21:41.920
<v Speaker 2>about loaded minifilters, their instances, attached volumes, even their internal state.

434
00:21:42.000 --> 00:21:44.359
<v Speaker 1>It's like having x ray vision into the world of

435
00:21:44.400 --> 00:21:45.920
<v Speaker 1>minifilters exactly.

436
00:21:46.240 --> 00:21:49.519
<v Speaker 2>And there are other techniques like using kernel mode logging

437
00:21:50.000 --> 00:21:53.119
<v Speaker 2>or carefully crafted test cases to try to isolate and

438
00:21:53.160 --> 00:21:53.920
<v Speaker 2>reproduce issues.

439
00:21:54.000 --> 00:21:57.440
<v Speaker 1>It sounds like debugging mini filters requires a special blend

440
00:21:57.559 --> 00:22:00.119
<v Speaker 1>of patients, persistence and creativity.

441
00:22:00.279 --> 00:22:03.000
<v Speaker 2>It definitely does. But for those who dare to venture

442
00:22:03.039 --> 00:22:06.240
<v Speaker 2>into this realm, the rewards can be great. There's nothing

443
00:22:06.319 --> 00:22:09.160
<v Speaker 2>quite like the feeling of tracking down a tricky bug

444
00:22:09.240 --> 00:22:12.599
<v Speaker 2>in a minifilter and knowing that you've made the system

445
00:22:12.720 --> 00:22:14.680
<v Speaker 2>a little bit more stable, a little bit more secure.

446
00:22:14.759 --> 00:22:17.559
<v Speaker 1>It's like solving a puzzle, except the pieces are scattered

447
00:22:17.599 --> 00:22:20.920
<v Speaker 1>throughout the kernel, right, and the solution could impact millions

448
00:22:20.920 --> 00:22:21.400
<v Speaker 1>of users.

449
00:22:21.480 --> 00:22:24.720
<v Speaker 2>Yeah, well said. And as we wrap up part two

450
00:22:24.759 --> 00:22:27.160
<v Speaker 2>of our deep dive, I want to leave our listeners

451
00:22:27.160 --> 00:22:30.319
<v Speaker 2>with a question to ponder. Okay, if you had the

452
00:22:30.400 --> 00:22:35.000
<v Speaker 2>power to intercept and manipulate file system operations at such

453
00:22:35.039 --> 00:22:38.039
<v Speaker 2>a low level, what kind of creative solutions could you build?

454
00:22:38.119 --> 00:22:41.000
<v Speaker 2>What problems could you solve? Think about it, and we'll

455
00:22:41.039 --> 00:22:43.880
<v Speaker 2>explore some of those possibilities when we return for part three.

456
00:22:44.079 --> 00:22:46.240
<v Speaker 1>Back for the final part of our deep dive the

457
00:22:46.279 --> 00:22:49.279
<v Speaker 1>Windows kernel. Man, it's a wild ride down there, it is,

458
00:22:49.559 --> 00:22:53.039
<v Speaker 1>but we're not done yet. We're exploring these mini filters,

459
00:22:53.079 --> 00:22:56.359
<v Speaker 1>these tiny but mighty drivers that can really just get

460
00:22:56.359 --> 00:22:59.000
<v Speaker 1>in there and manipulate file system operations at such a

461
00:22:59.039 --> 00:23:01.680
<v Speaker 1>low level. And if you thought the stuff we talked

462
00:23:01.720 --> 00:23:04.000
<v Speaker 1>about last time was impressive, Hold onto your hats, yep,

463
00:23:04.640 --> 00:23:07.359
<v Speaker 1>because we're going to go even deeper. Okay, exploring some

464
00:23:07.400 --> 00:23:10.480
<v Speaker 1>of the more advanced things these minifilter developers can do.

465
00:23:11.319 --> 00:23:13.640
<v Speaker 1>You left us last time with that challenge to really

466
00:23:13.720 --> 00:23:16.000
<v Speaker 1>imagine the solutions we could build if we had that

467
00:23:16.119 --> 00:23:18.759
<v Speaker 1>kind of power at our fingertips. Right, my mind is

468
00:23:18.799 --> 00:23:22.119
<v Speaker 1>still kind of boggled by the possibilities, to be honest. Yeah,

469
00:23:22.400 --> 00:23:24.880
<v Speaker 1>give me some inspiration. What are some of the really

470
00:23:24.920 --> 00:23:27.359
<v Speaker 1>advanced things that many filters can do.

471
00:23:27.920 --> 00:23:31.079
<v Speaker 2>So one area that Yosvovich really dives into is is

472
00:23:31.119 --> 00:23:34.759
<v Speaker 2>the world of file system transactions. Okay, remember how we

473
00:23:34.759 --> 00:23:39.240
<v Speaker 2>talked about IRPs being like these envelopes carrying information about

474
00:23:40.079 --> 00:23:43.240
<v Speaker 2>file system requests. Right, A transaction is kind of like

475
00:23:44.079 --> 00:23:47.319
<v Speaker 2>bundling several of those envelopes together and treating them as

476
00:23:47.319 --> 00:23:50.440
<v Speaker 2>a single, indivisible unit of work.

477
00:23:50.680 --> 00:23:53.920
<v Speaker 1>So it's like saying, either all these operations succeed or

478
00:23:53.960 --> 00:23:55.440
<v Speaker 1>none of them do exactly.

479
00:23:55.640 --> 00:23:59.359
<v Speaker 2>Yeah, like an all or nothing approach to file system changes. Yeah,

480
00:23:59.400 --> 00:24:02.119
<v Speaker 2>and the beauty of it is mini filters can actually

481
00:24:02.160 --> 00:24:05.319
<v Speaker 2>participate in these transactions. Oh wow, Right, so they can

482
00:24:05.400 --> 00:24:08.920
<v Speaker 2>register callback functions that are invoked at different stages of

483
00:24:08.960 --> 00:24:13.119
<v Speaker 2>the transaction, giving them the opportunity to like monitor, modify,

484
00:24:13.319 --> 00:24:16.319
<v Speaker 2>or even veto operations that are part of that transaction.

485
00:24:16.440 --> 00:24:20.039
<v Speaker 1>Hold on, mini filters can veto operations within a transaction.

486
00:24:20.200 --> 00:24:23.880
<v Speaker 1>That's incredible. Yeah, what would be an example of when

487
00:24:23.920 --> 00:24:25.079
<v Speaker 1>that might be necessary?

488
00:24:25.160 --> 00:24:27.480
<v Speaker 2>Okay, Let's say you have a mini filter that's responsible

489
00:24:27.519 --> 00:24:31.880
<v Speaker 2>for enforcing disc quotas, right, okay, So a user might

490
00:24:31.920 --> 00:24:34.759
<v Speaker 2>try to write a large file that would exceed their

491
00:24:34.759 --> 00:24:38.279
<v Speaker 2>allocated space right now within a transaction, this might involve

492
00:24:38.359 --> 00:24:41.640
<v Speaker 2>several smaller right operations, right okay, So the mini filter

493
00:24:41.799 --> 00:24:44.880
<v Speaker 2>can can monitor those operations, and if at any point

494
00:24:44.920 --> 00:24:48.680
<v Speaker 2>the quota is exceeded, it can actually veto the entire transaction,

495
00:24:49.279 --> 00:24:51.519
<v Speaker 2>preventing any of the rights from actually happening.

496
00:24:51.640 --> 00:24:53.440
<v Speaker 1>So the mini filter can act as kind of like

497
00:24:53.480 --> 00:24:55.960
<v Speaker 1>a guardian, right, ensuring that the integrity of the file

498
00:24:56.000 --> 00:24:59.960
<v Speaker 1>system is maintained even when you have these complex multi

499
00:25:00.160 --> 00:25:01.319
<v Speaker 1>step operations.

500
00:25:01.599 --> 00:25:05.759
<v Speaker 2>Exactly, and yatif of A highlights some fascinating use cases

501
00:25:05.799 --> 00:25:09.640
<v Speaker 2>for mini filters and transactions. He even talks about scenarios

502
00:25:09.640 --> 00:25:12.960
<v Speaker 2>where minifilters can initiate their own transactions, giving them even

503
00:25:13.000 --> 00:25:17.200
<v Speaker 2>finer grained control over how file system operations are performed.

504
00:25:17.519 --> 00:25:23.400
<v Speaker 1>It's amazing how much power and flexibility these mini filters offer. Yeah,

505
00:25:23.440 --> 00:25:25.920
<v Speaker 1>I'm realizing that mini filter development is not for the

506
00:25:25.960 --> 00:25:29.480
<v Speaker 1>faint of heart. You need a deep understanding of the kernel,

507
00:25:29.640 --> 00:25:32.880
<v Speaker 1>the file system, just a whole bunch of advanced concepts.

508
00:25:33.640 --> 00:25:35.799
<v Speaker 1>What are some of the other challenges that these developers

509
00:25:35.799 --> 00:25:37.200
<v Speaker 1>face and how do they overcome them?

510
00:25:37.599 --> 00:25:40.200
<v Speaker 2>Well, one challenge we touched on earlier is concurrency.

511
00:25:40.400 --> 00:25:40.599
<v Speaker 1>Right.

512
00:25:40.839 --> 00:25:43.480
<v Speaker 2>Remember we talked about how multiple threads might be accessing

513
00:25:43.480 --> 00:25:45.559
<v Speaker 2>the same resources concurrently, Right, and.

514
00:25:45.519 --> 00:25:48.799
<v Speaker 1>Those race conditions where the outcome of an operation can

515
00:25:48.839 --> 00:25:52.640
<v Speaker 1>depend on the unpredictable timing of different threads.

516
00:25:53.319 --> 00:25:57.319
<v Speaker 2>Yeah, exactly, And if you're not careful, those race conditions

517
00:25:57.359 --> 00:26:01.559
<v Speaker 2>can lead to data corruption, dem in stability, all sorts

518
00:26:01.599 --> 00:26:02.680
<v Speaker 2>of nasty surprises.

519
00:26:02.880 --> 00:26:03.359
<v Speaker 1>Yeah.

520
00:26:03.400 --> 00:26:06.400
<v Speaker 2>So mini filtered developers need to be very, very diligent

521
00:26:06.480 --> 00:26:13.000
<v Speaker 2>about synchronization, you know, using techniques like locks, semaphores, atomic

522
00:26:13.079 --> 00:26:16.799
<v Speaker 2>operations to ensure that shared resources are accessed in a

523
00:26:17.160 --> 00:26:18.440
<v Speaker 2>safe and orderly manner.

524
00:26:18.680 --> 00:26:21.920
<v Speaker 1>It's like choreographing a very complex dance, right, making sure

525
00:26:21.920 --> 00:26:24.279
<v Speaker 1>all the dancers are moving in sync. No one's stepping

526
00:26:24.279 --> 00:26:25.359
<v Speaker 1>on anyone else's toes.

527
00:26:25.440 --> 00:26:28.960
<v Speaker 2>That's a great analogy. And it's not just about synchronizing

528
00:26:29.000 --> 00:26:32.079
<v Speaker 2>access to data structures within the mini filter itself, right,

529
00:26:32.319 --> 00:26:36.200
<v Speaker 2>minifilters also have to synchronize their actions with other kernel components,

530
00:26:36.240 --> 00:26:38.200
<v Speaker 2>you know, like the file system, the ile manager.

531
00:26:38.400 --> 00:26:43.359
<v Speaker 1>It sounds incredibly intricate. Yusifovich mentioned something called opportunistic locks

532
00:26:43.480 --> 00:26:46.240
<v Speaker 1>or oplocks for short. Are those related to this whole

533
00:26:46.279 --> 00:26:47.640
<v Speaker 1>synchronization challenge?

534
00:26:47.720 --> 00:26:50.720
<v Speaker 2>They are? Yeah, So op blocks or a mechanism that

535
00:26:50.839 --> 00:26:54.359
<v Speaker 2>allows mini filters to acquire exclusive access to a file,

536
00:26:54.960 --> 00:26:56.240
<v Speaker 2>you know, for a short period of time.

537
00:26:56.319 --> 00:26:58.160
<v Speaker 1>So it's like putting a do not disturb sign on

538
00:26:58.200 --> 00:27:00.720
<v Speaker 1>a file while the minifilter is working on it precisely.

539
00:27:01.279 --> 00:27:05.640
<v Speaker 2>And this can be incredibly useful for operations that require

540
00:27:05.680 --> 00:27:09.279
<v Speaker 2>that exclusive access, you know, like caching, encryption, or deduplication.

541
00:27:09.920 --> 00:27:12.240
<v Speaker 1>But those operations might take a while to complete, right,

542
00:27:12.240 --> 00:27:14.759
<v Speaker 1>So what happens if another process wants to access that

543
00:27:14.839 --> 00:27:17.799
<v Speaker 1>file while the mini filter is holding that OP block.

544
00:27:18.079 --> 00:27:21.599
<v Speaker 2>That's where the opportunistic part comes in. Okay, So when

545
00:27:21.680 --> 00:27:24.480
<v Speaker 2>a mini filter acquires an op block, it can actually

546
00:27:24.480 --> 00:27:27.720
<v Speaker 2>specify the conditions under which it's willing to release that lock.

547
00:27:28.319 --> 00:27:31.000
<v Speaker 2>For example, it might release the lock if another process

548
00:27:31.039 --> 00:27:33.400
<v Speaker 2>wants to write to the file, but hold onto it

549
00:27:33.440 --> 00:27:35.599
<v Speaker 2>if the other process only wants to read from the file.

550
00:27:36.240 --> 00:27:38.599
<v Speaker 1>Okay, So it's a way for mini filters to kind

551
00:27:38.599 --> 00:27:42.119
<v Speaker 1>of share access to files in a controlled and efficient

552
00:27:42.160 --> 00:27:46.039
<v Speaker 1>way without sacrificing data integrity or performance exactly.

553
00:27:46.079 --> 00:27:48.480
<v Speaker 2>And Yosefovich goes into a lot of detail about the

554
00:27:48.519 --> 00:27:52.279
<v Speaker 2>different types of oplocks, you know, how they're acquired and released,

555
00:27:52.640 --> 00:27:54.799
<v Speaker 2>and the various scenarios where they can be used.

556
00:27:54.839 --> 00:27:57.240
<v Speaker 1>It's clear that oplocks are a powerful tool in the

557
00:27:57.920 --> 00:28:02.000
<v Speaker 1>minifilter developer's arsenal. But let's shift gears for a moment

558
00:28:02.039 --> 00:28:05.319
<v Speaker 1>and talk about performance. We've discussed how mini filters can

559
00:28:05.359 --> 00:28:09.880
<v Speaker 1>intercept and manipulate IRPs, and that could potentially introduce, you know,

560
00:28:10.000 --> 00:28:14.400
<v Speaker 1>additional processing overhead. How do developers make sure that their

561
00:28:14.400 --> 00:28:18.359
<v Speaker 1>minifilters are as efficient as possible and don't negatively impact

562
00:28:18.519 --> 00:28:20.720
<v Speaker 1>the overall performance of the system.

563
00:28:21.319 --> 00:28:25.359
<v Speaker 2>Performance is always a critical concern in kernel development, right,

564
00:28:26.119 --> 00:28:31.039
<v Speaker 2>and many filters are no exception. Yosefovich actually dedicates a

565
00:28:31.039 --> 00:28:35.079
<v Speaker 2>whole section of his book to optimization techniques okay, and

566
00:28:35.200 --> 00:28:37.839
<v Speaker 2>one of the key principles is to minimize the amount

567
00:28:37.880 --> 00:28:40.680
<v Speaker 2>of time that the mini filter spends processing each IRP.

568
00:28:41.039 --> 00:28:43.359
<v Speaker 1>Makes sense, so the less time the minifilter is holding

569
00:28:43.359 --> 00:28:48.160
<v Speaker 1>onto an IRP, the faster that request can be completed.

570
00:28:47.759 --> 00:28:51.000
<v Speaker 2>Exactly, And there are several strategies that developers can use

571
00:28:51.039 --> 00:28:53.839
<v Speaker 2>to achieve that. One common technique is to use caching.

572
00:28:54.480 --> 00:28:56.279
<v Speaker 2>You know, if a mini filter needs to perform some

573
00:28:56.960 --> 00:29:01.720
<v Speaker 2>complex operation like encryption or decryption, able to cash the

574
00:29:01.759 --> 00:29:04.559
<v Speaker 2>results of that operation so it doesn't have to repeat

575
00:29:04.599 --> 00:29:06.839
<v Speaker 2>the work every time the same request comes through.

576
00:29:06.720 --> 00:29:09.400
<v Speaker 1>So it's like keeping a cheat sheet handy, right, avoid

577
00:29:09.480 --> 00:29:12.559
<v Speaker 1>having to redo the same calculations.

578
00:29:11.880 --> 00:29:15.960
<v Speaker 2>Over and over again exactly. Another technique is to defer processing.

579
00:29:16.720 --> 00:29:18.680
<v Speaker 2>You know, if a mini filter doesn't need to act

580
00:29:18.720 --> 00:29:22.319
<v Speaker 2>on an IRP immediately, it can simply pass it along

581
00:29:22.359 --> 00:29:24.720
<v Speaker 2>to the next driver in the chain and then handle

582
00:29:24.720 --> 00:29:26.200
<v Speaker 2>it insynchronously later on.

583
00:29:26.400 --> 00:29:28.880
<v Speaker 1>So it's kind of like delegating a task to someone else, right,

584
00:29:28.920 --> 00:29:31.440
<v Speaker 1>so you can focus on more urgent matters precisely.

585
00:29:31.759 --> 00:29:34.839
<v Speaker 2>And there are even more advanced techniques like using work

586
00:29:34.839 --> 00:29:38.799
<v Speaker 2>items or system threads to offload processing to a separate context,

587
00:29:39.000 --> 00:29:42.200
<v Speaker 2>freeing up that main driver thread to handle other requests.

588
00:29:42.680 --> 00:29:45.960
<v Speaker 1>Many filter performance optimization. That sounds like a delicate balancing act.

589
00:29:46.039 --> 00:29:48.799
<v Speaker 1>That is a yeah, requiring and deep understanding of the

590
00:29:48.880 --> 00:29:53.200
<v Speaker 1>kernel's inner workings and a willingness to you know, experiment

591
00:29:53.279 --> 00:29:54.319
<v Speaker 1>and fine tune.

592
00:29:54.640 --> 00:29:57.400
<v Speaker 2>Definitely, but the rewards are worth it. You know, a

593
00:29:57.920 --> 00:30:02.839
<v Speaker 2>well optimized minifilter and provide really valuable functionality without noticeably

594
00:30:02.880 --> 00:30:07.039
<v Speaker 2>impacting the system's performance. Right, and Yusifovich provides some excellent

595
00:30:07.039 --> 00:30:09.720
<v Speaker 2>guidance on how to achieve that delicate balance.

596
00:30:10.119 --> 00:30:13.039
<v Speaker 1>This has been an incredible journey, it has. We've explored

597
00:30:13.039 --> 00:30:15.880
<v Speaker 1>the fundamentals of the Windows kernel. We delved into the

598
00:30:15.920 --> 00:30:20.279
<v Speaker 1>intricacies of many filters, uncovered a world of complexity and

599
00:30:20.319 --> 00:30:24.960
<v Speaker 1>power that most people frankly never even know exists. Right, But,

600
00:30:25.079 --> 00:30:27.680
<v Speaker 1>as we wrap up, one final question for you, For

601
00:30:27.720 --> 00:30:30.599
<v Speaker 1>those listening who are feeling inspired to learn more, to

602
00:30:30.680 --> 00:30:34.000
<v Speaker 1>maybe even explore the world of kernel development themselves, what

603
00:30:34.039 --> 00:30:35.359
<v Speaker 1>advice would you give them?

604
00:30:35.839 --> 00:30:38.640
<v Speaker 2>First and foremost, I would say, embrace the challenge, right,

605
00:30:39.039 --> 00:30:41.400
<v Speaker 2>I mean, clernel development is not easy, but it is

606
00:30:41.440 --> 00:30:44.720
<v Speaker 2>incredibly rewarding. It's like learning a new language, a language

607
00:30:44.720 --> 00:30:47.599
<v Speaker 2>that allows you to communicate directly with with the heart

608
00:30:47.599 --> 00:30:48.559
<v Speaker 2>of the operating system.

609
00:30:48.599 --> 00:30:51.480
<v Speaker 1>It's like cracking a secret code, gaining access to this

610
00:30:52.079 --> 00:30:53.759
<v Speaker 1>hidden world of knowledge and.

611
00:30:53.680 --> 00:30:56.680
<v Speaker 2>Power exactly, and as you embark on that journey, be

612
00:30:56.799 --> 00:31:00.920
<v Speaker 2>sure to arm yourself with the right tools and resources.

613
00:31:01.200 --> 00:31:04.880
<v Speaker 2>Pavel Yusifovich's book is an excellent starting point, provides a

614
00:31:04.920 --> 00:31:08.400
<v Speaker 2>really comprehensive and insightful guide to the world of Windows

615
00:31:08.480 --> 00:31:09.359
<v Speaker 2>Kernel programming.

616
00:31:09.559 --> 00:31:12.319
<v Speaker 1>Couldn't agree more. It's been an invaluable resource for us

617
00:31:12.319 --> 00:31:14.920
<v Speaker 1>as we've gone through all the twists and turns of

618
00:31:14.960 --> 00:31:18.559
<v Speaker 1>this deep dive, and for our listeners. If you're intrigued

619
00:31:18.559 --> 00:31:21.039
<v Speaker 1>by what you've heard today, I highly encourage you to

620
00:31:21.119 --> 00:31:25.400
<v Speaker 1>check out Yusifovich's book. A deep dive into a world

621
00:31:25.440 --> 00:31:29.200
<v Speaker 1>that is both fascinating and challenging, a world where the

622
00:31:29.240 --> 00:31:32.640
<v Speaker 1>possibilities are really only limited by your imagination.

623
00:31:32.920 --> 00:31:35.480
<v Speaker 2>And who knows, maybe one day you'll be one of

624
00:31:35.519 --> 00:31:39.559
<v Speaker 2>the people creating the software that powers our digital lives,

625
00:31:40.000 --> 00:31:42.240
<v Speaker 2>shaving the future of technology in ways that you never

626
00:31:42.279 --> 00:31:43.000
<v Speaker 2>thought possible.

627
00:31:43.119 --> 00:31:45.119
<v Speaker 1>That's a perfect note to end on. Thank you for

628
00:31:45.200 --> 00:31:47.599
<v Speaker 1>joining us on this deep dive into the Windows kernel.

629
00:31:47.799 --> 00:31:51.160
<v Speaker 1>Until next time, keep exploring, keep learning, and keep pushing

630
00:31:51.200 --> 00:31:52.519
<v Speaker 1>the boundaries of what's possible.
