update peda

This commit is contained in:
firmianay 2017-09-08 13:05:10 +08:00
parent 6b41f36a7f
commit 9298ad049d
6 changed files with 290 additions and 18 deletions

View File

@ -53,7 +53,7 @@
- [5.2 Pin 动态二进制插桩](doc/5.2_pin.md)
- [5.3 angr 二进制自动化分析](doc/5.3_angr.md)
- [5.4 反调试技术](doc/5.4_antidbg.md)
- [5.5 Symbolic Execution 符号执行技术](doc/5.5_symbolic.md)
- [5.5 符号执行](doc/5.5_symbolic.md)
- [5.6 LLVM](doc/5.6_llvm.md)
- [六、附录](doc/6_appendix.md)

View File

@ -50,7 +50,7 @@
* [5.2 Pin 动态二进制插桩](doc/5.2_pin.md)
* [5.3 angr 二进制自动化分析](doc/5.3_angr.md)
* [5.4 反调试技术](doc/5.4_antidbg.md)
* [5.5 Symbolic Execution 符号执行](doc/5.5_symbolic.md)
* [5.5 符号执行](doc/5.5_symbolic.md)
* [5.6 LLVM](doc/5.6_llvm.md)
* [六、附录](doc/6_appendix.md)
* [6.1 更多 Linux 工具](doc/6.1_Linuxtools.md)

View File

