Skip to content

Commit

Permalink
update 20241212
Browse files Browse the repository at this point in the history
  • Loading branch information
c01dkit committed Dec 12, 2024
1 parent 56bd76c commit 54a10b9
Show file tree
Hide file tree
Showing 11 changed files with 246 additions and 7 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "mkdocs-toolchain"]
path = mkdocs-toolchain
url = https://github.com/TonyCrane/mkdocs-toolchain.git
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
## Deploy

git add .
git commit -m "xxx"
git push origin main:main

mkdocs gh-deploy --clean
mkdocs gh-deploy --clean

## Acknowledgments

Most of the blog configurations are from [Xiaokang2022](https://github.com/Xiaokang2022/)

The category menu plugin is from [TonyCrane](https://github.com/TonyCrane/).
20 changes: 20 additions & 0 deletions docs/algorithm-and-data-structure/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# 算法与数据结构

!!! note
有关算法与数据结构的一点笔记,先占个坑,之后慢慢填充


{{ BEGIN_TOC }}
- 算法:
- 贪心算法: algorithm/greedy-algo
- 动态规划算法: algorithm/dynamic-algo
- 图算法: algorithm/graph-algo
- 分支定界算法: algorithm/branch-and-bound-algo
- 数据结构:
- 数组: data-structure/array
- 堆栈: data-structure/stack
- 队列: data-structure/queue
- 链表: data-structure/linkedlist
- 树: data-structure/tree
- 图: data-structure/graph
{{ END_TOC }}
17 changes: 17 additions & 0 deletions docs/programming-languages/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# 编程语言

!!! note
有关各类编程语言的一点学习笔记,不定期更新


{{ BEGIN_TOC }}
- 编译型:
- C: c
- C++: cpp
- Go: go
- Java: java
- 解释型:
- Python: python
- 优化:
- 优雅编程: code-gracely
{{ END_TOC }}
18 changes: 18 additions & 0 deletions docs/researching-is-living/general/readings.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,31 @@

* [ESEC/FSE 2022网安清单](https://mp.weixin.qq.com/s/rzEIY-VUuxO8kj_wuh98dg)

## 报告PPT

* 2024-11-28 [清华大学:2024年AIGC发展研究报告3.0版(PPT)](https://mp.weixin.qq.com/s/rp8ijD8s5hlCEuKZzr9Fgg)

## AI 安全

* 2024-12-06 [一张图看清AI安全的位置](https://mp.weixin.qq.com/s/j4E6hJOInGQPRcouMyi0ig)

## 软件供应链

* [软件供应链检测工具现状分析](https://mp.weixin.qq.com/s/FCPBzsRg9XGnjlWbV64KmA)
* 2024-12-10 [黑白通吃:Glutton木马潜伏主流PHP框架,隐秘侵袭长达1年](https://mp.weixin.qq.com/s/1B0lv_Xuu8sAb0d55f-Rbw)

## 网络流量识别

* [基于包长语义的隧道内部攻击流量识别](https://mp.weixin.qq.com/s/tx4xsyLRkQDMUtWGCIsZzw)

## 大模型

* [智能安全运营:大模型工具协同与学习框架](https://mp.weixin.qq.com/s/azE65dTp9lBEumioBfIq8w)
* 2024-05-09 [今日arXiv最热大模型论文:浙江大学:如何减轻视觉大模型中的幻觉问题](https://mp.weixin.qq.com/s/ptJSDjM80uCZ4hewcyQs9g)
* 2024-12-08 [OpenAI的强化微调:RL+Science 创造新神还是灭霸?](https://mp.weixin.qq.com/s/faP5z275E45-U5EGHeSc3A)
* 2024-12-09 [北交开源o1代码版!强化学习+蒙特卡洛树搜索,源代码、精选数据集以及衍生模型通通开源](https://mp.weixin.qq.com/s/Y7qZDFtBklmoTeRUxjV_fw)
* 2024-12-09 [基于LLM的单元测试生成,你在第几级?](https://mp.weixin.qq.com/s/qRGjAFE-VlzaYuCfj0Kh6g)


## Google

Expand Down
13 changes: 13 additions & 0 deletions docs/software-security/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# 软件安全

!!! note
有关软件安全的一点笔记,主要包括一点CTF笔记(虽然不是ctfer),以及学习一些程序逆向、程序分析时的一点笔记。


{{ BEGIN_TOC }}
- 程序分析:
- 逆向分析: reverse/
- LLVM: program-analysis/llvm
- CTF:
- pwn.college: ctf/pwn-college-cse365-spring2023
{{ END_TOC }}
166 changes: 161 additions & 5 deletions docs/software-security/program-analysis/llvm.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ LLVM Pass工作在LLVM IR文件的基础之上。IR包括ll(文本格式,便
.bc -> .s: llc a.bc -o a.s
```

### 可视化

`opt -p dot-cfg xxx.ll`可以将ll文件生成.dot文件,进一步用Graphviz的`dot xxx.dot -Tpng -o xxx.png`生成CFG图片。

### 项目例子

利用LLVM构建静态分析框架时,考虑用cmake来组织整个项目的编译。假设需要构建一个程序,它接收一个bc文件名作为参数,然后用两个pass来进行处理,打印出bc文件所包含的函数名,以及函数的参数个数,可以这么来组织项目:
Expand Down Expand Up @@ -116,8 +120,146 @@ LLVM Pass工作在LLVM IR文件的基础之上。IR包括ll(文本格式,便
--8<-- "docs/assets/llvm/src/PrintFunctionNamesPass.hpp"
```


### 前端分析

`clang -Xclang -ast-dump -fsyntax-only sample.c`将源码解析为语法树。

## LLVM IR

### 基础指令

```c title="sample.c"
#include<stdio.h>

int main() {
int a = 1, b = 2;
if (a < b)
{
a = 1;
} else {
a = 2;
}

return 0;
}
```

运行`clang -S -emit-llvm -O0 test.c -o test.ll`后,上述代码生成下列ll文件:

```llvm
; ModuleID = 'test.c'
source_filename = "test.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
store i32 0, ptr %1, align 4
store i32 1, ptr %2, align 4
store i32 2, ptr %3, align 4
%4 = load i32, ptr %2, align 4
%5 = load i32, ptr %3, align 4
%6 = icmp slt i32 %4, %5
br i1 %6, label %7, label %8
7: ; preds = %0
store i32 1, ptr %2, align 4
br label %9
8: ; preds = %0
store i32 2, ptr %2, align 4
br label %9
9: ; preds = %8, %7
ret i32 0
}
attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
!llvm.module.flags = !{!0, !1, !2, !3, !4}
!llvm.ident = !{!5}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{i32 7, !"frame-pointer", i32 2}
!5 = !{!"clang version 15.0.7"}
```
target datalayout即[目标数据布局](https://llvm.org/docs/LangRef.html#data-layout),指定了大小端、符号表命名格式、整型对齐格式等信息。
target triple即目标三元组,依次指定了CPU-vendor-OS,决定了生成目标程序的平台。
dso_local即[运行时抢占性修饰符](https://llvm.org/docs/LangRef.html#runtime-preemption-specifiers),在生成动态链接库的时候直接调用对应函数,不在PLT表中进行搜索,可以提高运行效率。

* 使用`%xx`来指定引用变量,使用`@xx`来引用全局变量
* 使用`@name = global type value`定义全局变量,使用`@name = global constant type value`定义全局只读变量
* `value = alloca type, align n`声明栈上变量value指针,n字节对齐
* `store type value1, ptr value2, align n`将value1保存到value2的地址中,n字节对齐
* `value1 = load type, ptr value2, align n`从value2地址加载type类型数据到value1中,n字节对齐
* `value1 = icmp cmp type value2, value3`比较type类型的数据value2和value3的关系,将比较结果保存在value1中,这里的cmp可以包括eq、ne(相等与不相等),ugt、uge、ult、ule的无符号数比较,以及sgt、sge、slt、sle的有符号数比较
* `br i1 value1, label value2, label value3`检查bool类型的value1是否为真,若是则跳转到value2对应的位置,否则跳转至value3对应的位置
* `value1 = trunc type1 value2 to type2`将type1类型的value2截断成type2类型的value1
* `value1 = zext type1 value2 to type2`将type1类型的value2零扩展成type2类型的value1,零扩展即高位补0
* `value1 = sext type1 value2 to type2`将type1类型的value2符号扩展成type2类型的value1,符号扩展即高位补符号位
* `value1 = ptrtoint ptr value2 to i64`将指针类型的value2转化成整数,保存在value1中
* `value1 = inttoptr i64 value2 to ptr`将整数类型的value2转化成指针,保存在value1中
* `value = alloca [n x type]`定义一个数组,包含n个type类型的元素,注意这里是x不是*
* `value = type { type1, type2 }`定义一个结构体,注意这里的type是关键字
* `value1 = getelementptr typevalue, ptr value2, i64 index1, i32 index2`从typevalue类型的value2中,取下标index1的元素(若为0就表示直接使用指针本身进行索引)的第index2的成员(从0开始计数),保存到value1里。如果value1本身还是个数组,可以继续在getelementptr后面追加`i64 index3`来继续索引
* `value1 = extractvalue typevalue value2, index`假如聚合类型value2本身不是指针,则不使用getelementptr,而是extractvalue。从类型为typevalue的value2中取第index的字段赋值给value1(从0开始计数)
* `value1 = insertvalue typevalue value2, type value3, index`将typevalue类型的value2值的第index的成员(从0开始计数)
* `value1 = select i1 value2, type1 value3, type2 value4`如果value2为真,将value3赋值给value1;否则将value4赋值给value1,类似三目运算
* `value1 = phi type [value2, block1], [value3, block2]`如果前一个block是block1,则给value1赋值type value2;如果前一个block是block2,则给value1赋值type类型的value3。这些block数量可以一直往后加,实现多分支赋值的功能

### LLVM IR 内置函数

#### Memory Use Markers

```llvm
; llvm.lifetime.start 声明了内存对象声明周期的开始,第一个参数是一个常量整数,表示对象的大小;如果对象大小可变,则为 -1。第二个参数是指向该对象的指针。
declare void @llvm.lifetime.start(i64 <size>, ptr nocapture <ptr>)
```

```llvm
; llvm.objectsize 内在函数旨在向优化器提供信息,以确定 a) 操作(如 memcpy)是否会溢出与对象对应的缓冲区,或 b) 不需要运行时检查溢出。此上下文中的对象意味着特定类、结构、数组或其他对象的分配。四个参数分别表示:对象指针;对象大小未知时函数应当返回0(若为true)还是-1(若为false);NULL用作指针参数时函数应当返回0字节(若为false)或大小未知(若为true);是否应在运行时评估该值。
declare i32 @llvm.objectsize.i32(ptr <object>, i1 <min>, i1 <nullunknown>, i1 <dynamic>)
declare i64 @llvm.objectsize.i64(ptr <object>, i1 <min>, i1 <nullunknown>, i1 <dynamic>)
```

### 抢占性

对于C比较常用的extern、static,假如有以下定义:

=== "C源代码变量定义"
```c
int a; // 当前文件的全局变量
extern int b; // 外部文件的全局变量
static int c; // 仅限当前文件的全局变量
void d(void); // 外部文件函数
void e(void) {} // 当前文件函数
static void f(void) {} // 仅限当前文件的函数
```
=== "LLVM IR表现形式"
```llvm
@a = dso_local global i32 0, align 4
@b = external global i32, align 4
@c = internal global i32 0, align 4
declare void @d()
define dso_local void @e() {
ret void
}
define internal void @f() {
ret void
}
```



### opaque pointer

不透明指针即不关心具体的指针类型,而使用`ptr`来取代之前的具体类型比如`i32*`。不透明指针在LLVM 15成为默认选项,并在LLVM 17移除透明指针。对于允许禁用不透明指针的LLVM版本而言,在命令行编译时,可以添加`-Xclang -no-opaque-pointers`来保留显式类型。cmake可以使用`-DCLANG_ENABLE_OPAQUE_POINTERS=OFF`
Expand Down Expand Up @@ -283,7 +425,7 @@ class FunctionPass : public Pass {

通过`#include "llvm/IRReader/IRReader.h"`使用`std::unique_ptr<Module> parseIRFile(StringRef Filename, SMDiagnostic &Err, LLVMContext &Context)`来获取bc文件的指针,随后可以在自定义方法如`myParseFunc(const Module &Mod)`中遍历指针内容(即解引用),得到llvm::Module下一层的llvm::Function。类似地,对llvm::Function进一步遍历可以获取llvm::BasicBlock,再进一步遍历可以获取llvm::Instruction,每一级可以调用相关API函数。

### 四大关键程序对象
### 关键程序对象

根据LLVM分析的程序对象不同,可以按从大到小的顺序分为Module、Function、BasicBlock、Instruction四个等级。可以直接采用for循环遍历高等级对象的方法,获取其中的下一级对象。可见前文的项目例子。

Expand All @@ -298,22 +440,36 @@ class FunctionPass : public Pass {
```cpp
const llvm::BasicBlock BB;
BB.getTerminator(); // 获取基本块最后一条指令

BB.printfAsOperand(errs()); // 获取label %num 即BB的编号
```


#### llvm::Instruction

```cpp
const llvm::Instruction I;
I.printAsOperand(errs()); // 将指令作为操作数打印,即打印返回值
I.print(errs()); // 打印指令本身,包括操作符、操作数等,不包括返回值
I.getOpcodeName(); // 获取操作符的字符串名称
I.getNumOperands(); // 获取操作数个数
I.getNumOperands(); // 获取该指令的操作数个数
I.getOperand(i); // 获取第i个操作数,返回llvm::Value*

I.getNumUses(); // 获取该指令返回值被其他指令使用的次数
I.users(); // 获取该指令返回值被其他指令使用的迭代器,通过const User* U : I.users()可以进行遍历
I.hasMetaData(); // 检查当前指令是否附有metadata,比如调试信息
I.getMetaData("dbg"); // 获取当前指令的dbg调试信息

const llvm::BranchInst* BI = dyn_cast<BranchInst>(&I); // BranchInst继承Instruction
BI.getOperand(i); // BranchInst的getOperand返回的似乎不是操作数
```



### 调试信息分析

[前文提到](#opaque-pointer),在编译程序时添加`-g`选项,可以生成类似
[前文提到](#opaque-pointer),在编译程序时添加`-g`选项,也可以从调试信息中恢复部分类型信息。


## 参考文章

1. [LLVM IR入门指南](https://evian-zhang.github.io/llvm-ir-tutorial/01-LLVM%E6%9E%B6%E6%9E%84%E7%AE%80%E4%BB%8B.html)
2. [LLVM API参考手册](https://llvm.org/docs/LangRef.html)
Empty file.
1 change: 1 addition & 0 deletions mkdocs-toolchain
Submodule mkdocs-toolchain added at c53ad8
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ nav:
- 软件安全:
- software-security/index.md
- 程序逆向:
- software-security/reverse/index.md
- IDA基础: software-security/reverse/IDA.md
- 逆向基础: software-security/reverse/reverse-basic.md
- 逆向高阶: software-security/reverse/reverse-advanced.md
Expand Down Expand Up @@ -382,4 +383,5 @@ plugins:
minify_html: true
htmlmin_opts:
remove_comments: true
- toc # cd ./mkdocs-toolchain/mkdocs-toc-plugin && pip install -e .

3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ mkdocs-git-committers-plugin-2
mkdocs-git-revision-date-localized-plugin
mkdocs-statistics-plugin
mkdocs-minify-plugin
mike
mike
pyyaml

0 comments on commit 54a10b9

Please sign in to comment.