pwncollegeAssembly30
算术
加法
.intel_syntax noprefix |
乘法
.intel_syntax noprefix |
除法
intelx86架构的除法div,商存放在rax,余数存放在rdx,在运算之前需要将rdx清空
.intel_syntax noprefix |
Sizes
将 ax 寄存器的高 8 位设置为 0x42。
.intel_syntax noprefix |
快速实现计算余数
如果我们有“x % y”,并且 y 是 2 的幂,例如 2^n,则结果将是 x 的低 n 位
计算以下内容:
rax = rdi % 256
rbx = rsi % 65536
.intel_syntax noprefix |
字长
将 rax 设置为 0x404000 处的字节
将 rbx 设置为 0x404000 处的字
设置 rcx设置为位于 0x404000 处的双字
将 rdx 设置为位于 0x404000 处的四字
.intel_syntax noprefix |
从存储在 rdi 中的地址加载两个连续的四字
计算前面步骤四字的总和。
将总和存储在 rsi 中的地址
1个四字等于8个字节
.intel_syntax noprefix |
Bitwise
移位
将 rax 设置为 rdi 的第 5 个最低有效字节。
例如:
rdi = | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
将 rax 设置为 B4 的值
rdi共64位(8字节),所以向右移4字节(32位),最低位就是原先的第五个字节
.intel_syntax noprefix |
与
不使用 MOV
和 XCHG
指令的情况下执行 RAX = RDI AND RSI
.intel_syntax noprefix |
异或
仅使用and,xor,or实现以下逻辑:
if x 为偶数,则
y = 1
else
y = 0
其中:
x = rdi
y = rax
.intel_syntax noprefix |
内存
读,写
.intel_syntax noprefix |
Stack
获取堆栈顶部的值,从中减去 rdi,然后将其放回
.intel_syntax noprefix |
不使用 pop,请计算存储在堆栈上的 4 个连续四字的平均值。 将平均值推送到堆栈上。 提示: RSP+0x?? 四字 A RSP+0x?? 四字 B RSP+0x?? 四字 C RSP 四字 D
控制流
绝对跳转
.intel_syntax noprefix |
相对跳转
将代码中的第一条指令设为 jmp
将 jmp 设为从当前位置到 0x51 字节的相对跳转
在相对跳转将重定向控制流的代码位置,将 rax 设置为 0x1
.rept
和 .endr
指令用来重复 nop
操作码
.intel_syntax noprefix |
间接跳转
实现以下逻辑:
如果 rdi 为 0:
jmp 0x403061
否则,如果 rdi 为 1:
jmp 0x40310d
否则,如果 rdi 为 2:
jmp 0x4031a2
否则,如果 rdi 为 3:
jmp 0x40325a
否则:
jmp 0x403357
假设 rdi 不会为负数
使用不超过 1 个 cmp 指令
使用不超过 3 个跳转(任何变体)
我们将为您提供在 rdi 中“切换”的数字。
我们将为您提供 rsi 中的跳转表基址。
.intel_syntax noprefix |
实现以下内容:
if [x] is 0x7f454c46:
y = [x+4] + [x+8] + [x+12]
else if [x] is 0x00005A4D:
y = [x+4] - [x+8] - [x+12]
else:
y = [x+4] * [x+8] * [x+12]
其中:
x = rdi,y = rax。
.intel_syntax noprefix |
Exam
For循环
请计算 n 个连续四字的平均值,其中:
rdi = 第一个四字的内存地址
rsi = n(循环次数)
rax = 计算的平均值
.intel_syntax noprefix |
While循环
计算连续内存区域中连续的非零字节数,其中:
rdi = 第一个字节的内存地址
rax = 连续非零字节数
此外,如果 rdi = 0,则设置 rax = 0
.intel_syntax noprefix |
函数
函数使用指令“call”和“ret”。
“call”指令将下一条指令的内存地址推送到堆栈上,然后跳转到存储在第一个参数中的值。
ret 从堆栈中弹出顶部值并跳转到该值。
请实现以下逻辑:
str_lower(src_addr): |
foo 在 0x403000 处提供。
foo 将单个参数作为值并返回一个值。
所有函数(foo 和 str_lower)都必须遵循 Linux amd64 调用约定(也称为 System V AMD64 ABI):
https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI
因此,您的函数 str_lower 应该在 rdi 中查找 src_addr,并将函数返回放在 rax 中。
需要注意的是,src_addr 是内存中的地址(字符串所在的位置),而 [src_addr] 指的是 src_addr 中存在的字节。
因此,函数 foo 接受一个字节作为其第一个参数并返回一个字节
.intel_syntax noprefix |