ak922.sys分析

-*- begin -*-
 
这是一个 C 语言编写的驱动级的 rootkit 程序。这个驱动可以隐藏名为 AK922.SYS 的文件。

 

该驱动加载后首先获取 nt!IofCompleteRequest 函数的地址。以及在 kpeb 中定位进程名的偏移。之后,该驱动会依次完成以下操作:

 

1、通过 nt!ObReferenceObjectByName 打开磁盘驱动 /Driver/Disk,并遍历该驱动创建的所有设备对象,该驱动会保存 Disk 创建的名字以 '/DR' 开头并且类型为磁盘设备类型的设备对象指针,最多可以存 8 个设备对象指针。该驱动记录这些设备对象的地址用来在将来进行文件隐藏操作时用。

2、创建一个名为 /Device/AzyKit922 的设备,目前截获的版本没有创建符号链接,或许以后的版本会进行创建符号连接以便可以通过用户态程序控制来灵活地控制要隐藏的文件。

 

3、设置 irp 处理回调以及卸载驱动的回调例程。

 

4、通过把 nt!IofCompleteRequest 函数的入口前 6 个字节替换成 push hook_IofCompleteRequest / ret 实现对该函数的挂钩。该驱动对文件的隐藏操作全部在 nt!IofCompleteRequest 的钩子处理例程中完成。

 

完成上述操作后,该驱动会保存自身的驱动对象以及设备对象指针并返回成功给 i/o 管理器。当系统中发生的文件 i/o 操作完成时,rootkit 的钩子会被激活,并依次完成以下操作:

 

1、关闭可屏蔽中断。
2、对已经完成的 irp 进行修改来实现文件隐藏。
3、恢复 eflags 并跳回执行 nt!IofCompleteRequest 的原入口代码。

 

以下是 rootkit 实现文件隐藏的流程分析:

 

流程1、判断该 i/o 请求是否为 IRP_MJ_DIRECTORY_CONTROL,并且 MinorFunction 为 IRP_MN_QUERY_DIRECTORY。如果不是则转入下一个流程;如果是,则判断传入的请求结构类型,并查找文件系统返回的遍历结果,如果发现文件系统遍历到的结果为 'AK922.sys',则对结果进行修改(根据该结构在整个结构链中的位置决定是截断该链还是只断开一个节点)。

 

流程2、依次执行以下操作:
1、如果 i/o 请求不是 IRP_MJ_READ,则该 rootkit 不再进行处理,并直接返回。

 

2、检查传入的设备对象指针是否是之前保存的 8 个 /Driver/Disk 创建的设备对象之一,如果不是则不再进行处理,直接返回。

 

3、判断是否当前在 system 进程下运行,如果是则直接返回。

 

4、检查当前的 irql,如果不在 DISPATCH_LEVEL 则直接返回不进行下一步处理。

 

5、排队一个 WorkItem 来对磁盘驱动读出的 AK922.SYS 文件记录的元数据进行修改实现磁盘级的隐藏。

 

该驱动隐藏的文件可以躲过目前绝大多数安全检测工具,包括类似 WinHex 的基于磁盘分区格式遍历的工具。

