zoukankan      html  css  js  c++  java
  • APM软件原理分析

    目录

    APM软件原理分析    1

    0x00 背景    1

    0x01 安装过程    1

    0x02 启动过程    5

    0x03 触发过程    7

    0x04 整体流程    13

    0x05 资源    13

     

     

    APM软件原理分析

    0x00 背景

    本次使用PHP网站的APM监控插件作为研究对象,目的在于搞清:

    1)分析安装过程中对哪些进程和文件进行了修改;

    2)插件启动过程中对哪些进程进行了修改,调用了哪些函数;

    3)程序运行过程中,如何触发监控,相关进程之间的数据传递;

    4)得到监听插件对mysql,apache的hook点;

     

    相关工具:IDA,gdb,strace,tcpdump,ps,lsof

    相关知识:PHP扩展原理,PHP基本运行原理,socket进程间通信

    环境:kail linux + apache2 + mysql + php5

    Tips:APM 全称Application Performance Management & Monitoring,应用性能管理 & 监控。用来监控和管理应用软件是否有效运行的。主要指对企业的关键业务应用进行监测、优化,提高企业应用的可靠性和质量,保证用户得到良好的服务,降低IT总拥有成本(TCO)。

    0x01 安装过程

    百度搜索了一个APM软件作为研究对象。

    1. 用strace 跟踪安装过程,分析安装软件对哪些文件做了修改

    用ps命令找到安装文件的PID为7096

    然后用strace –p 7096 –o log.txt(-p指定进程PID,-o指定输出结果保存目录)

    安装过程中会需要填写licensekey,php安装路径等。

     

    2. strace结果分析

    安装程序修改了php.ini

    将安装包中的so文件拷贝到php的扩展库路径下

    将守护文件拷贝到/usr/bin/目录下

    将安装过程写入log日志中

    找到日志文件可以直接对安装过程进行分析,不过跟strace中找到的结果类似

    还对php5的cli和apache2的conf.d进行了修改。

     

    Php.ini

     

    3. 安装过程分析

    安装程序找到

    这个过程中可以找到扩展oneapm.so,守护进程oneapm-daemon,可以丢到IDA中去分析了。

     

    Tips: php扩展

    有些频繁使用的函数如果使用php语言编写效率很低,如果采用php扩展,即用C语言编写函数,然后编译成so文件,修改php.ini文件,即可调用该函数。通过这种调用C语言库函数的方式可以极大的提升函数效率。

    参考:http://www.open-open.com/lib/view/open1392188698114.html

    0x02 启动过程

    在oneapm.so文件中,有get_module入口,该函数通过获取PC值,然后加一定的偏移,进入到apm_module_entry_ptr模块入口。

    在apm_module_entry_ptr中是一张函数表,包含了一下几个函数

    其中activate相关函数是激活模块,发生在请求阶段,需要触发一定的条件才会执行,其他几个函数在程序启动时,初始化阶段执行。

    Tips:PHP运行原理

    开始阶段

    PHP的整一个开始阶段会经历模块初始化和模块激活两个阶段。

    MINIT 即模块初始化阶段,发生在Apache/Nginx启动以后的整个生命周期或者命令行程序整个执行过程中,此阶段只进行一次

    RINIT模块激活,发生在请求阶段。

    参考:http://www.mamicode.com/info-detail-1028100.html

     

    Apache2 启动时会自动调用其他几个函数,因为php.ini中引入了oneapm.so,这几个函数是在模块初始化阶段被执行的。通过ps与cat /proc/{PID}/maps可以看到apache对oneapm.so进行了引用。

     

    zm_startup_apm

    zm_startup_apm会fork()进程,然后去启动oneapm-daemon守护进程。所以软件安装完成后,需要重启apache。其余的则是做一些初始化工作。

     

     

    zm_info_apm

    zm_info_apm则是收集一些基础信息。

     

    整个启动阶段,apache2 加载oneapm.so,对模块进行初始化,自动调用以上几个函数,启动守护进程oneapm-daemon,收集一些基本函数。

    0x03 触发过程

    用tcpdump抓包,可以看到服务器向展示网站传输性能信息。

    1.监控oneapm-daemon守护进程获取数据交互线索

    用strace对oneapm-daemon进程进行监控。

    Strace –ff –p 1278 –s 1024 –o oneapm (-ff监控子进程子线程,与-o配合使用将结果写到不同的文件中, -s指定一行的长度, -p指定进程PID)

    oneapm-daemon会启动4个子线程,strace生成4个文件oneapm.1278 oneapm.1279, oneapm.1280, oneapm.1281

    oneapm.1280

    线程1280不停获取时间,然后向目标网站发送数据,发送的数据与tcpdump抓到的数据相同

     

    oneapm.1279

    线程1279 开启了一个监听,用accept()函数等待连接。 然后用read()函数从这个句柄读取数据。句柄fd=6。

    由此可知oneapm-daemon 通过一个线程开启监听,等待数据传输过来,读取数据。然后用另外一个线程将数据发送到展示网站上。 这里使用了socket进行本地进程间的通信。

     

    2.找到socket句柄

    由于socket 的fd是瞬时性的,所以无法用lsof直接看到该句柄。用gdb attach 上去。

    Read调用有以下几个点,都断住。

    Fd=6,buffer中读出我们想要的数据。此时用lsof查看句柄信息

    连接到/tmp/.oneapm-daemon.domain文件上。

     

    3.找到发送数据的进程

    由于只有apache2 连接了oneapm.so扩展,所以先监听apache2。

    Strace –ff –p 5046 –s 1024 –o apache

    在结果文件中找到如下信息

    Apache2 通过socket连接到/tmp/.oneapm-daemon.domain,向其发送数据。 通过这样与oneapm-daemon实现进程间数据的传递。

     

    4. 数据传输与收集过程

    Gdb attach上apache,进入子进程模式,并对oneapm.so的几个激活函数下断点。

    断点命中

    可以看到调用的次序zm_activate_apm,zm_deactivate_apm,zm_post_zend_deactivate_apm

    打印其调用栈,这几个函数都是在一定条件达成后,php激活zend相关函数自动调用的。

     

    分析这几个函数的代码

    1)zm_activate_apm()

    zm_activate_apm调用了很重要的函数hook_start()。

    Hook_start()函数如下

    这边是监控程序的核心hook入口点,apm程序对网站性能监控的hook都可以在这里找到。

    2)zm_deactivate_apm()做的就是一些反激活的事

    3)zm_post_zend_deactivate_apm()

    send_connect_data()

    talk_to_server()

    do_write()

    调用过程如下

    zm_post_zend_deactivate_apm()àsend_connect_data()àtalk_to_server()à

    do_connect(),do_write()->send()

     

    zm_post_zend_deactivate_apm()负责发送数据。

    5. 代码流程

    监控阶段代码流程如上图所示

    0x04 整体流程

    1) 安装文件将oneapm.so与oneapm-daemon拷贝到对应的文件夹下,然后修改php配置文件,以实现php扩展

    2) Apache启动过程中,载入扩展oneapm.so,自动执行一些初始化函数,拉起守护进程

    oneapm-daemon,并收集一些系统信息。oneapm-daemon进程创建监听,等待本地socket连接。

    3) 网站请求与一些时间条件激发apache中的oneapm.so 激活函数,开始hook收集当前的一些服务器性能信息,然后反激活,接着将这些信息通过本地socket的方式进行进程通信,连接到oneapm-daemon的监听上,然后向其发送收集到的数据。oneapm-daemon进程接收到连接,并读取数据,用另外一个线程向展示网站发送数据。

    0x05 资源

    Hook信息,位于hook_start()函数中

    相关ELF文件

  • 相关阅读:
    RocketMQ之二:分布式开放消息系统RocketMQ的原理与实践(消息的顺序问题、重复问题、可靠消息/事务消息)
    Redis 发布/订阅机制原理分析
    Guava 12-数学运算
    Guava] 11
    Guava 10-散列
    Guava 9-I/O
    Guava 8-区间
    mat(Eclipse Memory Analyzer tool)之二--heap dump分析
    Python流程控制语句
    监控和管理Cassandra
  • 原文地址:https://www.cnblogs.com/alert123/p/5217821.html
Copyright © 2011-2022 走看看