@ -203,6 +203,13 @@ long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
PEDAPython Exploit Development Assistance for GDB是一个强大的 gdb 插件。它提供了高亮显示反汇编代码、寄存器、内存信息等人性化的功能。同时PEDA 还有一些实用的新命令,比如 checksec 可以查看程序开启了哪些安全机制等等。
#### 安装
安装 peda 需要的软件包:
```shell
$ sudo apt-get install nasm micro-inetd
$ sudo apt-get install libc6-dbg vim ssh
```
安装 peda
```shell
$ git clone https://github.com/longld/peda.git ~/peda
$ echo "source ~/peda/peda.py" >> ~/.gdbinit
@ -217,37 +224,78 @@ $ yaourt -S peda
#### peda命令
- **`aslr`** -- 显示/设置 gdb 的 ASLR
- `asmsearch` -- Search for ASM instructions in memory
- `asmsearch "int 0x80"`
- `asmsearch "add esp, ?" libc`
- `assemble` -- On the fly assemble and execute instructions using NASM
- `assemble`
- ```
assemble $pc
> mov al, 0xb
> int 0x80
> end
```
- **`checksec`** -- 检查二进制文件的安全选项
- `cmpmem` -- Compare content of a memory region with a file
- `cmpmem 0x08049000 0x0804a000 data.mem`
- `context` -- Display various information of current execution context
- `context_code` -- Display nearby disassembly at $PC of current execution context
- `context_register` -- Display register information of current execution context
- `context_stack` -- Display stack of current execution context
- `context reg`
- `context code`
- `context stack`
- `crashdump` -- Display crashdump info and save to file
- `deactive` -- Bypass a function by ignoring its execution (eg sleep/alarm)
- `deactive setresuid`
- `deactive chdir`
- `distance` -- Calculate distance between two addresses
- **`dumpargs`** -- 在调用指令停止时显示传递给函数的参数
- `dumpmem` -- Dump content of a memory region to raw binary file
- `dumpmem libc.mem libc`
- **`dumprop`** -- 在特定的内存范围显示 ROP gadgets
- `dumprop`
- `dumprop binary "pop"`
- `eflags` -- Display/set/clear/toggle value of eflags register
- **`elfheader`** -- 获取正在调试的 ELF 文件的头信息
- `elfheader`
- `elfheader .got`
- **`elfsymbol`** -- 从 ELF 文件中获取没有调试信息的符号信息
- `elfsymbol`
- `elfsymbol printf`
- `gennop` -- Generate abitrary length NOP sled using given characters
- `gennop 500`
- `gennop 500 "\x90"`
- `getfile` -- Get exec filename of current debugged process
- `getpid` -- Get PID of current debugged process
- `goto` -- Continue execution at an address
- `help` -- Print the usage manual for PEDA commands
- `hexdump` -- Display hex/ascii dump of data in memory
- `hexdump $sp 64`
- `hexdump $sp /20`
- `hexprint` -- Display hexified of data in memory
- `hexprint $sp 64`
- `hexprint $sp /20`
- `jmpcall` -- Search for JMP/CALL instructions in memory
- `jmpcall`
- `jmpcall eax`
- `jmpcall esp libc`
- `loadmem` -- Load contents of a raw binary file to memory
- `loadmem stack.mem 0xbffdf000`
- **`lookup`** -- 搜索属于内存范围的地址的所有地址/引用
- `lookup address stack libc`
- `lookup pointer stack ld-2`
- `nearpc` -- Disassemble instructions nearby current PC or given address
- `nearpc 20`
- `nearpc 0x08048484`
- `nextcall` -- Step until next 'call' instruction in specific memory range
- `nextcall cpy`
- `nextjmp` -- Step until next 'j*' instruction in specific memory range
- `nextjmp`
- `nxtest` -- Perform real NX test to see if it is enabled/supported by OS
- **`patch`** -- 使用字符串/十六进制字符串/整形数
- `patch $esp 0xdeadbeef`
- `patch $eax "the long string"`
- `patch (multiple lines)`
- **`pattern`** -- 生成,搜索或写入循环 pattern 到内存
- `pattern_arg` -- Set argument list with cyclic pattern
- `pattern_create` -- Generate a cyclic pattern
@ -255,46 +303,268 @@ $ yaourt -S peda
- `pattern_offset` -- Search for offset of a value in cyclic pattern
- `pattern_patch` -- Write a cyclic pattern to memory
- `pattern_search` -- Search a cyclic pattern in registers and memory
- `pattern create 2000`
- `pattern create 2000 input`
- `pattern offset $pc`
- `pattern search`
- `pattern patch 0xdeadbeef 100`
- `payload` -- Generate various type of ROP payload using ret2plt
- `payload copybytes`
- `payload copybytes target "/bin/sh"`
- `payload copybytes 0x0804a010 offset`
- `pdisass` -- Format output of gdb disassemble command with colors
- `pdisass $pc /20`
- `pltbreak` -- Set breakpoint at PLT functions match name regex
- `pltbreak cpy`
- **`procinfo`** -- 显示调试进程的 /proc/pid/
- `procinfo`
- `procinfo fd`
- `profile` -- Simple profiling to count executed instructions in the program
- `pyhelp` -- Wrapper for python built-in help
- `pyhelp peda`
- `pyhelp hex2str`
- **`pshow`** -- 显示各种 PEDA 选项和其他设置
- `pshow`
- `pshow option context`
- **`pset`** -- 设置各种 PEDA 选项和其他设置
- `pset arg '"A"*200'`
- `pset arg 'cyclic_pattern(200)'`
- `pset env EGG 'cyclic_pattern(200)'`
- `pset option context "code,stack"`
- `pset option badchars "\r\n"`
- **`readelf`** -- 获取 ELF 的文件头信息
- `readelf libc .text`
- `refsearch` -- Search for all references to a value in memory ranges
- `refsearch "/bin/sh"`
- `refsearch 0xdeadbeef`
- `reload` -- Reload PEDA sources, keep current options untouch
- **`ropgadget`** -- 获取二进制或库的常见 ROP gadgets
- `ropgadget`
- `ropgadget libc`
- **`ropsearch`** -- 搜索内存中的 ROP gadgets
- `ropsearch "pop eax"`
- `ropsearch "xchg eax, esp" libc`
- **`searchmem|find`** -- 搜索内存中的 pattern; 支持正则表达式搜索
- `find "/bin/sh" libc`
- `find 0xdeadbeef all`
- `find "..\x04\x08" 0x08048000 0x08049000`
- `searchmem` -- Search for a pattern in memory; support regex search
- `session` -- Save/restore a working gdb session to file as a script
- `set` -- Set various PEDA options and other settings
- `set exec-wrapper ./exploit.py`
- `sgrep` -- Search for full strings contain the given pattern
- **`shellcode`** -- 生成或下载常见的 shellcode
- `shellcode x86/linux exec`
- `show` -- Show various PEDA options and other settings
- **`skeleton`** -- 生成 python exploit 代码模板
- `skeleton argv exploit.py`
- `skipi` -- Skip execution of next count instructions
- `snapshot` -- Save/restore process's snapshot to/from file
- `snapshot save`
- `snapshot restore`
- `start` -- Start debugged program and stop at most convenient entry
- `stepuntil` -- Step until a desired instruction in specific memory range
- `stepuntil cmp`
- `stepuntil xor`
- `strings` -- Display printable strings in memory
- `strings`
- `strings binary 4`
- `substr` -- Search for substrings of a given string/number in memory
- `telescope` -- Display memory content at an address with smart dereferences
- `telescope 40`
- `telescope 0xb7d88000 40`
- `tracecall` -- Trace function calls made by the program
- `tracecall`
- `tracecall "cpy,printf"`
- `tracecall "-puts,fflush"`
- `traceinst` -- Trace specific instructions executed by the program
- `traceinst 20`
- `traceinst "cmp,xor"`
- `unptrace` -- Disable anti-ptrace detection
- `unptrace`
- `utils` -- Miscelaneous utilities from utils module
- **`vmmap`** -- 在调试过程中获取段的虚拟映射地址范围
- `cmmap`
- `vmmap binary / libc`
- `vmmap 0xb7d88000`
- `waitfor` -- Try to attach to new forked process; mimic "attach -waitfor"
- `waitfor`
- `waitfor myprog -c`
- `xinfo` -- Display detail information of address/registers
- `xinfo register eax`
- `xinfo 0xb7d88000`
- **`xormem`** -- 用一个 key 来对一个内存区域执行 XOR 操作
- `xormem 0x08049000 0x0804a000 “thekey”`
- `xprint` -- Extra support to GDB's print command
- `xrefs` -- Search for all call/data access references to a function/variable
- `xuntil` -- Continue execution until an address or function
#### 使用 PEDA 和 Python 编写 gdb 脚本
- 全局类
- `pedacmd`
- 交互式命令
- 没有返回值
- 例如:`pedacmd.context_register()`
- `peda`
- 与 gdb 交互的后端功能
- 有返回值
- 例如:`peda.getreg("eax")`
- 小工具
- 例如:`to_int()`、`format_address()`
- 获得帮助
- `pyhelp peda`
- `pyhelp hex2str`
- 单行/交互式使用
- `gdb-peda$ python print peda.get_vmmap()`
- ```
gdb-peda$ python
> status = peda.get_status()
> while status == "BREAKPOINT":
> peda.execute("continue")
> end
```
- 外部脚本
- ```
# myscript.py
def myrun(size):
argv = cyclic_pattern(size)
peda.execute("set arg %s" % argv)
peda.execute("run")
```
```
gdb-peda$ source myscript.py
gdb-peda$ python myrun(100)
```
下面我们通过一道 CTF 题目来练习一下 PEDA 脚本的编写:[asis-ctf-quals-2014 serial-number re-300](../src/Reverse/2.2_serial_number_300)
```
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
__int64 result; // rax@5
int v4; // ecx@9
int v5; // ecx@9
int v6; // ecx@9
int v7; // ecx@9
int v8; // ecx@9
unsigned __int64 v9; // [sp+8h] [bp-68h]@4
int v10; // [sp+10h] [bp-60h]@9
int v11; // [sp+14h] [bp-5Ch]@9
int v12; // [sp+18h] [bp-58h]@9
int v13; // [sp+1Ch] [bp-54h]@9
int v14; // [sp+20h] [bp-50h]@9
int v15; // [sp+24h] [bp-4Ch]@9
int v16; // [sp+28h] [bp-48h]@9
int v17; // [sp+2Ch] [bp-44h]@9
unsigned __int64 v18; // [sp+38h] [bp-38h]@6
int v19; // [sp+44h] [bp-2Ch]@4
_QWORD *v20; // [sp+48h] [bp-28h]@1
int i; // [sp+54h] [bp-1Ch]@1
int v22; // [sp+58h] [bp-18h]@1
int v23; // [sp+5Ch] [bp-14h]@1
v23 = 0;
v22 = 1;
v20 = malloc(4uLL);
for ( i = 0; i <= 3; ++i )
{
v20[i] = malloc(0xCuLL);
*(_DWORD *)(v20[i] + 8LL) = 1;
}
printf("Enter serial number in hex formet (without 0x prefix) : ", a2);
v19 = scanf("%llx", &v9);
if ( v19 > 0 )
{
v18 = v9;
while ( v9 )
{
v22 ^= 1u;
if ( *(_DWORD *)*v20 != v22 && v22 )
{
v14 = v9 & 1;
v9 >>= 1;
v15 = v9 & 1;
v9 >>= 1;
v16 = v9 & 1;
v9 >>= 1;
v17 = v9 & 1;
v9 >>= 1;
v23 = *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_BYTE *)(v20[3] + 4LL) & (unsigned __int8)v14 & (v15 == 0) & (unsigned __int8)(v16 & v17) & *(_DWORD *)(*v20 + 4LL);
v4 = *(_BYTE *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (unsigned __int8)(*(_BYTE *)(v20[3] + 4LL) & (v14 | (v15 == 0) | v16 | (v17 == 0))) & (*(_DWORD *)(*v20 + 4LL) == 0) | (*(_DWORD *)(v20[1] + 4LL) == 0) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (unsigned __int8)(*(_BYTE *)(v20[3] + 4LL) & ((v14 == 0) | (v15 == 0) | v16 | v17)) & *(_DWORD *)(*v20 + 4LL) | (*(_DWORD *)(v20[1] + 4LL) == 0) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (unsigned __int8)(*(_BYTE *)(v20[3] + 4LL) & (v14 | v15 | (v16 == 0) | v17)) & (*(_DWORD *)(*v20 + 4LL) == 0) | *(_DWORD *)(*v20 + 4LL) & *(_DWORD *)(v20[1] + 4LL) & *(_DWORD *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (v14 == 0) & (v15 == 0) & (unsigned __int8)(v16 & v17);
v13 = v4 | *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_DWORD *)(v20[3] + 4LL) & *(_DWORD *)(*v20 + 4LL);
v5 = *(_BYTE *)(v20[1] + 4LL) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)((v14 == 0) | v15 | (v16 == 0) | v17) & (*(_DWORD *)(*v20 + 4LL) == 0) | (*(_DWORD *)(v20[1] + 4LL) == 0) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)(v14 | (v15 == 0) | v16 | v17) & *(_DWORD *)(*v20 + 4LL) | (*(_DWORD *)(v20[1] + 4LL) == 0) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)((v14 == 0) | v15 | v16 | v17) & (*(_DWORD *)(*v20 + 4LL) == 0) | *(_DWORD *)(*v20 + 4LL) & *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)v14 & (unsigned __int8)v15 & (unsigned __int8)v16 & (v17 == 0);
v12 = v5 | *(_DWORD *)(v20[1] + 4LL) & *(_DWORD *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & *(_DWORD *)(*v20 + 4LL);
v6 = (*(_DWORD *)(v20[1] + 4LL) == 0) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (v14 == 0) & (unsigned __int8)v15 & (v17 == 0 && v16 == 0) & *(_DWORD *)(*v20 + 4LL) | *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0 && *(_DWORD *)(v20[2] + 4LL) == 0) & *(_DWORD *)(*v20 + 4LL) | *(_BYTE *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0 && *(_DWORD *)(v20[3] + 4LL) == 0 && (v14 == 0 || v15 == 0 || v17 == 0 || v16 == 0)) & (*(_DWORD *)(*v20 + 4LL) == 0) | *(_DWORD *)(*v20 + 4LL) & (*(_DWORD *)(v20[1] + 4LL) == 0) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)v14 & (v15 == 0) & (v16 == 0) & (unsigned __int8)v17;
v11 = *(_BYTE *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (unsigned __int8)(*(_BYTE *)(v20[3] + 4LL) & (v14 | (v15 == 0) | v16 | (v17 == 0))) & (*(_DWORD *)(*v20 + 4LL) == 0) | (*(_DWORD *)(v20[1] + 4LL) == 0) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_BYTE *)(v20[3] + 4LL) & (unsigned __int8)v14 & (unsigned __int8)v15 & (v17 == 0 && v16 == 0) & *(_DWORD *)(*v20 + 4LL) | *(_DWORD *)(v20[1] + 4LL) & *(_DWORD *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & *(_DWORD *)(*v20 + 4LL) | *(_BYTE *)(v20[1] + 4LL) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)((v14 == 0) | v15 | (v16 == 0) | v17) & (*(_DWORD *)(*v20 + 4LL) == 0) | v6 | *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_DWORD *)(v20[3] + 4LL) & *(_DWORD *)(*v20 + 4LL);
v7 = *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0 && *(_DWORD *)(v20[2] + 4LL) == 0) & *(_DWORD *)(*v20 + 4LL) | *(_BYTE *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)(v14 & v15 & v16 & v17) & (*(_DWORD *)(*v20 + 4LL) == 0) | (*(_DWORD *)(v20[1] + 4LL) == 0 && *(_DWORD *)(v20[3] + 4LL) == 0 && *(_DWORD *)(v20[2] + 4LL) == 0) & *(_DWORD *)(*v20 + 4LL) | (*(_DWORD *)(*v20 + 4LL) == 0) & (*(_DWORD *)(v20[1] + 4LL) == 0) & (*(_DWORD *)(v20[2] + 4LL) == 0) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)v14 & (v15 == 0) & (unsigned __int8)(v16 & v17);
v8 = *(_DWORD *)(v20[1] + 4LL) & *(_DWORD *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & *(_DWORD *)(*v20 + 4LL) | *(_BYTE *)(v20[1] + 4LL) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)v14 & (v15 == 0) & (unsigned __int8)v16 & (v17 == 0) & (*(_DWORD *)(*v20 + 4LL) == 0) | (*(_DWORD *)(v20[1] + 4LL) == 0) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & *(_DWORD *)(*v20 + 4LL) | (*(_DWORD *)(v20[1] + 4LL) == 0) & *(_BYTE *)(v20[2] + 4LL) & (*(_DWORD *)(v20[3] + 4LL) == 0) & (unsigned __int8)v14 & (v15 == 0 && v17 == 0 && v16 == 0) & (*(_DWORD *)(*v20 + 4LL) == 0) | v7;
v10 = *(_BYTE *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_BYTE *)(v20[3] + 4LL) & (v14 == 0) & (unsigned __int8)v15 & (v16 == 0) & (unsigned __int8)v17 & (*(_DWORD *)(*v20 + 4LL) == 0) | (*(_DWORD *)(v20[1] + 4LL) == 0) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_BYTE *)(v20[3] + 4LL) & *(_DWORD *)(*v20 + 4LL) | (*(_DWORD *)(v20[1] + 4LL) == 0) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_BYTE *)(v20[3] + 4LL) & (v14 == 0) & (v15 == 0) & (unsigned __int8)v16 & (v17 == 0) & (*(_DWORD *)(*v20 + 4LL) == 0) | v8 | *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_DWORD *)(v20[3] + 4LL) & *(_DWORD *)(*v20 + 4LL);
sub_40064D((unsigned int)v13, v20[3]);
sub_40064D((unsigned int)v12, v20[2]);
sub_40064D((unsigned int)v11, v20[1]);
sub_40064D((unsigned int)v10, *v20);
}
*(_DWORD *)v20[3] = v22;
*(_DWORD *)v20[2] = v22;
*(_DWORD *)v20[1] = v22;
*(_DWORD *)*v20 = v22;
}
if ( v23 == 1 )
printf("\nCongratulation! Send \"ASIS_MD5(%llx)\" as the flag!", v18);
else
printf("Sorry! The serial number is incorrect!");
result = 0LL;
}
else
{
printf("Invalid number.");
result = 0LL;
}
return result;
}
```
上面是在 IDA Pro 中 F5 的结果,可以看到程序中有非常长的位操作逻辑,如果硬着头皮分析的话会非常困难。下面我们借用 PEDA 强大的能力来解决它,首先简化下上面的代码:
```
int v9; // serial_number
int v23; // correct_serial
v23 = 0;
while (v9) {
v14 = v9 & 1;
v9 >>= 1;
v15 = v9 & 1;
v9 >>= 1;
v16 = v9 & 1;
v9 >>= 1;
v17 = v9 & 1;
v9 >>= 1;
v23 = v23 = *(_DWORD *)(v20[1] + 4LL) & (*(_DWORD *)(v20[2] + 4LL) == 0) & *(_BYTE *)(v20[3] + 4LL) & (unsigned __int8)v14 & (v15 == 0) & (unsigned __int8)(v16 & v17) & *(_DWORD *)(*v20 + 4LL);
(v20, v20[1], v20[2], v20[3]) = very_long_bit_operation_asm((v20, v20[1], v20[2], v20[3]), (v14, v15, v16, v17));
}
if (v23 == 1) {
printf("Congratulation!");
}
```
大概就是这样,我们用 `very_long_bit_operation_asm()` 函数代替了近千行的位操作,它的参数可以分为两组,`(v20, v20[1], v20[2], v20[3])` 和 `(v14, v15, v16, v17)`,每个组表示 4 比特的变量。所以,无论这个函数是什么操作,都只有 `16 * 16 = 256` 种可能,我们就可以使用暴力的方式破解它。
通过设置 `rip` 为循环代码的开始,并在 `` 函数结束处设置断点,我们就可以使代码循环执行了。
```text
0000000000400768 loc_400768: ; CODE XREF: main+E43
...
.text:0000000000400788 mov rax, [rbp+var_68]
...
000000000040149C
.text:000000000040149C loc_40149C: ; CODE XREF: main+DC
.text:000000000040149C ; main+E6
...
00000000004014D8
.text:00000000004014D8 loc_4014D8: ; CODE XREF: main+C7
.text:00000000004014D8 mov rax, [rbp+var_68]
```
参考 http://blog.ztrix.me/blog/2014/05/10/asis-quals-2014-serial-number-writeup/
#### 更多资料
http://ropshell.com/peda/

View File

@ -1 +1,6 @@
# Fuzz 测试
- [AFL](#afl)
## AFL

View File

@ -1,7 +1,8 @@
# Symbolic Execution 符号执行技术
# 5.5 符号执行
- [符号执行的历史](#符号执行的历史)
- [什么是符号执行](#什么是符号执行)
* [符号执行的历史](#符号执行的历史)
* [什么是符号执行](#什么是符号执行)
## 符号执行的历史
@ -10,8 +11,4 @@
或者进入[https://github.com/enzet/symbolic-execution](https://github.com/enzet/symbolic-execution)查看SVG大图。
## 什么是符号执行

BIN
src/Reverse/2.2_serial_number_300 Executable file

Binary file not shown.