为了账号安全,请及时绑定邮箱和手机立即绑定

【go语言】wait,why not safe

标签:
Go

slice?俺知道,不就是基于数组的一个视窗嘛!

出个题呗~

好~

package main


func main() {

var arr = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

s := arr[2:6]


modify(s)

}


func modify(tmp []int) {

       // 实现该函数,把arr[8]的值修改为200

}



你千万别告诉我是这样实现的:

var point = &tmp[3]

point += 3

*point = 200

这样做你真的可费瞎了心了 :)

因为golang指针不允许运算,像这样会抛invalid operation: point += 3 (mismatched types *int and int)错误~~~



算了吧,还是放着让哥来

wKioL1iZ0BmBs3L0AAAHd1AuZAE024.png

浅蓝色的是slice当前的长度,整个蓝色(浅蓝色+深蓝色)是slice的容量

站在从slice的视窗来看当前能看到{2,3,4,5},但如果扩大slice的容量就可以看到{2,3,4,5,6,7,8,9},从slice的意义上来看,由slice可以修改数组的arr[8]。



(1)获取s[3]的地址,即arr[5]的地址

&s[3]

(2)把s[3]的地址转换为不安全的指针

unsafe.Pointer(&s[3])

(3)把s[3]不安全的指针转换为uint地址

uintptr(unsafe.Pointer(&s[3]))


(4)把指针向后移3个元素

var nextElement = uintptr(unsafe.Pointer(&s[3])) + 3 * 8   // 我怎么知道每个int占8个字节,可以用unsafe.Offsetof查看


(5)把目标元素的uint地址转换为不安全的指针

unsafe.Pointer(nextElement )

(6)把目标元素的不安全指针转换为地址

(*int)(unsafe.Pointer(nextElement ))


(7)修改目标元素的值

*(*int)(unsafe.Pointer(nextElement )) = 200


完整的程序如下:

package main


import "fmt"

import "unsafe"


func main() {

var arr = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

s := arr[2:6]


modify(s)


fmt.Println(arr)

}


func modify(tmp []int) {

var src = uintptr(unsafe.Pointer(&tmp[3]))

var dest = (*int)(unsafe.Pointer(src + 3*8))

*dest = 200

}

执行一下结果为:

[0 1 2 3 4 5 6 7 200 9]



所以尽管只是slice了数组的一部分,并且没有扩容,攻击者只是通过对slice的操作,依旧可以攻到底层数组不可见的元素,从安全编码角度来看,这是一个安全隐患 :)



关于slice的一些知识,我想做一个动画,从视窗的维度再解释一下。



点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消