Skip to content

Commit b95f5df

Browse files
committed
汇编
1 parent 15fff80 commit b95f5df

File tree

2 files changed

+33
-24
lines changed

2 files changed

+33
-24
lines changed

Android/C02/README.md

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,16 @@ Linux的虚拟地址空间范围为0~4G(intel x86架构32位),Linux内
2525
I:中断禁止位,1:禁止 0允许,
2626
A:异常屏蔽位
2727
E:大小端序 0:小端序 1:大端序 linux就是小端序
28-
T:rm还是thumb
29-
***,整型运算用的
28+
T:arm还是thumb
29+
***NZCV整型运算用的***
3030
N:符号位,负数或小于
3131
Z:0标志位 Z标志位赋值为1就是一定执行
3232
C:进位标志位
3333
V:溢出标志位
3434
)
3535
```
3636

37-
**arm标志位**
37+
**arm条件和标志位响应**
3838

3939
![img](pic/02.png)
4040

@@ -51,14 +51,15 @@ V 可以有2种方法设置V的值:
5151
对于其它的非加/减运算指令,V的值通常不会改变。
5252
https://blog.csdn.net/nanfangqiulin/article/details/51122718
5353
54+
-------------
5455
一般机器码最高位E是最常见的,代表着AL,无条件执行,通常会忽略此后缀
5556
5657
CMPCS R2, R3 本来有个CMP指令,加了一个条件后缀CS
57-
58+
-------------
5859
ADD R0, R0, R1 arm一般的第一个寄存器就是写入的目标值,r0 = R0 + R1
5960
6061
ADDS R0, R0, R1
61-
62+
6263
ADDS和ADD的区别就是操作完后会影响标志位,ADD不会影响标志位。
6364
-------------
6465
@@ -70,9 +71,10 @@ subs r0, r0, r1 r0,0x00000002 r1,0x00000001,结果r0=0x00000001, 此时没
7071
减法的时候,只要看到SUBS指令先把C位置1,C位放在被减位的的第一位,变成了0x10000002,0x10000002-1,此时如果产生了借位C=0,否则 C=1,这时因为我们没借位,所以C被留下来了=1。
7172
-------------
7273
1A 00 00 9A BLS loc_EA2C,怎么理解BLS?
73-
B + LS标志位后缀还是BL指令 + S后缀,怎么理解?
74-
bl 指令就是跳转一个地方,同时把返回地址写入他的lr寄存器里。此机器码最高位是9,他的二进制为1001,1001对应条件码就是LS,所以是B + LS条件
74+
B + LS标志位后缀还是BL指令 + S后缀,怎么理解?
75+
bl 指令就是跳转一个地方,同时把返回地址写入他的lr寄存器里。此机器码最高位是9,他的二进制为1001,1001对应条件码就是LS,所以是B + LS条件
7576
77+
-------------
7678
01 00 50 E1 CMP r0, r1 第三列(20位)为奇数一定更新Z标志位,偶数就是不需要更新标志位
7779
7880
SUBS 既要结果,又要标志寄存器
@@ -99,15 +101,15 @@ LDR R3, [R5],这条指令有寄存器和内存两个操作数,寄存操作
99101
100102
MOVEQ R2,#0x1F 这条指令有寄存器和立即数两个操作数,寄存操作数总在最前。
101103
102-
LDR r0,[r1, #4], 第一个操作数r0 寄存器,第二个操作数[r1, #4]内存,#4不是立即数,只是内存的一个索引模式
104+
LDR r0,[r1, #4] 第一个操作数r0 寄存器,第二个操作数[r1, #4]内存,#4不是立即数,只是内存的一个索引模式
103105
104-
MOV R6,R6,LSLR2 第一个操作数R6 寄存器, 第二个操作数(R6,LSL,R2) R6左移R2这么多位
106+
MOV R6,R6,LSL R2 第一个操作数R6 寄存器, 第二个操作数(R6,LSL,R2) R6左移R2这么多位
105107
106-
LDREQ R0, [r4],#4 第一个操作数R6 寄存器, 第二个操作数[r4],#4 内存操作数,,#4缓存之后附加行为
108+
LDREQ R0, [r4],#4 第一个操作数R6 寄存器, 第二个操作数[r4],#4 内存操作数,,#4的意思为访存之后的附加行为
107109
108-
lDR R5, =(dword_493D4 - 0x13190) 伪指令,不是原生的arm指令。只要有等号的就是一个内存操作数,相当于看到中括号
110+
lDR R5, =(dword_493D4 - 0x13190) 伪指令,不是原生的arm汇编指令。只要有等号的就是一个内存操作数,相当于看到中括号
109111
110-
STMFD SP!, {R4,R5,LR} SP! 寄存器操作数,{R4,R5,LR}为寄存器组,寄存器组也是寄存器操作数
112+
STMFD SP!, {R4,R5,LR} SP!为寄存器操作数,{R4,R5,LR}为寄存器组,寄存器组也是寄存器操作数
111113
112114
BLS loc_131FC 标签这种就是立即数操作数
113115
@@ -119,7 +121,9 @@ BLS loc_131FC 标签这种就是立即数操作数
119121
### 1.3.1 arm模式下
120122

121123
```
122-
MOV PC, R0 r0的值给PC
124+
PC寄存器指在当前位置下,在r0寄存器位置点击edit,赋值一个新地址。
125+
使用keypatch 修改当前机器码为 MOV PC, R0,意思就是r0的值给PC,下一步,调试就会跳到刚才给R0赋值的地址位置,因为pc就是指向当前位置,实现内存跳。
126+
123127
MOV R0, PC arm模式下读pc的值就是要地址+8, thumb就是+4,即使遇到跳转也是+8。
124128
```
125129

@@ -152,12 +156,14 @@ BLS loc_131FC 标签这种就是立即数操作数
152156
```
153157

