@@ -338,21 +338,21 @@ debug.sethook(print, "l")
338
338
在这种方案下,分析器可以获取 ` arg[1] ` 中的文件名,打开钩子并运行该文件:
339
339
340
340
``` lua
341
- {{# include ../ scripts / profiler .lua :15 :18 }}
341
+ {{# include ../ scripts / reflection / profiler .lua :15 :18 }}
342
342
```
343
343
344
344
最后一步是显示结果。图 25.3 “获取函数名称” 中的函数 ` getname ` ,会产生某个函数的名字。
345
345
346
346
<a name =" f-25.3 " ></a > ** 图 25.3,获取函数名字**
347
347
348
348
``` lua
349
- {{# include ../ scripts / profiler .lua :20 :32 }}
349
+ {{# include ../ scripts / reflection / profiler .lua :20 :32 }}
350
350
```
351
351
352
352
由于 Lua 中函数的名字非常不确定,因此我们给各个函数添加了位置,以 ` file:line ` 对的形式给出。若某个函数没有名字,我们就只使用其位置。对于 C 函数,我们只使用其名字(因为他没有位置)。该定义之后,我们就要打印各个函数及其计数器:
353
353
354
354
``` lua
355
- {{# include ../ scripts / profiler .lua :34 :}}
355
+ {{# include ../ scripts / reflection / profiler .lua :34 :}}
356
356
```
357
357
358
358
若咱们将咱们的分析器,应用到 [ 第 19 章 “插曲:马可夫链算法“] ( markov_chain_algorithm.md ) 中开发的 Markov 示例,咱们会得到如下结果:
@@ -396,42 +396,40 @@ nil 1
396
396
** Sandboxing**
397
397
398
398
399
- 在 [ “` _ENV ` 与 ` load ` ”] ( env.md#_env-与-load ) 小节中 ,我们曾看到使用 ` load ` 特性,在受限环境中运行某个 Lua 片段是多么容易。由于 Lua 与外部世界的所有通信,都是通过库函数完成的 ,因此一旦我们移除这些函数,也就消除了脚本对外部世界产生任何影响的可能性。不过,在脚本浪费大量 CPU 时间或内存下,我们仍然容易受到拒绝服务,denial of service,DoS 的攻击 。调试钩子形式下的反射,为遏制此类攻击提供了一种有趣方法。
399
+ 在称为 [ “` _ENV ` 与 ` load ` ”] ( env.md#_env-与-load ) 的小节 ,我们曾看到使用 ` load ` 功能在受限环境中,运行某个 Lua 片段是多么容易。由于 Lua 与外部世界的所有通信,都是通过库函数完成 ,因此一旦我们移除这些函数,也就消除了脚本对外部世界产生任何影响的可能性。不过,在脚本浪费大量 CPU 时间或内存下,我们仍然容易受到拒绝服务,denial of service,DoS 攻击 。调试钩子形式下的反射,为遏制此类攻击提供了一种有趣方法。
400
400
401
401
402
- 第一步是使用计数钩子,限制某个代码块可以执行的指令数量 。图 25.4 “使用钩子的简单沙箱”,展示了一个在这种沙箱中运行给定文件的程序 。
402
+ 第一步是使用计数钩子限制某个代码块可执行的指令数量 。图 25.4 “使用钩子的简单沙箱”,展示了在这种沙箱中运行给定文件的一个程序 。
403
403
404
404
<a name =" f-25.4 " ></a > ** 图 25.4,使用钩子的简单沙箱**
405
405
406
406
``` lua
407
407
{{# include ../ scripts / reflection / naive_sandbox .lua }}
408
408
```
409
409
410
- 程序加载给定文件,设置钩子,然后运行该文件。程序将钩子设置为计数钩子 ,这样 Lua 就会每 100 个指令调用一次钩子。钩子 (函数` step ` )只是递增一个计数器,并将其与一个固定限制进行比较。可能会出什么问题呢 ?
410
+ 程序加载给定文件,设置钩子,然后运行该文件。程序将其中的钩子设置为了计数钩子 ,这样 Lua 就会每 100 个指令调用一次钩子。这个钩子 (函数` step ` )只会递增一个计数器,并将其与一个固定限制做检查。那么可能会出什么问题呢 ?
411
411
412
- 当然,我们必须限制所加载代码块大小:只要加载一个巨大块 ,就会在加载时耗尽内存。另一个问题是,正如下面这个片段所示,程序可以用少得惊人的指令,消耗大量内存:
412
+ 当然,我们必须限制加载代码块大小:只要加载某个巨大代码块 ,就会在加载时耗尽内存。另一个问题是,正如下面这个片段所示,程序可以用少得惊人的指令,消耗大量内存:
413
413
414
414
``` lua
415
415
local s = " 123456789012345"
416
416
for i = 1 , 36 do s = s .. s end
417
417
```
418
418
419
- 在不到 150 条指令下,这个小片段就将尝试创建一个 1 TB 的字符串。显然,仅限制步骤和程序大小是不够的 。
419
+ 只需不到 150 条指令,这个小片段就将尝试创建出一个 1 TB 的字符串。显然,仅限制步骤数和程序大小是不够的 。
420
420
421
- 如图 25.5 “控制内存使用” 所示,一种改进方法是,在 ` step ` 函数中,检查并限制内存使用。
421
+ 如图 25.5 “控制内存使用” 所示,一种改进是在 ` step ` 函数中,检查并限制内存使用。
422
422
423
423
424
424
<a name =" f-25.5 " ></a > ** 控制内存使用**
425
425
``` lua
426
426
{{# include ../ scripts / reflection / improved_sandbox .lua :3 :22 }}
427
-
428
- -- 如前
429
427
```
430
428
431
429
432
- 由于在如此少的指令下,内存就能快速增长,我们应该设置一个非常低的限制,或者以小的步骤调用钩子。更具体地说,某个程序可以在 40 条指令内,将某个字符串的大小增加一千倍。因此,我们要么以比每 40 步更高的频率调用钩子,要么将内存限制设为我们真正能承受的千分之一。我(作者)可能会两者兼顾。
430
+ 由于在如此少的指令下,内存就能快速增长,我们应该设置一个非常低的限制,或者以小的步骤调用钩子。更具体地说,某个程序可以在 40 条指令内,将某个字符串的大小增加一千倍。因此,要么我们以比每 40 步更高的频率调用钩子,要么将内存限制设为我们真正能承受的千分之一。我(作者)可能会两者兼顾。
433
431
434
- 更微妙的问题便是 Lua 的字符串库。我们可在某个字符串上,以方法方式调用这个库中的任何函数 。因此,即使这些函数不在环境中,我们也可以调用他们;字面的字符串会将他们,偷偷地带入我们的沙箱。字符串库中的任何函数,都不会影响外部世界, 但他们会绕过我们的步骤计数器。(对 C 函数的一次调用,会算作 Lua 中的一条指令。)字符串库中的某些函数,可能是非常危险的 DoS 攻击。例如,在一个步骤中调用 ` (“x”):rep(2^30) ` 一次,就会吞噬 1 GB 的内存。再举个例子,在我(作者)的新机器上,运行下面的调用 Lua 5.2 需要 13 分钟:
432
+ 更微妙的问题是 Lua 的字符串库。在某个字符串上,我们可以方法的形式调用这个库中的任何函数 。因此,即使这些函数不在环境中,我们也可以调用他们;字面的字符串会将他们偷偷地带入我们的沙箱。字符串库中的任何函数都不会影响外部世界, 但他们会绕过我们的步骤计数器。(对某个 C 函数的一次调用,算作 Lua 中的一条指令。)字符串库中的某些函数,可能是非常危险的 DoS 攻击。例如,在某个步骤中调用 ` (“x”):rep(2^30) ` 一次,就会吞噬 1 GB 的内存。再举个例子,在我(作者)的新机器上运行下面的调用, Lua 5.2 需要 13 分钟:
435
433
436
434
437
435
``` lua
@@ -440,7 +438,7 @@ s:find(".*.*.*.*.*.*.*.*.*x")
440
438
```
441
439
442
440
443
- 限制对字符串库访问的一种有趣方法,是使用调用钩子 。每次调用某个函数时,我们都会检查该函数是否经过授权 。下图 25.6 “使用钩子禁止对未授权函数的调用”,实现了这一想法。
441
+ 限制对字符串库访问的一种有趣方法,是使用 ` call ` 钩子 。每次调用某个函数时,我们都要检查该函数是否经过授权 。下图 25.6 “使用钩子禁止对未授权函数的调用”,实现了这一想法。
444
442
445
443
446
444
<a name =" f-25.6 " ></a > ** 使用钩子禁止对未授权函数的调用**
0 commit comments