yak学习笔记

Yaklang语言简介

Yaklang 是一门上下文无关文法定义的 图灵完备 的程序语言,他基于 YakVM 运行,语法规则定义了 Yaklang 的语言结构

Yaklang 是一个 动态强类型语言

  1. Yaklang 允许用户可以在改变变量的值的时候也改变变量的类型;
  2. 在进行表达式运算的时候 Yaklang 允许程序或函数识别运行时的准确类型,并进行对应计算;

Yaklang 可以 编译 为 YakVM 可以支持的字节码运行;

Yaklang 语法博采众长,非常容易上手与学习;

Yaklang 可以作为一门“嵌入式语言”被其他语言调用或编译;

Yaklang 是业内第一门 CDSL (Cybersecurity Domain Specific Language),使用图灵完备特性融合原子化的安全能力。

Yaklang语法

注释:

1
2
3
# Comment
// Comment
/* Comment*/

声明变量:

1
2
3
4
var a	//声明变量a
var b,c //声明变量b,c
var d,e=1,2 //声明变量d,e并分别赋值为1,2
a,b = 1,2 //此时a=1,b=2

字符串:

1
2
3
4
5
6
7
"hello world"
a = "hello world"
a = `hello world`
abc = `hello world
hello BingTang`
//单引号包裹一个字符
c = '\x20'

字节序列:

1
2
3
4
5
6
7
name = b"hello world"
dump(name)]
/*
([]uint8) (len=11 cap=16) {
00000000 68 65 6c 6c 6f 20 77 6f 72 6c 64 |hello world|
}
*/

%格式化语法:

1
2
3
4
5
6
println("Hello %v" % "World")
//Hello World
println("Hello %v %v" % ["World","BingTang"])
//Hello World BingTang
println("Hello %v %05d" % ["World", 4])
//Hello World 00004

模板字符串语法 f-string:

1
2
3
4
a = "World"
name = "BingTang"
println(f`Hello ${a},Hello ${name}`)
println(f`1+1 = ${1+1}`)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var targetPath = "admin.php?id=1"
var addr = "example.com:8080"
var payload = codec.EncodeUrl("1'or''='1")

packet = f`GET /${targetPath} HTTP/1.1
Host: ${addr}

key=value&key2=${payload}`
/*
GET /admin.php?id=1 HTTP/1.1
Host: example.com:8080

key=value&key2=%31%27%6f%72%27%27%3d%27%31
*/

rsp, req, err = poc.HTTP(packet)
die(err)

Fuzztag 快速执行 x-string:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
a = x"Fuzztag int(1-10): {{int(1-10)}}"
dump(a)

/*
([]string) (len=10 cap=10) {
(string) (len=20) "Fuzztag int(1-10): 1",
(string) (len=20) "Fuzztag int(1-10): 2",
(string) (len=20) "Fuzztag int(1-10): 3",
(string) (len=20) "Fuzztag int(1-10): 4",
(string) (len=20) "Fuzztag int(1-10): 5",
(string) (len=20) "Fuzztag int(1-10): 6",
(string) (len=20) "Fuzztag int(1-10): 7",
(string) (len=20) "Fuzztag int(1-10): 8",
(string) (len=20) "Fuzztag int(1-10): 9",
(string) (len=21) "Fuzztag int(1-10): 10"
}
*/

字符串运算:

+ 号连接字符串

1
2
3
4
a = "Hello, "
b = "World"
println(a+b)
// Hello, World

* 号重复字符串n次

1
2
3
a = "powerful "
println(a * 5 + "yak")
// powerful powerful powerful powerful powerful yak

取子串或子元素:

1
2
3
4
5
字符串[头下标:尾下标:步长]
a = "Hello, Yak"
println(a[0]) // H
println(a[1:5]) // ello
println(a[3:0:-1]) // lle

字符串内置方法:

