
linux
wjx5210
积极努力...
-
原创 linux hook方法整理
在计算机中,基本所有的软件程序都可以通过hook方式进行行为拦截,hook方式就是改变原始的执行流,下面简要分类linux系统下的各种hook方式,主要有三类:修改函数指针,直接修改指令,利用系统提供的注册机制.函数指针hookC语言的一项强大的功能就是指针,指针代表一个地址,而函数指针就是指向一个函数地址的指针,通过函数指针来指向不同的函数地址控制执行流.一般这类函数指针存在于软件运行的整个周期中,要实施这类hook首先就是找到关键的函数指针,之后就和普通的指针修改一样进行改变就OK.函数指针的使2020-08-20 15:16:49266
0
-
原创 linux应用层内存统计
在内核中有很多的机制:KASAN,slab debug等,在应用层也有很多的优秀的工具:valgrind, ASAN,tcmalloc, glibc memcheck等。这里不讲这些已知的方案,只总结一下基于glibc的内存debug方法,主要分为两大类:一种是需要修改api名称,例如将malloc改成debug_malloc,另外一种不需要修改api名称。2020-07-06 23:41:20123
0
-
原创 变长参数va_list va_start va_arg va_end
对于int printf(const char *format, ...);这种变长参数,需要使用va_list va_start va_end va_arg来访问参数。下面是一个tutorialspoint 的一个使用demo,示范如何使用这几个接口#include<stdarg.h>#include<stdio.h>int sum(int num_args, ...) { int val = 0, i; va_list ap; va_start(ap,2020-06-29 16:34:163661
0
-
原创 静态编译文件是否真的到处可运行
这里只讨论一个问题,基于x86_64的静态编译文件是否真的到处可运行?例如在centos上静态链接一个程序是否在ubuntu、suse等linux发行版上运行毫无障碍,这个时间维度也不能毫无边界的扩散,运行的条件是内核支持ELF三种格式,在这讨论0.11版内核完全没有意义。首先一个简单的hello world运行大概率是没有任何问题。一个静态链接程序的排布,我们通过一个简单的helloworld程序来看一下它的链接过程:gcc hello.c -static -o hello -v...... /2020-06-25 01:39:13208
0
-
原创 linux虚拟文件系统-文件的打开
文件打开的过程主要有两件事,确认文件是否存在,文件存在建立fd,file,dentry,inode,address_space的关联关系dentry的hash管理,加速查找,rcu锁无dentry之后的文件查找,inode的lookup关联各种对象软链接文件的处理…和.的处理挂载点的处理fd和file的映射关系文件的关闭简单的关闭文件释放open flag的作用O_CLOEXEC...2020-06-20 03:44:4893
0
-
原创 linux虚拟文件系统综述
Linux延续了Unix的一个哲学观点:一切皆文件,应用看到的所有对象都是文件,里面除了socket不那么典型之外所有都是文件。而实际情况非常复杂,内核管理着非常多的设备:字符设备、块设备、网络设备,还支持许多类型的文件系统:ext2、ext3、ext4、fuse、ntfs等,另外还有很多的伪文件系统:proc、devfs、sys、debugfs等,特殊的节点类型:netlink、notify、epoll等。没有什么是不能通过增加一个抽象层解决的,VFS就作为linux中的这一抽象层完成了一切皆文件的哲学观2020-06-16 20:24:5672
0
-
原创 linux内存管理-反向映射
为什么需要反向映射正向映射是通过虚拟地址根据页表找到物理内存,反向映射就是通过物理地址找到哪些虚拟地址使用它。应用场景:页面回收compaction匿名页的反向映射文件页的反向映射struct anon_vma {}struct anon_vma_chain}...2020-06-11 11:16:06336
0
-
原创 ELF中模块间数据引用的重定位
在模块中进行各类数据引用的方式总共分有:模块内数据、函数访问,模块间数据、函数访问,其中模块内的访问在链接时就已经决定了他们的相对偏移,在运行时不再关心这部分的内容,而模块间访问相对就比较复杂了。为了复用物理内存,发明了PIC/PIE技术,将数据和指令分开GOT和PLT stub,这样重定位代码只需要修改GOT的数据部分就可以访问正确的函数了,ELF的PLT和GOT分析了模块间函数访问过程中的lazy bind机制。http://www.qnx.com/developers/docs/qnxcar2/i2020-06-08 23:43:08180
0
-
原创 linux内存管理-页面规整
页面整理页面申请失败有两种情况:1.空闲页不够,触及到回收的阈值2.申请order > 0的连续页时找不到连续的物理内存2020-06-06 02:08:41100
0
-
原创 linux内存管理-页面回收
页面回收Q1:那些页面可以被回收在页面申请的时候会将可回收的页加入到zone的active_list/inactive_list链表,并更新zone的NR_ACTIVE,NR_INACTIVE的数据do_wp_pageinstall_arg_pagedo_anonymous_pagedo_no_page页面回收的时候有两部分:LRU维护的页面,slab,其中slab中只回收注册了shrinker的slab,通常是dcache,icache,nfs,xfs,mbcache的slab,shrink2020-05-31 18:42:1387
0
-
翻译 linux bootmem memblock的演进
有人可能认为在系统启动的时候内存的分配应该非常容易:基本上所有的内存都是可用的,不需要考虑并发性。尽管如此,boot阶段的内存管理仍然不是一个简单的任务。物理内存不一定是连续的,系统之间他们的分布更是有很大的不同,如何检测内存的布局就不是一个简单的任务。在NUMA的机器上这件事情更加复杂,在内存分配的时候还需要考虑在当前节点上分配,构建内存的拓扑图。为了应对这些问题,在启动过程中的早期阶段需要一些复杂的机制来进行内存管理工作。有人会问,为什么不一开始就使用buddy这些系统来管理呢?因为linux的页分配2020-05-30 01:41:33106
0
-
原创 反汇编二进制代码
最近又做了一些内核hook的工作,繁琐的地方在于二进制指令的可读性上,下面简要记录dump出指令二进制,之后利用binutils来转成可读的汇编代码.hook的主要流程参考之前的linux内核态hook模块-splice,主要就是构建一个trampoline的代码区域,主要的工作就是操作堆栈,返回地址,还有修复跳转地址.不聊这么复杂的东西,回归主题,dump指令很简单,将指令按照16进制打印出来,4个字节一组void dump(void *buf, int len) { int i = 0;2020-05-22 17:40:51403
0
-
原创 linux内存-x86-64页表初始化
x86-64的地址空间x86-64的页表初始化2020-05-22 00:44:50289
0
-
原创 linux为什么限制用户栈空间的大小
coding的时候为什么不建议申请太大的临时变量,例如下面得这样的用法:int fun() { char buf[8192]; ...}我们通过ulimit -a看到系统对当前进程的栈size进行了限制,大部分是8M1.内核中对于每个线程的内核栈进行了限制,一般是8kb,它在栈底部放置了thread_info信息,当栈越界的时候就会乱写thread_info信息,基本上就会触发内核崩溃.为什么栈不放的大一点?每个线程的内核栈在创建线程的时候就已经实际分配了,一个线程就算什么也不做,它也占据了2020-05-21 00:15:42302
3
-
原创 浅析linux内存管理
CPU能够看到虚拟地址,MMU能够看到物理地址虚拟地址是指针,而物理地址是整数?CPU如何访问内存地址?MMU根据页表进行转换地址转换,还进行权限管理TLB进行页表缓存权限:进行内存保护,读写执行和用户/内核权限page fault是CPU提供的机制,地址不可访问就是在页表中不存在,权限不对其中这个权限是用户和内核空间模型的基础,用户坚决访问不了内核空间MPU:内存权限管理物理地...2020-05-18 20:22:23344
0
-
原创 linux内存中的page,pte,alloc_page的flag
内核中关于内存的这几个flag容易混淆,他们的功能相互关联,下面简要总结一下他们的区别,其中的重要flag的用途页表项的flag:使用页表项的有两个:CPU和MMU,MMU的功能有两个,将虚拟地址转换为物理地址,检查访问权限是否合法,它是arch完全相关的page的flag:page是物理地址空间管理的元数据,它是纯粹的软件概念,基本是通用的alloc_page的flag:根据物理内存的稀有程序,它受到区别对待分成了ZONE_DMA,ZONE_DMA32,ZONE_NORMAL,ZONE_HIGH;而2020-05-17 23:53:11346
0
-
原创 linux fork COW机制分析
1.整体设计2.拷贝时3.使用时按需分配2020-05-12 01:01:26296
0
-
原创 linux内存管理-per cpu数据管理
per-CPU是2.6内核中引入的,它是一种典型的空间换时间的方案,通过为每个处理器都分配自己的内存区间来避免并发问题, 访问per-CPU变量几乎不需要锁,只需要微不足道的原子操作.每个处理器都在其自己的副本上工作,这些副本是如何生成的呢?静态分配的per-CPU结构设计分为两个阶段:编译阶段和运行时阶段在编译阶段,实际上只生成了一个CPU原本。系统中所有per-CPU结构都放到了一个叫做data.percpu的section中,在ld.S链接脚本有如下内容:__per_cpu_load =2020-05-11 18:18:0769
0
-
原创 linux内存管理-永久映射,临时映射,固定映射
1.永久映射的作用1.1 永久映射和vmalloc有什么不同2.实现原理3.使用场景2020-05-09 18:28:42397
0
-
原创 copy_from_user copy_to_user的权限控制
在linux中核心的一个概念就是特权级别,用户地址空间使用ring 0,内核地址空间使用ring 3,内核空间管理系统中所有的资源和设备,应用只能通过系统调用陷入到内核空间向其发出请求,由内核来代为完成对硬件资源的操作。另外一个是内核不能随意访问用户空间的数据,这里传达了两个信息:内核可以访问用户空间,内核只能通过特定的api完成对用户空间数据的访问。虽然在页表项中有标志位记录当前的ring 状...2020-05-07 17:37:43112
0
-
原创 linux下ELF的加载运行
. 主要介绍PIC相关的代码PIC:Program Independentprogram tabledynamic为什么一个section会在几个program中dynamic的作用rela的作用init.array, fini_array一个ELF被加载执行的过程:当使用exec执行一个可执行文件时,它会首先解析它的PT_INTERP节,里面保存了动态链接器的路径,之后会首先...2020-04-23 01:09:03253
0
-
原创 linux内核hook方式
翻译:https://www.apriorit.com/dev-blog/544-hooking-linux-functions-1我们最近在开展linux系统上安全相关的工作,在上面我们需要hook内核中重要的函数调用,例如打开文件、创建进程。我们需要这样一个项目来监控系统的活动并且阻塞可疑的进程。实际上,最后我们采用了一种高效的方式来hook系统,借助于ftrace系统,可以通过函数...2019-07-02 17:28:55119
0
-
原创 centos6.5编译内核key.h: No such file or directory
crypto/signature/ksign-publickey.c:2:17: error: key.h: No such file or directorycrypto/signature/ksign-publickey.c: In function ‘ksign_init’:crypto/signature/ksign-publickey.c:10: error: ‘ksign_def_...2020-04-17 00:56:3484
0
-
原创 linux内核查找符号
从Linux内核的2.6某版本开始,内核引入了导出符号的机制,在内核中使用EXPORT_SYMBOL或EXPORT_SYMBOL_GPL导出的符号可以在其他内核模块中直接使用。但是并不是所有的符号都被导出了,这时候如果想要使用未导出的符号呢?1.kallsyms_lookup_name读取依赖于CONFIG_KALLSYMS,kallsyms_lookup_name在大多数情况下是被导出了,可...2020-04-14 12:03:50288
0
-
原创 打印机审计产品的一种思路
国内很多的苞米单位都需要过资质的,有了相应的资质才有资格接苞米的项目,所以催生出来了很多的苞米条例,之后就有很多公司主打苞米产品,其实做的就是为了过资质用的,市场的发展是由需求来决定的,而技术的方向是市场来控制的.目前很多的打印机监控产品或者功能都放在了终端安全产品里了,也就是通常在windows/linux PC上完成,Android需要定制ROM,和手机厂商不是铁兄弟一般是做不了的,MAC就...2020-04-11 13:31:03146
0
-
原创 协程简介
协程是一种用户态的轻量级线程,首先看一下有哪些语言已经具备协程实现:· 比较重量级的有C#、erlang、golang*· 轻量级有python、lua、javascript、ruby· 还有函数式的scala、scheme等。c/c++不直接支持协程语义,但有不少开源的协程库,如:Protothreads:一个“蝇量级” C 语言协程库libco:来自腾讯的开源协程库libco介绍,...2020-04-09 21:20:2273
0
-
原创 修改ELF文件统计内存泄露
本篇不走寻常路,想要正常的内存调试手段请查阅内核相关的内存debug功能.程序开发了很长时间,参与开发的人也很多,今天我想用实验统计来证明我们写的内核module没有产生内存泄露,通常的做法是封装内存的api,中间加上统计逻辑,但是我不想改他们的代码,有什么办法吗?我翻了一下code,里面有上百处申请内存的位置,主要使用了两种api,一种是kmalloc,另外一种是创建自己的kmem_cach...2020-04-09 19:57:1054
0
-
原创 死锁检测lockdep实现原理
死锁在编程中是再常见不过的错误了,和内存泄露一样是很难避免的问题,Ingo Molnar发明了lockdep用来检测死锁,它将问题产生的场景进行了归纳总结,避开了对锁进行单个追踪的方式来调试问题而是使用另外一种smart的方式,它不再处理单个锁而是处理锁类.死锁场景有:AA锁,ABAB锁,其中AA锁场景又分为简单重复上锁和上下文切换引起的上锁,前者不必多说,而后者可能是,锁使用场景可能有软中断和...2020-04-03 16:49:11496
0
-
原创 linux内核RCU
RCU基础RCU使用总结2020-03-13 11:48:2997
0
-
原创 centos4.0 yum源地址
错误提示:[root@fm3 yum.repos.d]# yum update yumSetting up Update ProcessSetting up repositoriesnot using ftp, http[s], or file for repos, skipping - 4 is not a valid release or hasnt been released yet...2020-03-05 14:38:53102
0
-
原创 linux下gtk开发环境搭建
环境搭建安装必要的工具apt install libgtk-3-dev pkg-config可以安装额外的example包,里面提供的一些demo程序是非常好的参考apt install gtk-3-examplesgtk-3-examples包中的hello-world.c程序#include <gtk/gtk.h>static voidprint_hello ...2020-02-13 22:48:3198
0
-
原创 linux module签名问题
前言内核对于可信计算支持的越来越完善,linux发行版在这个基础上也逐渐默认使能一些它的安全功能,其中一项就是内核module签名。原来是只要有root权限就可以随意insmod,后来DAC这套权限机制太过于宽松,出现了MAC,可信计算,就是使用两套权限模型,而且保持向后兼容,即同时满足两套模型的权限要求才能正确执行。可信计算主要解决BIOS -> grub -> kernel ...2020-02-10 23:50:24545
0
-
原创 linux内核的指令替换-alternative instruction
前言内核的开发一直遵循向前兼容的特性,最新版本的内核还可以在最古老的机器上运行,有时候看不懂内核代码为什么这样写,可能是当时的处理器设备有什么特殊的限制。不过兼容性也带来了一些问题,老的处理器不能使用内核新的feature。通常有两种方法能够配置feature:1.可以在运行时动态选择;2.可以在编译时通过配置的方式选择feature,但是这种方式编出来的内核可能不能在老机器上运行用户...2020-02-03 16:33:30471
0
-
原创 linux fork返回两次的问题
我们接触linux用户编程时,在做多进程程序处理时绕不过去的就是fork调用,经常被告诉它的特殊性:一次调用两次返回,父进程中返回子进程的pid,子进程返回0,和同事讨论的时候,走查代码的时候竟然没有找到子进程是如何返回的。父进程返回的路径非常清晰,进入内核中do_fork->copy_process,之后将新的进程wakeup放到运行队列上,子进程从哪返回的呢?do_fork只是检查了...2020-02-02 12:06:49108
0
-
原创 linux系统调用过程剖析
翻译:https://lwn.net/Articles/604287/https://lwn.net/Articles/604515/前言linux中用户空间程序调用内核功能的唯一方式就是系统调用,内核中实现了一种跨平台的通用框架和实现方式,使得系统调用接口一致并且高效。系统调用和普通的函数调用有一些不同,系统调用函数位于内核中,需要从ring 3切换到ring 0,而且系统调用函数是通...2020-01-31 09:26:08179
0
-
翻译 linux程序启动之ELF
翻译自:https://lwn.net/Articles/631631/前一篇主要是描述了用户空间程序调用execve()到内核是如何处理的,更加generic一些。上篇中讲到如何每个程序的执行都会通过search_binary_handler()来决定如何处理,不管是script还是misc,最终都会以调用ELF格式程序来结束,这一篇主要集中在ELF主题上。ELF格式ELF((Ex...2020-01-29 12:48:34253
0
-
翻译 linux程序启动过程
翻译自:https://lwn.net/Articles/630727/这个系列有两篇文章,第一篇主要描述当一个用户程序调用execve()系统调用的的时候发生了了什么,内核是怎么运行起来的,更加generic一些,里面会覆盖不同的可执行文件格式;而第二篇主要描述ELF格式可执行程序运行的过程,更加聚焦一些。作者最近准备增加一个新的系统调用execveat(3.19版内核已经合并到main...2020-01-29 12:47:58176
0
-
原创 linux函数调用过程中的寄存器
函数调用约定规则函数调用之间需要约定,就和我写这篇这个文档遵守markdown的语法一样,x86可以参考:摘自内核的头文件:arch/x86/include/asm/calling.hx86 function call convention, 64-bit:arguments [callee-clobbered]callee-savedextra caller-saved ...2020-01-20 03:15:57237
0
-
原创 linux fanotify
IT安全行业比较注重用户行为监控,在linux上如何做行为监控呢?首先监控可以分作两大类:本地行为和网络行为,大致是如何做的呢?在linux系统中分为用户空间和内核空间,又有进程来提供隔离,通常是不能实时监控到其他用户进程的行为的.不过linux通过/proc和/sys提供了很多有用的接口,工具通过这些接口提取信息使可读性更好,例如top,netstat等,其中有一些接口能够被用来进行monito...2020-01-19 18:17:05458
0
-
原创 Linux中程序单例运行的几种方式
我们写了个程序,但是只想让它只执行一次,但是我们没有权利来限制其他人运行这个程序,有以下几种方法来保证程序的单例运行:1.程序的运行需要特殊权限,而这个权限只有管理员才有,管理员自己来维护程序的单次运行,这个不是我们能控制的2.程序自己探测是否已经有进程在运行自己我们主要列举出第二个选项,毕竟我们是程序员嘛,让你相信自己的程序还是业余用户的计算机知识素养之间,我果断选择了自己的程序文件...2020-01-10 19:11:38294
0