import sys import akshare as ak import mplfinance as mpf from PyQt5 import QtWidgets from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg class KLineApp(QtWidgets.QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): # 创建GUI组件 self.code_input = QtWidgets.QLineEdit(self) self.plot_btn = QtWidgets.QPushButton('生成K线图', self) self.figure = mpf.figure(style='charles', figsize=(10,6)) self.canvas = FigureCanvasQTAgg(self.figure) # 布局设置 layout = QtWidgets.QVBoxLayout() input_layout = QtWidgets.QHBoxLayout() input_layout.addWidget(QtWidgets.QLabel("股票代码:")) input_layout.addWidget(self.code_input) input_layout.addWidget(self.plot_btn) layout.addLayout(input_layout) layout.addWidget(self.canvas) self.setLayout(layout) # 绑定事件 self.plot_btn.clicked.connect(self.plot_kline) def plot_kline(self): """获取数据并绘制K线图""" code = self.code_input.text() try: df = ak.stock_zh_a_daily(symbol=code, adjust="qfq") df.index = pd.to_datetime(df['date']) df = df.rename(columns={'open':'Open', 'high':'High', 'low':'Low', 'close':'Close', 'volume':'Volume'}) self.figure.clear() ax = self.figure.add_subplot(111) mpf.plot(df[-30:], type='candle', ax=ax, volume=True) self.canvas.draw() except Exception as e: QtWidgets.QMessageBox.warning(self, "错误", f"数据获取失败: {str(e)}") if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) ex = KLineApp() ex.setWindowTitle('股票K线图分析') ex.show() sys.exit(app.exec_())这个代码有什么问题,为什么无法获取股票数据
03-24
我将分开发送给你一个较长程序,请逐渐分析并记忆该程序,下面是第一段 # coding=utf-8 # /usr/bin/env python3 """ Author: Liu Liu Email: Nicke_liu@163.com DateTime: 2023/11/4 15:08 Description: 用于导航产品数据处理的文件 """ import sys import matplotlib.pyplot as plt from matplotlib import gridspec import numpy as np from scipy.optimize import least_squares import pandas as pd from tools import chooseFile, chooseFromInput, dataFilter, SpatialTrans, Plot np.set_printoptions(precision=2, suppress=True) # numpy输出精度的小数点个数为3,不以科学计数法输出 plt.rcParams['font.family'] = ['SimHei'] # 设置字体 plt.rcParams['axes.unicode_minus'] = False # 正确显示负号 #该函数读取特定格式的传感器数据文件(来自CB2板),解析并转换原始数据为物理量单位(磁场:uT,加速度:m/s²,转速:deg/s,角度:rad)。返回包含时间戳、通道数据和PCB板载传感器数据的字典。 def readDataCB2(fileName, start=0, end=sys.maxsize): """ 基于CB2板的输出结果,磁场单位: uT, 加速度单位: m/s^2, 转速单位: deg/s, 角度单位: rad :param fileName: 【string】数据文件名 :param start: 【int】起始行 :param end: 【int】结尾行 :return:【dict】原始数据字典 """ chNum = 12 # 通道数 mmcSen = 6.25e-3 # mmc5983磁传感器的灵敏度[uT/LSB] akSen = 1.1 # AK磁传感器的灵敏度[uT/LSB] g0 = 9.8 # 重力加速度常数 encoderFR = pow(2, 18) # 绝编的最大量程 sensorNames = ["m1x", "m1y", "m1z", "m2x", "m2y", "m2z", "check"] #传感器名称列表 chSensorNames = ["ch" + str(i) + sensor for i in range(1, chNum + 1) for sensor in sensorNames] #通道传感器名称列表 sensorPcb = ["ak1x", "ak1y", "ak1z", "ak2x", "ak2y", "ak2z", "ak3x", "ak3y", "ak3z", "ax", "ay", "az", "gx", "gy", "gz", "check", "e1", "e2"] data = pd.read_table(filepath_or_buffer=fileName, header=None, sep=',', skiprows=start, nrows=end - start, names=["ts"] + chSensorNames + sensorPcb) print("read {}, from {} to {}, done!".format(fileName, start, start + len(data))) ts = data.ts.values chData = {} for i in range(1, chNum + 1): ch = "ch" + str(i) chm1 = ch + "m1" chm2 = ch + "m2" chData[chm1] = (data.loc[:, [chm1 + 'x', chm1 + 'y', chm1 + 'z']].values - 2 ** 17) * 6.25e-3 chData[chm2] = (data.loc[:, [chm2 + 'x', chm2 + 'y', chm2 + 'z']].values - 2 ** 17) * 6.25e-3 chPcbm1 = "ak1" chPcbm2 = "ak2" chPcbm3 = "ak3" pcbA = "a" pcbG = "g" pcbData = {"ak1": data.loc[:, [chPcbm1 + 'x', chPcbm1 + 'y', chPcbm1 + 'z']].values * akSen, "ak2": data.loc[:, [chPcbm2 + 'x', chPcbm2 + 'y', chPcbm2 + 'z']].values * akSen, "ak3": data.loc[:, [chPcbm3 + 'x', chPcbm3 + 'y', chPcbm3 + 'z']].values * akSen, "acc": data.loc[:, [pcbA + 'x', pcbA + 'y', pcbA + 'z']].values * g0 / 2048, "gyro": data.loc[:, [pcbG + 'x', pcbG + 'y', pcbG + 'z']].values / 16.4, "encoder": data.loc[:, ["e1", "e2"]].values % encoderFR * 2 * np.pi / encoderFR } return {"ts": ts, "chData": chData, "pcbData": pcbData}
最新发布
07-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值