# 第 66 期：反向拆解让人上瘾的套路，找回自律

> @Author : Lewis Tian (<taseikyo@gmail.com>)
>
> @Link : github.com/taseikyo
>
> @Range : 2024-06-09 - 2024-06-15

## Weekly #66

[readme](https://taseikyo.gitbook.io/arts/readme) | [previous](https://taseikyo.gitbook.io/arts/liu-yue/202406w1) | [next](https://taseikyo.gitbook.io/arts/liu-yue/202406w3)

本文总字数 4903 个，阅读时长约：6 分 22 秒，统计数据来自：[算筹字数统计](http://www.xiqei.com/tools?p=tj)。

![](https://3093055548-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MMdedjHJjq-FX7CAnHy%2Fuploads%2Fgit-blob-26a1f18314c2d6779c0cce8766a1a90c1aecb039%2Fluke-witter-DersxYwcciQ-unsplash.jpg?alt=media)

\**Photo by* [*Luke Witter*](https://unsplash.com/@lukewitter) *on* [*Unsplash*](https://unsplash.com/photos/a-man-riding-a-bike-next-to-a-body-of-water-DersxYwcciQ)

### Table of Contents

* [algorithm](#algorithm-)
* [review](#review-)
  * 如果你能正确回答这 7 个问题，你就很擅长 Python
  * 在 Linux 中获取 PID 的 CR3 值
* [tip](#tip-)
* [share](#share-)
  * 反向拆解让人上瘾的套路，找回自律

### algorithm [🔝](#weekly-66)

### review [🔝](#weekly-66)

#### 1. [如果你能正确回答这 7 个问题，你就很擅长 Python](https://zlliu.medium.com/youre-decent-at-python-if-you-can-answer-these-7-questions-correctly-7de5e8279e7f)

1、`@print`

```python
@print
def testing():
    print('hello!!')
    return 1000
```

What does this do?

```markdown
A) Syntax error. There is no such thing as @ in Python
B) this causes testing() to automatically print 1000 when we call it
C) this prints <function testing at 0x1023e2340>
D) this prints 1000 automatically without us calling testing()
E) testing()'s metadata will automatically print whenever it is called
```

<details>

<summary>Answer</summary>

Answer: C

here, we are decorating testing() with print(). This is the same as:

```python
def testing():
    print('hello!!')
    return 1000

testing = print(testing)
```

since print(testing) is called, \<function testing at 0x1023e2340> will be printed (the gibberish numbers at the end might differ tho)

</details>

2、`*_`

```python
a, b, *_ = [1, 2, 3, 4, 5]
print(_)
```

What does this print?

```
A) Syntax error
B) [3, 4, 5]
C) [1, 2, 3, 4, 5]
D) <generator object <genexpr> at 0x1003847c0>
E) NameError: ‘_’ is not a valid variable name
```

<details>

<summary>Answer</summary>

Answer: B

* `_` is a valid variable name
* `a` is assigned to 1 and `b` is assigned to 2 (tuple unpacking)
* `*` in front of `_` allows `_` to "catch" multiple values (0 to infinite)
* `_` will thus "catch" all unassigned numbers — 3, 4, 5
* `_` will thus be `[3, 4, 5]`

</details>

3、more than 1 `*_`

```python
*__, a, b, *_ = [1, 2, 3, 4, 5, 6]
print(__, _)
```

What does this print?

```
A) Syntax error
B) [1] [4, 5, 6]
C) [1, 2] [5, 6]
D) [1, 2, 3] [6]
E) <generator object <genexpr> at 0x1003847c0>
```

<details>

<summary>Answer</summary>

Answer: A

Only ONE `*` is allowed per expression. Having 2 causes a SyntaxError

</details>

4、class shenanigans

```python
class Dog:
  def __init__(self, *args, **kwargs):
    args, kwargs = kwargs, args
    self.name = args['name']
    self.age = kwargs[0]

dog = Dog('rocky', 5)
```

What error does this cause?

```
A) No error
B) ZeroDivisionError
C) IndexError
D) KeyError
E) All of the above
```

<details>

<summary>Answer</summary>

Answer: D

`*args` allows our function to take in any number of positional arguments, while `**kwargs` allow our function to take in any number of keyword arguments.

`Dog('rocky', 5)` passes 2 positional arguments to `__init__`, and thus `args=('rocky', 5)` while `kwargs={}` (no keyword arguments here)

`args, kwargs = kwargs, args` switches args and kwargs. So now, `args={}` and `kwargs=('rocky', 5)`

When we attempt to call `args['name']`, we get a KeyError as at this point, args is an empty dictionary.

</details>

5、GIL

What is the Python Global Interpreter Lock (GIL)?

```
A) a physical lock that secures Python servers from intruders
B) a thing that prevents the Python interpreter from leaking data to other processes on your computer
C) a programming paradigm that allows us to run multiple Python processes concurrently
D) a thing that allows one thread to run per interpreter at one time
E) a thing that enables our Python interpreter to run code faster
```

<details>

<summary>Answer</summary>

Answer: D

The Python GIL makes is such that only 1 thread is able to run in the Python interpreter at one time. (tho we can use multiprocessing to circumvent this)

</details>

6、True = False

```python
True = False
False = True

print(not True, not False)
```

what does this print?

```
A) SyntaxError
B) False True
C) True False
D) True True
E) False False
```

<details>

<summary>Answer</summary>

Answer: A

We cannot assign anything to True as True is a reserved Python keyword. I hope you answered this correctly.

</details>

7、Context manager

What is a context manager used for?

```
A) to manage contexts
B) to properly handle resources eg file operations or databases
C) to ensure that type hints in Python are enforced
D) to make sure that any exceptions do not affect other contexts
E) to ensure that the Python interpreter does not taking up an excessive amount of RAM
```

<details>

<summary>Answer</summary>

Answer: B

```python
# let's say we need to read a file

file = open('hi.txt')

print(file.read())

file.close()
```

if we do this, there’s a chance that `file.close()` might not executed due to some error. Not closing the file might lead to the following problems:

* the file might take up RAM and slow down your program
* changes made to the file might not stick, as many files only save properly when they are closed
* in Windows, a file is treated as locked when it is open, so other scanners or programs might not be able to read it
* and other weird issues

```python
# reading file using context manager

with open('hi.txt') as file:
    print(file.read())
```

</details>

#### 2. [在 Linux 中获取 PID 的 CR3 值](https://carteryagemann.com/pid-to-cr3.html)

由于互联网上缺乏示例，编写低级代码可能很困难。 答案通常位于 3,000 页手册的某个地方，只有最敬业的程序员才能找到它。

上周我有过这样的经历。目前，我的研究涉及大量特定于 x86 的编程和虚拟机自省 （VMI）。 为了测试我正在开发的概念验证虚拟机管理程序之一，我需要一种方法来快速将 Linux PID 值转换为相应的 在 CPU 上执行该进程时加载到 CR3 寄存器中的值。对于那些不熟悉 x86 CPU 架构的人， 我建议在Linux x86页面表管理上阅读此页面。 简而言之，当一个进程在 x86 CPU 上执行时，CR3 寄存器会加载该进程的页面全局目录 （PGD） 的物理地址。 这是必需的，以便 CPU 可以执行从虚拟内存地址到物理内存地址的转换。 由于每个进程都需要自己的 PGD，因此 CR3 寄存器中的值对于系统中的每个计划进程都是唯一的。 这对 VMI 来说非常方便，因为这意味着我们不需要不断扫描客户机内核的内存来跟踪哪个进程 正在执行。相反，我们可以只监控对 CR3 寄存器的写入。

但是，仅仅跟踪 CR3 寄存器的更改并不能让我们深入了解客户机内核在做什么。 这通常被称为语义差距问题。为了跨越这个差距，我们需要绘制我们感兴趣的过程的 PID 值 到其相应的 CR3 值。以下 Linux 内核模块代码片段就是这样做的：

```c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/pid.h>
#include <asm/io.h>

unsigned long pid_to_cr3(int pid)
{
    struct task_struct *task;
    struct mm_struct *mm;
    void *cr3_virt;
    unsigned long cr3_phys;

    task = pid_task(find_vpid(pid), PIDTYPE_PID);

    if (task == NULL)
        return 0; // pid has no task_struct

    mm = task->mm;

    // mm can be NULL in some rare cases (e.g. kthreads)
    // when this happens, we should check active_mm
    if (mm == NULL) {
        mm = task->active_mm;
    }

    if (mm == NULL)
        return 0; // this shouldn't happen, but just in case

    cr3_virt = (void *) mm->pgd;
    cr3_phys = virt_to_phys(cr3_virt);

    return cr3_phys;
}
```

应该注意的是，虽然 CR3 寄存器可用于跟踪正在执行的进程，但它无法跟踪正在执行的线程 因为线程共享内存，因此将具有相同的 PGD 和 CR3 值。通过内省跟踪线程的调度是 一个更复杂的任务，是另一个时间的话题。

为简单起见，我将转换代码实现为 Linux 内核模块。如果您对如何使用纯内省进行此转换感兴趣 在未修改的内核上，您应该查看 [libVMI](https://github.com/libvmi/libvmi/blob/master/libvmi/os/linux/memory.c#L145) 的代码。

### tip [🔝](#weekly-66)

### share [🔝](#weekly-66)

#### 1. [反向拆解让人上瘾的套路，找回自律](https://xugaoyi.com/pages/d6d331/#%E6%89%BE%E5%9B%9E%E8%87%AA%E5%BE%8B-%E6%94%B6%E8%8E%B7%E7%A7%AF%E6%9E%81%E8%80%8C%E9%95%BF%E4%B9%85%E7%9A%84%E5%BF%AB%E4%B9%90)

当你打开手机准备学习或者查个资料的时候，很有可能不知不觉的就脱离的正规... 某某 app 发来通知：xx 明星官宣啦、xx 手游重磅上线，一起开启修仙之旅吧！ xx 结衣发布新番 - 4k 画质 & AR 体验、99 + 未读信息、支付宝到账 100 万元.... 你心想，就看一会，就一会儿... 不知不觉两三个小时过去了，你开始焦躁、后悔、自责。第二天，你又掉进相同的坑里。你可能会纳闷，为什么我的自制力这么差？为什么对某件事欲罢不能？

> 《欲罢不能》
>
> 数字时代比人类历史上的任何时代都更容易上瘾...Facebook、Instagram、网络色情、网购在下钩... 问题不出在人缺乏意志力上，而在于 “屏幕那边有数千人在努力工作，为的就是破坏你的自律”
>
> 来自《欲罢不能 - 刷屏时代如何摆脱行为上瘾》一书

我们正在被一个算法和娱乐所包裹的电子 ' 海洛因 ' 中却不自知，想要摆脱这些上瘾行为，第一步就是反向拆解那些让我们上瘾的产品的套路。《欲罢不能》书中总结了六个让人上瘾的钩子：

1、诱人的目标

* 色情片
* 游戏中成为 "王者"、层出不穷的高颜值皮肤...

2、无法抵挡无法预知的积极反馈

* 社交中的点赞功能
* 某音十几秒一条的视频，不需要你动脑就可以轻轻松松获得哈哈大笑的快感，有时候还有一种我学习到了的感觉，你永远猜不到下一条将会出现什么惊喜。你刷的越多算法就越精准，越知道你的情绪 G 点在哪里，你就越容易被俘获。
* 直播中的打赏被主播表示的感谢和送上的 ' 么么哒'

3、渐进式的进步和改善的感觉

* 游戏中的升级策略

4、随着时间的推移越来越困难的任务

* 游戏中的升级策略

5、需要解决却又暂未解决的紧张感

* 电影或电视剧结尾有意制造的一个悬念，给你一种未完成的紧张感，你迫切想知道后面会发生什么

6、强大的社会联系

* 与队友相约开黑
* 游戏中能彰显地位、财富、能力等的装备（如：吃鸡游戏中的玛莎拉蒂皮肤）

获得快乐的方式，你可以选择沉迷在你的手机里刷视频、打游戏、煲剧，毫不费力的收货大把的快乐。你还可以选择一条更难的路：选择自律、选择延迟满足、选择会让你不那么舒服的努力和成长。

收获快乐的方式没有绝对的对与错，但是，如果快乐触手可及，这种廉价的快乐也就不值得珍惜，随时都可能抛弃。过后还可能让你浪费了大把时间，该做的正事没有完成，你感觉空虚、焦躁、自责...

既然如此，我们一起选择那条更难的路吧！

[readme](https://taseikyo.gitbook.io/arts/readme) | [previous](https://taseikyo.gitbook.io/arts/liu-yue/202406w1) | [next](https://taseikyo.gitbook.io/arts/liu-yue/202406w3)
