csapp第八章——异常控制流
[TOC] 异常控制流现代系统通过使控制流发生突变来对系统状态的变化做出反应 。一般而言 ,我们把这些突变称为异常控制流 (Exceptional Control Flow, ECF) 。 异常异常是异常控制流的一种形式,它一部分由硬件实现,一部分由操作系统实现。 异常 (exception) 就是控制流中的突变,用来响应处理器状态中的某些变化。 当处理器检测到有事件发生时,它就会通过一张叫做异常表 (exception table)的跳转表,进行一个间接过程调用(异常),到一个专门设计用来处理这类事件的操作系统子程序(异常处理程序 (exception handler)) 。 异常处理 异常处理程序运行在内核模式下,这意味它们对所有的系统资源都有完全的访问权限。 异常的类别 同步异步表示的结果的获取方式是主动获取还是被动接收;阻塞非阻塞表示的是获取这个动作是否可以立即返回不用等待。 中断中断是异步发生的, 是来自处理器外部的 I/0 设备的信号的结果。例如定时器计时结束后会向处理器发送一个中断。 陷阱和系统调用陷阱是有意的异常,是执行一条指令的结果...
51单片机学习0x1
江科大51单片机学习笔记 单片机 单片机不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上。相当于一个微型的计算机。 命名规则: 51单片机 51单片机是对所有兼容Intel8031指令系统的单片机的统称,这一系列的单片机的始祖是Intel的8031单片机,后来随着flash...
csapp第六章——存储器层次结构
存储器层次结构计算机技术的成功很大程度上源自于存储技术的巨大进步 。 随机访问存储器静态RAM 由于 SRAM 存储器单元的双稳态特性,只要有电,它就会永远地保持它的值。 动态RAMDRAM 将每个位存储为对每个电容的充电。与 SRAM 不同, DRAM 存储器单元对干扰非常敏感 。 传统的DRAMDRAM 芯片中的单元(位)被分成d 个超单元 (supercell) , 每个超单元都个DRAM单元组成。 d*w 的DRAM 总共存储了d w位信息。 图示为168 DRAM 芯片的组织,有 d=l6 个超单元,每个超单元有 w=8 位, r=4 行,c=4 。 将 DRAM 组织成二维阵列而不是线性数组的一个原因是降低芯片上地址引脚的数量。 二维阵列组织的缺点是必须分两步发送地址,这增加了访问时间。 内存模块DRAM 芯片封装在内存模块 (memory module) 中,它插到主板的扩展槽上 。 内存控制器将超单元地址 发送到内存模块,然后内存模块再广播到每个 DRAM 。作为响应,每个DRAM...
csapp第七章——链接
链接链接 (linking) 是将各种代码和数据片段收集并组合成为一个单一文件的过程,这个文件可被加载(复制)到内存并执行 。 链接可以执行于编译时 (compile time), 也就是在源代码被翻译成机器代码时; 也可以执行与加载时 (load time), 也就是在程序被加载器 (loader) 加载到内存并执行时; 甚至执行于运行时 (run time), 也就是由应用程序来执行。 编译器驱动程序12345678910111213141516171819202122232425/* main.c *//* $begin main */int sum(int *a, int n);int array[2] = {1, 2};int main(){ int val = sum(array, 2); return val;}/* $end main *//* sum.c *//* $begin sum */int sum(int *a, int n){ int i, s = 0; for (i...
csapp第五章——优化程序性能
优化程序性能 第一,我们必须选择一组适当的算法和数据结构。 第二,我们必须编写出编译器能够有效优化以转换成高效可执行代码的源代码。 为什么我们需要优化程序,现代编译器不是具有很强的优化能力吗? ans:因为编译器只进行安全的优化,消除可能出现的异常的运行时行为。意味着我们需要写出适合编译器优化的代码,优化程序性能。 内存别名使用 两个指针可能指向同一个内存位置的情况称为内存别名使用 (memory aliasing) 12345678910void twiddlel(long *Xp, long *yp) { *XP += *yp; *XP += *yp; } void twiddle2(long *XP, long *yp) { *XP += 2* *yp; } 乍一看两个函数好像没有区别,但是当*XP与*YP指向同一内存时。twiddle1变为原来的四倍,twiddle2变为原来的三倍。改变了程序的行为。 ...
格式化字符串
C语言变参函数1man 3 printf //查看C语言格式化字符串 格式化字符串 $第n个参数%s变量所对应地址的内容%p获取对应栈的内存%n不输出字符,但是把已经成功输出的字符个数写入对应的整型指针参数所指的变量。hn(half int) hhn(half half int) 1.找到偏移值 通过fmtarg 来判断某个参数的偏移。 2.任意地址写入 3. ->RELRO->got表项->一般改printf函数 栈 one_gadget malloc_hook:printf参数超过 %43$p —>调用 malloc iofile jarvisoj_fm1关闭PIE,我们可以直接将x的地址写入后用%n修改所指的变量。buf为栈上第11个参数 1234567891011121314#!/usr/bin/env pythonfrom pwn import...
jarvisoj_level2
# 这题其实蛮简单的但是涉及到了gdb的多线程调试,故记录一下。 尝试gdb调试,提示gdb开始调试子进程,然后子进程退出,打开ida查看一下,可以看到在vulnerable_function()中,在system("echo Input:");才进入漏洞函数,那么我们就需要又 由于system函数会打开一个shell执行命令,会folk一个子进程,因此我们需要使gdb一只调试主进程, gdb多线程调试常用操作 GDB调试多进程的命令介绍和演示 - 刘跑跑 - 博客园 (cnblogs.com) info inferiors 查看所有进程 inferiors 2 切换到编号为2的进程 detach inferiors 2 detach掉编号为2的进程 kill inferiors 2 kill掉编号为2的进程 set follow-fork-mode parent 只调试父进程(GDB默认) set follow-fork-mode child 只调试子进程 show...
get_started_3dsctf_2016
#栈溢出,查看漏洞函数。 我们可以直接将程序控制流转移到打开文件来绕过if语句 exp123456789from pwn import *#sh= remote("node5.buuoj.cn",26045)sh = process('./get_started_3dsctf_2016')addr=0x080489b8offset = 56payload =...
CrackRTF
CrackRTF 函数atoi将输入的字符串化为整型,同时限定了v7为长度为6的字符串,因此我门可以尝试爆破,sub_401230有标识符0x8004u,判断为sha1 12345678910import hashlibstring='@DBApp'for i in range(100000,999999): flag=str(i)+string x = hashlib.sha1(flag.encode("utf8")) y = x.hexdigest() if "6e32d0943418c2c33385bc35a1470250dd8923a9" == y: print(flag) break 123321@DBApp passwd(2)只限定了输入的长度,有 95^6种可能 (可见字符),显然无法直接爆破。 在sub_4014D0我们发现了 hResInfo = FindResourceA(0, (LPCSTR)0x65,...
wp2
[WUSTCTF2020]level3 base64换表,给出了加密后的字符串,那么我们只需要找到换表函数即可,通过交叉引用查看到关键函数 12345678910base='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'base=list(base)for i in range (0,10): x=base[i] base[i]=base[19-i] tmp= 19-i base[tmp]=x print("".join(base)) base64解密即可 特殊的 BASE64 猜测是base64换表