We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ps. uintptr 并没有指针的语义,意思就是 uintptr 所指向的对象会被 gc 无情地回收。而 unsafe.Pointer 有指针语义,可以保护它所指向的对象在“有用”的时候不会被垃圾回收。
1.绕过私有成员的限制
可以通过unsafe包绕过私有属性限制对私有属性读写。
package A type A struct { name string age int mark bool }
package main import ( "A" "fmt" "unsafe" ) func main() { a := A.A{} fmt.Println(a) name := (*string)(unsafe.Pointer(&p)) age := (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&p)) + unsafe.Sizeof(string("")))) mark := (*bool)(unsafe.Pointer(uintptr(unsafe.Pointer(&p)) + unsafe.Sizeof(string("")) + unsafe.Sizeof(0))) *name = "A" *age = 20 *mark = false // output {A 20 false} fmt.Println(a) }
2.通过伪造快速对私有属性更改
这边以内置类型slice为例,可以参考slice的源码。
ps. 与本主题无关的提示: make得到的slice是实体,make得到的map是指针。
package main import ( "fmt" "unsafe" ) // 也可以使用小技巧,构造一个和 slice 一样的结构体来解析或操作切片 type slice struct { arrptr unsafe.Pointer l int c int } func main() { a := []int{1,2} a = append(a, 3) length := (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&a)) + unsafe.Sizeof(unsafe.Pointer(&a)))) ca := (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&a)) + unsafe.Sizeof(unsafe.Pointer(&a)) + unsafe.Sizeof(int(0)))) fmt.Println(*length, *ca) *length = *length + 1 // + 1024 没问题, 只要在保护的内存段中就行 //a = append(a, 4) fmt.Println(a, *length, *ca) s := *(*slice)(unsafe.Pointer(&a)) fmt.Println(s) fmt.Printf("[%d, %d, %d, %d]\n", *(*int)(s.arrptr), *(*int)(unsafe.Pointer(uintptr(s.arrptr) + unsafe.Sizeof(int(0)))), *(*int)(unsafe.Pointer(uintptr(s.arrptr) + 2*unsafe.Sizeof(int(0)))), *(*int)(unsafe.Pointer(uintptr(s.arrptr) + 3*unsafe.Sizeof(int(0)))), ) }
The text was updated successfully, but these errors were encountered:
GuoYuefei
No branches or pull requests
unsafe 包的使用
go指针的限制
unsafe 包提供了 2 点重要的能力
unsafe 包可以做什么坏事
1.绕过私有成员的限制
可以通过unsafe包绕过私有属性限制对私有属性读写。
2.通过伪造快速对私有属性更改
这边以内置类型slice为例,可以参考slice的源码。
The text was updated successfully, but these errors were encountered: