查找资料的高效性

retn 返回到栈顶地址

关于 .init .fini .init_array .fini_array

其中存放着的是在main函数执行前执行的代码,由__libc_start_main调用,(__libc_start_main在libc.so上,所以先有start()调用__libc_start_main,再调用init段的代码)在这段代码中就有我们经常使用的libc_csu的gadget

.init段:

.text:0000000000400CB0 ; __unwind {
.text:0000000000400CB0 push r15
.text:0000000000400CB2 mov r15d, edi
.text:0000000000400CB5 push r14
.text:0000000000400CB7 mov r14, rsi
.text:0000000000400CBA push r13
.text:0000000000400CBC mov r13, rdx
.text:0000000000400CBF push r12
.text:0000000000400CC1 lea r12, off_6011B0 //此处将init_array(0x6011B0)上的值给r12
.text:0000000000400CC8 push rbp
.text:0000000000400CC9 lea rbp, off_6011B8 //此处将fini_array(0x6011B8)上的值给rbp
.text:0000000000400CD0 push rbx
.text:0000000000400CD1 sub rbp, r12 //rbp为init_array和fini_array的差
.text:0000000000400CD4 xor ebx, ebx //rbx清零
.text:0000000000400CD6 sar rbp, 3 //rbp算术右移3位(地址大小),即变成init_array中有多少个地址
.text:0000000000400CDA sub rsp, 8
.text:0000000000400CDE call _init_proc
.text:0000000000400CE3 test rbp, rbp
.text:0000000000400CE6 jz short loc_400D06
.text:0000000000400CE8 nop dword ptr [rax+rax+00000000h]
.text:0000000000400CF0
.text:0000000000400CF0 loc_400CF0: ; CODE XREF: init+54↓j
.text:0000000000400CF0 mov rdx, r13 //这里到0x400D14就是我们常用的gadget
.text:0000000000400CF3 mov rsi, r14
.text:0000000000400CF6 mov edi, r15d
.text:0000000000400CF9 call qword ptr [r12+rbx*8] //call r12+rbx*8,正常执行情况下是执行init_array 中的函数
.text:0000000000400CFD add rbx, 1 //rbx算是array中的偏移
.text:0000000000400D01 cmp rbx, rbp //直到array中的所用函数执行完,才能往下走
.text:0000000000400D04 jnz short loc_400CF0 //没执行完所用函数返回0x400CF0继续执行
.text:0000000000400D06
.text:0000000000400D06 loc_400D06: ; CODE XREF: init+36↑j
.text:0000000000400D06 add rsp, 8
.text:0000000000400D0A pop rbx
.text:0000000000400D0B pop rbp
.text:0000000000400D0C pop r12
.text:0000000000400D0E pop r13
.text:0000000000400D10 pop r14
.text:0000000000400D12 pop r15
.text:0000000000400D14 retn
.text:0000000000400D14 ; } // starts at 400CB0
.text:0000000000400D14 init endp

.init_array

.init_array:00000000006011B0 ; Segment type: Pure data
.init_array:00000000006011B0 ; Segment permissions: Read/Write
.init_array:00000000006011B0 ; Segment alignment 'qword' can not be represented in assembly
.init_array:00000000006011B0 _init_array segment para public 'DATA' use64
.init_array:00000000006011B0 assume cs:_init_array
.init_array:00000000006011B0 ;org 6011B0h
.init_array:00000000006011B0 off_6011B0 dq offset sub_400850 ; DATA XREF: LOAD:00000000004000F8↑o
.init_array:00000000006011B0 ; init+11↑o
.init_array:00000000006011B0 _init_array ends

关于.fini段

我的文件中的.fini只有已经一句代码:retn

.text:0000000000400D20 ; void fini(void)
.text:0000000000400D20 fini proc near ; DATA XREF: start+F↑o
.text:0000000000400D20 ; __unwind {
.text:0000000000400D20 rep retn //返回到栈顶地址
.text:0000000000400D20 ; } // starts at 400D20
.text:0000000000400D20 fini endp

而.fini_array中的有一个函数需要执行

.fini_array:00000000006011B8 ; Segment type: Pure data
.fini_array:00000000006011B8 ; Segment permissions: Read/Write
.fini_array:00000000006011B8 ; Segment alignment 'qword' can not be represented in assembly
.fini_array:00000000006011B8 _fini_array segment para public 'DATA' use64
.fini_array:00000000006011B8 assume cs:_fini_array
.fini_array:00000000006011B8 ;org 6011B8h
.fini_array:00000000006011B8 qword_6011B8 dq 400830h ; DATA XREF: init+19↑o //0x400830需要执行
.fini_array:00000000006011B8 _fini_array ends

所以我猜想:会不会在__libc_start_main()中,在调用.fini段前,.fini_array中的函数就已经入栈了?这个猜想也和前面题目在栈中一个情况(在栈上修改.fini_array push在栈上的地址为 main的地址,从而实现在程序main结束之后可以再执行一次的效果)相符合。

问题是:不知道怎么找到这个.fini_array在栈上的值

汇编

LEA

LEA r16,m

8D /r 不影响标志位

将源操作数的有效地址送 r16

LEA r32,m

将源操作数的有效地址送 r32

c语言

atol(): 把字符串转换成长整型数用 法: long atol(const char *nptr); 返回长整型

atoll(): 把字符串转换成长长整型数用 法: long long atol(const char *nptr); 返回长长整型

size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ; 返回真实读取的项数,count是最多读取的项数

