C#语法

模式匹配+is/not/and/or关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int[] numbers = { 1, 2, 3 };

Console.WriteLine(numbers is [1, 2, 3]); //true
Console.WriteLine(numbers is [3, 2, 1]); //false
Console.WriteLine(numbers is [1 or 2, <= 2, <=3]); //true
Console.WriteLine(numbers is [_, _, _]); //true

//Capture a variable.
if(numbers is [var a, _, 3])
{
Console.WriteLine($"The first element of numbers is {a}");
}

//You can also nest a subpattern within a slice pattern.

Console.WriteLine(new[] { 1, 2, 3, 4, 5 } is [> 0, > 0, ..]); // true
Console.WriteLine(new[] { 1, 1 } is [_, _, ..]); // true
Console.WriteLine(new[] { 0, 1, 2, 3, 4 } is [> 0, > 0, ..]); // false
Console.WriteLine(new[] { 1 } is [1, 2, ..]); // false

Console.WriteLine(new[] { 1, 2, 3, 4 } is [.., > 0, > 0]); // true
Console.WriteLine(new[] { 2, 4 } is [.., > 0, 2, 4]); // false
Console.WriteLine(new[] { 2, 4 } is [.., 2, 4]); // true

Console.WriteLine(new[] { 1, 2, 3, 4 } is [>= 0, .., 2 or 4]); // true
Console.WriteLine(new[] { 1, 0, 0, 1 } is [1, 0, .., 0, 1]); // true
Console.WriteLine(new[] { 1, 0, 1 } is [1, 0, .., 0, 1]); // false

switch高级用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//Switch + Pattern matching
int a = 2, b = 2;
switch(a, b)
{
case (1, 2):
Console.WriteLine($"a = {a}, b = {b}");// if a = 1, b = 2
break;
case (2, 2) when a != b:
Console.WriteLine($"a = {a}, b = {b}"); // Cannot reach here.
break;
case (>0, >0):
Console.WriteLine($"a = {a}, b = {b}"); // bigger than zero.
break;
case (_, _):
Console.WriteLine($"a = {a}, b = {b}"); // same with default.
break;
}

//or maybe more brief...
int a = 2, b = 2;

bool c = (a, b) switch
{
(1, 2) => true,
( > 1, > 2) => false,
_ => false // same with (_, _) => false
};

//and so on...
int a = 2, b = 2;

int c = (a, b) switch
{
{ a: 0, b: 1 } => -1, // a = 0, b = 1, c = -1
{ a: var x, b: var y } when x > y => x - y, // capture a, b, when a > b, c = a - b
{ a: var x, b: var y } when x < y => y - x, // capture a, b, when a < b, c = b - a
{ a: var x, b: var y } => x * y, // capture a, b, default(a = b) c = a * b
};

record类

从 C# 9 开始,可以使用 record 关键字定义一个record,用来提供用于封装数据的内置功能。 C# 10 允许 record class 语法作为同义词来阐明引用类型,并允许 record struct 使用相同功能定义值类型。 通过使用位置参数或标准属性语法,可以创建具有不可变属性的记录类型。

两种声明方式:

1
2
3
public record Person(string FirstName, string LastName);
Person person = new("Zack", "Mount");
Console.WriteLine(person); // Person { FirstName = Zack, LastName = Mount }
1
2
3
4
5
6
7
public record Person
{
public required string FirstName { get; init; }
public required string LastName { get; init; }
};
Person person = new() { FirstName = "Zack", LastName = "Mount" };
Console.WriteLine(person); // Person { FirstName = Zack, LastName = Mount }

由于record的值不可变,使用with关键字,可以实现修改record属性的效果

1
2
3
4
5
6
7
8
Person person1 = new() { FirstName = "Zack", LastName = "Mount" };
Console.WriteLine(person1); // Person { FirstName = Zack, LastName = Mount }
var person2 = person1 with { FirstName = "Sakura", LastName = "Cora" };
Console.WriteLine(person2); // Person { FirstName = Sakura, LastName = Cora }
var person3 = person2 with {
LastName = "Desu!"
};
Console.WriteLine(person3); // Person { FirstName = Sakura, LastName = Desu! }

required关键字

语言集成查询LINQ

例如,用LINQ数聊天记录里有多少个‘您’字

1
2
3
4
5
6
7
8
9
10
11
var messages = File.ReadAllLines("D:\\聊天记录.txt");

int count = (
from line in messages // messages is an array, line is an element in messages
where line.Contains("您") // while the line contains "您"
from chr in line
where chr == '您' // select '您' in line
select chr
).Count();

Console.WriteLine(count);

或者,筛选结果

1
2
3
4
5
6
7
8
9
int[] numbers = { 6, 68, 71, 36, 90, 12, 62, 38 };

IEnumerable<int> below50 = (
from number in numbers
where number >= 50
select number
);

Console.WriteLine(string.Join(", ", below50)); //68, 71, 90, 62

甚至,使用orderby来对筛选结果排序, ascending是升序,descending是降序

1
2
3
4
5
6
7
8
9
10
int[] numbers = { 6, 68, 71, 36, 90, 12, 62, 38 };

IEnumerable<int> below50 = (
from number in numbers
where number >= 50
orderby number ascending // default is ascending, ignore it.
select number
);

Console.WriteLine(string.Join(", ", below50)); //62, 68, 71, 90

甚至嵌套,以第一个筛选“您”为例子,可以写成更容易读的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var messages = File.ReadAllLines("D:\\聊天记录.txt");

int count = (
from line in messages
let characters = (
from chr in line
where chr == '您'
select chr
)
where line.Contains("您")
select characters
).Sum(chars => chars.Count());

Console.WriteLine(count);

通过LINQ,查询可以写得非常骚气~代码在保持高可读性的情况下,仍然保持了优秀的效率,性能差距和传统写法并不大。

SMC

SMC,即自修改代码(Self-Modifying Code),很大程度上加大了静态分析的难度。

  1. 动态分析:因为 SMC 在运行时会改变自己的代码,因此,相比静态分析,动态分析会更有效。在运行时查看代码的变化,并在关键点设置断点,从而推断出程序流。

  2. 代码跟踪和日志记录:你可以使用工具来跟踪和记录所有执行的指令。然后你可以分析这些日志,找出代码修改和执行的模式。

  3. 绕过SMC:如果可能,可以尝试绕过SMC部分,直接获取或重构出原始的代码。SMC是通过一次性的解密或解压缩来改变代码,那么可以通过分析这个过程来获取原始代码。

  4. 逆向工程和代码分析工具:使用适合处理SMC的工具,如IDA Pro,Ghidra,radare2,binwalk,等等。这些工具可以帮助分析二进制文件,跟踪代码修改。

Session伪造/爆破

伪造脚本noraj/flask-session-cookie-manager: Flask Session Cookie Decoder/Encoder (github.com)

1
2
python flask_session_cookie_manager3.py decode -s '{Secret_Key}' -c '{Session}' 
python flask_session_cookie_manager3.py encode -s '{Secret_Key}' -t '{Session}'

爆破脚本

1
2
pip install flask-unsign			# 不带字典
pip install flask-unsign[wordlist] # 带字典

Usage

1
flask-unsign --unsign --cookie < cookie.txt