方法名 描述
Reverse() 翻转字符串
Contains(substr) 字符串是否包含substr,如果是则返回 True,否则返回 False
ReplaceN(old, new, n) 把 将字符串中的 old 替换成 new,最多替换不超过 n 次
ReplaceAll(old, new) / Replace(old, new) 把 将字符串中所有的 old 替换成 new
Split(substr) 以 substr 为分隔符截取字符串
SplitN(substr, n) 以 substr 为分隔符截取字符串,最多切割为 n 份
Join(seq) 以字符串作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串
Trim(cutstr…) 删除字符串头尾的空格和cutstr
TrimLeft(cutstr…) 删除字符串头部的cutstr
TrimRight(cutstr…) 删除字符串尾部的cutstr
HasPrefix(substr) / StartsWith(substr) 检查字符串是否是以指定子字符串 substr 开头
HasSuffix(substr) / EndsWith(substr) 检查字符串是否是以指定子字符串 substr 结尾
Zfill(width) 返回长度为 width 的字符串,原字符串右对齐,前面填充0
Rzfill(width) 返回长度为 width 的字符串,原字符串左对齐,后面填充0
Ljust(width) 返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串
Rjust(width) 返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串
Count(n) 返回 str 在 string 里面出现的次数
Find(substr) / IndexOf(substr) 检测 str 是否包含在字符串中,并返回开始的索引值,如没找到则返回-1
Rfind(substr) / LastIndexOf(substr) 类似于 find()函数,不过是从右边开始查找
Lower() 转换字符串中所有大写字符为小写
Upper() 转换字符串中的小写字母为大写
Title() 返回”标题化”的字符串,就是说所有单词都是以大写开始,其余字母均为小写
IsLower() 判断字符串是否全为小写,如果是则返回 True,否则返回 False
IsUpwer() 判断字符串是否全为大写,如果是则返回 True,否则返回 False
IsTitle() 如果字符串是标题化的则返回 True,否则返回 False
IsAlpha() 如果字符串所有字符都是字母则返回 True, 否则返回 False
IsDigit() 如果字符串所有字符都是数字则返回 True, 否则返回 False
IsAlnum() 如果字符串所有字符都是字母和数字则返回 True, 否则返回 False
IsPrintable() 如果字符串所有字符都是可见字符则返回 True, 否则返回 False

整数浮点数运算:

1
2
3
4
println(2 + 2)    // 4
println(50 - 5*6) // 20
println(8 / 5) // 1
println(17 % 3) // 2

多进制整数声明

1
2
3
4
5
6
7
8
// 二进制声明
a = 0b10 // 2
// 八进制声明
b = 0100 // 64
// 普通整数声明(十进制)
c = 100 // 100
// 十六进制声明
d = 0x10 // 16

浮点数声明

1
2
a = 1.5		// 1.5
b = a / 0.5 // 3.0

列表类型:创建与声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
a = [1, 2, 3]
println(typeof(a)) // []int
b = ["qwe", "asd"]
println(typeof(b)) // []string
c = [1, 2, "3"]
println(typeof(c)) // []any{}

// 创建一个不带长度的 []int
a = make([]int)
println(typeof(a)) // []int

// 创建一个带长度的 []int
b = make([]int, 2)
println(len(b)) // 2
方法名 描述
Append(elem…) / Push(elem…) 在列表末尾追加新的elem元素
Pop(n…) 弹出数组/切片的第n个元素,默认为最后一个
Insert(n, elem) 在指定位置n插入elem元素
Extend(arr) / Merge(arr) 用一个新的列表扩展原列表
Length() / Len() 返回列表的长度
Capability() / Cap() 返回列表的容量
StringSlice() 将列表转换成[]string类型
GeneralSlice() 将列表转换成[]var类型(即[]interface{})
Shift() 从数据开头移除一个元素,相当于Pop(0)
Unshift(elem) 从数据开头插入一个elem元素,相当于Insert(0, elem)
Map(func (elem)elem) 会根据提供的函数对列表中的每一个函数做映射,返回映射后的列表
Filter(func (elem)bool) 会根据提供的函数对列表中的每一个函数做过滤(该函数返回true/false,将返回false的元素筛除),返回过滤后的列表
Remove(elem) 删除在列表中第一次出现的elem元素
Reverse() 翻转列表
Sort(reverse…) 排序列表,默认为升序,若设置reverse=true,则改为降序
Clear() 清空列表
Count(elem) 统计elem元素在列表中出现的次数
Index(n) 返回列表中第n个元素,n支持负数表示倒数第n个元素