大多数题目的setbuf()/setvbuf()函数的作用是用来关闭I/O缓冲区,本题没有关闭缓冲区,函数运行开始阶段在fgets()函数以及printf()函数运行的时候,会malloc()两块内存区域。

震惊!

ida pro居然把我一个全局变量识别成了局部变量

然后在函数中将原本应该是全局变量的s,写成了 ::s ,我佛了

【CTF】关于 .init .fini .init_array .fini_array 日志 2019.7.16 pwn的更多相关文章

  1. 在Android so文件的.init、.init_array上和JNI_OnLoad处下断点

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/54233552 移动端Android安全的发展,催生了各种Android加固的诞生, ...

  2. 2019.9.16 linux安装软件lamp

    2019/9/16 Linux软件安装 方式:yum/rpm/源码安装 yum安装: yum 是通过分析RPM的包头数据后,根据各软件的相关性制作出属性相对应的解决方案,然后可以自动处理软件的相依属性 ...

  3. [2019.03.16]使用DOM操作函数和CSS选择器来针对已有的HTML进行只凭JS的改动

    刚入职的时候看到公司用的HTML日志生成工具附带的Panel,工具不够用,找个Fail还要找半天,于是自己琢磨着添砖加瓦.以前也是个半吊子前端工程师,现在可倒好,想要改页面却连页面生成的模板在哪里都不 ...

  4. 2019.02.16 bzoj5466: [Noip2018]保卫王国(链分治+ddp)

    传送门 题意简述: mmm次询问,每次规定两个点必须选或者不选,求树上的带权最小覆盖. 思路: 考虑链分治+ddpddpddp 仍然是熟悉的套路,先考虑没有修改的状态和转移: 令fi,0/1f_{i, ...

  5. 2019.3.16 noiac的原题模拟赛

    RT,这太谔谔了,我不承认这是模拟赛 但是虽然是搬了三道题,题目本身也还能看,就这么着吧 (怎么机房里就我一道原题都没做过啊 T1 CF24D Broken Robot 比较简单地列出式子之后,我们发 ...

  6. Android高可用移动网络连接---(转载自http://wingjay.com/2019/01/16/mobile-network-connection/)

    读者好,前面我们在 <Android 架构之网络连接与加速> 和<Android 架构之长连接技术>两篇文章中,讲解了 Http 短连接.TCP 长连接.连接复用与速度优化.数 ...

  7. [2019.04.16] 由Python写成的自动解压脚本

    很久很久以前(二十七天吧……大概)被要求写一个脚本来检索并解压磁盘上所有的以特定格式命名的tar文件,于是乎学习和摸鱼就一起开始了. 这次要写的脚本,针对的是这样的文件结构: 文件结构如上图所示 可以 ...

  8. 2019.04.16 python基础50

    第五十一节  pycharm安装 https://www.jetbrains.com/pycharm/download/#section=windows 这是另一个叫jetbrains公司开发的 默认 ...

  9. 2019/4/16 wen 反射与JVM

  10. 2019.04.16打卡(java 数组)

    1.  要求输出数组中数据的平均值,并输出所有大于平均值的数据 代码 package block; import java.util.*; public class Average { public ...

随机推荐

  1. if判断while循环

  2. Vue+SSM+Element-Ui实现前后端分离(3)

    前言:经过博文(1)vue搭建,(2)ssm搭建,到这里就该真真切切的实现小功能了<-_-> 规划:实现登录,用户列表查询,访问日志aop; 开始先解决跨域:在目录config/index ...

  3. OO_Lab2总结博客

    OO_Lab2 一.单元内容 本单元内容为规格化设计,即通过参考已经完成的JML描述实现一个社交网络相关功能. 本单元整体来说难度不大,但是却是我最惨的一次作业,所以本博客可能会主要谈一谈测试中的一些 ...

  4. 【基础知识】C++算法基础(头文件配置、获取输入、输出)

    基础的头文件配置.输入输出 <iostream> 和<iostream.h>的区别:加.h是C中的做法,C++里一般不加.h,但相应的,要加using namspace std ...

  5. 8.Vuex状态管理

    一.Vuex 概述 1.1 组件之间共享数据的方式 父传子: v-bind 属性绑定 子传父: v-on 事件绑定 兄弟组件之间共享数据: EventBus $on 接收数据的那个组件 (数据接收方) ...

  6. git push 报错error: remote unpack failed: error Short read of block

    1.解决办法:找管理代码的人给你开权限. 2如果你的push的命令写错的话,也是会出现远端拒绝的提示,所以记得检查自己的push 命令是否正确 另一种明显的权限拒绝的例子: 英语学习:to push ...

  7. 字符串练习2 最长抑或路径(01trie树)

    题目链接在这里:P4551 最长异或路径 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 是一道比较经典的问题,对于异或问题经常会使用01trie树来解决. 当然01trie树只是用 ...

  8. C++初识指针之一

    新手学习C/C++都跳不过去的地方,就是指针,用的话,确实好用,但是概念比较绕, 指针的通俗说法 1.简单的来说,就是说每一个变量,在电脑内都占一个地方,这个地方用一个16进掉的编号来进行标记,类似于 ...

  9. Leecode 21.合并两个有序链表(Java 迭代、递归两种方法)

      想法: 1.迭代 设两个指针pa和pb,不断移动pa和pb,并进行比较,则将较小元素接到新链表,该过程直至pa或pb为null,之后将未空的接到已空之后,得到升序链表   1 //官方: 2 cl ...

  10. Unidbgrid自动调整列宽

    UniDBGrid1 -> ClientEvents -> ExtEvents [Ext.data.Store[store] ] add store.load fn: function s ...