Linux下的程序的文件格式是ELF,里面分了各种段,有代码段、数据段、等。当运行这个程序时,系统也会给这个进程创建虚拟内存,然后把ELF中的数据分别加载到内存中的对应位置。...本文整理了用cpp程序读取内存中的代码段和rodata数据段的方法。...这个文件的前三列分别是代码段、rodata数据段、和普通数据段,可以看到代码段的权限是读和执行,rodata数据段是只读,普通数据段可读写。...用程序读取内存的代码段和rodata数据段 以tcpdump程序为例,用程序读取代码段和radata的过程如下: 1.查看tcpdump的进程ID。...2.运行自己写的程序,分别输入进程PID和代码段的地址。
就拿学习 Linux 操作系统来说,作为一个长期的学习计划,不太可能一上来就阅读最新的 Linux 5.13 版本的代码。...代码段:用来存放代码,段的基地址放在寄存器 CS 中,指令指针寄存器 IP 用来表示下一条指令在段中的偏移地址; 数据段:用来存放程序处理的数据,段的基地址存放在寄存器 DS 中。...在 Linux 2.6 代码中,由于 Linux 把整个 4 GB 的地址空间当做一个“扁平”的结果来处理(段的基地址是 0x0000_0000,偏移地址的最大值是 4GB),因此虚拟地址(逻辑地址)在数值上等于线性地址...这张图的意思是:在 Linux 2.6 中,用户代码段的开始地址是 0,最大范围是 4 GB;用户数据段的开始地址是 0,最大范围也是 4 GB;内核的数据段和代码段也是如此。 ?...另外,代码中最后一句 end start,用来告诉编译器:代码段中 start 标号代表的地址,就是这个程序的入口地址,编译之后这个入口地址信息也会被写入可执行程序中。
在windows系统下运行下面的代码可以正常运行但到了linux下,出现段错误通过gbd调试检测到是fwrite出现的问题(段错误提示在代码下面)通过打断点检测也确实是fwrite将数据写入流的时候不能写入出现的段错误...}void pipe(GLubyte* data){ cout<<"pipe start"<<endl; fwrite(data, lSize, 1, pPipe); //出现段错误
不过这里还是有一点需要注意,就是设置到regs->ip中的地址,并不是我们自己程序的起始地址,而是动态链接器 /lib64/ld-linux-x86-64.so.2 的起始地址。...auxiliary vector区存放的用户程序的起始地址,是上面linux内核初始化堆栈时设置的。 动态链接器相关的代码就是这些,它对应于上面全景图中紫色的部分。...在跳转到我们自己程序的起始地址后,首先执行的并不是我们写的main函数,而是glibc里名为_start的一段汇编代码。...再看_dl_start函数: 该函数调用了_dl_start_final,返回一个地址,这个地址就是我们自己程序的起始地址。...动态链接器从内核设置的auxiliary vector中,获取的用户程序的起始地址,还并不是我们的main函数,而是glibc中一段名为_start的代码,这个可以通过下面的方式确认: 该_start代码段内容如下
在linux内核映射物理地址的简单代码。 使用request_mem_region和ioremap映射物理地址。 映射之后,可通过虚拟地址读写对应的寄存器。
所以编译器会在调用puts函数的地方,先自动跳转到.plt段里面的给定位置,这个位置用puts@glt来表示。 从puts@glt对应的地址开始是一段二进制指令代码,其基本内容如下所示: 。 ?...注意到无论是puts@plt,还是__libe_start_main@plt它们对应的代码除了push一个数值后,然后都跳转到地址4003f0,而该地址就落在.plt段里面的某个位置。...4003f0这个位置其实对应一段代码的起始地址,这段代码的作用是从.got.plt段里面取出一个数值作为下一步跳转的地址,然后通过Jmp跳转到取出地址所在位置,将程序控制权交给那里的代码。...除了.got.plt段外,还需要理解的是.got段,后者的作用主要在于访问共享代码库到处的变量。两者区别在于.got.plt段包含了代码,而.got段会直接包含共享库到处的变量地址而不是包含代码。...同理.fini_array段也包含了一系列函数地址,他们在代码运行结束后会被系统调用,下一节我们再回头看看程序表头。
下面就记述下病毒的发现、清理和认识过程,一路下来可以给我们的Linux命令学习提供很多知识点。这里面大部分操作都在生信宝典的Linux系列教程有提及,也是我们常用的提高效率的方式。...SELinux是安全增强型 Linux(Security-Enhanced Linux),它是一个Linux内核模块,也是Linux的一个安全子系统。主要由美国国家安全局开发。...# ps获取运行的进程,grep屏蔽掉自己,然后grep其它挖矿程序,awk获取进程编号,kill -9 强制杀掉 # 如果大家看到自己电脑有这些程序,也都清除下,都是病毒 # 源代码有近百个病毒进程的清除...echo $1,$2 http_code=`curl -I -m 10 -o /dev/null -s -w %{http_code} $1` # 网页返回代码是否为...echo "don't kill" fi done } 调用函数 kill_miner_proc kill_sus_proc 定时执行,免密登录 下面这段代码比较长
在linux下,ELF想要调用动态函数库中的函数,为了避免没必要的消耗,而采用了延迟绑定的方法,其核心思想就是函数用到时才对该函数进行绑定(符号查找及重定位),如果没有用到便不会绑定,以便减少资源的消耗...函数内实际上是由_dl_fixup实现的,上面的两个参数也都是传到了这个函数里面 _dl_fixup源代码如下: _dl_fixup(struct link_map **l*, ElfW(Word) *..., flags, NULL); *// value**为**libc**基址加上要解析函数的偏移地址,也即实际地址* value = DL_FIXUP_MAKE_VALUE (result, sym...函数的过程 通过link_map参数得出.rel.plt\.dynsym\.dynstr三个表的地址 然后通过reloc_arg(_dl_fixup参数)+.rel.plt(起始地址) 计算出函数在...段的.dynamic节中,下面以readelf来说一下这三个表的主要作用 以图为例 ?
需要用到的url,请求头; 新建立一个列表来存储爬取的数据 class daili(): def __init__(self): ''' 初始化操作''' # 起始...www.xicidaili.com/nn" # 使用的是手机浏览器 self.headers = { 'User-Agent':'Mozilla/5.0 (Linux...= list() 这个函数代码写的比较乱 1.请求url,获取返回的内容 2.构造了一个 XPath 解析对象 3.解析网页中的ip,端口之类需要的内容 4.保存数据 5.查找下一页内容...= next_page[0].split('/') next_url = self.url + '/' + next_url[-1] print('下页地址...= next_page[0].split('/') next_url = self.url + '/' + next_url[-1] print('下页地址
其原理上一篇文章已经介绍过: 详解 Linux 可执行文件 ELF 文件的内部结构 ELF 文件是在 unix 环境上编译生成的可执行可连接文件,他通过多个 section 来组织编译后的可执行代码,若干个...此前我们对保护模式的工作原理、执行方式及相关代码已经有了非常详尽的介绍,我们可以直接复用那些已经写好的代码。 回忆一下,从实地址模式跳转到保护模式需要做哪些事呢?...创建 GDT 及对应的段选择子 在段内编写保护模式代码 将 GDT 首地址通过 lgdt 指令载入 gdtr 关闭硬件中断 打开 A20 地址总线 置位 cr0 寄存器的保护模式标志位 长跳转进入保护模式...这里需要说明的是,由于此前我们没有编写自己的 booter,而是使用 freedos 系统作为启动扇区拉起我们的系统,所以我们无法预期 freedos 会把我们的代码放在物理内存的哪个位置上,所以我们需要在跳转前动态计算保护模式代码所在的起始位置...如今,我们自己编写的 boot 可以直接指定 loader 被载入内存的起始物理地址,这样,我们在代码编写时就可以计算出进入保护模式的起始位置,因此,再也不需要之前那种 treak 的方法,直接可以在代码中编写操作数实现上述操作了
其中 0x0804a014 - 0x08048000 (起始地址) = 0x2014, 再看main函数的汇编代码: $ objdump -d ....段)的装载地址 got1: 本ELF的link_map数据结构描述符地址 got2: _dl_runtime_resolve函数的地址 其中, link_map数据结构的定义如下: struct link_map...接着, 跳转到了0x80483a0, 这个地址, 是.plt的起始地址, 这里的指令如下: (gdb) x/2i 0x080483a0 0x80483a0: push DWORD PTR ds...当然同时也放弃了延时绑定所带来的好处. return-to-dlresolve 首先小结下本文的介绍: .plt: 代码段(r-x),直接跳转到.got.plt中保存的地址,是plt的下一行或者绑定后的地址.... .got.plt: 数据段(rw-),保存了1,2,3以及plt的对应下一行地址,会在绑定后填充为实际地址. .dynamic地址 link_map地址 (启动后填充) dl_resolve地址
dynsym:保存了符号(symbol)的信息(符号的类型、起始地址、大小、符号名称在 .dynstr 中的索引编号等)。函数也是一种符号。 text:程序代码经过编译后生成的机器指令。...总的来说就是:Linux 下的动态库,把代码段中地址有关的部分,通过“增加一层”的原理,全部变成“地址无关”的。...这样的话,动态库的代码段在加载到物理内存中之后,就可以被多个不同的进程来共享了,只要把代码段的物理地址,映射到每个进程自己的虚拟地址即可。...但之所以还是失败了,是因为这段代码存在下面的3个问题: 3f90 是个相对内存地址,需要把它换算成绝对地址。 3f90 对应的绝对地址很可能没有写入权限,直接对这个地址赋值会引起段错误。...我们需要知道ELF的基地址,才能将相对地址换算成绝对地址。 没有错,熟悉Linux开发的聪明的你一定知道,我们可以直接调用 dl_iterate_phdr。详细的定义见这里。
为了理解IFUNC的功能,我们可以先看一段简单的示例代码,如下所示: #include #include void foo_1() { printf...在代码中定义了tbl_2的起始偏移为:tbl_2_offs=0x760,我们再计算一下表的大小和其差值:len(tbl_2_mem) - 0x760 = 16。...下面简单梳理一下上面代码的主要逻辑: 通过__tls_get_addr地址爆破出ld的基地址。 实现一个函数,能通过ELF文件的内存基地址,找到任意符号地址。...在上面的代码中是直接获取__tls_get_addr函数.got表的地址,所以可以直接获取函数的实际地址。...,比如对代码段进行反汇编,匹配出dl_audit地址,工作量是非常大的。
✕ 代理数据保存清洗 运行效果: 然后我的IP就给封了 代理测试 代码没问题。。。...Query # 以前发布过使用 更新了下写入文件的初始化操作 class daili(): def __init__(self): ''' 初始化操作''' # 起始...www.xicidaili.com/nn" # 使用的是手机浏览器 self.headers = { 'User-Agent':'Mozilla/5.0 (Linux...tinydb import TinyDB, Query class daili(): def __init__(self): ''' 初始化操作''' # 起始...= next_page[0].split('/') next_url = self.url + '/' + next_url[-1] print('下页地址
(结果为负数会触发sf置1) 汇编伪指令 , 代表当前指令的标号, 是 NASM编译器提供的另一个标记,代表当前汇编节(段)的起始汇编地址。...当前程序没有定义节或段,就默认地自成一个汇编段,而且起始的汇编地址是 0(程序起始处)。 这样,用当前汇编地址减去程序开头的汇编地址(0),就是程序实体的大小。...number: db 0,0,0,0,0 start: ; 设置数据段 基地址 mov ax,0x7c0 mov ds,ax ; 设置附加段基地址...mov bx,ax mov cx,5 ; 循环次数 mov si,10 digit: xor dx,dx div si mov [bx],dl...的起始汇编地址 db 0x55,0xaa 实践结果 nasm.exe -f bin .
建立程序段前缀 DX=新的程序段前缀 27 随机分块读 DS:DX=FCB首地址 AL=00 读成功 CX=记录数 =01 文件结束 =02 缓冲区太小,传输结束 =03 缓冲区不满...释放内容空间 ES=内存起始段地址 失败:AX=错误码 4A 调整已分配的存储块 ES=原内存起始地址 失败:BX=最大可用空间 BX=再申请的容量 AX=错误码 4B 装配/执行程序 DS:DX...=ASCIIZ串地址 失败:AX=错误码 ES:BX=参数区首地址 AL=0 装入执行 AL=3 装入不执行 4C 带返回码结束 AL=返回码 4D 取返回代码 AX=返回代码 4E...查找第一个匹配文件 DS:DX=ASCIIZ串地址 AX=出错代码(02,18) CX=属性 4F 查找下一个匹配文件 DS:DX=ASCIIZ串地址 AX=出错代码(18) (文件名中带有...BX=文件代号 CX:DX=文件位移 SI:DI=文件长度 62 取程序段前缀 BX=PSP地址 ASCII码 十进制代码 十六进制代码 MCS 字符或缩写 DEC 多国字符名
最简单的办法就是把想执行的代码用机器码表示, 即俗称的shellcode, 将其写入程序, 然后将返回地址修改为该段shellcode的起始地址, 不就OK了吗?..., 但我们这种小程序就比较难找到, 所以我为了方便就加了个 dummy函数, 来模拟大型程序中查找代码段的过程....'\x90'*50的作用是填充nop指令, 可以提高payload的鲁棒性, 不用精确指定指令起始地址也能执行, 通常称为NOP sled....我们注意到当canary异常时会进入异常处理中, 如果异常处理代码的地址也是在栈空间上的话, 我们可以随意覆盖canary和返回地址, 并把异常处理的代码地址覆盖为我们的payload地址, 同样也是可以实现程序执行流程的控制...在程序的一次运行过程中, 地址空间的布局只在被加载时随机化一次, 所以在运行过程中, 先在第一阶段 获取实际的地址, 再第二阶段构造相应的payload就可以实现上述的利用.
IDA + Bochs 调试器插件进行PE+ 格式DLL脱壳 By :obaby 在IDA Pro6.1中我们扩展了Bochs调试器插件,现在已经可以进行64位代码段的调试。...在启动调试器之后,注意观察下面的代码段,在这段代码中调用了unpack()函数: 如果我们继续单步执行到更远的地方我们将会到达修复输入表的代码处,为了实现输入表的修复程序将会循环调用LoadLibrary...Mpress外壳通过这两层循环来实现IAT修复: 在stosq执行之后我们将可以从rdi寄存器中得到IAT结构的起始地址,同样在两层循环全部结束之后我们可以从rdi寄存器中得到IAT结构的结束地址。...现在有了程序的OEP和IAT结构的起始/结束地址,我们就可以清空数据库并且重现脱壳之后的程序了。...PDF版下载:http://dl.dbank.com/c0edp2nnb8 好了文章到此结束,欢迎评论!
(选做部分:倒 序显示复制字符串) (1)实验流程图: (2)实验源代码(粘贴源代码): DATAS SEGMENT ;定义DATAS 代码段 string_str db 'The school...【第一个实验】倒序显示复制字符串 (1)实验流程图: (2)实验源代码(粘贴源代码): DATAS SEGMENT;定义DATAS 段 string_str db 'The School of...21H;换行输出 MOV CX,69;使循环的次数为69 MOV SI,68;令SI 为68,也就是最后一个字符(不包括$) LOOPPART:;定义循环部分 MOV DL,[SI];将si起始的一个字符数据存入....将CREATENUM的段基地址存入ES:[BX+2]中 STI ;允许中断发生,在STI起效之后,所有外部中断都被恢复,以打破被保护代码的运行,允许硬件中断转而处理中断的作用。...MOV AH,2 INT 21H;输出80-89区间段的人数 MOV DL,10 INT 21H;输出空格 LEA DX,OUTSCORE9;将DX 与OUTSCORE9地址链接 MOV
代码如下: #!...") print(" Start LCN:runlist开始的参考LCN值,如果是一段完整的runlist,这个值应为0.") ...print(" Start VCN:runlist开始的参考VCN值,如果是一段没有0x20的runlist,这个值多数为0.") ... = get_i(t,v1_l) if v1_dl < 0: print("***偏移%d:run片断长度不能为负!... Start LCN:runlist开始的参考LCN值,如果是一段完整的runlist,这个值应为0.
领取专属 10元无门槛券
手把手带您无忧上云