154158
```
155-
[pc, #4] 一般4立即数加#号
156-
ida中 按d可以将此类locret_B6ECA934 强行改成数据
157-
减去4个地址就是[pc, #-4], 此时pc=0xB6EF2934, 加8在减4,r0=0xEA00B501,自动识别出来。
159+
[pc, #4] 4为立即数,一般立即数前面需要加#号
160+
ida中 按d可以将此类locret_B6ECA934 强行改成数据格式。
161+
减去4个地址就是[pc, #-4]
162+
此时pc=0xB6EF2934, 加8在减4,r0=0xEA00B501,自动识别出来。
158163
但是按f8后,结果却不对,为何?
159-
0xB6EF2934 + 8 -4 = 0xb6ef2938为pc的下一指令。
160-
因为调试器机制,所以会有断点问题,点击f8,他会在下一条指令进行注入,r0的值已经是修改后的,所以不是我们想象的那样为EA00B501
164+
结果为:0xE7F001F0, 把结果改为 F0 01 F0 E7 指令 使用patch program修改后,发现是一个UND指令,相当于一个断点。
165+
0xB6EF2934 + 8 -4 = 0xb6ef2938为当前pc的下一指令。
166+
因为调试器机制,在下断点的时候,点击f8,他会在下一条指令进行注入。而我们计算得到的0xb6ef2938就是为下一条指令,所以实际得到的是断点指令,所以不是我们想象的那样为EA00B501。
161167
162168
libc.so:B6EF2934 04 00 1F E5 LDR R0, =0xEA00B501 ; Keypatch modified this from:
163169
libc.so:B6EF2934 ; BXPL LR

Android/C03/README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
```python
66
mov指令,不访问内存,没有读写内存的操作。因为不访存所以没有内存操作数,只有两个操作数要么是寄存器要么是立即数。
77
从第二个操作数给第一个操作数,所以第一个操作数一定是寄存器。
8-
arm指令长度就是4字节32位,立即数不能是任意的32位整形,指令长度不足以表示。
8+
arm指令长度就是4字节32位,所以立即数不能是任意的32位整形,指令长度不足以表示。
99
因为mov三种格式允许操作的立即数最多的就是A2编码16位,所以mov指令下立即数不能超16位。
1010
```
1111

@@ -16,13 +16,14 @@ arm指令长度就是4字节32位,立即数不能是任意的32位整形,指
1616
![](pic/01.png)
1717

1818
```
19-
mov r0,0x80000000 即使立即数超了16位也可以,为什么呢?因为采用了A1的这种方式,这种立即数比较常见,它的有效位只有它的最高位
19+
mov r0,0x80000000 即使立即数超了16位也可以,为什么呢?因为采用了A1的这种方式,这种立即数比较常见,它的有效位只有它的最高位8000
2020
02 01 A0 E3 MOV R0, #0x80000000
2121
2222
hex_str1 = "0xE3a00102"
23-
bin:1110 0011 1010 0000 0000 0001 00000010
23+
bin:1110 0011 1010 0000 0000 0001 00000010
24+
25+
图上又把后12位拆成2份,8-11位以及0-7位,这个立即数就是把机器码里面的02也就是低8位立即数00000010,进行向右循环移位。移多少位呢,就是imm12的高第8-11位乘2,也就是最后8位00000010 向右移动8-11位*2(0001*2=两位)。
2426
25-
图上又把后12位拆成2份,8-11位以及0-7位,机器码里面的02也就是低8位立即数00000010进行向右循环移位。移多少位呢,就是imm12的高第8-11位乘2,也就是最后8位00000010向右移动8-11位*2(0001*2=两位)。
2627
8位立即数向右移动,可以移动的范围就是4的2次方也就是0-16,为什么乘2?就是0-32,可以覆盖到0-32中的偶数可以移动的比较全,8位立即数可以向右移动0、2、4、8、16、32。
2728
2829
此指令A1作用就是 防止写入0x80000000时把机器码弄长,采用左移的方式。
@@ -44,7 +45,7 @@ hex_str1 = "0xE3011234"
4445
bin:1110 0011 0000 0001 0001 001000110100
4546
4647
倒数第1块后12位(imm12)就是立即数后三个字节0x234,倒数第3块4位(imm4)就是立即数第一个字节0x1,拼起来就是我们的立即数0x1234。
47-
倒数第2块Rd就是代表寄存器,12-15有4位,2的4次方可以表示0-15的数字,int("1111", 2)=15也就是寄存器r0-r15,后三个寄存器就是SP、LR、PC。此时我们是r0,看倒数第二块就是0,r1就是0001。
48+
倒数第2块Rd就是代表寄存器,12-15有4位,2的4次方可以表示0-15的数字,int( "1111", 2)=15也就是寄存器r0-r15,后三个寄存器就是SP、LR、PC。此时我们是r0,看倒数第二块就是0,r1就是0001。
4849
bin(16) =0b10000,16以后只能5位才能表示。
4950
```
5051

@@ -73,7 +74,7 @@ Rm = 0001 = r1, 操作的寄存器
7374
stype = 00 = LSL
7475
左移右移通过stype(5-6)两位表示,2的2次方代表4种模式:逻辑左移、逻辑右移、算术右移、循环移位。
7576
没有算数左移,因为算数左移和逻辑左移是一样的,算术右移是带符号的不等于逻辑右移,循环移位不区分左右。
76-
imm5 = 移位的位数 = 00100 = 4
77+
imm5 = 移位的位数 = 00100 = 4
7778
移位的数就是imm5,这里imm5不是指立即数而是移多少位,7-11位就是通过5位表示,2的5次方=32就是指可以表示0-31的数字。
7879
移位的范围是32,因为循环左移1位和循环右移31位是一样的,所以循环移位不区分左右。
7980
Rd = 0000 = r0
@@ -88,6 +89,8 @@ lsl r0, r1,4 = MOV R0, R1,LSL#4
8889
![](pic/04.png)
8990

9091
```
92+
寄存器带有寄存器的位移
93+
9194
MOV R0, R1,LSR R2 同上,只不过imm5立即数换成了Rs,与lsr r0, r1, r2两种相等,反汇编后都是move指令。
9295
```
9396

0 commit comments

Comments
 (0)