mirror of
https://github.com/NohamR/knowledge-kit.git
synced 2026-05-24 20:00:37 +00:00
docs: image url
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
|
||||
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ var str1: String = "0123456789"
|
||||
|
||||
实验很简单,就一行代码。来窥探下 String 的初始化和内存结构。出发断点看到下面汇编:
|
||||
|
||||
<img src="./../assets//SwiftStringExploreDemo1.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets//SwiftStringExploreDemo1.png" style="zoom:25%">
|
||||
|
||||
简单分析下:
|
||||
|
||||
@@ -45,7 +45,7 @@ QA:这个10是什么东西?1是什么东西?
|
||||
var str1: String = "01234"
|
||||
```
|
||||
|
||||
<img src="./../assets//SwiftStringExploreDemo2.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets//SwiftStringExploreDemo2.png" style="zoom:25%">
|
||||
|
||||
可以看到其他和上面的没变化,唯一不同的是 `movl $0x5, %esi` 将5赋值给寄存器 `esi`,即寄存器 `rsi`。实验的字符串 "01234" UTF8 字符个数为5
|
||||
|
||||
@@ -55,7 +55,7 @@ var str1: String = "01234"
|
||||
var str1: String = "01234😄"
|
||||
```
|
||||
|
||||
<img src="./../assets//SwiftStringExploreDemo3.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets//SwiftStringExploreDemo3.png" style="zoom:25%">
|
||||
|
||||
可以看到将9赋值给寄存器 `esi` 即 `rsi`,字符串赋值给寄存器 `rdi`,`xorl %edx, %edx` 异或运算结果 0 赋值给寄存器 `edx` 即 `rdx`,也就是不纯粹为
|
||||
|
||||
@@ -93,7 +93,7 @@ extension String: _ExpressibleByBuiltinStringLiteral {
|
||||
|
||||
继续探索:
|
||||
|
||||
<img src="./../assets//SwiftStringExploreDemo4.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets//SwiftStringExploreDemo4.png" style="zoom:25%">
|
||||
|
||||
可以看到 `str1` 地址为 `rip + 0x8853 = 0x1000039a5 + 0x8853 = 0x10000C1F8 `,然后读取对应堆上的内容为:
|
||||
|
||||
@@ -128,7 +128,7 @@ var str1: String = "0123456789ABCDEF"
|
||||
print(Mems.memStr(ofVal: &str1))
|
||||
```
|
||||
|
||||
<img src="./../assets//SwiftStringExploreDemo5.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets//SwiftStringExploreDemo5.png" style="zoom:25%">
|
||||
|
||||
分析下:
|
||||
|
||||
@@ -154,7 +154,7 @@ print(Mems.memStr(ofVal: &str1))
|
||||
|
||||
- LLDB 输入 finish 结束函数细节,外部可以看到第10行 `movq %rdx, 0x8864(%rip) ` 将 `rdx` 寄存器里的值(也就是:`字符串真实地址` + `0x7fffffffffffffe0` )赋值给 `str1` 指针的后8个字节
|
||||
|
||||
<img src="./../assets//SwiftStringExploreDemo6.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets//SwiftStringExploreDemo6.png" style="zoom:25%">
|
||||
|
||||
|
||||
|
||||
@@ -172,13 +172,13 @@ var str1: String = "0123456789ABCDEF"
|
||||
|
||||
字符串地址为 ` 0x10000397f + 0x3ea1 = 0x100007820`,看着像全局变量、也有可能是常量区?字符串内容写死的情况下,编译器编译后内存地址应该可以确定,那到底在什么地方呢?利用 `MachOView` 窥探下 `MachO` 文件吧
|
||||
|
||||
<img src="./../assets//SwiftStringExploreDemo7.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets//SwiftStringExploreDemo7.png" style="zoom:25%">
|
||||
|
||||
|
||||
|
||||
利用 MachOView 打开如下
|
||||
|
||||
<img src="./../assets//MacMachOViewExploreStringLocationDemo1.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets//MacMachOViewExploreStringLocationDemo1.png" style="zoom:25%">
|
||||
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@ print(Mems.memStr(ofVal: &str1)) // 0xd000000000000010 0x8000000100007800
|
||||
print(Mems.memStr(ofVal: &str2)) // 0x0000353433323130 0xe600000000000000
|
||||
```
|
||||
|
||||
<img src="./../assets//MacMachOViewExploreStringLocationDemo2.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets//MacMachOViewExploreStringLocationDemo2.png" style="zoom:25%">
|
||||
|
||||
可以看到:
|
||||
|
||||
@@ -323,7 +323,7 @@ print("explore")
|
||||
|
||||
上面可知, `字符串真实地址 = 指针内存8个字节地址 - 0x7fffffffffffffe0`,又等价于 `字符串真实地址 = 指针内存8个字节地址 + 0x20`
|
||||
|
||||
<img src="./../assets//MacMachOViewExploreStringLocationDemo3.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets//MacMachOViewExploreStringLocationDemo3.png" style="zoom:25%">
|
||||
|
||||
字符串真实地址:`0x0000600001700440 + 0x20 = 0x0000600001700460`,LLDB `x 0x0000600001700460 ` 可以看到字符串拼接后的结果。看上去是存储在堆上。如何验证?
|
||||
|
||||
@@ -331,11 +331,11 @@ print("explore")
|
||||
|
||||
我们知道堆上的内存初始化在 Swift 侧,关键方法为 `swift_allocObject ` -> `swift_slowAlloc` -> `malloc `。给 malloc 下断点,然后在断点出查看调用堆栈,可以看到在 `string.append()` 后有堆分配内存
|
||||
|
||||
<img src="./../assets//MacMachOViewExploreStringLocationDemo4.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets//MacMachOViewExploreStringLocationDemo4.png" style="zoom:25%">
|
||||
|
||||
结束当前函数调用,在外层可以看到 str2 地址值的后8个字节为 `0x000060000170410`,再 + `0x20` 就是字符串真实地址,打印如下。
|
||||
|
||||
<img src="./../assets//MacMachOViewExploreStringLocationDemo5.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets//MacMachOViewExploreStringLocationDemo5.png" style="zoom:25%">
|
||||
|
||||
0x20 是什么?这32个字节存放了什么信息?存储字符串的描述信息,比如:引用计数、字符串长度等信息。
|
||||
|
||||
@@ -374,7 +374,7 @@ Swift 中 `String` 类型的初始化方法(`init`)的地址是否采用延
|
||||
|
||||
|
||||
|
||||
<img src="./../assets//MachOStubBinderAndLazyBinding.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets//MachOStubBinderAndLazyBinding.png" style="zoom:25%">
|
||||
|
||||
`__stub_helper` 节是 `__TEXT` 段中的一个特定节,它包含了用于处理符号懒加载的辅助函数和代码。当动态链接的符号首次被调用时,这些辅助函数会被触发,以解析符号并将其地址绑定到调用点。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user