GG修改器破解版下载地址:https://ghb2023zs.bj.bcebos.com/gg/xgq/ggxgq?GGXGQ
大家好,今天小编为大家分享关于gg修改器找游戏数据基址_gg修改器怎么修改网游数据的内容,赶快来一起来看看吧。
我们从一个 Hello World 的例子来回顾一下 Go 程序初始化的过程:
在项目根目录下执行:
go build -gcflags “-N -l” -o hello src/main.go
-gcflags “-N -l” 是为了关闭编译器优化和函数内联,防止后面在设置断点的时候找不到相对应的代码位置。
得到了可执行文件 hello,执行:
[qcrao@qcrao hello-world]$ gdb hello
进入 gdb 调试模式,执行 info files,得到可执行文件的文件头,列出了各种段:
同时,我们也得到了入口地址:0x450e20。
(gdb) b *0x450e20
Breakpoint 1 at 0x450e20: file /usr/local/go/src/runtime/rt0_linux_amd64.s, line 8.
这就是 Go 程序的入口地址,我是在 linux 上运行的,所以入口文件为 src/runtime/rt0_linux_amd64.s,runtime 目录下有各种不同名称的程序入口文件,支持各种操作系统和架构,代码为:
主要是把 argc,argv 从内存拉到了寄存器。这里 LEAQ 是计算内存地址,然后把内存地址本身放进寄存器里,也就是把 argv 的地址放到了 SI 寄存器中。最后跳转到:
继续跳转到 runtime·rt0_go(SB),完成 go 启动时所有的初始化工作。位于 /usr/local/go/src/runtime/asm_amd64.s,代码:
这段代码完成之后,整个 Go 程序就可以跑起来了,是非常核心的代码。这一讲其实只讲到了第 80 行,也就是调度器初始化函数:
CALL runtime·schedinit(SB)
schedinit 函数返回后,调度器的相关参数都已经初始化好了,犹如盘古开天辟地,万事万物各就其位。接下来详细解释上面的汇编代码。
第一段代码,将 SP 调整到了一个地址是 16 的倍数的位置:
先是将 SP 减掉 39,也就是向下移动了 39 个 Byte,再进行与运算。
15 的二进制低四位是全 1:1111,其他位都是 0;取反后,变成了 0000,高位则是全 1。这样,与 SP 进行了与运算后,低 4 位变成了全 0,高位则不变。因此 SP 继续向下移动,并且这回是在一个地址值为 16 的倍数的地方,16 字节对齐的地方。
为什么要这么做?画一张图就明白了。不过先得说明一点,前面 _rt0_amd64_linux 函数里讲过,DI 里存的是 argc 的值,8 个字节,而 SI 里则存的是 argv 的地址,8 个字节。
SP 内存对齐
上面两张图中,左侧用箭头标注了 16 字节对齐的位置。第一步表示向下移动 39 B,第二步表示与 ~15 相与。
存在两种情况,这也是第一步将 SP 下移的时候,多移了 7 个 Byte 的原因。第一张图里,与 ~15 相与的时候,SP 值减少了 1,第二张图则减少了 9。最后都是移位到了 16 字节对齐的位置。
两张图的共同点是 SP 与 argc 中间多出了 16 个字节的空位。这个后面应该会用到,我们接着探索。
至于为什么进行 16 个字节对齐,就比较好理解了:因为 CPU 有一组 SSE 指令,这些指令中出现的内存地址必须是 16 的倍数。
接着往后看,开始初始化 g0 的栈了。g0 栈的作用就是为运行 runtime 代码提供一个“环境”。
代码 L2 把 g0 的地址存入 DI 寄存器;L4 将 SP 下移 (64K-104)B,并将地址存入 BX 寄存器;L6 将 BX 里存储的地址赋给 g0.stackguard0;L8,L10,L12 分别 将 BX 里存储的地址赋给 g0.stackguard1, g0.stack.lo, g0.stack.hi。
这部分完成之后,g0 栈空间如下图:
g0 栈空间
接着往下看,中间我们省略了很多检查 CPU 相关的代码,直接看主线程绑定 m0 的部分:
因为 m0 是全局变量,而 m0 又要绑定到工作线程才能执行。我们又知道,runtime 会启动多个工作线程,每个线程都会绑定一个 m0。而且,代码里还得保持一致,都是用 m0 来表示。这就要用到线程本地存储的知识了,也就是常说的 TLS(Thread Local Storage)。简单来说,TLS 就是线程本地的私有的全局变量。
一般而言,全局变量对进程中的多个线程同时可见。进程中的全局变量与函数内定义的静态(static)变量,是各个线程都可以访问的共享变量。一个线程修改了,其他线程就会“看见”。要想搞出一个线程私有的变量,就需要用到 TLS 技术。
如果需要在一个线程内部的各个函数调用都能访问、但其它线程不能访问的变量(被称为 static memory local to a thread,线程局部静态变量),就需要新的机制来实现。这就是 TLS。
继续来看源码,L3 将 m0.tls 地址存储到 DI 寄存器,再调用 settls 完成 tls 的设置,tls 是 m 结构体中的一个数组。
// thread-local storage (for x86 extern register)
tls [6]uintptr
设置 tls 的函数 runtime·settls(SB) 位于源码 src/runtime/sys_linux_amd64.s 处,主要内容就是通过一个系统调用将 fs 段基址设置成 m.tls[1] 的地址,而 fs 段基址又可以通过 CPU 里的寄存器 fs 来获取。
而每个线程都有自己的一组 CPU 寄存器值,操作系统在把线程调离 CPU 时会帮我们把所有寄存器中的值保存在内存中,调度线程来运行时又会从内存中把这些寄存器的值恢复到 CPU。
这样,工作线程代码就可以通过 fs 寄存器来找到 m.tls。
关于 settls 这个函数的解析可以去看阿波张的教程第 12 篇,写得很详细。
设置完 tls 之后,又来了一段验证上面 settls 是否能正常工作。如果不能,会直接 crash。
get_tls(BX)
MOVQ $0x123, g(BX)
MOVQ runtime·m0+m_tls(SB), AX
CMPQ AX, $0x123
JEQ 2(PC)
MOVL AX, 0 // abort
第一行代码,获取 tls,get_tls(BX) 的代码由编译器生成,源码中并没有看到,可以理解为将 m.tls 的地址存入 BX 寄存器。
L2 将一个数 0x123 放入 m.tls[0] 处,L3 则将 m.tls[0] 处的数据取出来放到 AX 寄存器,L4 则比较两者是否相等。如果相等,则跳过 L6 行的代码,否则执行 L6,程序 crash。
继续看代码:
// set the per-goroutine and per-mach “registers”
// 获取 fs 段基址到 BX 寄存器
get_tls(BX)
// 将 g0 的地址存储到 CX,CX = &g0
LEAQ runtime·g0(SB), CX
// 把 g0 的地址保存在线程本地存储里面,也就是 m0.tls[0]=&g0
MOVQ CX, g(BX)
// 将 m0 的地址存储到 AX,AX = &m0
LEAQ runtime·m0(SB), AX
// save m->g0 = g0
// m0.g0 = &g0
MOVQ CX, m_g0(AX)
// save m0 to g0->m
// g0.m = &m0
MOVQ AX, g_m(CX)
L3 将 m.tls 地址存入 BX;L5 将 g0 的地址存入 CX;L7 将 CX,也就是 g0 的地址存入 m.tls[0];L9 将 m0 的地址存入 AX;L13 将 g0 的地址存入 m0.g0;L16 将 m0 存入 g0.m。也就是:
tls[0] = g0
m0.g0 = &g0
g0.m = &m0
代码中寄存器前面的符号看着比较奇怪,其实它们最后会被链接器转化为偏移量。
看曹大 golang_notes 用 gobuf_sp(BX) 这个例子讲的:
这种写法在标准 plan9 汇编中只是个 symbol,没有任何偏移量的意思,但这里却用名字来代替了其偏移量,这是怎么回事呢?实际上这是 runtime 的特权,是需要链接器配合完成的,再来看看 gobuf 在 runtime 中的 struct 定义开头部分的注释:// The offsets of sp, pc, and g are known to (hard-coded in) libmach.
对于我们而言,这种写法读起来比较容易。
这一段执行完之后,就把 m0,g0,m.tls[0] 串联起来了。通过 m.tls[0] 可以找到 g0,通过 g0 可以找到 m0(通过 g 结构体的 m 字段)。并且,通过 m 的字段 g0,m0 也可以找到 g0。于是,主线程和 m0,g0 就关联起来了。
从这里还可以看到,保存在主线程本地存储中的值是 g0 的地址,也就是说工作线程的私有全局变量其实是一个指向 g 的指针而不是指向 m 的指针。目前这个指针指向g0,表示代码正运行在 g0 栈。
以上就是关于gg修改器找游戏数据基址_gg修改器怎么修改网游数据的全部内容,希望对大家有帮助。
gg修改器咋root, gg修改器-激发你的游戏潜力 大小:5.37MB7,143人安装 现如今,游戏成为了人们生活中不可或缺的一部分。无论你是电脑、手机还是主机游戏爱……
下载gg游戏修改器安卓下载,用GG游戏修改器,让您的安卓手机游戏更加精彩! 大小:18.87MB6,760人安装 随着手机设备的发展,越来越多的游戏可以在手机上畅玩。但是,有时候游戏难度太大,……
下载最新版本gg修改器怎么用,最新版本gg修改器介绍 大小:14.55MB7,094人安装 如果你是一个玩游戏的人,肯定有希望能够在游戏中得到更好的体验和更高的竞技水平。……
下载gg游戏修改器开心消消乐,GG游戏修改器,让你畅玩开心消消乐 大小:14.43MB7,100人安装 作为一款风靡全球的休闲游戏,开心消消乐已经赢得了无数玩家的喜爱和关注。然而,想……
下载无root用gg修改器,无root使用GG修改器,畅享游戏乐趣 大小:16.08MB6,519人安装 现在的手机游戏越来越火爆,许多玩家经常沉迷于游戏中,但是面对一些难以通过常规手……
下载正版GG修改器中文版_正版GG修改器中文 大小:14.19MB8,064人安装 大家好,今天小编为大家分享关于正版GG修改器中文版_正版GG修改器中文的内容,赶快……
下载正版gg修改器下载最新版,正版gg修改器下载最新版,功能强大免费使用 大小:17.74MB6,951人安装 正版gg修改器是一款功能强大的辅助工具,可以帮助玩家获得更好的游戏体验。它不仅可……
下载荒野乱斗gg修改器最新版下载,GG修改器怎么修改荒野乱斗 大小:1.29MB8,299人安装 但行前路,不负韶华! 大家好,今天小编为大家分享关于荒野乱斗gg修改器最新版下载,……
下载gg修改器990版本中文版,GG修改器990版本中文版:游戏中的万能利器 大小:19.45MB6,733人安装 近些年来,随着网络游戏的普及,越来越多的游戏开发公司推出了各种类型的游戏。随之……
下载使用gg修改器的教程中文版_gg修改器怎样使用教程 大小:19.38MB7,923人安装 大家好,今天小编为大家分享关于使用gg修改器的教程中文版_gg修改器怎样使用教程的……
下载