分类

类型:
不限 游戏开发 计算机程序开发 Android开发 网站开发 笔记总结 其他
评分:
不限 10 9 8 7 6 5 4 3 2 1
原创:
不限
年份:
不限 2018 2019

技术文章列表

  • 大数据分布式数据库7、HBase

    前文链接:https://write-bug.com/article/2108.html
    HBase原理上节我们介绍了Hive,其本质为MR Job,而HBase不同于Hive,它是一个面向存储的开源的非关系型分布式数据库(NoSQL),适合存储海量、稀疏数据(不保证每条记录每个字段都有值),大部分数据存在HDFS上,少量在自身内存cache中。
    Hbase(Nosql数据库)与关系型数据库对比:行存储:关系型数据库

    优点:写入一次性完成,保证数据完整性,写入时做检查
    缺点:数据读取过程中产生冗余数据,若有少量数据可以忽略

    列存储:Nosql数据库

    优点:读取过程,不会产生冗余数据,只查询了一个字段,特别适合对数据完整性要求不高的大数据领域
    缺点:写入效率差,保证完整性方面差

    优势:

    海量数据存储:大量数据存在HDFS中
    快速随机访问:在HDFS中更适合从头到尾的这种顺序读取,不适合随机访问,而Hbase只需要读取某一key的字段就可以了
    可以进行大量改写操作:为什么HDFS中不能呢?HBase在修改数据时,是在数据dump到磁盘之前还在cache中的时候做修改的,这样的速度是HDFS所不能比的,还有HBase在改写一个字段的时候,实质上还是在cache中完成操作的,而dump磁盘是一个异步的过程,其实修改后的数据与旧数据到了两个文件中,我们用户感知到的只是查询数据时候其返回了我们修改后的最新数据就可以了,这里我们下面会介绍的version号就知道了

    Hbase结构逻辑模型

    RowKey:有了这个key,我们才能查询到后面的value,是表中每条记录的“主键”,方便快速查找,Rowkey的设计非常重要。
    Column Family:列族,拥有一个名称(string),包含一个或者多个相关列
    Column qualifier:属于某一个columnfamily,familyName :columnName,每条记录可动态添加


    我们有了上面这三个信息,就可以定位到具体的列字段了。
    再看上面的表中有些cq中包含着几个timestamp时间戳,背后存着不同的value值,这就是前面说的改写具体字段存在不同的文件中。
    Version Number:类型为Long,默认值是系统时间戳,可由用户自定义,每一个时间戳的背后存着不同的版本,可以设置个数,默认显示最新时间戳的字段(即倒序)
    三维有序:
    三个维度:
    -rowkey
    -column family->column qualifier
    -version(timestamp)->value

    {rowkey => {family => {qualifier => {version => value}}}}
    a :cf1 :bar :1368394583:7

    有序:我们在存储数据时,系统会按照rowkey字典序去排序数据,然后里面列存储再按照cf、cq的字典序,和时间戳的倒序排序数据。
    物理模型我们前面介绍的数据模型格式都是以一张表格的形式去做剖析,为了我们所理解,而出现的逻辑概念。而真正机器存储时是怎么存储的呢?

    我们这里抽调出一张逻辑表格来看,假如这张表格数据量非常的大,一台机器很难存储一张表格,那我们计算机应该怎样去存储呢?肯定是把这张表格分片到很多台机器中才符合我们处理大数据的思想嘛,我们看到图中的数据依旧按照rowkey的字典序进行排序,并且上面切分为好多的region(区域),注意!这里的切分是按照行rowkey切分的。

    这里有一个细节:我们切分前后,里面的数据都是按照rowkey排好序的
    Hregion就相当于前面MR中的partition功能,进来一条数据,按照rowkey分配插入到一个region中,因为前面说了数据是按照key排好序的,所以这条数据就不可能分配到其他的region里面了,即相同的key也同样是肯定在同一个region上
    HBase集群分布数据的最小单位为region。想象成HDFS上的block,如果一台机器挂了,其上的所有block都将消失,数据也就失去了我们设置的3副本的平衡,需要去别的机器拷贝出数据到新的DN上来达到平衡和负载均衡(请求压力)。而HRegion是分布式存储负载均衡的最小单元,但不是最小存储的最小单元
    HRegion是物理概念(进程),Region是逻辑概念

    行锁定:假如我们rowkey为itemid,userA正在对一个itemid的字段做修改,与此同时,userB也想对这个字段的不同列做修改是不允许的,只有当时读写的进程具有绝对的主权,粒度按行锁定(粗)。

    前面说过,region数据分布就像HDFS中的block,所以换言之一个机器节点中有多个region,这个节点里面有一个进程叫Regionserver,主要负责用户的IO请求,与HDFS的交互,也就是一个HRegionserver进程中存储管理了多个HRegion对象(不一定来自于同一个table)。

    HRegion再划分,里面又分为多个Hstore,HStore是HBase中核心的存储单元。
    Hstore由两个部分组成:内存和HDFS文件
    即HStore=Memstore+StoreFile(HFile)
    HStore—-对应逻辑table中的columnFamily
    MapReduce中Memstore:100M->80%->往磁盘上spil
    Memstore: 写缓存,默认128M->将内存Flush为一个StoreFile,每个CF都有自己的Memstore
    HLog: WAL(Write-Ahead-Log)预写日志,避免数据丢失

    我们在往memStore和Hstore写数据时,假设正在写过程此Hregion挂了,那么我们写好的数据就会丢失,所以它不会直接写到某个机器上,而是先写到HDFS上,先有一个HDFS的公共区域(HLog),写完之后再写到一个Hregion里面去,所以这时Hregion挂了,我只需要从HLog中恢复数据就好了。
    每一个RegionServer都可以读取Hlog,管理维护多个Region,每一个Region都可以读HLog,如果Region不出现错误情况下,就和HLog没有任何交互,如果一个RegionServer挂掉,涉及到Region迁移,里面的数据已经消失了,是在Hlog中恢复到其他Region Server中,就像Mysql中的远程备份,replication,只是把Mysql操作的每一条sql语句重新执行一遍,就相当于恢复数据了。
    Client往Region Server 端提交数据时,会先写WAL日志,写成功后才会告诉客户端提交数据成功。在一个RegionServer上的所有的Region都共享一个HLog,一次数据的提交先写WAL,写入成功后,再写memstore,当memstore值到达一定阈值,就会形成一个个Store File(理解为Hfile格式的封装,本质为Hfile)
    blockcache:读缓存,加速读取效率(假设没有blockcache,读取顺序(指定好rowkey,CF: CQ):rowkey-》某HRegion-》CF-》Hstore-》MemStore-》二分法查找Store File(因为dump时rowkey是排序好的))读取后再缓存到blockcache中。

    这里引发一个问题:读取时可能会在memstore和多个Hfile中都出现相同的rowkey,这种情况怎么办呢,只能靠我们平时的合并机制(通常把很小的region merge到一起,手动完成,整合相同rowkey)了。

    分裂:我们在按照rowkey分配region时可能是同一个范围但一般每个region存储数据的规模是不一样的,随着数据插入,region随之增大,当增大到一个阈值时,按照大小平均分裂成两个新的region,分区参数默认10个G。
    Region数目:每一个region信息都要在zookeeper上有一个节点来维护。这之前还没讲过zookeeper,可以先类比HDFS的block在Name Node中作为元数据,不支持小文件。所以:

    太多:增加zookeeper负担,读写性能下降
    太少:降低读写并发性能,压力不够分散。

    对于region过大的要做切分,切分更小粒度的region分散到不同的regionserver上去缓解压力作负载均衡。
    这里出现一个问题:如果用户正在访问正在分裂的region上的数据时,是请求不到数据的,只能等到分裂完成后才能为用户继续服务。通常情况下,我们把自动切分禁止,请求量空闲时手动切分。
    Hbase架构
    我们在图中可以看到主要有这么几个角色(client、Hmaster、HRegionSever(本地化)、Zookeeper)

    HMaster(主):

    负载均衡,管理分配region
    DDL:增删改->table,cf,namespace
    类似于namenode上管理一些元数据,这里管理table元数据
    ACL权限控制
    可以启动多个Master,但真正服务只有一个master服务,Master挂了,其他的启动,进行一个选主。数据和storm一样都在zookeeper上,主挂了,不影响数据的读,但影响数据的写,还会影响region的分裂,也就是负载均衡,和storm的fail-fast很像,真正数据在hdfs上,zookeeper上存储的是元数据

    请查看HDFS元数据解析还有,https://blog.csdn.net/qq_33624952/article/details/79341477
    https://blog.csdn.net/vintage_1/article/details/38391209
    HRegionSever(从):—-通常和DN部署在一起,本地化原则。

    管理和存放本地的Hregion
    读写HDFS,提供IO操作,维护Table数据
    本地化,MapReduce中,数据不移动计算框架移动,是为了尽量减少数据迁移,在HBASE里面,Hregion的数据尽量和数据所属的DataNode在一块,但是这个本地化不能总是满足和实现,因为region是不断移动的,插入,不断分裂,一旦分裂就变了,什么时候本地化可以从不能保证到保证的过度呢,也就是合并。。。。

    Zookeeper:

    在master与zookeeper之间,master与regionsever之间提供心跳机制
    保证集群中只有一个Master
    存储所有Region的入口(ROOT)地址——新版本取消 ,比如操作一个表,第一件事要找到这张表所对应的服务器,第二找到存在那几个region上,读的key,定位到记录在哪个region,regionserver也就确定了,如果缓存里面没有这个表,就要去想办法找这个regionserver,第一步就要找到zookeeper上的相应地址,zookeeper为了寻址存储这个入口数据
    实时监控Region Server的上下线信息,并通知Master

    Client:

    寻址:通过zk获取HRegion的地址,同时client具有缓存rowkey-》HRegion映射关系的功能(读的数据表的机器地址预存,减少网络交互)加速RegionServer的访问
    表的设计rowkey设计原则:
    长度:最大长度64kb,越短越好,尽量不超过16byte(机器64位——》内存对齐8字节,所以控制在8字节整数倍可以获得最大性能)
    过长:内存利用率降低,不能缓存太多value数据
    分散:建议rowkey前加hash散列字段(程序位置固定生成)、反转—-避免固定开头解决热点问题
    唯一性
    反转例:
    IP:地区相同分在一个region中,负载不均匀:
    把IP地址倒序存储—思考:电话号码、时间戳
    hash散列字段例:
    加密算法:Hash(crc32,md5)
    CF设计原则:
    数量:在业务要求下,尽量少数量:建议一到两个。
    一个文件:传统行存储做法,如果想要访问个别列数据时,需要遍历每一列,效率低下。
    多个文件:列存储做法,过多时影响文件系统效率。
    折中方案:将不同CF数据列分开存储,比如把经常访问的类似的数据字段列尽可能分配到同一CF中。
    当某个CF数据flush时,其他CF也会被关联触发flush,如果CF设计比较多,一旦产生连锁反应,会导致系统产生很多IO,影响性能。
    flush和region合并时触发最小单位都是region,如果memstore数据少量时没有必要做flush
    Hbase容错在HMaster和HRegionSever连接到ZooKeeper后,通过创建Ephemeral临时节点,并使用Heartbeat机制维持这个节点的存活状态,如果某个Ephemeral节点失效,则Hmaster会收到通知,并作相应处理。
    HLog
    除了HDFS存储信息,HBase还在Zookeeper中存储信息,其中的znode信息:

    /hbase/root-region-server ,Root region的位置
    /hbase/table/-ROOT-,根元数据信息
    /hbase/table/.META.,元数据信息
    /hbase/master,当选的Mater
    /hbase/backup-masters,备选的Master
    /hbase/rs ,Region Server的信息
    /hbase/unassigned,未分配的Region
    Master容错:Zookeeper重新选择一个新的Master;无Master过程中,数据读取仍照常进行,region切分、负载均衡等无法进行
    Region Server容错:定时向Zookeeper汇报心跳,如果一旦时间内未出现心跳,Master将该RegionServer上的 Region重新分配到其他RegionServer上,失效服务器上“预写”日志由主服务器进行分割 并派送给新的RegionServer
    Zookeeper容错:一般配置3或5个Zookeeper实例

    Hbase操作安装笔记:http://note.youdao.com/noteshare?id=45a15ce17d5e6c0ead6db5f806d600d3&sub=3CB5F03947634E38811A45AE080F9028
    Hbaseshell操作
    pythonHbase
    mr+Hbase
    Java+Hbase
    Scala+Hbase
    Hive+Hbase
    2 留言 2019-02-08 14:31:02 奖励16点积分
  • 大数据分布式数据库6、Hive

    前文链接:https://write-bug.com/article/2091.html
    Hive原理
    一种Sql解析引擎—>把Sql语句解析成MR Job(本质就是MR)
    Hive中的表是纯逻辑表,就只是表的定义等,即表的元数据。本质就是Hadoop的目录/文件, 达到了元数据与数据存储分离的目的,本身不存储数据,真实数据存储在HDFS上,元数据存在MySql上
    读多写少,不支持数据改写和删除
    Hive中没有定义专门的数据格式,由用户指定,需要指定三个属性:

    列分隔符 ‘ ’ ‘\t’ ‘\001’
    行分隔符 \n
    读取文件数据的方法 TextFile、SquenceFile(二进制文件\<k,v>—-Java)、RCFile(面向列)


    为什么有了MR还用Hive?
    面向非开发人员,简单有效:
    word_countselect word, count(*) from ( select explode(split(sentence, ' ')) as word from article ) t group by wordHql和Sql区别

    可拓展性(用户自定义函数):

    UDF 普通函数 类比:map 一对一
    UDAF 聚合函数 类比:groupByKey 多对一
    UDTF 表生成函数 类比:flat Map 一对多

    数据检查:

    Hql:读时模式 读慢(读时检查、解析字段) load快(写时不需要加载数据)
    Sql:写时模式 读快 load慢(写时做索引、压缩、数据一致性、字段检查等等)

    Hive体系架构
    Cli用户接口, 进行交互式执行SQL: 直接与Driver进行交互

    JDBC驱动,作为JAVA的API:JDBC是 通过Thift Server来接入,然后发送给Driver

    Driver sql->MR

    元数据:是一个独立的关系型数 据库,通常Mysql,Hive会在其中保存表模式和其他系统元数据

    存储模式:
    derby(默认,本地单用户模式)—存储元数据结构信息meta store
    mysql 多用户模式

    本地
    远程 —-独立机器,互相解耦

    数据管理方式hive的表本质就是Hadoop的目录/文件 – hive默认表存放路径一般都是在你工作目录的hive目录里面,按表名做文件夹分开,如果你 有分区表的话,分区值是子文件夹,可以直接在其它的M/R job里直接应用这部分数据。

    Hive的create创建表的时候,选择的创建方式:

    create table 内部表
    create external table外部表(删表时只删除元数据)

    Partition

    分区表(/tablename/条件字段)表中的一个 Partition 对应于表下的一个目录,所有的 Partition 的 数据都存储在对应的目录中
    例如:pvs 表中包含 ds 和 city 两个 Partition,则

    对应于 ds = 20090801, ctry = US 的 HDFS 子目录为:/wh/pvs/ds=20090801/ctry=US;
    对应于 ds = 20090801, ctry = CA 的 HDFS 子目录为;/wh/pvs/ds=20090801/ctry=CA

    作用:辅助查询,缩小查询范围,加快数据的检索速度和对数据按照一定的 规格和条件进行管理。
    Bucket
    —分桶表(clusted by user into 32 buckets /lbs/mobile_user/action=insight/day=20131020/part-00000)数据采样sampling、控制数量
    —CLUSTERED BY —-bucket中的数据可以通过‘SORT BY’排序。
    ‘set hive.enforce.bucketing = true’ 可以自动控制上一轮reduce的数量从而适 配bucket的个数,
    当然,用户也可以自主设置mapred.reduce.tasks去适配 bucket个数
    —tablesample是抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y)
    查看sampling数据: – hive> select * from student tablesample(bucket 1 out of 2 on id); – tablesample是抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y) – y必须是table总bucket数的倍数或者因子。hive根据y的大小,决定抽样的比例。例如,table总共分了64份,当y=32 时,抽取(64/32=)2个bucket的数据,当y=128时,抽取(64/128=)1/2个bucket的数据。x表示从哪个bucket开始抽 取。例如,table总bucket数为32,tablesample(bucket 3 out of 16),表示总共抽取(32/16=)2个bucket的数据 ,分别为第3个bucket和第(3+16=)19个bucket的数据
    数据类型
    原生

    TINYINT
    SMALLINT
    INT
    BIGINT
    BOOLEAN
    FLOAT
    DOUBLE
    STRING
    BINARY(Hive 0.8.0以上才可用)
    TIMESTAMP(Hive 0.8.0以上才可用)

    复合

    Arrays:ARRAY<data_type>
    Maps:MAP<primitive_type, data_type>
    Structs:STRUCT<col_name: data_type[COMMENT col_comment],……>
    Union:UNIONTYPE<data_type, data_type,……>

    例:Map
    张三 “数学”:80,“语文”:90,“英语”:79
    李四 “数学”:70,“语文”:60,“英语”:79
    name scoreselect score from table{“数学”:80,“语文”:90,“英语”:79}{ “数学”:70,“语文”:60,“英语”:79}select name,score[‘数学’]from table
    张三 80
    李四 70
    例:Sql实现mr_join:
    INSERT OVERWRITE TABLE pv_usersSELECT pv.pageid,u.ageFROM page_view pvJOIN user uON(pv.userid=u.userid);
    例:Sql实现groupby —-mr_wordcountSELECT pageid,age,count(1)FROM pv_usersGROUP BY pageid,age
    Hive优化map优化优化并发个数减小
    set mapred.max.split.size=100000000;set mapred.min.split.size.per.node=100000000;set mapred.min.split.size.per.rack=100000000;set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;set mapred.map.tasks=10;—-适当加map数:几乎不起作用block大小会影响并发度set dfs.block.size(=128)hive.map.aggr=true ,相当于开启Combiner功能
    reduce优化优化并发个数
    set mapred.reduce.tasks=10
    mapreduce出现痛点:只有一个reduce的情况

    没有group by
    order by,建议用distribute by和sort by来替代

    order by:全局排序,因此只有一个reduce,当输入数据规模较大时,计算时间消耗严重sort by:不是全局排序,如果用sort by排序,并且设置多个reduce,每个reduce输出是有序的,但是不保证全局排序distribute by:控制map端的数据如果拆分给redcuce,可控制分区文件的个数cluster by:相当于distribute by和sort by的结合,但是只默认升序排序

    例子1:select * from TableA distribute by userid sort by itemid;
    例子2:select from TableA distribute by itemid sort by itemid asc;select from TableA cluster by itemid;

    笛卡尔积使用join的时候,尽量有效的使用on条件
    mapreduce出现痛点:如何加快查询速度(横向尽可能多并发,纵向尽可能少依赖)
    分区Partition
    Map Join:指定表是小表,内存处理,通常不超过1个G或者50w记录
    union all:先把两张表union all,然后再做join或者group by,可以减少mr的数量union 和 union all区别:union相当记录合并,union all不合并,性能后者更优
    multi-insert & multi group by查一次表完成多个任务
    Automatic merge:为了多个小文件合并
    – hive.merge.mapfiles = true 是否和并 Map 输出文件,默认为 True– hive.merge.mapredfiles = false 是否合并 Reduce 输出文件,默认为 False– hive.merge.size.per.task = 25610001000 合并文件的大小
    Multi-Count Distinct一个MR,拆成多个的目的是为了降低数据倾斜的压力必须设置参数:set hive.groupby.skewindata=true; 强制拆分,万能参数
    并行执行:set hive.exec.parallel=true 独立无依赖的MR

    mapreduce出现痛点:如何加快join操作
    语句优化:多表连接:如果join中多个表的join key是同一个,则join会转化为单个mr任务表的连接顺序:指定大、小表Hive默认把左表数据放到缓存中,右边的表的数据做流数据
    如果避免join过程中出现大量结果,尽可能在on中完成所有条件判断

    mapreduce解决数据倾斜问题
    操作 • Join • Group by • Count Distinct原因 • key分布不均导致的 • 人为的建表疏忽 • 业务数据特点症状 • 任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。• 查看未完成的子任务,可以看到本地读写数据量积累非常大,通常超过10GB可以认定为发生数据倾斜。倾斜度 • 平均记录数超过50w且最大记录数是超过平均记录数的4倍。 • 最长时长比平均时长超过4分钟,且最大时长超过平均时长的2倍。 万能方法 • hive.groupby.skewindata=true
    1、大小表关联
    Small_table join big_table
    2、大大表关联
    userid为0或null等情况,两个表做join

    方法一:业务层面干掉0或null的user
    方法二:sql层面key—tostring—randomon case when (x.uid = ‘-‘ or x.uid = ‘0‘ or x.uid is null) then concat(‘dp_hive_search’,rand()) else x.uid end = f.user_id;
    方法三:业务削减:先查询当天用户当小表做join

    3、聚合时存在大量特殊值
    select cast(count(distinct(user_id))+1 as bigint) as user_cntfrom tab_awhere user_id is not null and user_id <> ‘’
    4、空间换时间
    Select day,count(distinct session_id),count(distinct user_id) from log a group by day
    同一个reduce上进行distinct操作时压力很大
    select day, count(case when type='session' then 1 else null end) as session_cnt, count(case when type='user' then 1 else null end) as user_cnt from ( select day,session_id,type from ( select day,session_id,'session' as type from log union all select day user_id,'user' as type • from log ) group by day,session_id,type ) t1 group by day搭建参考:http://note.youdao.com/noteshare?id=22ac246cfddfe1e3f1a400a01a8f578a\&sub=34A84DA642E245E28E4C7B6172CD69FC
    实践:

    导入数据并统计
    join
    UDF
    从HDFS导入
    insert导入
    查询插入
    导出(local+hdfs)
    partition
    hive+hbase
    2 留言 2019-02-03 11:39:01 奖励15点积分
  • 大数据Spark平台5-1、spark-core

    前文链接:https://write-bug.com/article/2090.html
    下面开始新的章节:Spark
    MapReduce:分布式批量计算框架——对HDFS的强依赖。Spark-core:基于内存的分布式批量计算引擎/框架

    Spark的运行模式:

    单机模式:方便人工调试程序
    ./bin/run-example SparkPi 10 --master local[2] //一个进程模拟一个机器Standalone模式:自己独立一套集群(master/client/slave) 缺点:资源不利于充分利用
    ./bin/spark-submit --class org.apache.spark.examples.SparkPi --master spark://master:7077 lib/spark-examples-1.6.0-hadoop2.6.0.jar 100– Master/Slave结构• Master:类似Yarn中的RM• Worker:类似Yarn中的NM
    Yarn模式:

    Yarn-Client模式:Driver(spark Context)运行在本地Client。适合交互调试---本地和页面特定端口。



    Yarn-Cluster模式:Driver运行在集群(AM)。正式提交任务的模式(remote)--  yarn-cluster

    ./bin/spark-submit --class org.apache.spark.examples.SparkPi --master yarn-cluster lib/sparkexamples-1.6.0-hadoop2.6.0.jar 10Yarn Cluster vs. Yarn Client区别:本质是AM进程的区别,cluster模式下,driver运行在AM中,负责向Yarn申请资源 ,并监督作业运行状况,当用户提交完作用后,就关掉Client,作业会继续在yarn上运行。然而cluster模式不适合交互 类型的作业。而client模式,AM仅向yarn请求executor,client会和请求的container通信来调度任务,即client不能离开。
    Master/Slave结构

    RM:全局资源管理器,负责系统的资源管理和分配
    NM:每个节点上的资源和任务管理器
    AM:每个应用程序都有一个,负责任务调度和监视,并与RM调度器协商为任务获取资源


    Hadoop1.0中:

    一个MapReduce程序就是一个job,而一个job里面可以有一个或多个Task,Task又可以区分为Map Task和Reduce Task
    MapReduce中的每个Task分别在自己的进程中运行,当该Task运行完时,进程也就结束



    Spark中作业运行原理:

    Application:spark-submit提交的程序 ,一个Spark应用程序由一个Driver端和多个Executor组成,多个task 以多线程的形式运行在Executor中。
    Driver(AM):完成任务的调度以及executor和cluster manager进行协调

    Driver负责运行程序的main()方法,负责将代码发送到各个Executor去执行,然后取回结果,Driver端也是以Executor方式运行,可以运行在本地(Client),也可以运行在集群内部(Cluster),以Spark-shell形式运行的Spark应用程序,其Driver端都是运行在本地,以Spark-submit形式提交的作业可以通过参数- -deploy-mode来指定Driver端运行在哪里。 ———————-对应了集群中AM的功能
    构建SparkContext(Spark应用的入口,创建需要的变量,还包含集群的配置信息等)
    将用户提交的job转换为DAG图(类似数据处理的流程图)
    根据策略将DAG图划分为多个stage,根据分区从而生成一系列tasks
    根据tasks要求向RM申请资源
    提交任务并检测任务状态


    Executor(container): Executor是代码执行的地方,以进程的形式运行在节点之上(如standalone模式的Worker和yarn模式的NM)。每个worker node(NM)中有多个container(executor),是真正执行task的单元
    Task(线程): 一个Executor可以同时运行多个task(这里对应了上面说的一次提交多个任务,以多线程方式执行),每个task执行一个任务,窄依赖(split-》task一对一),其性质是以多线程的形式运行在Executor中。是Spark中最新的执行单元。RDD一般是带有partitions 的,每个partition在一个executor上的执行可以认为是一个 TaskCluster Manager(RM): 根据运行模式的不同(如Standalone,Apache Mesos,Hadoop YARN ,Kubernetes )其性质也会不同,主要是负责获取集群资源的外部服务(如standalone模式的Master和yarn模式的RM)。
    Job: 一个Action的触发即为一个job,一个job 存在多个task,和MR中Job不一样。MR中Job主要是Map或者Reduce Job。而Spark的Job其实很好区别,一个action算子就算一个 Job,比方说count,first等
    Stage:逻辑概念(dag) 分为水平关系(并行)和垂直关系(串),Job中如果有Shuffle(宽依赖,多对多)产生就会分为2个Stage,一个Job 可由多个Stage构成,一个Stage 可由多个task 组成,是spark中独有的。一般而言一个Job会切换成一定数量 的stage。各个stage之间按照顺序执行
    为什么一个application有多个job?比如分别跑用户特征和物品特征两个任务,这里可以用一个spark-submit同时提交两个任务--一个应用,捏合到一块并发执行
    在mr中,只能分别提交执行,串行。
    为什么一个Job有多个Stage?
    有宽依赖的,shuffle的时候是串行的stage (有partition和计算的中间结果),窄依赖的是一对一的是并行的stage。
    这里的并行和上面的两个job并行,像上面的特征任务,可以达到同样的效果,但是数据倾斜的时候就一般会变为两个job
    (万能方法:hive.groupby.skwindata=true)详情:Hive数据倾斜解决方法总结
    为什么一个Stage里有多个task?
    task ---线程
    Spark开发和MR开发
    MR:Map脚本

    Reduce脚本

    Spark:--Scala

    Scala基础参考:http://www.runoob.com/scala/scala-basic-syntax.html
    算子
    算子是RDD中定义的函数,可以对RDD中的数据进行转换和操作。
    算子分类:

    Value数据类型的Transformation算子,这种变换并不触发提交作业,针对处理的数据项是Value型的数据。
    Key-Value数据类型的Transfromation算子,这种变换并不触发提交作业,针对处理的数据项是Key-Value型的数据对。
    Action算子,这类算子会触发SparkContext提交Job作业。

    RDD有两种操作算子:

    Transformation(转换)--变换非为两类:窄依赖和宽依赖
    Ation(执行)

    transformation是得到一个新的RDD,方式很多,比如从数据源生成一个新的RDD,从RDD生成一个新的RDD,Transformation属于延迟计算,当一个RDD转换成另一个RDD时并没有立即进行转换,仅仅是记住了数据集的逻辑操作。action是得到一个值,或者一个结果(直接将RDDcache到内存中),触发Spark作业的运行,真正触发转换算子的计算。
    所有的transformation都是采用的懒策略,如果只是将transformation提交是不会执行计算的,计算只有在action被提交的时候才被触发。

    输入:在Spark程序运行中,数据从外部数据空间(如分布式存储:textFile读取HDFS等,parallelize方法输入Scala集合或数据)输入Spark,数据进入Spark运行时数据空间,转化为Spark中的数据块,通过BlockManager进行管理。
    运行:在Spark数据输入形成RDD后便可以通过变换算子,如filter等,对数据进行操作并将RDD转化为新的RDD,通过Action算子,触发Spark提交作业。 如果数据需要复用,可以通过Cache算子,将数据缓存到内存。
    输出:程序运行结束数据会输出Spark运行时空间,存储到分布式存储中(如saveAsTextFile输出到HDFS),或Scala数据或集合中(collect输出到Scala集合,count返回Scala int型数据)。

    Transformation和Actions操作概况
    Transformation具体内容

    map(func) :返回一个新的分布式数据集,由每个原元素经过func函数转换后组成。---一对一的处理
    filter(func) : 返回一个新的数据集,由经过func函数后返回值为true的原元素组成。把不符合条件的数据过滤掉---过滤器
    flatMap(func) : 类似于map,但是每一个输入元素,会被映射为0到多个输出元素(因此,func函数的返回值是一个Seq,而不是单一元素)。---一对多,比如句子变token
    sample(withReplacement, frac, seed) : 根据给定的随机种子seed,随机抽样出数量为frac的数据。---采样
    union(otherDataset) : 返回一个新的数据集,由原数据集和参数联合而成。---合并----unionall(不做去重)
    groupByKey([numTasks]) : 在一个由(K,V)对组成的数据集上调用,返回一个(K,Seq[V])对的数据集。注意:默认情况下,使用8个并行任务进行分组,你可以传入numTask可选参数,根据数据量设置不同数目的Task。---对某一字段key聚合 user-》(Sequence)item:score item:score item:score
    reduceByKey(func, [numTasks]) : 在一个(K,V)对的数据集上使用,返回一个(K,V)对的数据集,key相同的值,都被使用指定的reduce函数聚合到一起。和groupbykey类似,任务的个数是可以通过第二个可选参数来配置的。---对不同的主键,value做计算
    join(otherDataset, [numTasks]) : 在类型为(K,V)和(K,W)类型的数据集上调用,返回一个(K,(V,W))对,每个key中的所有元素都在一起的数据集。---两个表做聚合,根据key
    groupWith(otherDataset, [numTasks]) : 在类型为(K,V)和(K,W)类型的数据集上调用,返回一个数据集,组成元素为(K, Seq[V], Seq[W]) Tuples。
    cartesian(otherDataset) : 笛卡尔积。但在数据集T和U上调用时,返回一个(T,U)对的数据集,所有元素交互进行笛卡尔积。
    sort
    partitionBy---分桶

    Actions具体内容

    reduce(func) : 通过函数func聚集数据集中的所有元素。Func函数接受2个参数,返回一个值。这个函数必须是关联性的,确保可以被正确的并发执行。
    collect() : 在Driver的程序中,以数组的形式,返回数据集的所有元素。这通常会在使用filter或者其它操作后,返回一个足够小的数据子集再使用,直接将整个RDD集Collect返回,很可能会让Driver程序OOM。----明文输出
    count() : 返回数据集的元素个数。---数据统计
    take(n) : 返回一个数组,由数据集的前n个元素组成。注意,这个操作目前并非在多个节点上,并行执行,而是Driver程序所在机器,单机计算所有的元素内存压力会增大,需要谨慎使用。
    first() : 返回数据集的第一个元素(类似于take(1))。
    saveAsTextFile(path) : 将数据集的元素,以textfile的形式,保存到本地文件系统,hdfs或者任何其它hadoop支持的文件系统。Spark将会调用每个元素的toString方法,并将它转换为文件中的一行文本。
    saveAsSequenceFile(path) : 将数据集的元素,以sequencefile的格式,保存到指定的目录下,本地系统,hdfs或者任何其它hadoop支持的文件系统。RDD的元素必须由key-value对组成,并都实现了Hadoop的Writable接口,或隐式可以转换为Writable(Spark包括了基本类型的转换,例如Int,Double,String等等)。
    foreach(func) : 在数据集的每一个元素上,运行函数func。这通常用于更新一个累加器变量,或者和外部存储系统做交互。

    Spark会产生shuffle的算子---宽依赖

    去重(distinct)聚合(reduceByKey、groupBy、groupByKey、aggregateByKey、combineByKey)
    排序(sortBy、sortByKey)重分区(coalesce、repartition)集合或者表操作(intersection、subtract、subtractByKey、join、leftOuterJoin)

    Spark基于弹性分布式数据集(RDD)模型,具有良好的通用性、容错性与并行处理数据的能力
    RDD( Resilient Distributed Dataset ):弹性分布式数据集(相当于集合),它的本质是数据 集的描述(只读的、可分区的分布式数据集),而不是数据集本身 ----一块内存区域的格式化表达,描述数据前后依赖关系

    RDD使用户能够显式将计算结果保存在内存中,控制数据的划分,并使用更丰富的操作集合来处理
    使用更丰富的操作来处理,只读(由一个RDD变换得到另一个RDD,但是不能对本身的RDD修改)
    记录数据的变换而不是数据本身保证容错(lineage) ---DAG

    通常在不同机器上备份数据或者记录数据更新的方式完成容错,但这种对任务密集型任务代价很高
    RDD采用数据应用变换(map,filter,join),若部分数据丢失,RDD拥有足够的信息得知这部分数据是如何计算得到的,可通过重新计算来得到丢失 的数据
    这种恢复数据方法很快,无需大量数据复制操作,可以认为Spark是基于RDD模型的系统

    懒操作,延迟计算,action的时候才操作
    瞬时性,用时才产生,用完就释放
    Spark允许从以下四个方面构建RDD– 从共享文件系统中获取,如从HDFS中读数据构建RDD• val a = sc.textFile(“/xxx/yyy/file”)– 通过现有RDD转换得到• val b = a.map(x => (x, 1))– 定义一个scala数组• val c = sc.parallelize(1 to 10, 1)– 有一个已经存在的RDD通过持久化操作生成• val d = a.persist(), a. saveAsHadoopFile(“/xxx/yyy/zzz”)

    RDD的依赖关系

    窄依赖:不关心一条数据是从哪里来的,比如flatmap虽然是一到多,但是不关心纪录是哪里来的,只是把它分割为多条数据
    宽依赖:需要对key有一个严格的要求。有partition

    从后往前,将宽依赖 的边删掉,连通分量 及其在原图中所有依赖的RDD,构成一个 stage
    DAG是在计算过程 中 不 断 扩 展 , 在 action后才会启动计算
    每个stage内部尽可 能多地包含一组具有 窄依赖关系的转换, 并将它们流水线并行化(pipeline)


    RDD容错
    中间某一环节出现错误,部分数据失效(框架判断),这部分数据可以找到最近数据源(缓存)从新计算弥补回来
    一般如果要做cache的话,最好在shuffle类的算子后做cache,这类算子为宽依赖算子,数据很不容易得到,需要依赖于上游所有数据都准备数据之后才执行,哪怕有一块数据失效,都不能执行,为了保证下游失效不重新计算,在这里做一个cache。--既有内存又有磁盘

    优化
    每一个进程包含一个executor对象,每个executor对象包含一个线程池,每个线程执行一个tasks
    线程池好处:省去了频繁启停进程的开销
    Task并发度概念

    每一个节点可以启动一个或多个executor进程
    每个进程由多个core(相当于虚拟的cpu(通过配置配成但不能超过真实机核数))组成,每个core一次只能执行一个task
    调参:

    master yarn-cluster
    num-executors 100
    executor-memory 6G
    executor-cores 4
    driver-memory 1G

    内存划分

    20%:execution:执行内存---shuffle类算子会消耗内存,有的还需要cache缓存,如果内存满溢,把数据写到磁盘上(split)
    60%:Storage:存储cache、presist、broadcast数据(分发小数据集相当于-file---比如在本地完成一个mapside-join去代替处理大数据集的框架(小数据集没有必要使用,完全可以放在内存中实现))

    broadcast:分发小程序数据—mapsite-join

    适合做黑名单,白名单,字典。。。比如分发一个itemid-》itemname就可以在本地数据集里做一个id-》name 的转换
    20%:程序运行
    调参:

    conf spark.default.parallelism=1000每个stage默认的task数量
    conf spark.storage.memory Fraction=0.5默认0.6
    conf spark.shuffle.memory Fraction=0.3默认0.2

    剩下的百分比就是程序运行的内存

    spark1.6版本之前:每个类的内存是相互隔离的,导致了executor的内存利用率不高,需要人工调配参数百分比来优化内存
    spark1.6版本之后(包含):execution和storage内存是可以相互借用的(不够用时动态调整),减少了OOM的情况发生,但也需要参数值作为它的参考。---总内存空间够用的话就不用落地到磁盘了。

    开发调优

    原则一:避免创建重复的RDD
    原则二:尽可能复用同一个RDD
    原则三:对多次使用的RDD进行持久化处理
    原则四:避免使用shuffle类算子
    原则五:使用map-side预聚合的shuffle操作

    一定要使用shuffle的,无法用map类算子替代的,那么尽量使用map-site预聚合的算子
    思想类似MapReduce中的Combiner
    可能的情况下使用reduceByKey或aggregateByKey算子替代groupByKey算子,因为 reduceByKey或aggregateByKey算子会使用用户自定义的函数对每个节点本地相同的key进行 预聚合,而groupByKey算子不会预聚合

    原则六:使用Kryo优化序列化性能

    Kryo是一个序列化类库,来优化序列化和反序列化性能
    Spark默认使用Java序列化机制(ObjectOutputStream/ ObjectInputStream API)进行序列 化和反序列化
    Spark支持使用Kryo序列化库,性能比Java序列化库高很多,10倍左右


    Spark技术栈Spark Core : 基于RDD提供操作接口,利用 DAG进行统一的任务规划
    Spark SQL : Hive的表 + Spark的里。通过把 Hive的HQL转化为Spark DAG计算来实现
    Spark Streaming : Spark的流式计算框架
    MLIB : Spark的机器学习库,包含常用的机器 学习算法
    GraphX : Spark图并行操作库
    Spark搭建参考:http://note.youdao.com/noteshare?id=e8c9e725586227986f7abaeb7bada719&sub=74FBCEE204FE48F29C0A17370010B37C
    实践
    Scala-word countScala-UIgroupScala-cf—协同过滤pyspark-wordcountpyspark-jieba_word_clusterpyspark-LR+NB
    2 留言 2019-01-30 17:17:54 奖励22点积分
  • 大数据Hadoop平台4、Yarn

    前文链接:https://write-bug.com/article/2076.html
    在Haoop2.0中引入了Yarn这个分布式操作系统:
    在1.0中的 集群利用率过低,MR相当于灵魂的存在,想跑MR任务在一个HDFS上,想跑Spark.Storm又要创建个集群才行,不能共享资源,这时候我们想在一个集群中跑不同的计算框架任务这种需求,在1.0中就搞不定了
    1.0 组件相互独立,任务独立,整个的数据处理基本为MR包揽。
    2.0所有任务跑在一个集群,在这里,这些组件就相当于应用程序运行在其上,不同的计算框架任务都变成了一个很普通的插件了,这样就可以有效的利用集群资源了,yarn就相当于一个集群操作系统。

    作用:资源整合
    目的:系统资源利用最大化,在同一系统上运行不同的数据处理框架任务

    下面介绍一下Yarn的核心服务:

    ResouceManger—>RM资源管理器—->原来的Job Tracker
    Job—>application——-任务


    YARN负责管理集群上的各种资源,它也是master/slave结构:ResourceManager为master,NodeManager为slave,RM负责对NM上的资源进行统一管理和调度。当用户提交一个应用程序时(可以是MR程序、Spark程序或Storm程序等),会启动一个对应的ApplicationMaster用于跟踪和管理这个程序。它负责向RM申请资源,并在NM上启动应用程序的子任务。
    YARN的基本组成结构(组件)如下:
    1)ResourceManager——集群资源的仲裁者,1.0中Job Tracker的部分功能
    RM是一个全局的资源管理器,负责整个YARN集群上的资源管理和分配。它由如下两个组件构成:

    Scheduler(调度器):调度器根据各个应用的资源需求进行资源分配。资源分配单位用一个抽象概念“资源容器”(Resource Container,简称Container)表示。—-可插拔的调度组件(有很多配置选项)。—不负责应用程序的监控和状态跟踪,也不保证应用程序失败或者硬件失败的情况下对Task的重启

    FIFO Scheduler 按提交顺序,大任务阻塞
    Capacity Scheduler 专有队列运转小任务,但是小任务预先占一定集群资源
    Fair Scheduler 动态调整,公平共享

    Applications Manager(应用程序管理器):应用程序管理器负责管理整个系统中的所有应用程序,如启动应用程序对应的ApplicaitonMaster、监控AM运行状态并在失败时重启它。

    2)ApplicationMaster
    当客户端提交一个应用程序至YARN集群上时,启动一个对应的AM用于跟踪和管理这个程序。AM的主要功能包括:

    向RM调度器请求资源
    用户级别的作业进程,负责整个作业的运转周期
    监控所有任务的运行状态,并在任务运行失败时重新为任务申请资源以重启任务
    本质是一个特殊的container(Boss也是人嘛)——-随时关闭和启动,不需要一直启动

    注:AM是YARN对外提供的一个接口,不同的计算框架提供该接口的实现,如MRAppMaster、SparkAppMaster等等,使得该类型的应用程序可以运行在YARN集群上。
    3)NodeManager
    NM是每个节点上的资源和任务管理器。NM的主要功能包括:

    周期性向RM汇报(心跳)本(单)节点上的资源使用情况和Container的运行状态
    接收并处理来自AM的任务启动/停止等各种请求
    管理和启动container
    RM相当于山高皇帝远啊,通过NM(管理本地)就可以管辖整个集群

    4)Container——-资源—类似1.0的slot—-上面跑着真正的任务
    Container是YARN中的资源分配单位,它将内存、CPU、磁盘、网络等(任务运行环境)资源封装在一起。当AM向RM申请资源时,RM为AM返回的资源便是用Container的形式运转AM的应用。运行中的Container可能是一个Map,也可能是一个Reducer,Container也得和AM通信,报告任务的状态和健康信息。(任务级别)

    例子:RM是一个租房的中介老板,container是房源,如果来一个老板租房做美容院,那么不管他的分店还是办公地点都是不同的资源,办公楼管理着分店,那么办公楼就是个AM,管理着每个店面的销售额(任务调度),每一个地区都有一个销售经理,对接着所管辖区域的销售工作(但是NM同时一直监控管辖区域的房子完整和任务工作(自己店面资源)),这个销售经理就是个NM,然后美容店就可以开业运转了。

    1.0中JobTracker 是个独裁分子(资源管理、作业调度及监控),2.0Yarn中把其权力分权:RM、AM
    一个任务如果需要多个Container,则通过最小容量单位的多个Container来组成(为甚么yarn中存在虚拟Cpu的概念:根据具体硬件配置的不同,但也需根据实际情况)
    Yarn中优化:当MR执行结束,可以释放map的Container,请求更多的Reducer的Container
    不管是什么职位,大家工位都一样了,对于提交给集群的每个作业,会启动一个专用的、短暂的 JobTracker 来控制该作业中的任 务的执行,短暂的 JobTracker 由在从属节点上运行的 TaskTracker 启动不管AM(HR)在那个工位,他自己管理的团队和项目都能正常运转。
    Yarn优势

    减小了 JobTracker(也就是现在的 RM)的资源消耗,并且让监测每一个 Job 子任务 (tasks) 状态的程序分布式化了,更安全、更优美
    AM是一个可变更的部分,用户可以对不同的编程模型写自己的 AM,让更多类 型的编程模型(更多计算框架,不只是MR)能够跑在 Hadoop 集群中
    对于资源的表示以内存为单位,比之前以剩余 slot 数目更合理
    老的框架中,JobTracker 一个很大的负担就是监控 job 下的 tasks 的运行状况 ,现在,这个部分就扔给 ApplicationMaster 做了
    资源表示成内存量,那就没有了之前的 map slot/reduce slot 分开造成集群资 源闲置的尴尬情况(map释放后可以用于reduce)

    容错能力:RM挂掉:HA—-zookeeper
    NM挂掉:心跳告知RM,RM通知AM,AM进一步处理
    AM挂掉:RM负责重启,RM上有一个RMAM,是AM的AM,保存了已完成的信息,不再运行

    HDFS对Map Reduce彻底的重构—>MRv2或者Yarn
    MRv1: 不适合场景:实时(storm)、迭代(机器学习,模型训练)、图计算场景(Giraph)
    MRv2执行流程
    1、作业提交阶段
    作业提交阶段主要在客户端完成,过程如下图:

    当作业提交成功后,在HDFS上可以查看到相关作业文件:

    这些文件都是在Client端生成并上传至HDFS,对这些作业文件的说明如下:

    作业jar包:job.jar
    作业输入分片信息:job.split、job.splitmetainfo
    作业配置信息:job.xml

    这些作业文件存放在/tmp/hadoop-yarn/staging/hadoop/.staging/job_1435030889365_0001路径下,该路径又称为作业提交路径submitJobDir,它包括如下两部分:

    jobStagingArea:/tmp/hadoop-yarn/staging/hadoop/.staging是作业的staging目录
    jobID:唯一标识集群上的一个MR 任务

    2、作业的初始化阶段

    对上图更详细的表述如下:

    步骤1:当MR作业提交至YARN后,RM为该作业分配第一个Container,并与对应的NM通信,在Container中启动作业的MRAppMaster。
    步骤2:MRAppMaster向RM注册自己。这使得客户端可以直接通过RM查看应用程序的运行状态。
    步骤3:MRAppMaster读取作业的输入分片。作业的分片数(split)决定了启动的map任务数。

    3、作业执行阶段

    对上图更详细的表述如下:

    步骤1:MRAppMaster采用轮询的方式向RM申请任务所需资源。
    步骤2:资源分配成功后,MRAppMaster就与对应的NM通信,并启动YarnChild来执行具体的Map任务和Reduce任务。在任务运行前,还要将任务所需文件本地化(包括作业Jar包、配置信息等)。

    注:每个输入分片对应一个Map任务;Reduce任务数由mapreduce.job.reduces属性确定。

    步骤3:在YARN上运行时,任务每3秒钟向AM汇报进度和状态。
    步骤4:应用程序运行完成后,AM向RM注销自己,并释放所有资源。

    至此,MR作业执行结束。下图附上《Hadoop权威指南》中关于YARN上运行MR作业的流程图

    说明:上述步骤并没有考虑Shuffle过程,这是为了方便表述。
    1 留言 2019-01-30 17:03:55 奖励18点积分
  • 大数据Hadoop平台3-2、 HDFS2.0

    前文链接:https://write-bug.com/article/2058.html
    这节我们来介绍下HDFS2.0是如何一步步去解决1.0中存在的问题的,并在此基础上介绍2.0存储原理机制:
    首先我们先列出几个2.0的新特性,由这个为主线:

    NameNode HA 数据高可用
    NameNode Federation 联邦
    HDFS 快照
    HDFS 缓存
    HDFS ACL


    在Hadoop1.0整个集群只有一个NN,存在单点故障问题,一旦NN挂掉,整个集群也就无法使用了,而在1.0中的解决方法不管是NFS还是SNN都不是一个很好的解决办法,这个上节已经说了,所以HDFS2.0首当其冲的就是这个单点故障问题,引入了Name Node High Available(NNHA)高可用,不同于1.0中的不可靠实现(SNN),NNHA中有两个Name Node(分别为:ActiveName Node和StandByName Node),顾名思义,一个为工作状态一个为待命状态,当ANN所在服务器宕机时,SNN可以在数据不丢失的情况下,手工或自动切换并提供服务。
    ANN在集群中和原来的NN一样,承担着所有与客户端的交互操作,而SBNN在集群中不需要做任何交互操作,那他做什么呢?它只需要与ANN做好通信工作,什么意思,就是ANN数据发生变化时,SBNN和它做一个数据同步工作,这样就算我的ANN挂掉,SBNN可以随时顶上去成为新的ANN,提供快速的故障恢复。
    所以这里就引出一个问题:
    如何保持集群中两个NN的数据同步?HDFS2.0完整架构图:

    我们先来看下上面架构这个图,经过我们前面1.0的讲解,虽然这幅图确实发生了很大变化,但是我们先看下面一部分和前面还是很相似的,在1.0中我的NN和DN是通过心跳机制进行通信,DN去汇报block的健康情况、更新情况和任务进度,这里也不例外,只是DN同时向两个NN发送心跳罢了,目的就是保证两个NN维护的数据保持一致。而这里同步的数据是block->datanode的映射信息,每次心跳自动上报到NN中,所以NN中不必存储此类元数据。但是只靠心跳机制去维护还不够,因为还有内存中的path->blocklist去如何维护呢?两种方法:

    NFS(network file system):运维中的网络远程挂载目录,可以保证两台不同机器可以共享访问同一网络文件系统。(数据保存在了公共节点机器上)

    缺点:定制化硬件设备:必须是支持NAS的设备才能满足需求。复杂化部署过程:在部署好NameNode后,还必须额外配置NFS挂载、定制隔离脚本,部署易出错。简陋化NFS客户端:Bug多,部署配置易出错,导致HA不可用
    属于操作系统支持的配置——-fsimage镜像文件和edits编辑日志文件。

    QJM(基于Paxos(基于消息传递的一致性算法))最低法定人数管理机制:Hadoop自身提供的服务,借助了zookeeper,相当于把公共数据写在了zookeeper上,从而去维护两个NN上的log文件。

    属于应用软件级别的配置——用2N+1台机器存储editlog

    NameNode 为了数据同步,会通过一组称作Journal Nodes的独立进程进行相互通信。当active状态的Name Node命名空间有任何修改时,会告知大部分的JN进程,standby状态的Name Node再去读取JNs中的变更信息,并且一直监控editlog 中的变化,把变化应用到自己的命名空间,这样就可以确保集群出错时,命名空间状态已经是同步的了。
    Hadoop的元数据主要作用是维护HDFS文件系统中文件和目录相关信息。元数据的存储形式主要有3类:内存镜像、磁盘镜像(FSImage)、日志(EditLog)。在Namenode启动时,会加载磁盘镜像到内存中以进行元数据的管理,存储在NameNode内存;磁盘镜像是某一时刻HDFS的元数据信息的快照,包含所有相关Datanode节点文件块映射关系和命名空间(Namespace)信息,存储在NameNode本地文件系统;日志文件记录client发起的每一次操作信息,即保存所有对文件系统的修改操作,用于定期和磁盘镜像合并成最新镜像,保证NameNode元数据信息的完整,存储在NameNode本地和共享存储系统(QJM)中。
    如下所示为NameNode本地的EditLog和FSImage文件格式,EditLog文件有两种状态: inprocess和finalized, inprocess表示正在写的日志文件,文件名形式:editsinprocess[start-txid] finalized表示已经写完的日志文件,文件名形式:edits[start-txid][end-txid]; FSImage文件也有两种状态, finalized和checkpoint, finalized表示已经持久化磁盘的文件,文件名形式: fsimage[end-txid], checkpoint表示合并中的fsimage, 2.x版本checkpoint过程在Standby Namenode(SNN)上进行,SNN会定期将本地FSImage和从QJM上拉回的ANN的EditLog进行合并,合并完后再通过RPC传回ANN。
    name/├── current│ ├── VERSION│ ├── edits_0000000003619794209-0000000003619813881│ ├── edits_0000000003619813882-0000000003619831665│ ├── edits_0000000003619831666-0000000003619852153│ ├── edits_0000000003619852154-0000000003619871027│ ├── edits_0000000003619871028-0000000003619880765│ ├── edits_0000000003619880766-0000000003620060869│ ├── edits_inprogress_0000000003620060870│ ├── fsimage_0000000003618370058│ ├── fsimage_0000000003618370058.md5│ ├── fsimage_0000000003620060869│ ├── fsimage_0000000003620060869.md5│ └── seen_txid└── in_use.lock
    上面所示的还有一个很重要的文件就是seen_txid,保存的是一个事务ID,这个事务ID是EditLog最新的一个结束事务id,当NameNode重启时,会顺序遍历从edits_0000000000000000001到seen_txid所记录的txid所在的日志文件,进行元数据恢复,如果该文件丢失或记录的事务ID有问题,会造成数据块信息的丢失。
    HA其本质上就是要保证主备NN元数据是保持一致的,即保证fsimage和editlog在备NN上也是完整的。元数据的同步很大程度取决于EditLog的同步,而这步骤的关键就是共享文件系统,下面开始介绍一下关于QJM共享存储机制。
    QJM原理QJM全称是Quorum Journal Manager, 由JournalNode(JN)组成,一般是奇数点结点组成。每个JournalNode对外有一个简易的RPC接口,以供NameNode读写EditLog到JN本地磁盘。当写EditLog时,NameNode会同时向所有JournalNode并行写文件,只要有N/2+1结点写成功则认为此次写操作成功,遵循Paxos协议。其内部实现框架如下:

    从图中可看出,主要是涉及EditLog的不同管理对象和输出流对象,每种对象发挥着各自不同作用:
    FSEditLog:所有EditLog操作的入口JournalSet: 集成本地磁盘和JournalNode集群上EditLog的相关操作FileJournalManager: 实现本地磁盘上 EditLog 操作QuorumJournalManager: 实现JournalNode 集群EditLog操作AsyncLoggerSet: 实现JournalNode 集群 EditLog 的写操作集合AsyncLogger:发起RPC请求到JN,执行具体的日志同步功能JournalNodeRpcServer:运行在 JournalNode 节点进程中的 RPC 服务,接收 NameNode 端的 AsyncLogger 的 RPC 请求。JournalNodeHttpServer:运行在 JournalNode 节点进程中的 Http 服务,用于接收处于 Standby 状态的 NameNode 和其它 JournalNode 的同步 EditLog 文件流的请求。
    下面具体分析下QJM的读写过程。
    QJM 写过程分析
    上面提到EditLog,NameNode会把EditLog同时写到本地和JournalNode。写本地由配置中参数dfs.namenode.name.dir控制,写JN由参数dfs.namenode.shared.edits.dir控制,在写EditLog时会由两个不同的输出流来控制日志的写过程,分别为:EditLogFileOutputStream(本地输出流)和QuorumOutputStream(JN输出流)。写EditLog也不是直接写到磁盘中,为保证高吞吐,NameNode会分别为EditLogFileOutputStream和QuorumOutputStream定义两个同等大小的Buffer,大小大概是512KB,一个写Buffer(buffCurrent),一个同步Buffer(buffReady),这样可以一边写一边同步,所以EditLog是一个异步写过程,同时也是一个批量同步的过程,避免每写一笔就同步一次日志。
    这个是怎么实现边写边同步的呢,这中间其实是有一个缓冲区交换的过程,即bufferCurrent和buffReady在达到条件时会触发交换,如bufferCurrent在达到阈值同时bufferReady的数据又同步完时,bufferReady数据会清空,同时会将bufferCurrent指针指向bufferReady以满足继续写,另外会将bufferReady指针指向bufferCurrent以提供继续同步EditLog。上面过程用流程图就是表示如下:

    这里有一个问题,既然EditLog是异步写的,怎么保证缓存中的数据不丢呢,其实这里虽然是异步,但实际所有日志都需要通过logSync同步成功后才会给client返回成功码,假设某一时刻NameNode不可用了,其内存中的数据其实是未同步成功的,所以client会认为这部分数据未写成功。
    第二个问题是,EditLog怎么在多个JN上保持一致的呢。下面展开介绍。
    日志同步
    这个步骤上面有介绍到关于日志从ANN同步到JN的过程,具体如下:

    执行logSync过程,将ANN上的日志数据放到缓存队列中
    将缓存中数据同步到JN,JN有相应线程来处理logEdits请求
    JN收到数据后,先确认EpochNumber是否合法,再验证日志事务ID是否正常,将日志刷到磁盘,返回ANN成功码
    ANN收到JN成功请求后返回client写成功标识,若失败则抛出异常

    隔离双写:
    在ANN每次同步EditLog到JN时,先要保证不会有两个NN同时向JN同步日志。这个隔离是怎么做的。这里面涉及一个很重要的概念Epoch Numbers,很多分布式系统都会用到。Epoch有如下几个特性:
    当NN成为活动结点时,其会被赋予一个EpochNumber每个EpochNumber是惟一的,不会有相同的EpochNumber出现EpochNumber有严格顺序保证,每次NN切换后其EpochNumber都会自增1,后面生成的EpochNumber都会大于前面的EpochNumber
    QJM是怎么保证上面特性的呢,主要有以下几点:
    第一步,在对EditLog作任何修改前,QuorumJournalManager(NameNode上)必须被赋予一个EpochNumber第二步, QJM把自己的EpochNumber通过newEpoch(N)的方式发送给所有JN结点第三步, 当JN收到newEpoch请求后,会把QJM的EpochNumber保存到一个lastPromisedEpoch变量中并持久化到本地磁盘第四步, ANN同步日志到JN的任何RPC请求(如logEdits(),startLogSegment()等),都必须包含ANN的EpochNumber第五步,JN在收到RPC请求后,会将之与lastPromisedEpoch对比,如果请求的EpochNumber小于lastPromisedEpoch,将会拒绝同步请求,反之,会接受同步请求并将请求的EpochNumber保存在lastPromisedEpoch
    这样就能保证主备NN发生切换时,就算同时向JN同步日志,也能保证日志不会写乱,因为发生切换后,原ANN的EpochNumber肯定是小于新ANN的EpochNumber,所以原ANN向JN的发起的所有同步请求都会拒绝,实现隔离功能,防止了脑裂。
    NN切换时 恢复in-process日志
    为什么要这步呢,如果NN切换了,可能各个JN上的EditLog的长度都不一样,需要在开始写之前将不一致的部分恢复。恢复机制如下:

    ANN先向所有JN发送getJournalState请求;
    JN会向ANN返回一个Epoch(lastPromisedEpoch);
    ANN收到大多数JN的Epoch后,选择最大的一个并加1作为当前新的Epoch,然后向JN发送新的newEpoch请求,把新的Epoch下发给JN;
    JN收到新的Epoch后,和lastPromisedEpoch对比,若更大则更新到本地并返回给ANN自己本地一个最新EditLogSegment起始事务Id,若小则返回NN错误;
    ANN收到多数JN成功响应后认为Epoch生成成功,开始准备日志恢复;
    ANN会选择一个最大的EditLogSegment事务ID作为恢复依据,然后向JN发送prepareRecovery; RPC请求,对应Paxos协议2p阶段的Phase1a,若多数JN响应prepareRecovery成功,则可认为Phase1a阶段成功;
    ANN选择进行同步的数据源,向JN发送acceptRecovery RPC请求,并将数据源作为参数传给JN。
    JN收到acceptRecovery请求后,会从JournalNodeHttpServer下载EditLogSegment并替换到本地保存的EditLogSegment,对应Paxos协议2p阶段的Phase1b,完成后返回ANN请求成功状态。
    ANN收到多数JN的响应成功请求后,向JN发送finalizeLogSegment请求,表示数据恢复完成,这样之后所有JN上的日志就能保持一致。

    数据恢复后,ANN上会将本地处于in-process状态的日志更改为finalized状态的日志,形式如edits[start-txid][stop-txid]。
    通过上面一些步骤,日志能保证成功同步到JN,同时保证JN日志的一致性,进而备NN上同步日志时也能保证数据是完整和一致的。
    QJM读过程分析
    这个读过程是面向备NN(SNN)的,SNN定期检查JournalNode上EditLog的变化,然后将EditLog拉回本地。SNN上有一个线程StandbyCheckpointer(可以称为正在合并中的fsimage),会定期将SNN上FSImage和EditLog合并,并将合并完的FSImage文件传回主NN(ANN)上,就是所说的Checkpointing过程。下面我们来看下Checkpointing是怎么进行的。
    在2.x版本中,已经将原来的由SecondaryNameNode主导的Checkpointing替换成由SNN主导的Checkpointing。下面是一个CheckPoint的流向图:

    总的来说,就是在SNN上先检查前置条件,前置条件包括两个方面:距离上次Checkpointing的时间间隔和EditLog中事务条数限制。前置条件任何一个满足都会触发Checkpointing,然后SNN会将最新的NameSpace数据即SNN内存中当前状态的元数据保存到一个临时的fsimage文件( fsimage.ckpt)然后比对从JN上拉到的最新EditLog的事务ID,将fsimage.ckpt中没有,EditLog中有的所有元数据修改记录合并一起并重命名成新的fsimage文件,同时生成一个md5文件。将最新的fsimage再通过HTTP请求传回ANN。通过定期合并fsimage有什么好处呢,主要有以下几个方面:
    可以避免EditLog越来越大,合并成新fsimage后可以将老的EditLog删除可以避免主NN(ANN)压力过大,合并是在SNN上进行的可以保证fsimage保存的是一份最新的元数据,故障恢复时避免数据丢失
    主备切换机制要完成HA,除了元数据同步外,还得有一个完备的主备切换机制,Hadoop的主备选举依赖于ZooKeeper。下面是主备切换的状态图:

    从图中可以看出,整个切换过程是由ZKFC来控制的,具体又可分为HealthMonitor、ZKFailoverController和ActiveStandbyElector三个组件。
    ZKFailoverController: 是HealthMontior和ActiveStandbyElector的母体,执行具体的切换操作
    HealthMonitor: 监控NameNode健康状态,若状态异常会触发回调ZKFailoverController进行自动主备切换
    ActiveStandbyElector: 通知ZK执行主备选举,若ZK完成变更,会回调ZKFailoverController相应方法进行主备状态切换
    在故障切换期间,ZooKeeper主要是发挥什么作用呢,有以下几点:
    失败保护:集群中每一个NameNode都会在ZooKeeper维护一个持久的session,机器一旦挂掉,session就会过期,故障迁移就会触发
    Active NameNode选择:ZooKeeper有一个选择ActiveNN的机制,一旦现有的ANN宕机,其他NameNode可以向ZooKeeper申请排他成为下一个Active节点
    防脑裂: ZK本身是强一致和高可用的,可以用它来保证同一时刻只有一个活动节点
    那在哪些场景会触发自动切换呢,从HDFS-2185中归纳了以下几个场景:
    ActiveNN JVM奔溃:ANN上HealthMonitor状态上报会有连接超时异常,HealthMonitor会触发状态迁移至SERVICE_NOT_RESPONDING, 然后ANN上的ZKFC会退出选举,SNN上的ZKFC会获得Active Lock, 作相应隔离后成为Active结点。
    ActiveNN JVM冻结:这个是JVM没奔溃,但也无法响应,同奔溃一样,会触发自动切换。
    ActiveNN 机器宕机:此时ActiveStandbyElector会失去同ZK的心跳,会话超时,SNN上的ZKFC会通知ZK删除ANN的活动锁,作相应隔离后完成主备切换。
    ActiveNN 健康状态异常: 此时HealthMonitor会收到一个HealthCheckFailedException,并触发自动切换。
    Active ZKFC奔溃:虽然ZKFC是一个独立的进程,但因设计简单也容易出问题,一旦ZKFC进程挂掉,虽然此时NameNode是OK的,但系统也认为需要切换,此时SNN会发一个请求到ANN要求ANN放弃主结点位置,ANN收到请求后,会触发完成自动切换。
    ZooKeeper奔溃:如果ZK奔溃了,主备NN上的ZKFC都会感知断连,此时主备NN会进入一个NeutralMode模式,同时不改变主备NN的状态,继续发挥作用,只不过此时,如果ANN也故障了,那集群无法发挥Failover, 也就不可用了,所以对于此种场景,ZK一般是不允许挂掉到多台,至少要有N/2+1台保持服务才算是安全的。
    总结
    上面介绍了下关于HadoopHA机制,归纳起来主要是两块:元数据同步和主备选举。元数据同步依赖于QJM共享存储,主备选举依赖于ZKFC和Zookeeper。整个过程还是比较复杂的,如果能理解Paxos协议,那也能更好的理解这个。
    以上即是利用QJM和zookeeper实现HDFS的高可用,解决了单点故障问题。
    下面再介绍下另一特性:联邦Namenode Federation:—-解决了内存限制问题
    该特性允许一个HDFS集群中存在多个NN同时对外提供服务,这些NN分管一部分目录(水平切分),彼此之间相互隔离,但是本质还是共享了底层的DataNode资源,只不过上层分权了而已。

    架构设计:
    为了水平拓展Name Node,Federation使用了多个独立的Namenode/NameSpace。这些Name Node之间是联合的,也就是说他们之间相互独立且不需要相互协调,各自分工,管理自己的区域。分布式的datanode被用作通用的共享数据块存储设备,每个Datanode要向所有的NN注册,并周期性向所有NN发送心跳和块报告,并执行来自所有namenode的命令。
    这里引入了一个概念叫Block Pool块池,即单个命名空间的一组Block块(一个NN下维护多个DN),每一个命名空间可以根据大小和业务单独分配一个NN。
    DataNode是一个物理概念,Block Pool是一个重新将Block划分的逻辑概念,同一个dataNode中可以存在多个BlockPool的块,BlockPool允许一个命名空间NN在不通知其他NN的时候为一个新的Block创建Blockid,而一个NN失效同样也不会影响其下的DataNode为其他NN服务。
    每个BlockPool内部自治,不与其他Blockpool交流,一个NN挂了不影响其他NN。
    当DN和NN建立联系并开始会话后,自动建立BlockPool,每个Block都有一个唯一的表示,我们称之为拓展块ID,在HDFS集群中是唯一的,为集群归并创造了条件———blockid
    DN中的数据结构通过块池ID Block Pool id索引,即DN中的BlockMap,storage等都通过BPID索引。
    某个NN上的NameSpace和它对应的Block Pool一起被称为NameSpace Volume。它是管理的基本单位。当一个NN/NS被删除后,其所有DN上对应的Block Pool也会被删除。当集群升级时,每个NameSpace Volume作为一个基本单元进行升级。
    集群中提供多个NameNode,每个NameNode负责管理一部分DataNode:
    以上其实就可以理解为不同目录给不同部门管理,对不同命名空间做一个逻辑切分而已,其实下方存储还是没有变。
    如果一个目录比较大,建议用单独的NN维护。
    联邦本质:NN(元数据)与DN(真实数据)解耦,实际为共享数据
    HDFS快照快照snapshots是HDFS文件系统的只读的基于某时间点的拷贝,可以针对某个目录,或者整个文件系统做快照。快照比较常见的应用场景是数据备份,以防一些用户错误或灾难恢复。
    备份、灾备、快速恢复
    本质:也占空间,(但仅仅记录了block列表和大小而已,不涉及数据本身),即某个目录某一时刻的镜像,创建过程快O(1)
    快照的高效性实现:

    快照可以即时创建,耗时仅为O(1)。—excluding the inode lookup time
    只有当涉及到快照目录的修改被执行时,才会产生额外的内存消耗。而且内存消耗为O(M),其中M是被修改的文件或目录数。
    创建快照时,block块并不会被拷贝。快照文件中只记录了block列表和文件大小,不会做任何数据拷贝。
    快照不会对正常的HDFS操作有任何影响:创建快照以后发生的修改操作,被按操作时间的倒序(from newer to older)记录下来。所以当前的数据能被直接获取,而快照点的数据,则通过在当前的数据基础上减去执行过的操作来获取。

    • Snapshot 并不会影响HDFS 的正常操作:修改会按照时间的反序记录,这样可 以直接读取到最新的数据。• 快照数据是当前数据减去修改的部分计算出来的。• 快照会存储在snapshottable的目录下。• HDFS快照是对目录进行设定,是某个目录的某一个时刻的镜像• 对于一个snapshottable文件夹,“.snapshot” 被用于进入他的快照 /foo 是一个 snapshottable目录,/foo/bar是一个/foo下面的文件目录,/foo有一个快照s0,那么路径就是 :/foo/.snapshot/s0/bar
    • hdfs dfsadmin -allowSnapshot /user/spark • hdfs dfs -createSnapshot /user/spark s0 • hdfs dfs -renameSnapshot /user/spark s0 s_init • hdfs dfs -deleteSnapshot /user/spark s_init • hdfs dfsadmin -disallowSnapshot /user/spark注意:做过快照的目录,本身的父目录和子目录都不允许再次做快照。
    HDFS缓存
    1.0:user-》DN 经常读的数据提前加载到内存中
    2.0:集中式缓存—可指定要缓存的HDFS路径——-非递归,只缓存当前目录,缓存到当前机器本地内存中,DN Block-》DN内存

    HDFS中的集中缓存管理(Centralized cache management)是一种显式缓存机制,允许用户指定HDFS需要缓存的路径。NameNode将与磁盘上具有所需要的块的DataNodes进行通信,指示这些DataNodes将这些块缓存到 off-heap caches中。
    HDFS权限控制ACLHadoop中的ACL与Linux中的ACL机制基本相同,都是用于为文件系统提供更精细化的权限控制。首先参数上要开启基本权限和访问控制列表功能– dfs.permissions.enabled– dfs.namenode.acls.enabled
    基本命令操作:
    hdfs dfs -getfacl [-R] 获取目录和文件的ACL 信息– hadoop fs -getfacl /input/aclhdfs dfs -setfacl [-R] [-b |-k -m |-x ] |[--set ] 设置文件和目录的ACL信息– hdfs dfs -setfacl -m user:mapred:r-- /input/acl– hdfs dfs -setfacl -x user:mapred /input/aclhdfs dfs -ls 当ls的权限位输出以+结束时,那么该文件或目录正在启用一个ACL。请参考:Hdfs的ACL測试:https://www.cnblogs.com/mthoutai/p/6868846.html

    搭建这样的机制已在MR章节更新,这里再提醒下学习时可为体验:参考文章:https://www.cnblogs.com/selinux/p/4155814.html【192.168.87.150】master1:NN ZKFC RM【192.168.87.151】master2:NN ZKFC RM【192.168.87.155】slave1:DN NM ZK JN【192.168.87.156】slave2:DN NM ZK JN【192.168.87.157】slave3:DN NM【192.168.87.158】slave4:DN NM ZK JN
    这个章节没怎么写好,还在持续更新。
    2 留言 2019-01-26 19:11:09 奖励23点积分
  • 大数据Hadoop平台3-1、HDFS1.0

    前文链接:https://write-bug.com/article/2054.html
    前面的章节曾多次提到HDFS,而HDFS作为生态中一个不可或缺的角色足可说明其重要性。
    下面我们首先来介绍一下HDFS1.0:

    好我们进入no pic you say a j8 环节:那么这张图是什么意思呢?
    如图所示主要有三个角色:NameNode、DataNode、Client
    也就是主节点,从节点和客户端。简单地说,主节点主要存储着数据元信息,从节点存储着真实数据,client则是提交任务的客户端机器,其实本质就是向NN请求读写数据(在真正公司中是不会让你真正登陆到任何节点上的,只能是起另外一台机器去和master的地址通过配置文件起某种联系。),我们模拟是在master上提交任务的,后面会详细讲解这几个角色。
    HDFS 是一个主/从(Master/Slave)体系架构,由于分布式存储的性质,集群拥有两类节点 NameNode 和 DataNode。
    HDFS 由三个组件(本质是进程)构成:NameNode(NN)DataNode(DN)SecondaryNameNode(SNN)

    NameNode是主节点,也叫Master,一个hadoop集群只有一个NameNode
    DataNode是从节点,也叫Worker,一个hadoop集群可以有多个DataNode,一个节点只有一个Data Node
    SecondaryNameNode不是第二主节点,是助手节点,作用于数据持久化,你可以认为是一个镜像文件,备份。

    相信上面这几点细节,我们在前面搭建1.0集群时查看jps进程已经体会到了。
    client读取数据的时候,并不是从我们的namenode上读取数据,而是直接从datanode上读取,那他是怎么知道我要的数据在哪台datanode节点上呢?其实是NN告诉客户端的,我们后面会说这个问题。
    那么这个图下面的小方块是什么意思呢?
    HDFS数据的最小单位是block,一个Block默认大小是64M(可配置),这个可以直接影响到MapReduce并发个数,每个绿色相当于一个Block,如果有一个DataNode挂了,数据丢失,打破了3副本的平衡,由3变成2的时候,在配置文件里配3的目的是数据高可用性,所以要复制(Replication)一个副本,这样就保证了一个balance。
    client往NameNode上提交任务时,不是说client有请求时,我的NN和DN才进行交互,而是你来了一个任务,我就去查看我的DN有哪些是空闲的,再继续往空闲的上分配任务,那么NN是如何知道哪些DN是空闲的呢?是Heartbeat(心跳机制),这里我的NN通过这个机制管理了整个集群的DataNode,就相当于管理了所有DN上的Block。

    Heartbeat(心跳机制):NameNode与DataNode之间存在心跳连接,DataNode每隔3s就主动向NameNode汇报健康状况,资源利用情况、任务调度等。
    balance:当一个datanode挂了,block,为了达到平衡状态,内部数据会平均分配到其他datanode上。

    下面我们来详细介绍下这几个组件:
    NameNode(NN)1)管理着文件系统命名空间:维护着文件系统树及树中的所有文件和目录,存储元信息:

    文件名目录名及它们之间的层级关系
    文件目录的所有者及其权限
    每个文件块的名及文件有哪些块组成

    存储元数据信息(描述数据的数据)的映射关系path->blockid_list 这个是什么意思呢?我们在hadoop 命令查看文件的时候,我们直接可以看到目录,文件及里面的信息,对我们来说是透明的,但这个文件其实是被切分好后散落在不同的机器上的,而具体在哪里我们是不需要关心的,Name Node帮我们记录了文件包含了那些Block,而它仅仅告诉了我们存储在哪个block上的名字(block号),但对于client来说真正有意义的则是这些block在哪些机器上。
    block->datanode(节点地址) 在这个映射中我们就知道block是在哪台dataNode上了。
    这个时候我们再看上面那个图,刚才提出的问题client如何知道去哪台机器读取自己想要的信息:(这里解决了client访问时如何知道数据在哪个DataNode机器上的问题)
    那我们已经知道了去哪台机器上读取数据了,读取什么数据呢?这时候就涉及到了datanode的映射关系:block->path 这样我们就知道读取哪个具体路径信息了。所以datanode在Name Node里面只是作为value形式存在。
    那么元数据存储在什么地方呢:

    一:内存: 响应请求的数据在内存中—-真正对外服务的数据
    二:磁盘:数据持久化—-这里就引出了SNN的作用

    元数据放在内存中,重启机器或机器宕机时,内存中的数据消失,为防止数据丢失,定期把内存中的数据dump(转储)到edit logs中(引出延迟问题),这里需要用到SNN定期把edit logs中的数据merge到fsimage(元数据镜像文件—本地磁盘)中(引出二次延迟问题),这个过程被称为SNN的持久化过程,相当于备份。当机器重启时,load fsimage文件——-这里引出了数据备份更新时的延迟问题。
    2)通常搭建机器时,定位为master机器———-主
    Job Tracker也在其上运行,(但在大公司中有需要的情况下,这两个是可以部署在两台机器上的)——-本地化原则(就近原则)减少网络IO和拷贝时间成本。
    3)Hadoop更倾向存储大文件原因:
    一般来说,一条元信息记录会占用200byte内存空间。假设块大小为64MB,备份数量是3,那么一个1GB大小的文件将占用16*3=48个文件块。如果现在有1000个1MB大小的文件,则会占用1000*3=3000个文件块(多个文件不能放到一个块中)。我们可以发现,如果文件越小,存储同等大小文件所需要的元信息就越多,所以Hadoop更喜欢大文件。
    4)元信息持久化
    在NameNode中存放元信息的文件是 fsimage。在系统运行期间所有对元信息的操作都保存在内存中并被持久化到另一个文件edits中。并且edits文件和fsimage文件会被SecondaryNameNode周期性的合并。
    内存中的元数据定期存储到fsimage中:edits只dump修改的文件,fsimage是比较旧的文件,定期把相对实时的edits合并到fsimage中,在Secondary Name Node进程中执行。

    5)1.0时,还没有zookeeper和好的集群解决方案,所以一个集群中只有一个NN,但也因为如此,引起了单点故障问题,而以当时的技术,想要解决单点故障问题,只有NFS和SNN,SNN前面说了,负责镜像文件的备份,但还是有延迟问题存在,避免不了丢失部分数据,NFS是远程网络挂载硬盘,但是增加了时间成本,所以无论那种方法都不是一种好的解决方案。
    6)运行NameNode会占用大量内存和I/O资源,一般NameNode不会存储用户数据或执行MapReduce任务。
    NameNode只有一个进程,挂掉了就没了,而且数据变大了,不能持久化,内存不够,直接制约了集群的大小,这就是1.0的局限性。
    DataNode(DN)
    由block数据块组成,存储真实数据。根据NN指示做创建、复制、删除等操作。
    心跳机制:每3秒向NN发送心跳报告健康状况以及任务进程等。
    副本机制:防止数据丢失,保证数据冗余,数据高可用,是一个以空间换取安全性的机制。(同机架两个不同位置,第三个不同机架随机位置)
    通常搭建机器环境时,定位为Slave机器——-从

    TaskTracker 和其在同一机器上运行,和前面一样,本地化原则。
    Block—-数据块

    磁盘读写的基本单位
    HDFS默认数据块大小64MB,磁盘块一般为512B
    块增大可以减少寻址时间,降低寻址时间/文件传输时间,若寻址时间为10ms,磁盘传输速率为100MB/s,那么该比例仅为1%
    数据块过大也不好,因为一个MapReduce通常以一个块作为输入,块过大会导致整体任务数量过小,降低作业处理速度

    Block副本放置策略

    一:放在客户端相同的节点(如果客户端时集群外的一台机器,就随机算节点,但是系统会避免挑选太满和太忙的节点)
    二:放在不同机架(随机选择)的节点
    三:放在与第二个副本同机架不同节点上

    distance(/D1/R1/H1,/D1/R1/H1)=0 相同的datanode
    distance(/D1/R1/H1,/D1/R1/H3)=2 同一rack下的不同datanode
    distance(/D1/R1/H1,/D1/R2/H5)=4 同一IDC下的不同datanode
    distance(/D1/R1/H1,/D2/R3/H9)=6 不同IDC下的datanode


    5)如何保证数据完整性?
    在Client读写过程中为了保证数据完整性,HDFS中有一个数据校验:CRC32(循环冗余校验码)可以类比MD5,只是不同的加密方法,数据读写过程中,一共校验两次:client写到DN之前以每隔一个单位(512字节)创建一个校验码并加上数据(相当于打了个标记)写到DN上,第二次是DN接收数据时,同样每隔512求一个校验码和发送过来的比对,以上这样即保证了数据的完整性。
    第二方式:在后台存在一扫描进程:DataBlockScanner,一旦检测出问题Block,通过心跳通知NN,NN就会让DN修复此问题Block(即从副本上拷贝数据)
    Second Name node虽然在名字上看就像是第二节点,其实不是,他并不是NN的备份,只是一个SNN进程,前面我们已经引出了很多NN的容错机制,下面我们来介绍一下它的具体功能:
    这里主要有两个文件:

    fsimage:它是在NameNode启动时对整个文件系统的快照(镜像文件)
    edit logs:它是在NameNode启动后,对文件系统的改动序列(存在磁盘中)

    两个文件状态:数据是不断改动的,而NameNode是很少重启的,所以edit log是不断增大,而fsimage是比较旧的,永远也赶不上edit log文件的;
    NameNode重启或宕机那一瞬间,内存数据瞬间消失,如何才能找回数据呢?

    NameNode重启之后会先读fsimage,之前跟eidt,两者合并才能得到完整数据,这时edit log数据会比fsimage大很多,合并需要很长时间,这时就需要一个机制,尽可能想办法怎样减小你的eidt,并且让fsimage这个文件能够尽可能的保持最新的数据状态,这样的话NameNode重启的话就不需要有合并这样的影响了,它就可以从fsimage直接读数据然后启动。所以这时就引出了SecondNameNode。

    SecondNameNode作为助手节点,检查点节点,它的作用为:

    用来保存HDFS的元数据信息,比如命名空间信息、块信息等,由于这些信息是在内存的,SecondNameNode是为了考虑持久化到磁盘
    定时到NameNode去获取edit logs,并更新到fsimage[Secondary NameNode自己的fsimage]
    一旦它有了新的fsimage文件,它将其拷贝回NameNode中。(这时有两个数据一样的fsimage)
    NameNode在下次重启时会使用这个新的fsimage文件,从而减少重启的时间。

    Secondary NameNode所做的不过是在文件系统中设置一个检查点来帮助NameNode更好的工作。它不是要取代掉NameNode也不是NameNode的备份。
    NameNode把每一次改动都会存在edit log中,但是整个事件是由谁来触发的?(DataNode)
    元数据持久化的过程(SNN来完成):内存->edit log(磁盘)-> fsimage
    fsimage:多久加载一次?(重启才会加载)
    假如我们修改了数据,内存中的数据好改,但是磁盘中的镜像文件(磁盘中的镜像文件是由hadoop namenode-format生成的叫做fsimage)不好改,那么我们怎么做呢?客户端做的操作,内存中会立刻修改,同时会在磁盘中记录日志(这个日志也有名字:edits)。这样假如namenode宕机了,我们也可以根据日志记录恢复,如果数据过多,会让启动时间变长。所以namenode就会有一个助理secondary namenode,他会定期的将日志文件下载过来,而且第一次下载的时候会把镜像文件fsimage下载过来secondary namenode会有元数据计算引擎。它会把fsimage(镜像)加载到内存中变为内存元数据对象,然后元数据计算引擎会解析edits日志文件。一边加载,一边解读,一边修改元数据。等加载完之后这批数据就是比较新的了。接着secondary namenode要把元数据重新序列化成fsimage镜像文件,将其上传给namenode.这样做的话如果namenode宕机之后,它只要下载最新编号的镜像文件即可,而secondary namenode不必每次都下载镜像文件,因为它本身就拥有最新编号的镜像文件。它只需要下载最新编号的日志文件。但是是不是每次上传的日志以及镜像都会保存?当然不会,因为这样太占空间,对于镜像文件他会保留最近的两个,对于日志会多保留几个,但是过期的日志也不会马上删掉。SNN edit目录树

    NN edit目录树


    edits_inprogress文件为正在写的edit文件seen_txid文件:
    每重启一次这个数值就会再 + 1seen_txid文件记录的是edits滚动的序号,每次重启namenode时,namenode就知道要将哪些edits进行加载到内存.
    VERSION 文件 :
    各个属性的含义:
    namespaceID 是文件系统的唯一标识,在文件系统首次格式化之后生成;
    storageType 说明这个文件存储的是什么进程的数据结构信息(如果是 DataNode, 那么 storageType=DATA_NODE)
    cTime 表示NameNode 存储时间的创建时间,由于我的NameNode没有更新过,所以这里的记录值为0,以后对NameNode升级之后,cTime将会记录更新时间戳.
    layoutVersion 表示 HDFS 永久性数据结构的版本信息,只要数据结构变更,版本号也要递减,此时的HDFS也需要升级,否则磁盘仍旧是使用旧版本的数据结构,这会导致新版本的NameNode 无法使用;
    clusterID是系统生成或手动指定的集群ID,在-clusterid选项中可以使用它; (6) blockpoolID:是针对每一个Namespace所对应的blockpool的ID,上面的这个BP- 893790215-192.168.88.101-1383809616115就是在我的ns1的namespace下的存储块池的ID,这个ID包括了 其对应的NameNode节点的ip地址。

    备份过程:

    将hdfs更新记录写入一个新的文件——edits.new。将fsimage和editlog通过http协议发送至secondary namenode。将fsimage与editlog合并,生成一个新的文件——fsimage.ckpt。这步之所以要在secondary namenode中进行,是因为比较耗时,如果在namenode中进行,或导致整个系统卡顿。将生成的fsimage.ckpt通过http协议发送至namenode。重命名fsimage.ckpt为fsimage,edits.new为edits。等待下一次checkpoint触发SecondaryNameNode进行工作,一直这样循环操作。注:checkpoint触发的条件可以在core-site.xml文件中进行配置。fs.checkpoint.period表示多长时间记录一次hdfs的镜像。默认是1小时。fs.checkpoint.size表示一次记录多大的size,默认64M。模拟数据恢复hdfs文件系统删除之后的备份:删除之前hdfs文件系统上的所有的文件:

    接下来删除 dfs下的name文件:

    使用jps查看进程,发现hadoop进程还是启动着,原因是在内存中运行,可以杀死NameNode进程:

    然后手动启动namenode:hadoop-daemon.sh start namenode

    但是此时hadoop集群已经拒绝连接了,其他的机器也都是这样:

    并且在master上的namenode并没有启动成功:

    将namesecondary这个文件夹的内容全部复制到当前目录,取名叫作name

    复制好了这个namesecondary之后,再次启动namenode:

    这次能够正常启动,并且能够正常查询到hadoop集群上的hdfs文件系统上的文件,恢复了之前的样子.这两个工作目录 name 和 namesecondary 的结构是一样的.所以就可以用namesecondary来恢复.日过此时在hdfs上新建一个文件,然后把name目录删除,重复上面的恢复的步骤,那么这个新建的文件是不会恢复的,这个刚刚新建的文件还只是在日志文件里面,还没来得及做合并.namesecondary里面还没有这个元数据.所以恢复出来之后就会少一个文件.综上,namesecondary就可以做一个数据源的备份.checkpoint 的附滞作用:namenode 和 secondary namenode 的工作目录存储结构完全相同,所以,当namenode故障退出需要重新恢复时,可以从secondary namenode 的工作目录中将fsimage拷贝到namenode的工作目录,以恢复namenode的元数据.
    总结前面已经引出了部分1.0中存在的问题,总结下:

    单点故障NameSpace(命名空间的限制):由于Namenode再内存中存储所有的元数据(metadata),因此单个Namenode所能存储的对象(文件+块)数目收到Namenode所在JVM的heap(堆) size的限制。50G的heap能够存储20亿个对象,这20亿个对象支持4000个datanode,12PB的存储(假设文件爱呢平均大小为40MB)。随着数据的飞速增长,存储的需求也随之增长。单个datanode从4T增长到36T,集群的尺寸增长到8000个datanode。存储的需求从12PB增长到大于100PB。(内存的限制)
    性能的瓶颈:由于是单个Namenode的HDFS架构,因此整个HDFS文件系统的吞吐量受限于单个NameNode的吞吐量。
    隔离问题:由于HDFS仅有一个Namenode,无法隔离各个程序,因此HDFS上的一个实验程序很可能影响整个HDFS上运行的程序。
    集群的可用性:在只有一个Namenode的HDFS中,此Namenode的宕机无疑会导致整个集群的不可用。(低可用性)
    Namespace和Block Management的紧密耦合:Hadoop 1.x在Namenode中的Namespace和Block Management组合的紧密耦合关系会导致如果想要实现另外一套Namenode方案比较困难,而且也限制了其他想要直接使用块存储的应用。
    不适合小文件存储———数据块富余过多,浪费空间
    压缩文件——单独占一个split——-过大时存在问题
    内存问题—-元数据多时,内存不够存储
    不建议大量随机读(无法优化寻址时间成本),可以预读
    异步操作:速度快,不能保证数据完整性

    下面总结一下这里的可靠性保证:

    心跳机制
    副本机制
    CRC32数据校验
    DataBlockScanner
    SNN:保证元数据
    回收站:trash目录(core-site.xml设置)
    报告 命令 例:hdfs fsck /path -files - blocks -locations
    快照 命令

    HDFS 特性:

    能做什么

    存储并管理PB级数据处理非结构化数据 hive,hbase注重数据处理的吞吐量(延迟不敏感) 内存预写应用模式:write-once-read-many存取模式(无数据一致性问题)一次/user写入多次/user读取写错:通常是删除和追加不影响吞吐量
    不适合做

    存储小文件(不建议)大量随机读(不建议) 文件指针需要对文件修改(不支持)多用户写入(不支持)




    客户端调用 create()来创建文件,Distributed File System 用 RPC 调用 NameNode节点,在文件系统的命名空间中创建一个新的文件。NameNode 节点首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件。Distributed File System 返回 FSDOutputStream,客户端用于写数据。客户端开始写入数据,FSDOutputStream 将数据分成块,写入 Data Queue。Data Queue 由 DataStreamer 读取,并通知 NameNode 节点分配数据节点,用来存储数据块(每块默认复制 3块)。分配的数据节点放在一个 Pipeline 里。Data Streamer 将数据块写入 Pipeline 中的第一个数据节点。第一个数据节点将数据块发送给第二个数据节点。第二个数据节点将数据发送给第三个数据节点。DFSOutputStream 为发出去的数据块保存了 Ack Queue,等待 Pipeline 中的数据节点告知数据已经写入成功。写入一个datanode都说明写入数据成功,内部datanode会数据冗余。




    首先 Client 通过 File System 的 Open 函数打开文件,Distributed File System 用 RPC调用 NameNode 节点,得到文件的数据块信息。对于每一个数据块,NameNode 节点返回保存数据块的数据节点的地址。Distributed File System 返回 FSDataInputStream 给客户端,用来读取数据。客户端调用 stream的 read()函数开始读取数据。FSDInputStream连接保存此文件第一个数据块的最近的数据节点。DataNode 从数据节点读到客户端(client),当此数据块读取完毕时,FSDInputStream 关闭和此数据节点的连接,然后连接此文件下一个数据块的最近的数据节点。当客户端读取完毕数据的时候,调用FSDataInputStream 的 close 函数。在读取数据的过程中,如果客户端在与数据节点通信出现错误,则尝试连接包含此数据块的下一个数据节点。失败的数据节点将被记录,以后不再连接。
    同步与异步问题:

    同步:速度慢,但是可以保证全局数据一致性异步:速度快,但无法保证数据一致性—-HDFS用的就是异步操作
    本地模式

    本地模式:保证计算框架和任务调度管理部署在同一台机器上,体现本地化原则,尽量减少数据移动开销。类比后面的yarn功能把JobTracker的功能都分权了分为RM、AM。
    本地化原则针对map阶段,因为reduce阶段有个远程partition,不能保证是同一机器。

    下节我们介绍HDFS2.0原理,看看它是如何解决这些1.0中的故障问题的。这节还会持续修改
    4 留言 2019-01-23 20:15:29 奖励18点积分
  • 大数据Hadoop平台2-2、MapReduce

    前文链接
    https://write-bug.com/article/1698.html
    介绍铺垫
    开发语言:Linux、python、java、c++、sql、scala
    开发工具:Linux、Hadoop、spark、tensorflow、pytorch
    开发方式:shell、vim、IDE(idea)
    项目:推荐系统——模板,融会贯通(检索、反作弊、预测)
    重点:架构思维,思考方式,解决方法。

    在正式介绍MR之前,先铺垫一些Hadoop生态圈组件,如图所示,这些组件从下到上看,底层偏存储,上层多是计算框架,而zookeeper贯穿了整个生态。
    1.Hadoop1.0生态圈

    webserver—-给用户提供服务
    Map Reduce:存储批量、离线任务,调度很多的机器节点共同处理数据
    Storm:实时计算
    Spark:批量(spark-core)、实时(stream)、机器学习(mllib)、统计和数据计算sql
    hive(SQL引擎)—-本质:Map Reduce —封装简便工作—-非专业编程人员使用
    mahout—-本质:Map Reduce—>机器学习—封装算法库
    zookeeper—-全局锁,分布式锁服务,协调员
    Hbase—-分布式数据库,HDFS更上层的一个服务存在,本质还是存在HDFS上。
    HDFS—-相当于新硬盘格式化成各种文件系统的格式,只不过是分布式文件系统,可以存储大量的数据。

    2.常见业务搜索
    以前:人们主动去搜索内容
    现在:手机网站主动给人推荐服务:天气提醒、外卖推荐、广告推荐等。现在的人每天拿着手机滑来滑去,精神需求已经不满足于内容索引,除了这些服务推荐,市面上比较火的抖音类软件也是此推荐道理。
    名词:

    分词的每一个结果叫token音乐—>物品(item)->itemid—-网站量级base:几十万个用户—>人(user)->userid
    大数据—>用户多、物品多

    用户多:产生用户行为多(用户行为挖掘)
    用户行为:通过监控实时获取—-个性化推荐(不同user推荐不同item)
    物品多:产生大量的元数据(Metadata)
    元数据:物品的属性Schema(描述数据的数据)


    个性化推荐

    检索例子

    基于Map Reduce的建库系统(建库流)
    下载页面—>解析Parser—>倒排索引Inverter(网页包含字段)—>merger一下(归并)—>正式索引文件—>索引库里

    广告
    搜索广告:搜索后得到的广告信息
    展示广告:推送

    点击、CPM展示曝光、CPS转化

    推荐
    由此业务,大家应该可以看出不管是推荐还是搜索都是息息相关的。
    以上简单给大家介绍了Hadoop平台的生态圈和一些应用业务,后面如果有时间会掺杂一些机器学习算法(NLP、推荐、分类、聚类、神经网络等)应用在里面做出简单的推荐系统。
    重点:检索、推荐系统定位 架构层次理解
    正文内容我们在上面看到Map Reduce只是生态圈中的计算框架,而这个生态圈是Hadoop1.0的,2.0后引入Yarn概念产生了很大改变,但总要有一个过度,这里就先介绍下HDFS1.0后再介绍基于1.0的MR是什么样的,再谈及后面的2.0.
    上面的的文章我们已经介绍了早期对于大数据量(数据库分表问题Hash)和大流量请求(一致性哈希)的最简单的##分而治之##思想,那么面对大计算的情况怎么搞?
    由此引出了Map Reduce这个计算框架。
    我们通过上面的生态圈架构图很容易看出这个计算框架只是上层的一种封装,不管是输出还是输入源全部来自HDFS上,这里既然涉及到了HDFS,就简单介绍一下这个底层存储,后面会单独拉出来一篇文章介绍,其1.0和2.0有着很大区别。
    我们通过前面的文章,已经搭建体验了一下Hadoop1.0的集群,主节点为master,从节点为slave1,slave2。
    主是什么,就相当于部门的领导,从节点就是部门的员工,通常一个集群里面还有第三个角色client,是向master提交任务的,类似于公司的甲方,分配给master任务,然后master再分配给员工。
    client读取数据时,通常并不知道所要读写的数据在那台机器上,这时就要请求master获取数据真实位置,并直接和slave建立某种联系,从而读写数据,但这里面还有着很多细节,会在后面的HDFS章节讲解,这里主要是为了铺垫存储关系。
    好我们再继续介绍MR,这个要从以前的海量数据处理方式说起,原来处理数据的方式是集中式处理,也就是把海量数据不停的往同一个应用程序上挪,从而消耗了大量的时间成本在网络传输和磁盘的IO上,串行处理过大的数据量,性能低下。
    此时需要改进一下计算流程和方法,我们把程序放到各个数据节点上,根据本地化原则只map处理本地的数据,并行处理完后得到多个中间结果,再交给reduce程序把各个地方的map结果merge到reduce节点,处理完后输出到datanode上。
    map处理本地操作可以节省网络传输,在本地就可以把数据处理了.map程序适合于计算的本地化.我们的Reduce程序不能实现计算的本地化,因为是汇总map的输出,map的输出必然会分布在很多的机器上。而这里就引出了一个MR核心思想:分而治之。
    这里举一个俗气例子:数钱:假如说有很多100元50元20元的钞票杂乱的放在桌子上,我应该如何利用这种思想去快速的解决它呢,这个时候一个人去一张张数和分类就会花费很多时间还有可能出错,那么我们就多找几个人一起工作,比如找103个人,前100个人每个人只需要规整自己面前的一堆钱,并且把这堆钱按照面值分堆,然后100个人工作结束,剩下三个人进来,100个人统一把三种面值发给三个人,100个人退出,而这三个人只需要数张数然后乘面值就好了。在这个例子里:100个人只做分类工作,3个人做合并工作。也就是先切分(map)再合并(reduce)。
    上面这个例子还有一些细节:

    map:就近原则,也就是说100个人只需要处理自己面前的钱
    reduce:如果3种面值分配给5个人,就必然会导致2个人闲置的情况

    这些细节会在后面实践中有更深的体会。

    这里我画了一个图(比较丑),由这个图我们了解一下这个计算框架的执行流程:
    首先真实数据源来自我们的HDFS的各个数据块上,这里先不管是在哪个机器上,我们的input输入源进来后先通过inputformat这个接口类的两个方法:split和recordReader对数据进行切分,切成一小块一小块的数据作为真正map这个算子真正要读入的数据源,而map拿到这个数据源就相当于100个人里面的一个人拿到自己的数据去做一些归并逻辑处理并输出在自己的节点上,之后按照key作一个hash为一个partition,partition是什么意思呢,这个就相当于我们在前面把每种面值分别分配给3个人一样的过程,partition0区域全是100面值,这个区域也就相当于给了一个reduce的输入去做一些逻辑处理然后对应的做一个输出。细心如你一定会发现一个inputspilt只对应一个map,一个partition区域对应了一个output这个细节,除了这个还有涉及这些方法的作用,shuffle的其他用法,后面会一点点介绍,这里先要有一个大概的执行流程概念。

    如图所示又多了一些细节,我们这个map其实就是个程序,拿到split数据做一些逻辑处理,而每个程序任务呢在计算机系统中必然占用维护着自己的进程空间或线程空间(这里的MR任务是进程,后面学spark为线程会有一个对比),map的结果必然先写在自己的内存空间中(buffer in memory),而占用的内存空间必然是有限的,通常默认是100M,很容易就写满了,而MR通常会满80%就把数据锁住,并清空内存把这些数据转储(dump)到磁盘(disk)中(溢写),而在转储的过程中不仅仅是简简单单的存储数据了,它会在这个过程中做一个shuffle(sort、partition等等),提前排序分好了很多小的区域(三种面值),随着split数据的不断涌入,我们磁盘上多出了很多这种小区域文件了,这里就需要一次归并排序,而归并排序的前提就是前面这些小文件已经是排好序的文件,而做完归并排序后的大文件也是已经排好序的了,这个归并排序merge也就是上面说过的partition分区的过程,最后每个map都得到了这样的三个区域的大文件,在这个图中和类比前面的100人,你会发现还有很多很多的map。接着再看reduce,我们的reduce设置了固定的个数,比如说我们图上的reduce只处理100元面值钞票,这时候他只是把每台机器节点上的100元这个区域的数据硬拷贝到自己这台机器上做逻辑处理,而这时候从每台机器过来的数据就是我们reduce上的输入源的一个个小数据,通过俩俩合并成为一个大的reduce,这个reduce再去做一个计数或者什么工作,并且输出。
    我们把归并排序的过程细化,就是如图所示下面三个过程:

    这里介绍数据存储格式:partition分区号,key(面值),value(数量)

    这里介绍在map阶段本地做一个数据归并排序,本地化原则。

    这里把每一个map及其节点的相同分区文件copy到reducer任务节点上并作merge为reduce程序进程的输入源。
    在这里的开发中,我们只需要开发框架中的map和reduce逻辑代码就可以了,不需要去开发框架中的split、shuffle等等逻辑代码。map用来处理本机数据,在处理本地的数据时,不需要想我的数据存放在本机的什么位置,我要进行什么样的计算,计算结果我要放在本机的什么位置.这些东西都是由mapreduce框架给我们实现的,数据在哪,我们只需要知道hdfs就行了,数据处理之后的中间结果放在哪,这个也是mapreduce框架给我们做的,我们自己不需要管.reduce是把map输出的结果给汇总到一起,map输出的结果在哪,怎样传输到reduce中,我们开发人员也不需要管,我们只需要管数据汇总这一件事就可以了,处理之后的结果,只需要再写进hdfs中就可以了,我们的数据是放在hdfs中,hdfs决定把数据是放在哪个datanode上的,决定的权利不在于我们的处理,而是在于hdfs.到底放在哪个datanode上不需要我们去关心.———-后面HDFS映射关系会介绍位置。
    那我们现在就开发一个小的word Count示例去套用上面的框架做分析:
    map任务处理这里map收到的参数为文件的一行例如数据是:“hello lijie hello word spark scala java java java”,然后对上面的一行进行split(” “)切分,然后用context.write输出(hello ,1)(lijie ,1)(hello ,1)(word ,1)(spark ,1)(scala ,1)(java,1)(java,1)(java,1)也就是读取hdfs文件为内容,把内容中的每一行解析成一个个的键(key)值(value)对.文件总是有行的,键是字节的偏移量,值是每一行的内容,每一个键值对调用一次map函数.map函数处理输入的每一行.这里是for循环强制加1,key为word,value为数值。即自定义map函数,写自己的逻辑,对输入的key,value(把每一行解析出的key,value)处理,转换成新的key,value输出。
    上面的输出(map的中间结果)会先写到一个缓冲区里面(环形缓冲区,默认100M),当写入百分之80的时候会对里面的数据进行dump,dump的过程会对里面的数据先进行分区(partition)然后排序,如果有combiner会进行局部的combiner,之后写入运行map程序的那台服务器的本地磁盘中,如果map一直执行,那么会每满百分之80又会执行上面的过程直到map执行完成。
    上面的步骤走完之后产生了很多小的文件,然后会触发mr的文件合并,把多个文件进行合并,合并过程中又会进行排序和局部的combiner,如果定义的是2个reduce,那么最后每个map端就会生产2个分区文件,并且文件里面的内容会已经排序且局部combiner(前提是设置了combiner)
    shuffle:把我们map中的数据分发到reduce中去的一个过程(Partion, Sort, Spill, Meger, Combiner, Copy, Memery, Disk……),基本都是在map这边的。
    reduce任务处理map任务执行完成之后,reduce会从map端下载对应的文件,并且又会对下载过来的文件进行合并且排序并且会调用GroupComparator 对象(用来自定义哪些是一组的,mr程序默认key相同为同一组,但是可以自己定义GroupComparator,这样不同的key也可以进入同一个reduce方法进行处理,详情见:http://blog.csdn.net/qq_20641565/article/details/53491257)
    <group(textPair01,textPair02,textPair04),1 1 1>执行reduce方法,并且执行reduce的逻辑,执行完成之后就会调用FileOutputFormat,这个同FileInputFormat一样,同样可以自定义,也是继承FileOutPutFormat返回一个RecordWriter,这里就不过多介绍,默认是TextFileOutputFormat写入到hdfs里面整个mapreduce的执行流程就完成了,如果FileOutputFormat和FileInputFormat是默认的话,那么数据流就是:HDFS -> 本地磁盘 ->HDFS,并且多次进行IO操作,所以mr的瓶颈在于他的IO操作,只适合进行离线计算。

    在Map Reduce计算框架中呢,有两个重要的进程:JobTracker和TaskTracker。
    MapReduce是一种分布式计算模型,运行时不会在一台机器上运行,它是运行在很多的TaskTracker之上的。在我们的TaskTracker上面跑的是Map或者是Reduce Task任务。

    master : JobTracker NameNode
    slave: TaskTracker DataNode
    进程:worker

    JobTracker是主进程,TaskTracker是从进程。
    JobTracker:用来接收客户的请求并且做任务调度,然后把这个任务分配到从节点。并兼任监控的工作,监控Task Tracker的健康状态,如果有一台发生故障,Job Tracker就会把任务分配给其他Task Tracker。JobTracker一直在等待JobClient提交作业 。
    TaskTracker:是由JobTracker来派任务的,并且在本地开始进行工作,然后每隔3秒钟会发送心跳向主进程做一次工作的汇报和自身健康状况。
    Slave主动向master拉生意。

    这个图是什么意思呢?当工程师在本地机器(Job Client)上提交作业时,每提交一次任务就跟Job Tracker打一次交道,Job Tracker会返回一个id号和提交路径给Job Client,这个id就代表着我们的任务,Job Client就拿着这个id在HDFS上创建一个JobId名字的目录,这个目录里面存储的就是(Jar包、分片信息(代码)、作业配置信息),是从本地分发拷贝到HDFS上的,之后请求Job Tracker运行,Job Tracker拿到提交的需求(代码)后,这个老板就立刻制定方案(Job初始化),寻找空闲的员工机器Task Tracker工作,把HDFS上的需求数据进行分发给Task Tracker,与此同时Task Tracker在工作时也是不断地通过心跳机制汇报给Job Tracker当前的工作状态。
    Client JVM ---> JobTracker <---> TaskTracker:Child JVM以上便是Map Reduce的任务执行流程。
    MR任务调度优先级默认FIFO:very_high、high、normal,low,very low
    这里我们通过一个python_wordcount的代码例子去理解:(这里的代码是Hadoop2.6.5的环境)后面我会发2.6.5的搭建笔记。run.sh脚本中,由于我们用python开发,就必须通过Hadoop streaming的方式提交作业:
    HADOOP_CMD="/usr/local/src/hadoop-2.6.5/bin/hadoop"STREAM_JAR_PATH="/usr/local/src/hadoop-2.6.5/share/hadoop/tools/lib/hadoop-streaming-2.6.5.jar"#引入jar包提交INPUT_FILE_PATH_1="/The_Man_of_Property.txt" #HDFS的目录#INPUT_FILE_PATH_1="/a.txt"OUTPUT_PATH="/output"$HADOOP_CMD fs -rmr -skipTrash $OUTPUT_PATH #删除文件# Step 1.$HADOOP_CMD jar $STREAM_JAR_PATH \ -input $INPUT_FILE_PATH_1 \ -output $OUTPUT_PATH \ -mapper "python map_new.py" \#如何执行代码 -reducer "python red_new.py" \ -file ./map_new.py \#分发代码到HDFS的各个节点 -file ./red_new.py`
    map代码:
    import sys for line in sys.stdin: ss=line.strip().split(" ") #来了一行split以空格分隔 for word in ss: print word.strip() #获取分割后的单词并strip分割制表符换行符之类的符号
    head /文章 |python map.py这时你就会看到文章的前十行的单词被分开成一个单词独占一行显示。好,我们再回头改一下输出:
    print'\t'.join([word.strip(),'1'])再次查看你会发现,我们把每个单词的后面都强制加了个1,相当于单词就是key,1就是value。
    reduce代码:
    import syscur_word=Nonesum=0for line in sys.stdin:#标准输入map结果 ss=line.strip().split('\t') if len(ss)!=2: continue word,cnt=ss if cur_word==None: cur_word=word if cur_word!=word: print'\t'.join([word, str(sum)]) cur_word=word sum=0 sum+=int(cnt)print'\t'.join([word,str(sum)])
    单机调试Linux命令: cat /文章 |python may.py|sort -k1|python reduce.py > result.data wc -l result.data head result.data cat result.data |sort -k2 -rn|head
    单机调试成功后就可以run脚本把代码提交到集群了,不要忘了输入目录文件要先上传到集群中哦:hadoop fs -put 文件 /hdfspath
    查看Hadoop目录命令:hadoop fs -ls /查看结果:hadoop fs -text /output/part-000000 |head
    3 留言 2019-01-22 11:51:56 奖励20点积分
  • 大数据Hadoop平台2-1、Map Reduce

    Map Reduce前文链接https://write-bug.com/article/1692.html
    一、传统Hash应用流量分发MapReduce它是属于并发计算,那么可以认为MapReduce是一个海量数据分流处理技术,因为它自身是基于hadoop平台的,在hadoop生态里面它承担着一个集成框架这么核心的角色,那么它自身是可以处理大数据的。传统海量数据处理的方法就是Hash方法,什么是Hash方法呢?比方说我们要a模3,那么a模3是怎么计算的呢?(如下图所示)
    python环境命令输入:
    print a%3 得2
    传统Hash,最基本的划分方法

    如何将大数据、流量均分到N台服务器找到合理的key,hash(key)尽量分布均匀hash(key)mod N == 0 分到 第0台,hash(key)mod N == i 分到 第i台hash(key)mod N == N-1 分到 第N-1台
    随机划分
    一致性Hash:支持动态增长,更高级的划分方法

    那么这张图是什么意思呢?
    假设说我们访问一个新浪的首页,因为这个全国各地很多的人在去同时请求新浪的首页,那大家呢都是通过流量请求,瞬间或者是同一秒钟那有大量的并发进来,如果你要用同一台机器去扛这个高并发的话是很难的,很容易把这个机器给扛爆了,通常在互联网行业里面提供服务的一台机器肯定是不行的,需要多台机器进行相互合作,那么这Hash()%max下面有六条线,代表的是六台服务器集群,然后每一个数字代表一个节点,每一个节点代表一个具体的一个服务器,那这个时候如果要是前面有那么大的流量请求的话,只用一台机器是扛不住的,怎么办呢?那么需要把这个流量请求进行一个让别人来帮我共同分担,那这个时候相当于是整体的集群它承担的压力总数不变,但是每台机器上扛得压力是被均分了,使得每一个服务器它的一个压力就减少很多,这就是一个非常简单的一个负载均衡的一个原理。
    来了一个流量请求,然后我通过一定的算法,通过一定的hash方法把这个请求直接打到了相应的服务器上去,那具体我来了一个流量请求,我这个流量请求应该打到哪台服务器上去呢?就通过这么一个hash方法
    那当前来了一个流量请求,怎么知道把这个流量请求打到哪台服务器上去呢?那如果这个流量请求里面带了一个固定的数字的话那也是不行的,所以呢得对每一个流量请求会有一个随机数,通常这个随机值根据你的时间作为一个种子然后random一下,保证他的这种随机性非常均匀的一个状态,那么我们在master终端模拟一下随机数(如下图所示)

    假设说我们在随机数上面乘一个100,因为随机数乘完100以后呢,它还是一个浮点型(就是带小数点的值),那么这个时候强制的把浮点型转换为int(整数型)
    Python环境命令输入:
    print int(random.random() * 100)
    随机生成一个100以内的整数型的随机数(如下图所示)相当于我来了一个流量请求就得到一个随机的数字,而且这个随机得来的数字是非常均匀的

    刚刚上面写的余数0到5之间,那么1是代表第二台机器。那么就是比如在随机数上得到的第一个数字给第一个流量请求进行服务器的服务。
    通过这样的一个模拟,也就是说通过一个很简单的hash方法把大量的这种流量请求进行分流,其实大量的请求也就是大数据的一个场景。
    假设说来了一个流量请求,刚刚好把这个流量请求分配到第三号机器上,那就在这个时候,这个机器突然挂掉了,那既然把这个数据发送过来给第三号机器出现问题了已经死掉了,那这第三号机器就不能给你正常的提供服务了,那么相当于本次请求是一个失败的请求,那么很容易引起就是很多的请求都不能服务的到,那么对于网站来说就是一个损失,那有没有解决这样的一个问题的方法呢?答案是肯定是有的,还有一种更高级的hash方法就是:一致性hash方法。
    二、一致性hash哈希方法动态增长更高级的一个划分方法,一致性hash哈希算法设计目标是为了解决因特网中的热点(Hotspot)问题(如下图所示)

    通过这么一个页面,你可能感受不到什么是一致性哈希方法,你看到的是一个环,那对于这种比如说一个uint16,uint16的最大值是多少?我们来看一下(如下操作和下图所示)
    Python环境命令输入:
    import math //这是一个数学算法的一个模块
    Python环境命令再输入:
    print math.pow(2,16) //2的16次方
    最后得到的值是:65536,那么也就是说uint16就是一个0到65536的这么一个范围,那如果是说当前正好声明这个变量刚刚是uint16并且当前它这个赋的值就赋了一个最大值65536,那如果是再往上加一个1,那么其实它就超出了这个一个范围了,加完1之后相当于最大值变成一个最小值,这个概念在我们大家学编程的时候应该知道把?如果uint16,那你从一个最大值又加了一个1,它就会变成最小值,变成个0。所以我们发现如果我们一直对这个数字一直加的话呢相当于一个环(就如下环图所示),

    那么在这下面环图里面列的是int32类型的,int32类型负的2的31次幂到2的31次幂减一这么一个范围
    那如果是2的31次幂加1的话呢相当于是又变成它的最小值,所以你可以想象把这个数字的最大值和这个最小值首尾相接变成了这样的一个环形(如下图所示),相当于哈希方法在这么一个环形的哈希空间上然后呢同样借助刚才那种传统的哈希思想然后把相应的key然后往这个环型上进行一个映射
    第二个例子

    假设说有三台机器,这三台机器可以认为是新浪的三台不同服务器,每台机器都可以向外提供服务,然后每台机器提供服务都是一模一样的,无论你这个请求达到一个任何服务器的其中一个,得到的服务都是一样的。然后呢这三台机器对应着三台不同的ip地址(如上图所示)
    Ip1到ip3,那么我们用一个非常直观的方法来对应这三台机器,比如用一个三角形来描述这个A这台机器,四方形描述这个B这台机器,圆形描述C这台机器,代表着这三台不同的机器,但是由于这三台机器可能它部署的机房的原因或者是这三台机器自身的硬件有一定的差别,所以导致这三台机器它能够承担压力是不一样的,比如说这个三角形A这台机器它可能是32核的机器并且内存超大,那么它就可以扛得住非常大的并发请求,那么圆形C这个机器可能比较弱一点,它可能就是一个32位的一个处理器,内存小一点,它承担的这种压力是非常小的就比如我们的笔记本性能的差异,每台笔记本都有性能不同的机子。所以既然出现这么一个彼此的自身的一个差异的存在,所以我们假设ABC三台机器他们的处理能力不同,那么我们就假定说A 可以承担百分之50,B可以承担百分之30,C可以承担百分之20,就是说A这台机器是好的呢,那么我们尽量让A这台机器多干点活也就是说把更多的流量请求发到A这台机器上进行处理。那我们怎么能够去实现这么一个方案呢?那么这时候我们需要做一些个虚拟机器的创建,但是这个虚拟机器不是一个真实的存在,它只是个虚拟的一个节点,这个虚拟节点怎么虚拟呢?我们有三台机器如A,B,C然后A这台机器不是可以承担百分之50吗?那我就按照比例,5比3比2的方式假设说我由A衍生出五个不同的机器(A1到A5,如下图所示)分别是5个虚拟出来的机器,但是你去访问任何一个机器都是A来提供服务
    然后B呢衍生出3个机器(B1到B3,如下图所示)
    C呢衍生出2个机器(C1和C2,如下图所示)
    那比如说虚拟出一个三台机器,到底是通过怎么样的一个形式去描述呢?那相当于最简单的方式就是如上图所示有IP地址,可以在这IP地址可以认为是一个字符串,你可以在这字符串的节点上就加一个1,A2就是192.168.1.100_2(如下图所示)
    所以相当于你可以通过这样的一个虚拟的一个映射瞬间能达到10台不同的ip地址,然后这个时候呢你就得到了不同的10个字符串,你拥有这10个不同的字符串通过一个哈希方法或者通过一个加密方法就可以映射出一个数字出来,然后这个数字就可以在这个环上(如下图所示)找到相应的位置,那既然A这台机器拥有5台机器,那肯定是我在如下图的环上可以找到5个不同的三角形点,然后B呢就是环形图中3个四方形的点,而C呢就是环形图中2个圆形的点(如下图所示)
    从这三台不同的机器,然后一直到往这个环上进行映射整个的流程应该都明白了把?
    那这个时候呢再做一个假设,那这个数字是由着最大值变成一个最小值,那相当于在这个环上可以认为一个顺时针也好逆时针也好,只要这个顺序不变就可以,那就按照顺时针的方式去遍历,那这个时候呢假设说我有一个请求比如有一个用户叫张三进来了,他通过页面访问新浪,按了下回车,然后呢它会得到一个随机数,那这个随机数就映射到环上的随意的一个地方(如下图所示)下面三角形旁边有一个笑脸的就代表着张三,那么这ABC三台机器应该由哪台机器给他进行服务呢?顺时针嘛,从笑脸那个点开始走找到离笑脸最近的是四方形B机器,那么就由B机器来给张三提供服务。这就是非常简单的一个一致性哈希的一个思想

    相当于是我是用一台实际的一个ip地址,虚拟出了多个相互之间不会重复的一个字符串,然后来表示那些虚拟的机器。不是说这个机器A处理能力强吗?那我在环形上多建立几个A的节点,通过这样的一个方式在这个环上A的节点是不是最多啊?
    随着这种请求的流量的增大,会发现A的命中肯定是百分之50,如果要是在用哈希方法在这个环上哈希的够均匀的话,其实A承受的这种压力也就是大概是5比3比2这样的比例。
    那如果是张三或者是李四请求落到了(如下图所示)的点上

    那么你会发现C不是只有两个节点吗?所以很难去命中C的节点
    那么这就是很简单的一个一致性哈希方法。
    那这个一致性哈希方法刚才说过了,它可以弥补传统的哈希方法的不足。
    那传统哈希方法有什么不足呢?我们提到了假设说有一台机器突然挂掉了,没有办法提供服务,假设说这个B这台机器可以给张三提供服务,但是这台B机器刚刚好出现故障了,那么这个时候B这台机器在这个环上删除,删除之后呢,那接下来的B它不能提供服务了,那我该由谁来帮B服务呢?起码要有人接班嘛(如下图所示)

    那么顺时针走,发现A离自己最近,那么自然而然的就到A这台机器进行处理请求服务了
    那么这时候突然B机器修好了,那么这B机器映射好的字符串是不变的,那它又在环上做了个还原,那接下来呢如果有同样的这样流量请求达到这个区间的话呢,那么这个区间和流量仍然由这个B机器进行处理。
    所以它是一个动态的一个调节的一个方法
    后面章节正式介绍mapreduce
    2 留言 2018-11-12 15:18:57 奖励15点积分
  • 大数据1、hadoop搭建体验

    一、Linux
    熟练基本命令
    安装操作
    Nat设置

    ps:由于集群需要多个模拟系统所以网卡地址不能一样,为防止本地IP冲突,所以使用Nat虚拟IP地址
    Linux设置好IP地址
    二、Hadoop1.0集群搭建Hadoop源码包下载
    http://mirror.bit.edu.cn/apache/hadoop/common/
    2.1 集群环境
    Master 192.168.xx.10
    Slave1 192.168.xx.11
    Slave2 192.168.xx.12

    2.2 关闭系统防火墙及内核防火墙Master、Slave1、Slave2
    暂时关闭防火墙
    /etc/init.d/iptables stop查看防火墙状态
    iptables -L临时关闭内核防火墙
    setenforce 0永久关闭内核防火墙
    vim /etc/selinux/configSELINUX=disabled查看内核防火墙状态
    getenforce2.3 修改主机名Master
    vim /etc/sysconfig/networkNETWORKING=yesHOSTNAME=masterSlave1
    vim /etc/sysconfig/networkNETWORKING=yesHOSTNAME=slave1Slave2
    vim /etc/sysconfig/networkNETWORKING=yesHOSTNAME=slave22.4 修改IP地址Master、Slave1、Slave2
    vim /etc/sysconfig/network-scripts/ifcfg-eth0DEVICE=eth0HWADDR=00:50:56:89:25:3ETYPE=EthernetUUID=de38a19e-4771-4124-9792-9f4aabf27ec4ONBOOT=yesNM_CONTROLLED=yesBOOTPROTO=staticIPADDR=192.168.xx.10/11/12NETMASK=255.255.255.0GATEWAY=192.168.xx.2DNS1=#本省2.5 修改主机文件Master、Slave1、Slave2
    vim /etc/hosts192.168.xx.10 master192.168.xx.11 slave1192.168.xx.12 slave22.6 SSH互信配置Master、Slave1、Slave2
    生成密钥对(公钥和私钥)
    ssh-keygen -t rsa三次回车

    cat /root/.ssh/id_rsa.pub > /root/.ssh/authorized_keyschmod 600 /root/.ssh/authorized_keys相互追加Key
    Master
    ssh slave1 cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keysssh slave2 cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keysSlave1
    ssh master cat /root/.ssh/authorized_keys > /root/.ssh/authorized_keysSlave2
    ssh master cat /root/.ssh/authorized_keys > /root/.ssh/authorized_keys2.7 安装JDKhttp://www.oracle.com/technetwork/java/javase/downloads/index.html
    Master
    cd /usr/local/srcwget 具体已上面的链接地址为准tar zxvf jdk1.8.0_152.tar.gz2.8 配置JDK环境变量Master、Slave1、Slave2
    vim ~/.bashrcexport JAVA_HOME=/usr/local/src/jdk1.6.0_45export CLASSPATH=.:$CLASSPATH:$JAVA_HOME/libexport PATH=:$PATH:$JAVA_HOME/bin2.9 JDK拷贝到Slave主机Master
    scp -r /usr/local/src/jdk1.8.0_152 root@slave1:/usr/local/src/jdk1.8.0_152scp -r /usr/local/src/jdk1.8.0_152 root@slave2:/usr/local/src/jdk1.8.0_1522.10 下载HadoopMaster
    wget http://mirror.bit.edu.cn/apache/hadoop/common/hadoop-1.2.1/hadoop-1.2.1.tar.gztar zxvf hadoop-1.2.1.tar.gzcd hadoop-1.2.1.tar.gzmkdir tmp2.11 修改Hadoop配置文件Master
    cd confvim mastersmastervim slavesslave1slave2vim core-site.xml
    <configuration><property><name>hadoop.tmp.dir</name><value>/usr/local/src/hadoop-1.2.1/tmp</value></property><property><name>fs.default.name</name><value>hdfs://#masterip:9000</value></property></configuration>vim mapred-site.xml
    <configuration><property><name>mapred.job.tracker</name><value>http://#masterip:9001</value></property></configuration>vim hdfs-site.xml
    <configuration><property><name>dfs.replication</name><value>3</value></property></configuration>vim hadoop-env.shexport JAVA_HOME=/usr/local/src/jdk1.8.0_1522.12 配置环境变量Master、Slave1、Slave2
    vim ~/.bashrcHADOOP_HOME=/usr/local/src/hadoop-1.2.1export PATH=$PATH:$HADOOP_HOME/bin刷新环境变量
    source ~/.bashrc2.13 安装包拷贝到Slave主机Master
    scp -r /usr/local/src/hadoop-1.2.1 root@slave1:/usr/local/src/hadoop-1.2.1scp -r /usr/local/src/hadoop-1.2.1 root@slave2:/usr/local/src/hadoop-1.2.12.14 启动集群Master
    初始化NameNode
    hadoop namenode -format启动Hadoop启动Hadoop集群
    start-all.sh2.15 集群状态jps



    2.16 监控页面NameNode
    http://master:50070/dfshealth.jsp
    SecondaryNameNode
    http://master:50090/status.jsp
    DataNode
    http://slave1:50075/
    http://slave2:50075/
    JobTracker
    http://master:50030/jobtracker.jsp
    TaskTracker
    http://slave1:50060/tasktracker.jsp
    http://slave2:50060/tasktracker.jsp
    2.17 关闭集群stop-all.sh总结一下搭建遇见的坑1.1Linux系统安装时占存大小一定要选好,这个东西思想是集群式,只有在真正HDFS这种分布式存储上才能展现威力,在本地会显得慢一点
    1.2相比于桥接模式直接连接物理网络,NAT模式更加人性化解决IP冲突问题,如果想用NAT模式重新获取到本地IP对应的虚拟IP,需要从虚拟机的虚拟网络编辑器中删除NAT模式的网络并新建一个网络改为NAT模式,就会获取到新的对应IP,并且每台Linux中都需要根据这个nat网关IP从新分配静态IP,可以利用
    curl www.baidu.com测试连接外网,在srt软件中测试时乱码问题需要自己设置下(还可以设置背景和系统哦)
    1.3集群搭建还需要做到master和slave之间无密码连接(ssh互信),而阻挡连接的问题也就是iptables和selinux了,而修改主机名可以方便以后不需要再蛋疼的打IP了可以达到dns的效果
    1.4本地上传和从网上download -jdk和Hadoop包都可以,上传的话虚拟机设置选项里面有一个共享文件夹,设置后可以在/mnt/hgfs中找到然后拷贝到各个机器中(scp/cp)
    1.5Hadoop中的配置文件一共就那么几个,一定要配置好,千万不要打错字母,不然启动集群时某些任务起不来,IP都是master的IP,Hadoop1.0不像2.0一样不显示jobtracker&tasktracker

    千万不要打错字母出错的时候先检查配置文件再说
    1.6环境变量:更方便地在任何目录下使用
    3 留言 2018-11-12 11:35:44 奖励10点积分
  • 32位和64位驱动开发区别概述

    在用户层上,64 位系统为了向下兼容 32 位程序,确保 32 位程序可以正常在 64 位系统上正常运行,于是提供了 WOW64 子系统。WOW64 为现有的 32 位应用程序提供了 32 位的模拟环境,可以使大多数 32 位应用程序在无需修改的情况下运行在 64 位Windows版本上。但是,在内核层下,Windows并没有提供类似WOW64的子系统,所以,64 位内核系统只能运行 64 位的驱动程序。
    无论是用户层还是内核层程序开发,绝大部分程序功能是基于 Windows 提供的API函数接口实现的。尽管各个版本的 Windows 操作系统 API 函数内部的实现方法不尽相同,但 API 函数保持着相同的函数名称、相同的参数以及返回值。这便保证了绝大多数的程序,不需要修改源码,也不用重新编译,即可在不同版本的 Windows 上运行,保证二进制级的兼容性。所以,对于基于 API 函数接口实现的功能代码,无论是 32 位还是 64 位 Windows 系统都是兼容的。在 32 位和 64 位程序开发中,需要额外注意指针长度变化的问题。
    但是,内核层下的 Rootkit 开发与正常的开发有一个很大的不同就是,Rootkit 程序为了躲避杀软的检测,将自己做得更底层,所以就会舍弃调用 Windows 提供的API函数接口,而去调用更底层的、Windows 未公开、未文档化的函数或者结构。由于各个版本的 Windows 内核是不相同的,导致各个版本上的特征码也不相同,所以通过特定码定位地址的方式兼容性很差,需要获取各个系统版本的特征码。
    32 位和 64 位的内核开发也有很大的不同,总的来说,64 位内核增加了两大保护机制,一个是KPP(Kernel Patch Protection)内核补丁保护,另一个是DSE((Driver Signature Enforcement)驱动签名强制。KPP 保护机制利用 Patch Guard 技术来检查内核的关键内存有没有被修改,若保护区域被修改,则会触发蓝屏。其中,Patch Guard 技术保护的内存包括关键的结构体(例如 SSDT 和 GDT 等)以及关键的系统驱动内存(例如ntoskrnl.exe、ndis.sys、hal.dll等)。DSE 保护机制则是拒绝加载不包含正确签名的驱动,要求驱动程序必须正确签名方可加载运行。
    所以,要想在 64 位 Windows 内核下开发稳定运行的驱动程序,就不要触犯上述两大保护机制。当然,有保护机制出现,自然也会有相应的绕过方法。由于绕过方法已经超出了本书《WINDOWS黑客编程技术详解》的内容范围,在此就不进行介绍了。
    参考参考自《Windows黑客编程技术详解》一书
    2 留言 2018-12-07 09:31:59 奖励40点积分
  • 有关go管道,锁和dlv调试的细节分享

    在做流媒体服务时对三处细节印象深刻,特整理记录下来。
    管道中的<-简单来说就是这样子的:接受者<-发送者。
    然而中间会多个管道,所以我借用Go语言圣经中的三处例子做解释
    ch <- x // x作为发送者发送给管道x = <-ch // 管道作为发送者发送数据给接受者x<-ch // 管道发送数据,没有接收者,丢弃,同时造成管道堵塞,等待接收者
    所以我们可以具体化刚才说的发送接收流程,它应该为:接收者 <- 管道 <- 发送者。如果缺了接收者或发送者,都会造成管道堵塞。
    互斥锁举个例子
    import "sync"var (mu sync.Mutex // guards balancebalance int)func Deposit(amount int) { mu.Lock() balance = balance + amount mu.Unlock()}func Balance() int { mu.Lock() b := balance mu.Unlock() return b}
    先Lock锁住,再使用Unlock解锁。
    如果Lock中再套一个Lock,就会造成死锁,需要将前一个Lock解开才行。
    dlv调试流程1,./dlv debug xxxx(程序名) ##启动dlv调试2,r(restart) 3,c(continue)4,b(break) ##打断点,可以打函数名,也可以打文件下对应的行号5,n(next)或s(step) ##n按一次单步执行,后面只需一直按回车;遇到需要深究的函数按s进去查看##如果碰到多线程,建议在线程内打个断点6,bt(stack) ##查看堆栈7,frame ##查看指定堆栈的内容8,q(exit) ##退出调试收获
    接触一个新东西,除了保证理解了流程,还要对每个函数的作用,影响范围都要了然于胸才行;
    流程这东西,光知道不行,最好的办法是自己画个流程图出来,一步步跟着代码走;
    IDE有时会因为环境参数或内在bug而报错,所以推荐使用dlv(针对go)和gdb进行调试;
    多对自己提几个为什么,有助于理解技术的本质;
    心态放平和,坦然接受bug和不足,耐心寻求突破。
    2 留言 2019-04-06 23:59:09 奖励12点积分
  • 编程实现自定义资源释放

    背景用VS2013写一个释放资源的小程序,除了自定义的资源外,还可以释放其他类型的资源,只要是程序里的资源,使用这个小程序,都可以实现。
    这个小功能可以帮助我们把程序变得更简洁,意思是说,如果你的程序额外需要一些DLL文件、文本文件、图片文件或是其它的音视频文件等等,你都可以把它们作为资源插入到程序里,等到程序运行时,再把它们释放到本地上。这样做的好处便是,你编译出来就只有一个EXE文件,而不需要附带其它的文件,所以程序变得就很简洁。你只需把EXE发送给其他人,而不需要连同其他文件一起发送。
    那么,现在把这一程序的实现原理和过程,写成文档,分享给大家。
    插入资源到程序的步骤在讲解程序原理之前,先介绍下在使用VS2013开发程序的过程中,如何插入资源到程序里。
    我们以名为 “520” 的这个文件为例,进行讲解。

    在工程项目中,选择“添加资源(A)…”。

    如果是添加一个现成的资源文件的话,可以选择对应的资源类型。本文演示的是插入自定义资源,所以点击“自定义(C)…”按钮。

    然后,在“新建自定义资源”对话框中,输入“资源类型”,如“MYRES”。然后点击“确定”。

    然后,我们在“添加资源”对话框里,选择刚才我们新建的“MYRES”资源类型,接着点击“导入(M)…”按钮。

    选择我们之前新建的 “520” 这个文件,作为资源添加到程序里。

    然后,为 “520” 选择资源类型 “MYRES”,并点击“确定”。

    这样,自定义资源的添加就完成了。现在,我们开始讲解资源释放的原理和实现。
    主要函数介绍FindResource介绍
    函数声明
    HRSRC FindResource( HMODULE hModule, LPCWSTR lpName,LPCWSTR lpType );
    参数

    hModule:处理包含资源的可执行文件的模块。NULL值则指定模块句柄指向操作系统通常情况下创建最近过程的相关位图文件。lpName:指定资源名称。若想了解更多的信息,请参见注意部分。lpType:指定资源类型。若想了解更多的信息,请参见注意部分。作为标准资源类型。这个参数的含义同EnumResLangProc\lpType。
    返回值

    如果函数运行成功,那么返回值为指向被指定资源信息块的句柄。为了获得这些资源,将这个句柄传递给LoadResource函数。如果函数运行失败,则返回值为NULL。若想获得更多错误信息,请调用GetLastError函数。

    SizeofResource 介绍
    函数声明
    DWORD SizeofResource( HMODULE hModule, // module handle HRSRC hResInfo // resource handle );
    参数

    hModule:包合资源的可执行文件模块的句柄。hReslnfo:资源句柄。此句柄必须由函数FindResource或FindResourceEx来创建。
    返回值

    如果函数运行成功,返回值资源的字节数。如果函数运行失败,返回值为零。若想获得更多的错误信息,请调用GetLastError函数。

    LoadResource 介绍
    函数声明
    HGLOBAL LoadResource( HMODULE hModule, // module handle HRSRC hResInfo // resource handle );
    参数

    hModule:处理包合资源的可执行文件的模块句柄。若hModule为NULL,系统从当前过程中的模块中装载资源。hReslnfo:将被装载资源的句柄。它必须由函数FindResource或FindResourceEx创建。
    返回值

    如果函数运行成功,返回值是相关资源的数据的句柄。如果函数运行失败,返回值为NULL。若想获得更多的错误信息,请调用GetLastError函数。

    LockResource 介绍
    函数声明
    LPVOID LockResource( HGLOBAL hResData // handle to resource );
    参数

    hResDate:被装载的资源的句柄。函数LoadResource可以返回这个句柄。
    返回值

    如果被装载的资源被锁住了,返回值是资源第一个字节的指针;否则为NULL。

    程序实现原理Windows为方便开发人员获取程序里的资源,提供了一系列操作资源的API函数,所以,我们的程序的实现,也是基于这些API的基础上,进行操作的。

    首先,我们先定位到我们程序里的资源,主要是根据“资源类型”和“资源名称”进行定位,获取资源信息块的句柄
    然后,根据上面获取的资源信息块的句柄,把资源加载到我们程序的内存中
    接着,锁定加载到内存中的资源的内存,防止程序的其他操作影响到这块内存
    最后,我们根据资源的内存地址以及资源的大小,将资源数据保存成文件

    这样,经过上述的5个步骤,便可以定位出资源,并释放到本地磁盘上。
    程序实现BOOL FreeMyResource(UINT uiResouceName, char *lpszResourceType, char *lpszSaveFileName){ // 获取指定模块里的指定资源 HRSRC hRsrc = ::FindResource(NULL, MAKEINTRESOURCE(uiResouceName), lpszResourceType); if (NULL == hRsrc) { FreeRes_ShowError("FindResource"); return FALSE; } // 获取资源的大小 DWORD dwSize = ::SizeofResource(NULL, hRsrc); if (0 >= dwSize) { FreeRes_ShowError("SizeofResource"); return FALSE; } // 将资源加载到内存里 HGLOBAL hGlobal = ::LoadResource(NULL, hRsrc); if (NULL == hGlobal) { FreeRes_ShowError("LoadResource"); return FALSE; } // 锁定资源 LPVOID lpVoid = ::LockResource(hGlobal); if (NULL == lpVoid) { FreeRes_ShowError("LockResource"); return FALSE; } // 保存资源为文件 FILE *fp = NULL; fopen_s(&fp, lpszSaveFileName, "wb+"); if (NULL == fp) { FreeRes_ShowError("LockResource"); return FALSE; } fwrite(lpVoid, sizeof(char), dwSize, fp); fclose(fp); return TRUE;}
    程序测试我们创建一个MFC工程项目,按照上述步骤,插入资源,并调用封装好的函数,进行释放资源的测试。
    其中,调用封装好的释放资源函数部分的代码为:
    void CResourceFree_TestDlg::OnBnClickedButtonRelease(){ // TODO: 在此添加控件通知处理程序代码 char szSaveName[MAX_PATH] = "520.txt"; // 释放资源 BOOL bRet = FreeMyResource(IDR_MYRES2, "MYRES", szSaveName); if (FALSE == bRet) { ::MessageBox(NULL, "Free Resource Error!", "ERROR", MB_OK); } else { ::MessageBox(NULL, "Free Resource OK!", "OK", MB_OK); }}
    测试结果:
    当我们点击 “释放” 按钮,释放资源的时候,提示释放成功。

    然后,查看目录,本地生成 “520.txt” 文件,打开文件查看内容,与我们之前插入的 “520” 文件的内容相同。所以,资源释放成功。

    总结这个小程序并不是很复杂,只要弄清楚程序的逻辑关系,然后调用相应的API函数进行操作就可以了。
    参考参考自《Windows黑客编程技术详解》一书
    2 留言 2019-01-20 09:49:52 奖励11点积分
  • 基于myeclipse java+mysql 学生信息系统 实现验证码登录 查询 删除 修改 查看 功能。

    bean类
    package com.student.bean;public class Student { private int id; private String stuno; private String name; private String gender; private int age; public Student(int id,String stuno,String name,String gender,int age){ super(); this.id=id; this.stuno=stuno; this.name=name; this.gender=gender; this.age=age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getStuno() { return stuno; } public void setStuno(String stuno) { this.stuno = stuno; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}
    DAO层代码
    package com.student.Dao;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;import com.student.Pool.connPool;import com.student.bean.Student;public class studentDao { public List<Student> queryAll() { List<Student> list = new ArrayList<Student>(); // 1.取得连接对象 Connection conn = connPool.getConn(); PreparedStatement ps = null; ResultSet rs = null; try { ps = conn.prepareStatement("select * from ZC"); // 执行 rs = ps.executeQuery(); while (rs.next()) { list.add(new Student(rs.getInt(1), rs.getString(2), rs .getString(3), rs.getString(4), rs.getInt(5))); } } catch (SQLException e) { e.printStackTrace(); }finally{ connPool.close(rs, ps, conn); } return list; } public void delById(int id){ Connection conn = connPool.getConn(); String sql = "delete from ZC where id=?"; PreparedStatement ps = null; try { ps = conn.prepareStatement(sql); //给参数赋值 ps.setInt(1, id); // 执行 ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); }finally{ connPool.close(null, ps, conn); } } public void alterById(int id,String stuno,String name,String gender,int age){ Connection conn = connPool.getConn(); String sql = "update ZC set stuno=?,name=?,gender=?,age=? where id=?"; PreparedStatement ps = null; try { ps = conn.prepareStatement(sql); //给参数赋值 ps.setString(1, stuno); ps.setString(2, name); ps.setString(3, gender); ps.setInt(4, age); ps.setInt(5, id); // 执行 ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); }finally{ connPool.close(null, ps, conn); } } public void addstudent(int id,String stuno,String name,String gender,int age){ Connection conn = connPool.getConn(); String sql = "insert into ZC values (?,?,?,?,?)"; PreparedStatement ps = null; try { ps = conn.prepareStatement(sql); //给参数赋值 ps.setInt(1, id); ps.setString(2, stuno); ps.setString(3, name); ps.setString(4, gender); ps.setInt(5, age); // 执行 ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); }finally{ connPool.close(null, ps, conn); } } public Student queryById(int id){ String sql = "select * from ZC where id = ?"; Connection conn = null; PreparedStatement ps = null; ResultSet res = null; Student student = null; try { conn = connPool.getConn(); ps =(PreparedStatement) conn.prepareStatement(sql); ps.setInt(1, id); res = ps.executeQuery(); while(res.next()){ student = new Student(res.getInt(1),res.getString(2), res.getString(3), res.getString(4), res.getInt(5)); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try{ if(null!=res){ res.close(); } if(null!=ps){ ps.close(); } if(null!=conn){ conn.close(); } }catch(SQLException e){ e.printStackTrace(); } } return student; } }
    连接类
    package com.student.Pool;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;public class connPool { static Connection con; static String url="jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false"; static String user="root"; static String password="1196"; static{ //加载驱动 try { Class.forName("com.mysql.cj.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /* * 获取连接对象 * */ public static Connection getConn(){ Connection conn=null; try{ conn=DriverManager.getConnection(url,user,password); System.out.println("成功连接数据库"); }catch(SQLException e){ e.printStackTrace(); } return conn; } /** * 关闭连接 * @param rs * @param ps * @param conn */ public static void close(ResultSet rs, PreparedStatement ps, Connection conn) { if(rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if(ps != null) { try { ps.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } public static void main(String[] args) { System.out.println(connPool.getConn()); } }
    SERVLET
    package com.student.servlet;import java.io.IOException;import java.util.List;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.student.Dao.studentDao;import com.student.bean.Student;public class AddServlet extends HttpServlet { private static final long serialVersionUID = 1L; private studentDao dao = new studentDao(); public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); //获取参数 String idstr=request.getParameter("id"); int id = Integer.parseInt(idstr); String stuno = request.getParameter("stuno"); String name = request.getParameter("name"); String gender = request.getParameter("gender"); String agestr = request.getParameter("age"); int age = Integer.parseInt(agestr); //调用dao方法修改 dao.addstudent(id,stuno,name,gender,age); List<Student> list = dao.queryAll(); request.setAttribute("student", list); //跳转回列表页面 request.getRequestDispatcher("list.jsp").forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } public void init() throws ServletException { // Put your code here }}
    登录 jsp代码
    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <script type="text/javascript"> function reImg() { var img = document.getElementById("Img"); img.src = "image.jsp?code=" + Math.random(); } </script> <style> #main{ width:100%; height:100%; position:absolute; left:50%; top:50%; margin-left:-150px; margin-top:-100px;} </style><body> </head> <body> <div id="main"> <span style="font-size: 3em">用户登录/LOGIN</span> <br> ----------------------------------------------------------- <div style="color:red;">${errmsg }</div> <form action="UserServlet" method="post"> <table style="padding-left: 1em;"> <tr> <td>用户名:</td> <td><input type=text name=uname /> </td> </tr> <tr> <td>密 码:</td> <td><input type="password" name="upwd" /> </td> </tr> <tr> <td>验证码:</td> <td><input type="text" name="yanzhengma" /><img border=0 id="Img" src="image.jsp" alt="验证码"><a href="#" onclick="reImg();">看不清,请点击刷新</a> </td> </tr> </table> <table style="padding-left: 0.6em"> <tr> <td><input type=radio name=type value=partment>部门 <input type=radio name=type value=teacher>教师 <input type=radio name=type value=student checked>学生 <input type=radio name=type value=guest>访客</td> </tr> <tr> <td> 保存密码时间:<select name="daylength"> <option value="-1">请选择</option> <option value="3">3天</option> <option value="7">7天</option> <option value="30">30天</option> </select> <br><br> <input type="submit" value="登录" /> <input type="reset" value="重置" /> </td> </tr> </table> </form></div> </body></html>
    2 留言 2019-04-05 21:38:22 奖励5点积分
  • ring0解锁文件

    背景当我们要删除一个文件的的时候,有时候会出现“文件被占用”或是“无法删除”的提示框,这往往是由于该文件句柄已经在其它进程中打开未关闭的缘故。
    本文要介绍的是关闭在其它进程中的文件句柄,对文件进行解锁。现在,我把实现过程和原理,整理成文档,分享给大家。
    实现原理要实现对指定文件进行解锁,我们首先要做的就是获取这个文件所有被打开的文件句柄,然后在关闭这些句柄即可。那么接下来,我就对指定文件句柄的遍历以及结束文件句柄的实现原理分别进行解析。
    遍历指定文件句柄
    首先,我们使用 16 号功能调用 ZwQuerySystemInformation 函数,获取系统上所有的句柄数据。其中,ZwQuerySystemInformation 是一个未导出的内核函数,16号功能即 SystemHandleInformation 功能,用来获取系统上的所有句柄信息,根据 SYSTEM_HANDLE_INFORMATION 结构体来获取返回的数据信息。
    然后,遍历系统上每一个句柄并进行判断。
    1> 首先,我们可以从上述 16 号功能中获取到句柄对应进程 ID 的信息,这样,可以先调用 ZwOpenProcess 打开句柄所在的进程;
    2> 然后,调用 ZwDuplicateObject 函数将已打开进程中的文件句柄复制到当前进程 NtCurrentProcess 中;
    3> 接着,使用1 号功能调用 ZwQueryObject 函数获取句柄的类型和名称;
    4> 最后,根据句柄对应的文件名称判断是否是要解锁的文件,若是,则开始对文件进行解锁;若不是,则继续对下一个句柄进行判断。
    最后,释放内存。

    结束指定文件句柄
    首先,我们根据要解锁的文件句柄对应的进程ID,调用内核函数 PsLookupProcessByProcessId 来获取进程结构对象 EPROCESS;
    然后,调用 KeStackAttachProcess 附件到目标进程中;
    接着,调用未导出函数 ObSetHandleAttributes 函数,对文件句柄的属性进行设置,将其文件句柄设置为“可以关闭”;
    接着,调用 ZwClose 函数,关闭文件句柄;
    最后,调用 KeUnstackDetachProcess 结束附加到目标进程。

    编码实现获取并遍历系统上所有句柄// 遍历句柄, 解锁文件BOOLEAN Unlockfile(UNICODE_STRING ustrUnlockFileName){ NTSTATUS status = STATUS_SUCCESS; SYSTEM_HANDLE_INFORMATION tempSysHandleInfo = {0}; PSYSTEM_HANDLE_INFORMATION pSysHandleInfo = NULL; ULONG ulSysHandleInfoSize = 0; ULONG ulReturnLength = 0; ULONGLONG ullSysHandleCount = 0; PSYSTEM_HANDLE_TABLE_ENTRY_INFO pSysHandleTableEntryInfo = NULL; ULONGLONG i = 0; BOOLEAN bRet = FALSE; // 调用ZwQuerySystemInformation的16号功能来枚举系统里的句柄 // 先获取缓冲区大小 ZwQuerySystemInformation(16, &tempSysHandleInfo, sizeof(tempSysHandleInfo), &ulSysHandleInfoSize); if (0 >= ulSysHandleInfoSize) { ShowError("ZwQuerySystemInformation", 0); return FALSE; } DbgPrint("ulSysHandleInfoSize=%d\n", ulSysHandleInfoSize); // 申请缓冲区内存 pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION)ExAllocatePool(NonPagedPool, ulSysHandleInfoSize); if (NULL == pSysHandleInfo) { ShowError("ExAllocatePool", 0); return FALSE; } RtlZeroMemory(pSysHandleInfo, ulSysHandleInfoSize); // 获取系统中所有句柄的信息 status = ZwQuerySystemInformation(16, pSysHandleInfo, ulSysHandleInfoSize, &ulReturnLength); if (!NT_SUCCESS(status)) { ExFreePool(pSysHandleInfo); ShowError("ZwQuerySystemInformation", status); return FALSE; } // 获取系统所有句柄数量以及句柄信息数组 ullSysHandleCount = pSysHandleInfo->NumberOfHandles; pSysHandleTableEntryInfo = pSysHandleInfo->Handles; // 开始遍历系统上所有句柄 for (i = 0; i < ullSysHandleCount; i++) { // 获取句柄信息并判断是否是解锁文件句柄 bRet = IsUnlockFileHandle(pSysHandleTableEntryInfo[i], ustrUnlockFileName); if (bRet) { // 关闭文件句柄, 解锁文件 CloseFileHandle(pSysHandleTableEntryInfo[i]); // 显示 DbgPrint("[UnlockFile][%d][%d]\n", pSysHandleTableEntryInfo[i].UniqueProcessId, pSysHandleTableEntryInfo[i].HandleValue); } } // 释放 ExFreePool(pSysHandleInfo);}
    获取句柄信息并判断是否是解锁文件句柄// 获取句柄信息并判断是否是解锁文件句柄BOOLEAN IsUnlockFileHandle(SYSTEM_HANDLE_TABLE_ENTRY_INFO sysHandleTableEntryInfo, UNICODE_STRING ustrUnlockFileName){ NTSTATUS status = STATUS_SUCCESS; CLIENT_ID clientId = { 0 }; OBJECT_ATTRIBUTES objectAttributes = { 0 }; HANDLE hSourceProcess = NULL; HANDLE hDupObj = NULL; POBJECT_NAME_INFORMATION pObjNameInfo = NULL; ULONG ulObjNameInfoSize = 0; BOOLEAN bRet = FALSE; WCHAR wszSrcFile[FILE_PATH_MAX_NUM] = { 0 }; WCHAR wszDestFile[FILE_PATH_MAX_NUM] = { 0 }; // 根据句柄对应的PID打开进程获取句柄对应的进程句柄 do { InitializeObjectAttributes(&objectAttributes, NULL, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); RtlZeroMemory(&clientId, sizeof(clientId)); clientId.UniqueProcess = sysHandleTableEntryInfo.UniqueProcessId; status = ZwOpenProcess(&hSourceProcess, PROCESS_ALL_ACCESS, &objectAttributes, &clientId); if (!NT_SUCCESS(status)) { ShowError("ZwOpenProcess", status); break; } // 将已打开进程中的文件句柄复制到当前进程 NtCurrentProcess 中 status = ZwDuplicateObject(hSourceProcess, sysHandleTableEntryInfo.HandleValue, NtCurrentProcess(), &hDupObj, PROCESS_ALL_ACCESS, 0, DUPLICATE_SAME_ACCESS); if (!NT_SUCCESS(status)) { ShowError("ZwDuplicateObject", status); break; } // 查询句柄的名称信息 // 先获取缓冲区大小 ZwQueryObject(hDupObj, 1, NULL, 0, &ulObjNameInfoSize); if (0 >= ulObjNameInfoSize) { ShowError("ZwQueryObject", 0); break; } // 申请缓冲区内存 pObjNameInfo = ExAllocatePool(NonPagedPool, ulObjNameInfoSize); if (NULL == pObjNameInfo) { ShowError("ExAllocatePool", 0); break; } RtlZeroMemory(pObjNameInfo, ulObjNameInfoSize); // 获取句柄名称类型信息 status = ZwQueryObject(hDupObj, 1, pObjNameInfo, ulObjNameInfoSize, &ulObjNameInfoSize); if (!NT_SUCCESS(status)) { ShowError("ZwQueryObject", 0); break; } // 判断是否要解锁的文件 DbgPrint("[File]%wZ\n", &pObjNameInfo->Name); RtlZeroMemory(wszSrcFile, FILE_PATH_MAX_NUM*sizeof(WCHAR)); RtlZeroMemory(wszDestFile, FILE_PATH_MAX_NUM*sizeof(WCHAR)); RtlCopyMemory(wszSrcFile, pObjNameInfo->Name.Buffer, pObjNameInfo->Name.Length); RtlCopyMemory(wszDestFile, ustrUnlockFileName.Buffer, ustrUnlockFileName.Length); if (NULL != wcsstr(wszSrcFile, wszDestFile)) { bRet = TRUE; break; } } while (FALSE); // 释放 if (NULL != pObjNameInfo) { ExFreePool(pObjNameInfo); } if (NULL != hDupObj) { ZwClose(hDupObj); } if (NULL != hSourceProcess) { ZwClose(hSourceProcess); } return bRet;}
    关闭文件句柄// 关闭文件句柄, 解锁文件BOOLEAN CloseFileHandle(SYSTEM_HANDLE_TABLE_ENTRY_INFO sysHandleTableEntryInfo){ NTSTATUS status = STATUS_SUCCESS; PEPROCESS pEProcess = NULL; HANDLE hFileHandle = NULL; KAPC_STATE apcState = { 0 }; OBJECT_HANDLE_FLAG_INFORMATION objectHandleFlagInfo = { 0 }; // 获取文件句柄 hFileHandle = sysHandleTableEntryInfo.HandleValue; // 获取文件句柄对应的进程结构对象EPROCESS status = PsLookupProcessByProcessId(sysHandleTableEntryInfo.UniqueProcessId, &pEProcess); if (!NT_SUCCESS(status)) { ShowError("PsLookupProcessByProcessId", status); return FALSE; } // 附加到文件句柄对应的进程空间 KeStackAttachProcess(pEProcess, &apcState); // 将文件句柄的属性设置为“可以关闭” objectHandleFlagInfo.Inherit = 0; objectHandleFlagInfo.ProtectFromClose = 0; ObSetHandleAttributes((HANDLE)hFileHandle, &objectHandleFlagInfo, KernelMode); // 关闭文件句柄 ZwClose((HANDLE)hFileHandle); // 结束进程附加 KeUnstackDetachProcess(&apcState); return TRUE;}
    程序测试在 Win7 32 位系统下,驱动程序正常执行:

    在 Win8.1 32 位系统下,驱动程序正常执行:

    在 Win10 32 位系统下,驱动程序正常执行:

    在 Win7 64 位系统下,驱动程序正常执行:

    在 Win8.1 64 位系统下,驱动程序正常执行:

    在 Win10 64 位系统下,驱动程序正常执行:

    总结对于这个程序的实现,关键是要获取系统上所有的句柄,并对句柄进行判断,判断哪些句柄是指定文件的句柄。在获取文件句柄信息之后,我们就可以通过进程附加,结束文件句柄即可。
    所以,大家要着重理解句柄遍历的实现过程。
    参考参考自《Windows黑客编程技术详解》一书
    2 留言 2019-04-04 16:33:40 奖励10点积分
  • 枚举并删除系统上CmRegisterCallback回调

    背景我们学习内核 Rootkit 编程,那么肯定会接触到各种无 HOOK 回调函数的设置,这些回调函数都是官方为我们做好的接口,我们直接调用就好。这些回调使用方便,运行在底层,功能强大,而且非常稳定。很多杀软、游戏保护等就是设置这些回调,实现对计算机的监控的。
    既然可以设置回调,自然也可以删除回调。如果是自己程序设置的回调,当然可以很容易删除。但是,我们要做的是要枚举系统上存在的回调,不管是不是自己程序创建的,然后,并对这些回调进行删除,使其失效。
    本文要介绍的是枚举并删除系统上 CmRegisterCallback 回调,支持 32 位和 64 位、Win7 到 Win10 全平台系统。现在,我把实现的过程和原理整理成文档,分享给大家。
    实现原理我们注册的注册表回调,会存储在一个表头为 CallbackListHead 的双向链表里,它存储着系统里所有 CmRegisterCallback 注册表回调函数地址和 Cookie 的信息。
    经过使用 WinDbg 逆向,总结得出 CallbackListHead 双向链表指向的数据结构为:
    typedef struct _CM_NOTIFY_ENTRY { LIST_ENTRY ListEntryHead; ULONG UnKnown1; ULONG UnKnown2; LARGE_INTEGER Cookie; PVOID Context; PVOID Function; }CM_NOTIFY_ENTRY, *PCM_NOTIFY_ENTRY;
    其中,ListEntryHead 中存储着下一个或者上一个 CM_NOTIFY_ENTRY 结构体指针的信息,我们通过遍历这个双向链表,就可以枚举出 CmRegisterCallback 注册表回调函数地址和 Cookie 的信息。
    CallbackListHead 表头地址的获取CallbackListHead 表头,可以从内核导出函数 CmUnRegisterCallback 中获取。 我们借助 WinDbg 帮助我们逆向 CmUnRegisterCallback 内核函数,下面是 Win10 64 位系统上 CmUnRegisterCallback 函数的逆向代码:
    nt!CmUnRegisterCallback+0x44:fffff800`24b17dc8 4533c0 xor r8d,r8dfffff800`24b17dcb 488d542438 lea rdx,[rsp+38h]fffff800`24b17dd0 488d0d39f5dbff lea rcx,[nt!CallbackListHead (fffff800`248d7310)]
    由上面的代码,我们可以通过在内核函数 CmUnRegisterCallback 中扫描内存特征码,在 32 位系统下,可以直接定位得到 CallbackListHead 表头的地址;在 64 位下,可以获取 CallbackListHead 表头的偏移,从而根据偏移计算出地址。但是,特征码在不同系统上也会不同,下面是我使用 WinDbg 逆向各个版本系统上的函数,总结的特征码:




    Win7
    win8.1
    win10




    32 位
    BF
    BE
    B9


    64 位
    488D54
    488D0D
    488D0D



    上述中,Win7 64 位的逆向信息如下:
    nt!CmUnRegisterCallback+0xc6:fffff800`042b7856 4533c0 xor r8d,r8dfffff800`042b7859 488d542420 lea rdx,[rsp+20h]fffff800`042b785e 488d0d6b69dcff lea rcx,[nt!CallbackListHead (fffff800`0407e1d0)]
    特征码我们选用的是 488D54,因为特征码 488D0D 在出现 CallbackListHead 内存之前就多次出现,为了特征码唯一,所以,选取 488D54 特征码来定位。
    总的来说,我们直接通过扫描 CmUnRegisterCallback 函数内存,就可获取 CallbackListHead 表头地址了。其中,特征码的确定就变得至关重要。
    删除回调我们可以通过上述介绍的方法,枚举系统中的回调函数。那么,要删除回调函数可以有 3 种方式:

    可以直接调用 CmUnRegisterCallback 函数,传入回调 Cookie,即可删除回调
    修改 CallbackListHead 双向链表中的数据,使其指向我们自己定义的空回调函数地址。这样,当触发回调函数的时候,执行的是我们自己的空回调函数
    修改回调函数的前几字节内存数据,写入直接返回指令 RET,不进行任何操作

    编码实现遍历回调// 遍历回调BOOLEAN EnumCallback(){ ULONG i = 0; PVOID pCallbackListHeadAddress = NULL; PCM_NOTIFY_ENTRY pNotifyEntry = NULL; // 获取 CallbackListHead 链表地址 pCallbackListHeadAddress = GetCallbackListHead(); if (NULL == pCallbackListHeadAddress) { DbgPrint("GetCallbackListHead Error!\n"); return FALSE; } DbgPrint("pCallbackListHeadAddress=0x%p\n", pCallbackListHeadAddress); // 开始遍历双向链表 pNotifyEntry = (PCM_NOTIFY_ENTRY)pCallbackListHeadAddress; do { // 判断 pNotifyEntry 地址是否有效 if (FALSE == MmIsAddressValid(pNotifyEntry)) { break; } // 判断 回调函数 地址是否有效 if (MmIsAddressValid(pNotifyEntry->Function)) { // 显示 DbgPrint("CallbackFunction=0x%p, Cookie=0x%I64X\n", pNotifyEntry->Function, pNotifyEntry->Cookie.QuadPart); } // 获取下一链表 pNotifyEntry = (PCM_NOTIFY_ENTRY)pNotifyEntry->ListEntryHead.Flink; } while (pCallbackListHeadAddress != (PVOID)pNotifyEntry); return TRUE;}
    移除回调// 移除回调NTSTATUS RemoveCallback(LARGE_INTEGER Cookie){ NTSTATUS status = CmUnRegisterCallback(Cookie); if (!NT_SUCCESS(status)) { ShowError("CmUnRegisterCallback", status); } return status;}
    获取 CallbackListHead 链表地址// 获取 CallbackListHead 链表地址PVOID GetCallbackListHead(){ PVOID pCallbackListHeadAddress = NULL; RTL_OSVERSIONINFOW osInfo = { 0 }; UCHAR pSpecialData[50] = { 0 }; ULONG ulSpecialDataSize = 0; LONG lSpecialOffset = 0; // 获取系统版本信息, 判断系统版本 RtlGetVersion(&osInfo); if (6 == osInfo.dwMajorVersion) { if (1 == osInfo.dwMinorVersion) { // Win7#ifdef _WIN64 // 64 位 // 488D54 pSpecialData[0] = 0x48; pSpecialData[1] = 0x8D; pSpecialData[2] = 0x54; ulSpecialDataSize = 3; lSpecialOffset = 5;#else // 32 位 // BF pSpecialData[0] = 0xBF; ulSpecialDataSize = 1;#endif } else if (2 == osInfo.dwMinorVersion) { // Win8#ifdef _WIN64 // 64 位#else // 32 位#endif } else if (3 == osInfo.dwMinorVersion) { // Win8.1#ifdef _WIN64 // 64 位 // 488D0D pSpecialData[0] = 0x48; pSpecialData[1] = 0x8D; pSpecialData[2] = 0x0D; ulSpecialDataSize = 3;#else // 32 位 // BE pSpecialData[0] = 0xBE; ulSpecialDataSize = 1;#endif } } else if (10 == osInfo.dwMajorVersion) { // Win10#ifdef _WIN64 // 64 位 // 488D0D pSpecialData[0] = 0x48; pSpecialData[1] = 0x8D; pSpecialData[2] = 0x0D; ulSpecialDataSize = 3;#else // 32 位 // B9 pSpecialData[0] = 0xB9; ulSpecialDataSize = 1;#endif } // 根据特征码获取地址 pCallbackListHeadAddress = SearchCallbackListHead(pSpecialData, ulSpecialDataSize, lSpecialOffset); return pCallbackListHeadAddress;}
    根据特征码获取 CallbackListHead 链表地址// 根据特征码获取 CallbackListHead 链表地址PVOID SearchCallbackListHead(PUCHAR pSpecialData, ULONG ulSpecialDataSize, LONG lSpecialOffset){ UNICODE_STRING ustrFuncName; PVOID pAddress = NULL; LONG lOffset = 0; PVOID pCmUnRegisterCallback = NULL; PVOID pCallbackListHead = NULL; // 先获取 CmUnRegisterCallback 函数地址 RtlInitUnicodeString(&ustrFuncName, L"CmUnRegisterCallback"); pCmUnRegisterCallback = MmGetSystemRoutineAddress(&ustrFuncName); if (NULL == pCmUnRegisterCallback) { ShowError("MmGetSystemRoutineAddress", 0); return pCallbackListHead; } // 然后, 查找 PspSetCreateProcessNotifyRoutine 函数地址 pAddress = SearchMemory(pCmUnRegisterCallback, (PVOID)((PUCHAR)pCmUnRegisterCallback + 0xFF), pSpecialData, ulSpecialDataSize); if (NULL == pAddress) { ShowError("SearchMemory", 0); return pCallbackListHead; } // 获取地址#ifdef _WIN64 // 64 位先获取偏移, 再计算地址 lOffset = *(PLONG)((PUCHAR)pAddress + lSpecialOffset); pCallbackListHead = (PVOID)((PUCHAR)pAddress + lSpecialOffset + sizeof(LONG) + lOffset);#else // 32 位直接获取地址 pCallbackListHead = *(PVOID *)((PUCHAR)pAddress + lSpecialOffset);#endif return pCallbackListHead;}
    指定内存区域的特征码扫描// 指定内存区域的特征码扫描PVOID SearchMemory(PVOID pStartAddress, PVOID pEndAddress, PUCHAR pMemoryData, ULONG ulMemoryDataSize){ PVOID pAddress = NULL; PUCHAR i = NULL; ULONG m = 0; // 扫描内存 for (i = (PUCHAR)pStartAddress; i < (PUCHAR)pEndAddress; i++) { // 判断特征码 for (m = 0; m < ulMemoryDataSize; m++) { if (*(PUCHAR)(i + m) != pMemoryData[m]) { break; } } // 判断是否找到符合特征码的地址 if (m >= ulMemoryDataSize) { // 找到特征码位置, 获取紧接着特征码的下一地址 pAddress = (PVOID)(i + ulMemoryDataSize); break; } } return pAddress;}
    程序测试在 Win7 32 位系统下,驱动程序正常执行:

    在 Win8.1 32 位系统下,驱动程序正常执行:

    在 Win10 32 位系统下,驱动程序正常执行:

    在 Win7 64 位系统下,驱动程序正常执行:

    在 Win8.1 64 位系统下,驱动程序正常执行:

    在 Win10 64 位系统下,驱动程序正常执行:

    总结要理解清楚获取 CallbackListHead 表头地址的流程,其中,不同系统的内存特征码是不同的,要注意区分。大家也不用记忆这些特征码,如果需要用到,可以随时使用 WinDbg 来进行逆向查看就好。
    删除回调常用就有 3 种方式,自己根据需要选择一种使用即可。
    参考参考自《Windows黑客编程技术详解》一书
    附录Win7 32 位 CmUnRegisterCallbacklkd> uf CmUnRegisterCallbacknt!CmUnRegisterCallback:840b0791 6a38 push 38h840b0793 683082e683 push offset nt! ?? ::FNODOBFM::`string'+0x57a0 (83e68230)840b0798 e8ebe5ddff call nt!_SEH_prolog4 (83e8ed88)840b079d c745d80d0000c0 mov dword ptr [ebp-28h],0C000000Dh840b07a4 33f6 xor esi,esi840b07a6 8975b8 mov dword ptr [ebp-48h],esi840b07a9 33c0 xor eax,eax840b07ab 8d7dbc lea edi,[ebp-44h]840b07ae ab stos dword ptr es:[edi]840b07af ab stos dword ptr es:[edi]840b07b0 c645e201 mov byte ptr [ebp-1Eh],1840b07b4 b101 mov cl,1840b07b6 ff155c01e183 call dword ptr [nt!_imp_KfRaiseIrql (83e1015c)]840b07bc 8ad8 mov bl,al840b07be b80098f783 mov eax,offset nt!CallbackUnregisterLock (83f79800)840b07c3 8bc8 mov ecx,eax840b07c5 f00fba3100 lock btr dword ptr [ecx],0840b07ca 7209 jb nt!CmUnRegisterCallback+0x44 (840b07d5)nt!CmUnRegisterCallback+0x3b:840b07cc 8bf0 mov esi,eax840b07ce e850f0d8ff call nt!KiAcquireFastMutex (83e3f823)840b07d3 33f6 xor esi,esint!CmUnRegisterCallback+0x44:840b07d5 64a124010000 mov eax,dword ptr fs:[00000124h]840b07db a30498f783 mov dword ptr [nt!CallbackUnregisterLock+0x4 (83f79804)],eax840b07e0 0fb6c3 movzx eax,bl840b07e3 a31c98f783 mov dword ptr [nt!CallbackUnregisterLock+0x1c (83f7981c)],eax840b07e8 c745c49cffffff mov dword ptr [ebp-3Ch],0FFFFFF9Ch840b07ef 834dc8ff or dword ptr [ebp-38h],0FFFFFFFFh840b07f3 8975d4 mov dword ptr [ebp-2Ch],esi840b07f6 64a124010000 mov eax,dword ptr fs:[00000124h]840b07fc 66ff8884000000 dec word ptr [eax+84h]840b0803 bbfc97f783 mov ebx,offset nt!CallbackListLock (83f797fc)840b0808 8bc3 mov eax,ebx840b080a f00fba2800 lock bts dword ptr [eax],0840b080f 7307 jae nt!CmUnRegisterCallback+0x87 (840b0818)nt!CmUnRegisterCallback+0x80:840b0811 8bcb mov ecx,ebx840b0813 e8b612dfff call nt!ExfAcquirePushLockExclusive (83ea1ace)nt!CmUnRegisterCallback+0x87:840b0818 c645e301 mov byte ptr [ebp-1Dh],1840b081c 56 push esi840b081d 8d4dd4 lea ecx,[ebp-2Ch]840b0820 bff097f783 mov edi,offset nt!CallbackListHead (83f797f0)840b0825 8bc7 mov eax,edi840b0827 e8221cf3ff call nt!CmListGetNextElement (83fe244e)840b082c 8bd0 mov edx,eax840b082e 8955dc mov dword ptr [ebp-24h],edx840b0831 3bd6 cmp edx,esi840b0833 750a jne nt!CmUnRegisterCallback+0xad (840b083f)nt!CmUnRegisterCallback+0xa4:840b0835 e9c1000000 jmp nt!CmUnRegisterCallback+0x163 (840b08fb)nt!CmUnRegisterCallback+0xaa:840b083c 8b55dc mov edx,dword ptr [ebp-24h]nt!CmUnRegisterCallback+0xad:840b083f 8b4210 mov eax,dword ptr [edx+10h]840b0842 3b4508 cmp eax,dword ptr [ebp+8]840b0845 7508 jne nt!CmUnRegisterCallback+0xbd (840b084f)nt!CmUnRegisterCallback+0xb5:840b0847 8b4214 mov eax,dword ptr [edx+14h]840b084a 3b450c cmp eax,dword ptr [ebp+0Ch]840b084d 741d je nt!CmUnRegisterCallback+0xd4 (840b086c)nt!CmUnRegisterCallback+0xbd:840b084f 56 push esi840b0850 8d4dd4 lea ecx,[ebp-2Ch]840b0853 8bc7 mov eax,edi840b0855 e8f41bf3ff call nt!CmListGetNextElement (83fe244e)840b085a 8945dc mov dword ptr [ebp-24h],eax840b085d 3bc6 cmp eax,esi840b085f 0f8496000000 je nt!CmUnRegisterCallback+0x163 (840b08fb)nt!CmUnRegisterCallback+0xd3:840b0865 ebd5 jmp nt!CmUnRegisterCallback+0xaa (840b083c)nt!CmUnRegisterCallback+0xd4:840b086c 8b02 mov eax,dword ptr [edx]840b086e 8b4a04 mov ecx,dword ptr [edx+4]840b0871 8901 mov dword ptr [ecx],eax840b0873 894804 mov dword ptr [eax+4],ecx840b0876 8b4208 mov eax,dword ptr [edx+8]840b0879 eb79 jmp nt!CmUnRegisterCallback+0x15c (840b08f4)nt!CmUnRegisterCallback+0xe3:840b087b 807de300 cmp byte ptr [ebp-1Dh],0840b087f 7462 je nt!CmUnRegisterCallback+0x14b (840b08e3)nt!CmUnRegisterCallback+0xe9:840b0881 8b0dfc97f783 mov ecx,dword ptr [nt!CallbackListLock (83f797fc)]840b0887 8bc1 mov eax,ecx840b0889 83e0f0 and eax,0FFFFFFF0h840b088c 83f810 cmp eax,10h840b088f 7605 jbe nt!CmUnRegisterCallback+0xfe (840b0896)nt!CmUnRegisterCallback+0xf9:840b0891 8d41f0 lea eax,[ecx-10h]840b0894 eb02 jmp nt!CmUnRegisterCallback+0x100 (840b0898)nt!CmUnRegisterCallback+0xfe:840b0896 33c0 xor eax,eaxnt!CmUnRegisterCallback+0x100:840b0898 f6c102 test cl,2840b089b 750e jne nt!CmUnRegisterCallback+0x113 (840b08ab)nt!CmUnRegisterCallback+0x105:840b089d 8bd0 mov edx,eax840b089f 8bfb mov edi,ebx840b08a1 8bc1 mov eax,ecx840b08a3 f00fb117 lock cmpxchg dword ptr [edi],edx840b08a7 3bc1 cmp eax,ecx840b08a9 7407 je nt!CmUnRegisterCallback+0x11a (840b08b2)nt!CmUnRegisterCallback+0x113:840b08ab 8bcb mov ecx,ebx840b08ad e8de2fe1ff call nt!ExfReleasePushLock (83ec3890)nt!CmUnRegisterCallback+0x11a:840b08b2 648b0d24010000 mov ecx,dword ptr fs:[124h]840b08b9 8d8184000000 lea eax,[ecx+84h]840b08bf 66ff00 inc word ptr [eax]840b08c2 0fb700 movzx eax,word ptr [eax]840b08c5 663bc6 cmp ax,si840b08c8 7515 jne nt!CmUnRegisterCallback+0x147 (840b08df)nt!CmUnRegisterCallback+0x132:840b08ca 8d4140 lea eax,[ecx+40h]840b08cd 3900 cmp dword ptr [eax],eax840b08cf 740e je nt!CmUnRegisterCallback+0x147 (840b08df)nt!CmUnRegisterCallback+0x139:840b08d1 6639b186000000 cmp word ptr [ecx+86h],si840b08d8 7505 jne nt!CmUnRegisterCallback+0x147 (840b08df)nt!CmUnRegisterCallback+0x142:840b08da e8a663d8ff call nt!KiCheckForKernelApcDelivery (83e36c85)nt!CmUnRegisterCallback+0x147:840b08df c645e300 mov byte ptr [ebp-1Dh],0nt!CmUnRegisterCallback+0x14b:840b08e3 8d45c4 lea eax,[ebp-3Ch]840b08e6 50 push eax840b08e7 56 push esi840b08e8 56 push esi840b08e9 e831b8ddff call nt!KeDelayExecutionThread (83e8c11f)840b08ee 8b45dc mov eax,dword ptr [ebp-24h]840b08f1 8b4008 mov eax,dword ptr [eax+8]nt!CmUnRegisterCallback+0x15c:840b08f4 85c0 test eax,eax840b08f6 7583 jne nt!CmUnRegisterCallback+0xe3 (840b087b)nt!CmUnRegisterCallback+0x160:840b08f8 8975d8 mov dword ptr [ebp-28h],esint!CmUnRegisterCallback+0x163:840b08fb 89350498f783 mov dword ptr [nt!CallbackUnregisterLock+0x4 (83f79804)],esi840b0901 8a1d1c98f783 mov bl,byte ptr [nt!CallbackUnregisterLock+0x1c (83f7981c)]840b0907 33c9 xor ecx,ecx840b0909 41 inc ecx840b090a ba0098f783 mov edx,offset nt!CallbackUnregisterLock (83f79800)840b090f 8bc2 mov eax,edx840b0911 f00fc108 lock xadd dword ptr [eax],ecx840b0915 85c9 test ecx,ecx840b0917 7423 je nt!CmUnRegisterCallback+0x1a4 (840b093c)nt!CmUnRegisterCallback+0x181:840b0919 f6c102 test cl,2840b091c 751e jne nt!CmUnRegisterCallback+0x1a4 (840b093c)nt!CmUnRegisterCallback+0x186:840b091e 41 inc ecx840b091f 8d41fe lea eax,[ecx-2]840b0922 8bf0 mov esi,eax840b0924 8bc1 mov eax,ecx840b0926 f00fb132 lock cmpxchg dword ptr [edx],esi840b092a 3bc1 cmp eax,ecx840b092c 750e jne nt!CmUnRegisterCallback+0x1a4 (840b093c)nt!CmUnRegisterCallback+0x196:840b092e 6a00 push 0840b0930 6a01 push 1840b0932 680c98f783 push offset nt!CallbackUnregisterLock+0xc (83f7980c)840b0937 e8d959ddff call nt!KeSetEvent (83e86315)nt!CmUnRegisterCallback+0x1a4:840b093c 8acb mov cl,bl840b093e ff155801e183 call dword ptr [nt!_imp_KfLowerIrql (83e10158)]840b0944 807de301 cmp byte ptr [ebp-1Dh],1840b0948 7565 jne nt!CmUnRegisterCallback+0x217 (840b09af)nt!CmUnRegisterCallback+0x1b2:840b094a 8b0dfc97f783 mov ecx,dword ptr [nt!CallbackListLock (83f797fc)]840b0950 8bc1 mov eax,ecx840b0952 83e0f0 and eax,0FFFFFFF0h840b0955 83f810 cmp eax,10h840b0958 7605 jbe nt!CmUnRegisterCallback+0x1c7 (840b095f)nt!CmUnRegisterCallback+0x1c2:840b095a 8d41f0 lea eax,[ecx-10h]840b095d eb02 jmp nt!CmUnRegisterCallback+0x1c9 (840b0961)nt!CmUnRegisterCallback+0x1c7:840b095f 33c0 xor eax,eaxnt!CmUnRegisterCallback+0x1c9:840b0961 f6c102 test cl,2840b0964 7511 jne nt!CmUnRegisterCallback+0x1df (840b0977)nt!CmUnRegisterCallback+0x1ce:840b0966 8bd0 mov edx,eax840b0968 befc97f783 mov esi,offset nt!CallbackListLock (83f797fc)840b096d 8bc1 mov eax,ecx840b096f f00fb116 lock cmpxchg dword ptr [esi],edx840b0973 3bc1 cmp eax,ecx840b0975 740a je nt!CmUnRegisterCallback+0x1e9 (840b0981)nt!CmUnRegisterCallback+0x1df:840b0977 b9fc97f783 mov ecx,offset nt!CallbackListLock (83f797fc)840b097c e80f2fe1ff call nt!ExfReleasePushLock (83ec3890)nt!CmUnRegisterCallback+0x1e9:840b0981 648b0d24010000 mov ecx,dword ptr fs:[124h]840b0988 8d8184000000 lea eax,[ecx+84h]840b098e 66ff00 inc word ptr [eax]840b0991 0fb700 movzx eax,word ptr [eax]840b0994 6685c0 test ax,ax840b0997 7516 jne nt!CmUnRegisterCallback+0x217 (840b09af)nt!CmUnRegisterCallback+0x201:840b0999 8d4140 lea eax,[ecx+40h]840b099c 3900 cmp dword ptr [eax],eax840b099e 740f je nt!CmUnRegisterCallback+0x217 (840b09af)nt!CmUnRegisterCallback+0x208:840b09a0 6683b98600000000 cmp word ptr [ecx+86h],0840b09a8 7505 jne nt!CmUnRegisterCallback+0x217 (840b09af)nt!CmUnRegisterCallback+0x212:840b09aa e8d662d8ff call nt!KiCheckForKernelApcDelivery (83e36c85)nt!CmUnRegisterCallback+0x217:840b09af 8b45d8 mov eax,dword ptr [ebp-28h]840b09b2 85c0 test eax,eax840b09b4 0f8c8a010000 jl nt!CmUnRegisterCallback+0x3ac (840b0b44)nt!CmUnRegisterCallback+0x222:840b09ba 8d45cc lea eax,[ebp-34h]840b09bd 8945d0 mov dword ptr [ebp-30h],eax840b09c0 8945cc mov dword ptr [ebp-34h],eax840b09c3 64a124010000 mov eax,dword ptr fs:[00000124h]840b09c9 66ff8884000000 dec word ptr [eax+84h]840b09d0 bbf897f783 mov ebx,offset nt!ContextListLock (83f797f8)840b09d5 8bc3 mov eax,ebx840b09d7 f00fba2800 lock bts dword ptr [eax],0840b09dc 7307 jae nt!CmUnRegisterCallback+0x24d (840b09e5)nt!CmUnRegisterCallback+0x246:840b09de 8bcb mov ecx,ebx840b09e0 e8e910dfff call nt!ExfAcquirePushLockExclusive (83ea1ace)nt!CmUnRegisterCallback+0x24d:840b09e5 8b7ddc mov edi,dword ptr [ebp-24h]840b09e8 83c728 add edi,28h840b09eb 8b37 mov esi,dword ptr [edi]840b09ed 3bf7 cmp esi,edi840b09ef 7444 je nt!CmUnRegisterCallback+0x29d (840b0a35)nt!CmUnRegisterCallback+0x259:840b09f1 8b1e mov ebx,dword ptr [esi]840b09f3 8b5614 mov edx,dword ptr [esi+14h]840b09f6 e83839dfff call nt!ObReferenceObjectSafe (83ea4333)840b09fb 84c0 test al,al840b09fd 7427 je nt!CmUnRegisterCallback+0x28e (840b0a26)nt!CmUnRegisterCallback+0x267:840b09ff 8b06 mov eax,dword ptr [esi]840b0a01 8b4e04 mov ecx,dword ptr [esi+4]840b0a04 8901 mov dword ptr [ecx],eax840b0a06 894804 mov dword ptr [eax+4],ecx840b0a09 8b46f8 mov eax,dword ptr [esi-8]840b0a0c 8b4efc mov ecx,dword ptr [esi-4]840b0a0f 8901 mov dword ptr [ecx],eax840b0a11 894804 mov dword ptr [eax+4],ecx840b0a14 8b45d0 mov eax,dword ptr [ebp-30h]840b0a17 8d4dcc lea ecx,[ebp-34h]840b0a1a 890e mov dword ptr [esi],ecx840b0a1c 894604 mov dword ptr [esi+4],eax840b0a1f 8930 mov dword ptr [eax],esi840b0a21 8975d0 mov dword ptr [ebp-30h],esi840b0a24 eb04 jmp nt!CmUnRegisterCallback+0x292 (840b0a2a)nt!CmUnRegisterCallback+0x28e:840b0a26 c645e200 mov byte ptr [ebp-1Eh],0nt!CmUnRegisterCallback+0x292:840b0a2a 8bf3 mov esi,ebx840b0a2c 3bdf cmp ebx,edi840b0a2e 75c1 jne nt!CmUnRegisterCallback+0x259 (840b09f1)nt!CmUnRegisterCallback+0x298:840b0a30 bbf897f783 mov ebx,offset nt!ContextListLock (83f797f8)nt!CmUnRegisterCallback+0x29d:840b0a35 8b0df897f783 mov ecx,dword ptr [nt!ContextListLock (83f797f8)]840b0a3b 8bc1 mov eax,ecx840b0a3d 83e0f0 and eax,0FFFFFFF0h840b0a40 83f810 cmp eax,10h840b0a43 7605 jbe nt!CmUnRegisterCallback+0x2b2 (840b0a4a)nt!CmUnRegisterCallback+0x2ad:840b0a45 8d41f0 lea eax,[ecx-10h]840b0a48 eb02 jmp nt!CmUnRegisterCallback+0x2b4 (840b0a4c)nt!CmUnRegisterCallback+0x2b2:840b0a4a 33c0 xor eax,eaxnt!CmUnRegisterCallback+0x2b4:840b0a4c f6c102 test cl,2840b0a4f 750e jne nt!CmUnRegisterCallback+0x2c7 (840b0a5f)nt!CmUnRegisterCallback+0x2b9:840b0a51 8bd0 mov edx,eax840b0a53 8bf3 mov esi,ebx840b0a55 8bc1 mov eax,ecx840b0a57 f00fb116 lock cmpxchg dword ptr [esi],edx840b0a5b 3bc1 cmp eax,ecx840b0a5d 7407 je nt!CmUnRegisterCallback+0x2ce (840b0a66)nt!CmUnRegisterCallback+0x2c7:840b0a5f 8bcb mov ecx,ebx840b0a61 e82a2ee1ff call nt!ExfReleasePushLock (83ec3890)nt!CmUnRegisterCallback+0x2ce:840b0a66 648b0d24010000 mov ecx,dword ptr fs:[124h]840b0a6d 8d8184000000 lea eax,[ecx+84h]840b0a73 66ff00 inc word ptr [eax]840b0a76 0fb700 movzx eax,word ptr [eax]840b0a79 6685c0 test ax,ax840b0a7c 7516 jne nt!CmUnRegisterCallback+0x2fc (840b0a94)nt!CmUnRegisterCallback+0x2e6:840b0a7e 8d4140 lea eax,[ecx+40h]840b0a81 3900 cmp dword ptr [eax],eax840b0a83 740f je nt!CmUnRegisterCallback+0x2fc (840b0a94)nt!CmUnRegisterCallback+0x2ed:840b0a85 6683b98600000000 cmp word ptr [ecx+86h],0840b0a8d 7505 jne nt!CmUnRegisterCallback+0x2fc (840b0a94)nt!CmUnRegisterCallback+0x2f7:840b0a8f e8f161d8ff call nt!KiCheckForKernelApcDelivery (83e36c85)nt!CmUnRegisterCallback+0x2fc:840b0a94 8d4dcc lea ecx,[ebp-34h]840b0a97 8b45cc mov eax,dword ptr [ebp-34h]840b0a9a 3bc1 cmp eax,ecx840b0a9c 7461 je nt!CmUnRegisterCallback+0x367 (840b0aff)nt!CmUnRegisterCallback+0x306:840b0a9e 8bc8 mov ecx,eax840b0aa0 8b00 mov eax,dword ptr [eax]840b0aa2 8945cc mov dword ptr [ebp-34h],eax840b0aa5 8d55cc lea edx,[ebp-34h]840b0aa8 895004 mov dword ptr [eax+4],edx840b0aab 8d71f8 lea esi,[ecx-8]840b0aae 8975d4 mov dword ptr [ebp-2Ch],esi840b0ab1 8b461c mov eax,dword ptr [esi+1Ch]840b0ab4 8945b8 mov dword ptr [ebp-48h],eax840b0ab7 8b4620 mov eax,dword ptr [esi+20h]840b0aba 8945bc mov dword ptr [ebp-44h],eax840b0abd 8365fc00 and dword ptr [ebp-4],0840b0ac1 8d45b8 lea eax,[ebp-48h]840b0ac4 50 push eax840b0ac5 6a28 push 28h840b0ac7 8b45dc mov eax,dword ptr [ebp-24h]840b0aca ff7018 push dword ptr [eax+18h]840b0acd ff501c call dword ptr [eax+1Ch]840b0ad0 c745fcfeffffff mov dword ptr [ebp-4],0FFFFFFFEh840b0ad7 eb11 jmp nt!CmUnRegisterCallback+0x352 (840b0aea)nt!CmUnRegisterCallback+0x352:840b0aea 8b4e1c mov ecx,dword ptr [esi+1Ch]840b0aed e8d171ddff call nt!ObfDereferenceObject (83e87cc3)840b0af2 68434d6363 push 63634D43h840b0af7 56 push esi840b0af8 e8bd0fe8ff call nt!ExFreePoolWithTag (83f31aba)840b0afd eb95 jmp nt!CmUnRegisterCallback+0x2fc (840b0a94)nt!CmUnRegisterCallback+0x367:840b0aff 8b7ddc mov edi,dword ptr [ebp-24h]840b0b02 807de200 cmp byte ptr [ebp-1Eh],0840b0b06 7516 jne nt!CmUnRegisterCallback+0x386 (840b0b1e)nt!CmUnRegisterCallback+0x370:840b0b08 8d7728 lea esi,[edi+28h]840b0b0b eb0d jmp nt!CmUnRegisterCallback+0x382 (840b0b1a)nt!CmUnRegisterCallback+0x375:840b0b0d 8d45c4 lea eax,[ebp-3Ch]840b0b10 50 push eax840b0b11 6a00 push 0840b0b13 6a00 push 0840b0b15 e805b6ddff call nt!KeDelayExecutionThread (83e8c11f)nt!CmUnRegisterCallback+0x382:840b0b1a 3936 cmp dword ptr [esi],esi840b0b1c 75ef jne nt!CmUnRegisterCallback+0x375 (840b0b0d)nt!CmUnRegisterCallback+0x386:840b0b1e b8b08bf483 mov eax,offset nt!CmpCallBackCount (83f48bb0)840b0b23 83c9ff or ecx,0FFFFFFFFh840b0b26 f00fc108 lock xadd dword ptr [eax],ecx840b0b2a 8b4724 mov eax,dword ptr [edi+24h]840b0b2d 85c0 test eax,eax840b0b2f 7408 je nt!CmUnRegisterCallback+0x3a1 (840b0b39)nt!CmUnRegisterCallback+0x399:840b0b31 6a00 push 0840b0b33 50 push eax840b0b34 e8810fe8ff call nt!ExFreePoolWithTag (83f31aba)nt!CmUnRegisterCallback+0x3a1:840b0b39 6a00 push 0840b0b3b 57 push edi840b0b3c e8790fe8ff call nt!ExFreePoolWithTag (83f31aba)840b0b41 8b45d8 mov eax,dword ptr [ebp-28h]nt!CmUnRegisterCallback+0x3ac:840b0b44 e884e2ddff call nt!_SEH_epilog4 (83e8edcd)840b0b49 c20800 ret 8
    Win7 64 位 CmUnRegisterCallbacklkd> uf CmUnRegisterCallbacknt!CmUnRegisterCallback:fffff800`042b7790 48894c2408 mov qword ptr [rsp+8],rcxfffff800`042b7795 53 push rbxfffff800`042b7796 56 push rsifffff800`042b7797 57 push rdifffff800`042b7798 4154 push r12fffff800`042b779a 4155 push r13fffff800`042b779c 4156 push r14fffff800`042b779e 4157 push r15fffff800`042b77a0 4883ec60 sub rsp,60hfffff800`042b77a4 41bc0d0000c0 mov r12d,0C000000Dhfffff800`042b77aa 4489a424b0000000 mov dword ptr [rsp+0B0h],r12dfffff800`042b77b2 33db xor ebx,ebxfffff800`042b77b4 48895c2448 mov qword ptr [rsp+48h],rbxfffff800`042b77b9 33c0 xor eax,eaxfffff800`042b77bb 4889442450 mov qword ptr [rsp+50h],raxfffff800`042b77c0 4889442458 mov qword ptr [rsp+58h],raxfffff800`042b77c5 448d6b01 lea r13d,[rbx+1]fffff800`042b77c9 458afd mov r15b,r13bfffff800`042b77cc 4488ac24a8000000 mov byte ptr [rsp+0A8h],r13bfffff800`042b77d4 440f20c7 mov rdi,cr8fffff800`042b77d8 450f22c5 mov cr8,r13fffff800`042b77dc f00fba351b6adcff00 lock btr dword ptr [nt!CallbackUnregisterLock (fffff800`0407e200)],0fffff800`042b77e5 720c jb nt!CmUnRegisterCallback+0x63 (fffff800`042b77f3)nt!CmUnRegisterCallback+0x57:fffff800`042b77e7 488d0d126adcff lea rcx,[nt!CallbackUnregisterLock (fffff800`0407e200)]fffff800`042b77ee e85db7b9ff call nt!KiAcquireFastMutex (fffff800`03e52f50)nt!CmUnRegisterCallback+0x63:fffff800`042b77f3 65488b042588010000 mov rax,qword ptr gs:[188h]fffff800`042b77fc 488905056adcff mov qword ptr [nt!CallbackUnregisterLock+0x8 (fffff800`0407e208)],raxfffff800`042b7803 400fb6c7 movzx eax,dilfffff800`042b7807 8905236adcff mov dword ptr [nt!CallbackUnregisterLock+0x30 (fffff800`0407e230)],eaxfffff800`042b780d 48c78424b80000009cffffff mov qword ptr [rsp+0B8h],0FFFFFFFFFFFFFF9Chfffff800`042b7819 48895c2420 mov qword ptr [rsp+20h],rbxfffff800`042b781e 65488b042588010000 mov rax,qword ptr gs:[188h]fffff800`042b7827 4183ceff or r14d,0FFFFFFFFhfffff800`042b782b 664401b0c4010000 add word ptr [rax+1C4h],r14wfffff800`042b7833 f0480fba2dab69dcff00 lock bts qword ptr [nt!CallbackListLock (fffff800`0407e1e8)],0fffff800`042b783d 730c jae nt!CmUnRegisterCallback+0xbb (fffff800`042b784b)nt!CmUnRegisterCallback+0xaf:fffff800`042b783f 488d0da269dcff lea rcx,[nt!CallbackListLock (fffff800`0407e1e8)]fffff800`042b7846 e875aabbff call nt!ExfAcquirePushLockExclusive (fffff800`03e722c0)nt!CmUnRegisterCallback+0xbb:fffff800`042b784b 418af5 mov sil,r13bfffff800`042b784e 4c8b9424a0000000 mov r10,qword ptr [rsp+0A0h]nt!CmUnRegisterCallback+0xc6:fffff800`042b7856 4533c0 xor r8d,r8dfffff800`042b7859 488d542420 lea rdx,[rsp+20h]fffff800`042b785e 488d0d6b69dcff lea rcx,[nt!CallbackListHead (fffff800`0407e1d0)]fffff800`042b7865 e8a261e5ff call nt!CmListGetNextElement (fffff800`0410da0c)fffff800`042b786a 488bf8 mov rdi,raxfffff800`042b786d 4889442428 mov qword ptr [rsp+28h],raxfffff800`042b7872 483bc3 cmp rax,rbxfffff800`042b7875 0f84b8000000 je nt!CmUnRegisterCallback+0x1a3 (fffff800`042b7933)nt!CmUnRegisterCallback+0xeb:fffff800`042b787b 4c395018 cmp qword ptr [rax+18h],r10fffff800`042b787f 75d5 jne nt!CmUnRegisterCallback+0xc6 (fffff800`042b7856)nt!CmUnRegisterCallback+0xf1:fffff800`042b7881 488b08 mov rcx,qword ptr [rax]fffff800`042b7884 488b4008 mov rax,qword ptr [rax+8]fffff800`042b7888 488908 mov qword ptr [rax],rcxfffff800`042b788b 48894108 mov qword ptr [rcx+8],raxfffff800`042b788f 8b4710 mov eax,dword ptr [rdi+10h]fffff800`042b7892 3bc3 cmp eax,ebxfffff800`042b7894 0f848f000000 je nt!CmUnRegisterCallback+0x199 (fffff800`042b7929)nt!CmUnRegisterCallback+0x10a:fffff800`042b789a 403af3 cmp sil,blfffff800`042b789d 746c je nt!CmUnRegisterCallback+0x17b (fffff800`042b790b)nt!CmUnRegisterCallback+0x10f:fffff800`042b789f 0f0d0d4269dcff prefetchw [nt!CallbackListLock (fffff800`0407e1e8)]fffff800`042b78a6 488b053b69dcff mov rax,qword ptr [nt!CallbackListLock (fffff800`0407e1e8)]fffff800`042b78ad 488bc8 mov rcx,raxfffff800`042b78b0 4883e1f0 and rcx,0FFFFFFFFFFFFFFF0hfffff800`042b78b4 4883f910 cmp rcx,10hfffff800`042b78b8 7606 jbe nt!CmUnRegisterCallback+0x130 (fffff800`042b78c0)nt!CmUnRegisterCallback+0x12a:fffff800`042b78ba 488d48f0 lea rcx,[rax-10h]fffff800`042b78be eb03 jmp nt!CmUnRegisterCallback+0x133 (fffff800`042b78c3)nt!CmUnRegisterCallback+0x130:fffff800`042b78c0 488bcb mov rcx,rbxnt!CmUnRegisterCallback+0x133:fffff800`042b78c3 a802 test al,2fffff800`042b78c5 750b jne nt!CmUnRegisterCallback+0x142 (fffff800`042b78d2)nt!CmUnRegisterCallback+0x137:fffff800`042b78c7 f0480fb10d1869dcff lock cmpxchg qword ptr [nt!CallbackListLock (fffff800`0407e1e8)],rcxfffff800`042b78d0 740c je nt!CmUnRegisterCallback+0x14e (fffff800`042b78de)nt!CmUnRegisterCallback+0x142:fffff800`042b78d2 488d0d0f69dcff lea rcx,[nt!CallbackListLock (fffff800`0407e1e8)]fffff800`042b78d9 e89283b8ff call nt!ExfReleasePushLock (fffff800`03e3fc70)nt!CmUnRegisterCallback+0x14e:fffff800`042b78de 65488b0c2588010000 mov rcx,qword ptr gs:[188h]fffff800`042b78e7 664401a9c4010000 add word ptr [rcx+1C4h],r13wfffff800`042b78ef 7517 jne nt!CmUnRegisterCallback+0x178 (fffff800`042b7908)nt!CmUnRegisterCallback+0x161:fffff800`042b78f1 488d4150 lea rax,[rcx+50h]fffff800`042b78f5 483900 cmp qword ptr [rax],raxfffff800`042b78f8 740e je nt!CmUnRegisterCallback+0x178 (fffff800`042b7908)nt!CmUnRegisterCallback+0x16a:fffff800`042b78fa 663999c6010000 cmp word ptr [rcx+1C6h],bxfffff800`042b7901 7505 jne nt!CmUnRegisterCallback+0x178 (fffff800`042b7908)nt!CmUnRegisterCallback+0x173:fffff800`042b7903 e8a85eb7ff call nt!KiCheckForKernelApcDelivery (fffff800`03e2d7b0)nt!CmUnRegisterCallback+0x178:fffff800`042b7908 408af3 mov sil,blnt!CmUnRegisterCallback+0x17b:fffff800`042b790b 4c8d8424b8000000 lea r8,[rsp+0B8h]fffff800`042b7913 33d2 xor edx,edxfffff800`042b7915 33c9 xor ecx,ecxfffff800`042b7917 e800f7bcff call nt!KeDelayExecutionThread (fffff800`03e8701c)fffff800`042b791c 448b5f10 mov r11d,dword ptr [rdi+10h]fffff800`042b7920 443bdb cmp r11d,ebxfffff800`042b7923 0f8571ffffff jne nt!CmUnRegisterCallback+0x10a (fffff800`042b789a)nt!CmUnRegisterCallback+0x199:fffff800`042b7929 448be3 mov r12d,ebxfffff800`042b792c 899c24b0000000 mov dword ptr [rsp+0B0h],ebxnt!CmUnRegisterCallback+0x1a3:fffff800`042b7933 48891dce68dcff mov qword ptr [nt!CallbackUnregisterLock+0x8 (fffff800`0407e208)],rbxfffff800`042b793a 448a2def68dcff mov r13b,byte ptr [nt!CallbackUnregisterLock+0x30 (fffff800`0407e230)]fffff800`042b7941 ba01000000 mov edx,1fffff800`042b7946 8bc2 mov eax,edxfffff800`042b7948 f00fc105b068dcff lock xadd dword ptr [nt!CallbackUnregisterLock (fffff800`0407e200)],eaxfffff800`042b7950 3bc3 cmp eax,ebxfffff800`042b7952 7427 je nt!CmUnRegisterCallback+0x1eb (fffff800`042b797b)nt!CmUnRegisterCallback+0x1c4:fffff800`042b7954 a802 test al,2fffff800`042b7956 7523 jne nt!CmUnRegisterCallback+0x1eb (fffff800`042b797b)nt!CmUnRegisterCallback+0x1c8:fffff800`042b7958 03c2 add eax,edxfffff800`042b795a 8d48fe lea ecx,[rax-2]fffff800`042b795d f00fb10d9b68dcff lock cmpxchg dword ptr [nt!CallbackUnregisterLock (fffff800`0407e200)],ecxfffff800`042b7965 7514 jne nt!CmUnRegisterCallback+0x1eb (fffff800`042b797b)nt!CmUnRegisterCallback+0x1d7:fffff800`042b7967 4533c0 xor r8d,r8dfffff800`042b796a 488d0da768dcff lea rcx,[nt!CallbackUnregisterLock+0x18 (fffff800`0407e218)]fffff800`042b7971 e88accbcff call nt!KeSetEvent (fffff800`03e84600)fffff800`042b7976 ba01000000 mov edx,1nt!CmUnRegisterCallback+0x1eb:fffff800`042b797b 410fb6c5 movzx eax,r13bfffff800`042b797f 440f22c0 mov cr8,raxfffff800`042b7983 403af2 cmp sil,dlfffff800`042b7986 756d jne nt!CmUnRegisterCallback+0x265 (fffff800`042b79f5)nt!CmUnRegisterCallback+0x1f8:fffff800`042b7988 0f0d0d5968dcff prefetchw [nt!CallbackListLock (fffff800`0407e1e8)]fffff800`042b798f 488b055268dcff mov rax,qword ptr [nt!CallbackListLock (fffff800`0407e1e8)]fffff800`042b7996 488bc8 mov rcx,raxfffff800`042b7999 4883e1f0 and rcx,0FFFFFFFFFFFFFFF0hfffff800`042b799d 4883f910 cmp rcx,10hfffff800`042b79a1 7606 jbe nt!CmUnRegisterCallback+0x219 (fffff800`042b79a9)nt!CmUnRegisterCallback+0x213:fffff800`042b79a3 488d48f0 lea rcx,[rax-10h]fffff800`042b79a7 eb03 jmp nt!CmUnRegisterCallback+0x21c (fffff800`042b79ac)nt!CmUnRegisterCallback+0x219:fffff800`042b79a9 488bcb mov rcx,rbxnt!CmUnRegisterCallback+0x21c:fffff800`042b79ac a802 test al,2fffff800`042b79ae 750b jne nt!CmUnRegisterCallback+0x22b (fffff800`042b79bb)nt!CmUnRegisterCallback+0x220:fffff800`042b79b0 f0480fb10d2f68dcff lock cmpxchg qword ptr [nt!CallbackListLock (fffff800`0407e1e8)],rcxfffff800`042b79b9 740c je nt!CmUnRegisterCallback+0x237 (fffff800`042b79c7)nt!CmUnRegisterCallback+0x22b:fffff800`042b79bb 488d0d2668dcff lea rcx,[nt!CallbackListLock (fffff800`0407e1e8)]fffff800`042b79c2 e8a982b8ff call nt!ExfReleasePushLock (fffff800`03e3fc70)nt!CmUnRegisterCallback+0x237:fffff800`042b79c7 65488b142588010000 mov rdx,qword ptr gs:[188h]fffff800`042b79d0 b801000000 mov eax,1fffff800`042b79d5 660182c4010000 add word ptr [rdx+1C4h],axfffff800`042b79dc 7517 jne nt!CmUnRegisterCallback+0x265 (fffff800`042b79f5)nt!CmUnRegisterCallback+0x24e:fffff800`042b79de 488d4a50 lea rcx,[rdx+50h]fffff800`042b79e2 483909 cmp qword ptr [rcx],rcxfffff800`042b79e5 740e je nt!CmUnRegisterCallback+0x265 (fffff800`042b79f5)nt!CmUnRegisterCallback+0x257:fffff800`042b79e7 66399ac6010000 cmp word ptr [rdx+1C6h],bxfffff800`042b79ee 7505 jne nt!CmUnRegisterCallback+0x265 (fffff800`042b79f5)nt!CmUnRegisterCallback+0x260:fffff800`042b79f0 e8bb5db7ff call nt!KiCheckForKernelApcDelivery (fffff800`03e2d7b0)nt!CmUnRegisterCallback+0x265:fffff800`042b79f5 443be3 cmp r12d,ebxfffff800`042b79f8 7d08 jge nt!CmUnRegisterCallback+0x272 (fffff800`042b7a02)nt!CmUnRegisterCallback+0x26a:fffff800`042b79fa 418bc4 mov eax,r12dfffff800`042b79fd e9e5010000 jmp nt!CmUnRegisterCallback+0x457 (fffff800`042b7be7)nt!CmUnRegisterCallback+0x272:fffff800`042b7a02 488d442438 lea rax,[rsp+38h]fffff800`042b7a07 4889442440 mov qword ptr [rsp+40h],raxfffff800`042b7a0c 488d442438 lea rax,[rsp+38h]fffff800`042b7a11 4889442438 mov qword ptr [rsp+38h],raxfffff800`042b7a16 65488b042588010000 mov rax,qword ptr gs:[188h]fffff800`042b7a1f 664401b0c4010000 add word ptr [rax+1C4h],r14wfffff800`042b7a27 f0480fba2daf67dcff00 lock bts qword ptr [nt!ContextListLock (fffff800`0407e1e0)],0fffff800`042b7a31 730c jae nt!CmUnRegisterCallback+0x2af (fffff800`042b7a3f)nt!CmUnRegisterCallback+0x2a3:fffff800`042b7a33 488d0da667dcff lea rcx,[nt!ContextListLock (fffff800`0407e1e0)]fffff800`042b7a3a e881a8bbff call nt!ExfAcquirePushLockExclusive (fffff800`03e722c0)nt!CmUnRegisterCallback+0x2af:fffff800`042b7a3f 4c8d6f40 lea r13,[rdi+40h]fffff800`042b7a43 498b7500 mov rsi,qword ptr [r13]fffff800`042b7a47 493bf5 cmp rsi,r13fffff800`042b7a4a 745f je nt!CmUnRegisterCallback+0x31b (fffff800`042b7aab)nt!CmUnRegisterCallback+0x2bc:fffff800`042b7a4c 4c8b36 mov r14,qword ptr [rsi]fffff800`042b7a4f 488b4e20 mov rcx,qword ptr [rsi+20h]fffff800`042b7a53 e8a851beff call nt!ObReferenceObjectSafe (fffff800`03e9cc00)fffff800`042b7a58 3ac3 cmp al,blfffff800`042b7a5a 7438 je nt!CmUnRegisterCallback+0x304 (fffff800`042b7a94)nt!CmUnRegisterCallback+0x2cc:fffff800`042b7a5c 488b0e mov rcx,qword ptr [rsi]fffff800`042b7a5f 488b4608 mov rax,qword ptr [rsi+8]fffff800`042b7a63 488908 mov qword ptr [rax],rcxfffff800`042b7a66 48894108 mov qword ptr [rcx+8],raxfffff800`042b7a6a 488b4ef0 mov rcx,qword ptr [rsi-10h]fffff800`042b7a6e 488b46f8 mov rax,qword ptr [rsi-8]fffff800`042b7a72 488908 mov qword ptr [rax],rcxfffff800`042b7a75 48894108 mov qword ptr [rcx+8],raxfffff800`042b7a79 488b442440 mov rax,qword ptr [rsp+40h]fffff800`042b7a7e 488d4c2438 lea rcx,[rsp+38h]fffff800`042b7a83 48890e mov qword ptr [rsi],rcxfffff800`042b7a86 48894608 mov qword ptr [rsi+8],raxfffff800`042b7a8a 488930 mov qword ptr [rax],rsifffff800`042b7a8d 4889742440 mov qword ptr [rsp+40h],rsifffff800`042b7a92 eb03 jmp nt!CmUnRegisterCallback+0x307 (fffff800`042b7a97)nt!CmUnRegisterCallback+0x304:fffff800`042b7a94 448afb mov r15b,blnt!CmUnRegisterCallback+0x307:fffff800`042b7a97 498bf6 mov rsi,r14fffff800`042b7a9a 4d3bf5 cmp r14,r13fffff800`042b7a9d 75ad jne nt!CmUnRegisterCallback+0x2bc (fffff800`042b7a4c)nt!CmUnRegisterCallback+0x30f:fffff800`042b7a9f 4488bc24a8000000 mov byte ptr [rsp+0A8h],r15bfffff800`042b7aa7 4183ceff or r14d,0FFFFFFFFhnt!CmUnRegisterCallback+0x31b:fffff800`042b7aab 0f0d0d2e67dcff prefetchw [nt!ContextListLock (fffff800`0407e1e0)]fffff800`042b7ab2 488b052767dcff mov rax,qword ptr [nt!ContextListLock (fffff800`0407e1e0)]fffff800`042b7ab9 488bc8 mov rcx,raxfffff800`042b7abc 4883e1f0 and rcx,0FFFFFFFFFFFFFFF0hfffff800`042b7ac0 4883f910 cmp rcx,10hfffff800`042b7ac4 7606 jbe nt!CmUnRegisterCallback+0x33c (fffff800`042b7acc)nt!CmUnRegisterCallback+0x336:fffff800`042b7ac6 488d48f0 lea rcx,[rax-10h]fffff800`042b7aca eb03 jmp nt!CmUnRegisterCallback+0x33f (fffff800`042b7acf)nt!CmUnRegisterCallback+0x33c:fffff800`042b7acc 488bcb mov rcx,rbxnt!CmUnRegisterCallback+0x33f:fffff800`042b7acf a802 test al,2fffff800`042b7ad1 750b jne nt!CmUnRegisterCallback+0x34e (fffff800`042b7ade)nt!CmUnRegisterCallback+0x343:fffff800`042b7ad3 f0480fb10d0467dcff lock cmpxchg qword ptr [nt!ContextListLock (fffff800`0407e1e0)],rcxfffff800`042b7adc 740c je nt!CmUnRegisterCallback+0x35a (fffff800`042b7aea)nt!CmUnRegisterCallback+0x34e:fffff800`042b7ade 488d0dfb66dcff lea rcx,[nt!ContextListLock (fffff800`0407e1e0)]fffff800`042b7ae5 e88681b8ff call nt!ExfReleasePushLock (fffff800`03e3fc70)nt!CmUnRegisterCallback+0x35a:fffff800`042b7aea 65488b0c2588010000 mov rcx,qword ptr gs:[188h]fffff800`042b7af3 b801000000 mov eax,1fffff800`042b7af8 660181c4010000 add word ptr [rcx+1C4h],axfffff800`042b7aff 7517 jne nt!CmUnRegisterCallback+0x388 (fffff800`042b7b18)nt!CmUnRegisterCallback+0x371:fffff800`042b7b01 488d4150 lea rax,[rcx+50h]fffff800`042b7b05 483900 cmp qword ptr [rax],raxfffff800`042b7b08 740e je nt!CmUnRegisterCallback+0x388 (fffff800`042b7b18)nt!CmUnRegisterCallback+0x37a:fffff800`042b7b0a 663999c6010000 cmp word ptr [rcx+1C6h],bxfffff800`042b7b11 7505 jne nt!CmUnRegisterCallback+0x388 (fffff800`042b7b18)nt!CmUnRegisterCallback+0x383:fffff800`042b7b13 e8985cb7ff call nt!KiCheckForKernelApcDelivery (fffff800`03e2d7b0)nt!CmUnRegisterCallback+0x388:fffff800`042b7b18 488d442438 lea rax,[rsp+38h]fffff800`042b7b1d 488b742438 mov rsi,qword ptr [rsp+38h]fffff800`042b7b22 483bf0 cmp rsi,raxfffff800`042b7b25 747a je nt!CmUnRegisterCallback+0x411 (fffff800`042b7ba1)nt!CmUnRegisterCallback+0x397:fffff800`042b7b27 488b06 mov rax,qword ptr [rsi]fffff800`042b7b2a 4889442438 mov qword ptr [rsp+38h],raxfffff800`042b7b2f 488d4c2438 lea rcx,[rsp+38h]fffff800`042b7b34 48894808 mov qword ptr [rax+8],rcxfffff800`042b7b38 4883c6f0 add rsi,0FFFFFFFFFFFFFFF0hfffff800`042b7b3c 4889742430 mov qword ptr [rsp+30h],rsifffff800`042b7b41 488b4630 mov rax,qword ptr [rsi+30h]fffff800`042b7b45 4889442448 mov qword ptr [rsp+48h],raxfffff800`042b7b4a 488b4638 mov rax,qword ptr [rsi+38h]fffff800`042b7b4e 4889442450 mov qword ptr [rsp+50h],raxfffff800`042b7b53 4c8d442448 lea r8,[rsp+48h]fffff800`042b7b58 ba28000000 mov edx,28hfffff800`042b7b5d 488b4f20 mov rcx,qword ptr [rdi+20h]fffff800`042b7b61 ff5728 call qword ptr [rdi+28h]fffff800`042b7b64 eb20 jmp nt!CmUnRegisterCallback+0x3f6 (fffff800`042b7b86)nt!CmUnRegisterCallback+0x3f6:fffff800`042b7b86 488b4e30 mov rcx,qword ptr [rsi+30h]fffff800`042b7b8a e8b128bdff call nt!ObfDereferenceObject (fffff800`03e8a440)fffff800`042b7b8f ba434d6363 mov edx,63634D43hfffff800`042b7b94 488bce mov rcx,rsifffff800`042b7b97 e8f441cfff call nt!ExFreePoolWithTag (fffff800`03fabd90)fffff800`042b7b9c e977ffffff jmp nt!CmUnRegisterCallback+0x388 (fffff800`042b7b18)nt!CmUnRegisterCallback+0x411:fffff800`042b7ba1 443afb cmp r15b,blfffff800`042b7ba4 751c jne nt!CmUnRegisterCallback+0x432 (fffff800`042b7bc2)nt!CmUnRegisterCallback+0x416:fffff800`042b7ba6 488d7740 lea rsi,[rdi+40h]nt!CmUnRegisterCallback+0x41a:fffff800`042b7baa 483936 cmp qword ptr [rsi],rsifffff800`042b7bad 7413 je nt!CmUnRegisterCallback+0x432 (fffff800`042b7bc2)nt!CmUnRegisterCallback+0x41f:fffff800`042b7baf 4c8d8424b8000000 lea r8,[rsp+0B8h]fffff800`042b7bb7 33d2 xor edx,edxfffff800`042b7bb9 33c9 xor ecx,ecxfffff800`042b7bbb e85cf4bcff call nt!KeDelayExecutionThread (fffff800`03e8701c)fffff800`042b7bc0 ebe8 jmp nt!CmUnRegisterCallback+0x41a (fffff800`042b7baa)nt!CmUnRegisterCallback+0x432:fffff800`042b7bc2 f0440135ca12d5ff lock add dword ptr [nt!CmpCallBackCount (fffff800`04008e94)],r14dfffff800`042b7bca 488b4f38 mov rcx,qword ptr [rdi+38h]fffff800`042b7bce 483bcb cmp rcx,rbxfffff800`042b7bd1 7407 je nt!CmUnRegisterCallback+0x44a (fffff800`042b7bda)nt!CmUnRegisterCallback+0x443:fffff800`042b7bd3 33d2 xor edx,edxfffff800`042b7bd5 e8b641cfff call nt!ExFreePoolWithTag (fffff800`03fabd90)nt!CmUnRegisterCallback+0x44a:fffff800`042b7bda 33d2 xor edx,edxfffff800`042b7bdc 488bcf mov rcx,rdifffff800`042b7bdf e8ac41cfff call nt!ExFreePoolWithTag (fffff800`03fabd90)fffff800`042b7be4 418bc4 mov eax,r12dnt!CmUnRegisterCallback+0x457:fffff800`042b7be7 4883c460 add rsp,60hfffff800`042b7beb 415f pop r15fffff800`042b7bed 415e pop r14fffff800`042b7bef 415d pop r13fffff800`042b7bf1 415c pop r12fffff800`042b7bf3 5f pop rdifffff800`042b7bf4 5e pop rsifffff800`042b7bf5 5b pop rbxfffff800`042b7bf6 c3 ret
    Win8.1 32 位 CmUnRegisterCallbacklkd> uf CmUnRegisterCallbacknt!CmUnRegisterCallback:8118a854 6a38 push 38h8118a856 68a84afe80 push offset nt!RtlpSparseBitmapCtxPrepareRanges+0x6429 (80fe4aa8)8118a85b e8183dd9ff call nt!_SEH_prolog4 (80f1e578)8118a860 c745d80d0000c0 mov dword ptr [ebp-28h],0C000000Dh8118a867 33db xor ebx,ebx8118a869 895db8 mov dword ptr [ebp-48h],ebx8118a86c 895dbc mov dword ptr [ebp-44h],ebx8118a86f 895dc0 mov dword ptr [ebp-40h],ebx8118a872 895dd0 mov dword ptr [ebp-30h],ebx8118a875 e8a4020000 call nt!CmpLockCallbackListExclusive (8118ab1e)8118a87a be00fb0081 mov esi,offset nt!CallbackListHead (8100fb00)nt!CmUnRegisterCallback+0x2b:8118a87f 53 push ebx8118a880 8d55d0 lea edx,[ebp-30h]8118a883 8bce mov ecx,esi8118a885 e81458f4ff call nt!CmListGetNextElement (810d009e)8118a88a 8bf8 mov edi,eax8118a88c 85ff test edi,edi8118a88e 897dd4 mov dword ptr [ebp-2Ch],edi8118a891 0f8409010000 je nt!CmUnRegisterCallback+0x14c (8118a9a0)nt!CmUnRegisterCallback+0x43:8118a897 ba00000080 mov edx,80000000h8118a89c 8b4f10 mov ecx,dword ptr [edi+10h]8118a89f 3b4d08 cmp ecx,dword ptr [ebp+8]8118a8a2 75db jne nt!CmUnRegisterCallback+0x2b (8118a87f)nt!CmUnRegisterCallback+0x50:8118a8a4 8b4714 mov eax,dword ptr [edi+14h]8118a8a7 3b450c cmp eax,dword ptr [ebp+0Ch]8118a8aa 75d3 jne nt!CmUnRegisterCallback+0x2b (8118a87f)nt!CmUnRegisterCallback+0x58:8118a8ac 8b4708 mov eax,dword ptr [edi+8]8118a8af 8945dc mov dword ptr [ebp-24h],eax8118a8b2 3bc3 cmp eax,ebx8118a8b4 0f8591000000 jne nt!CmUnRegisterCallback+0xf7 (8118a94b)nt!CmUnRegisterCallback+0x66:8118a8ba 8b0f mov ecx,dword ptr [edi]8118a8bc 8b4704 mov eax,dword ptr [edi+4]8118a8bf 397904 cmp dword ptr [ecx+4],edi8118a8c2 0f85e6000000 jne nt!CmUnRegisterCallback+0x15a (8118a9ae)nt!CmUnRegisterCallback+0x74:8118a8c8 3938 cmp dword ptr [eax],edi8118a8ca 0f85de000000 jne nt!CmUnRegisterCallback+0x15a (8118a9ae)nt!CmUnRegisterCallback+0x7c:8118a8d0 8908 mov dword ptr [eax],ecx8118a8d2 894104 mov dword ptr [ecx+4],eax8118a8d5 e8467befff call nt!CmpUnlockCallbackList (81082420)8118a8da 895dd8 mov dword ptr [ebp-28h],ebxnt!CmUnRegisterCallback+0x89:8118a8dd 8d45c4 lea eax,[ebp-3Ch]8118a8e0 8945c8 mov dword ptr [ebp-38h],eax8118a8e3 8945c4 mov dword ptr [ebp-3Ch],eax8118a8e6 885de3 mov byte ptr [ebp-1Dh],bl8118a8e9 e8f0020000 call nt!CmpLockContextListExclusive (8118abde)8118a8ee 8d4728 lea eax,[edi+28h]8118a8f1 8b30 mov esi,dword ptr [eax]8118a8f3 3bf0 cmp esi,eax8118a8f5 0f85c8d40800 jne nt! ?? ::NNGAKEGL::`string'+0x79759 (81217dc3)nt!CmUnRegisterCallback+0xa7:8118a8fb e86e020000 call nt!CmpUnlockContextList (8118ab6e)nt!CmUnRegisterCallback+0xac:8118a900 8d4dc4 lea ecx,[ebp-3Ch]8118a903 8b45c4 mov eax,dword ptr [ebp-3Ch]8118a906 3bc1 cmp eax,ecx8118a908 0f853fd50800 jne nt! ?? ::NNGAKEGL::`string'+0x797e3 (81217e4d)nt!CmUnRegisterCallback+0xba:8118a90e 807de300 cmp byte ptr [ebp-1Dh],08118a912 0f85aad50800 jne nt! ?? ::NNGAKEGL::`string'+0x79858 (81217ec2)nt!CmUnRegisterCallback+0xc4:8118a918 b9787eff80 mov ecx,offset nt!CmpCallBackCount (80ff7e78)8118a91d 83c8ff or eax,0FFFFFFFFh8118a920 f00fc101 lock xadd dword ptr [ecx],eax8118a924 48 dec eax8118a925 0f84d8d50800 je nt! ?? ::NNGAKEGL::`string'+0x79899 (81217f03)nt!CmUnRegisterCallback+0xd7:8118a92b 8b4724 mov eax,dword ptr [edi+24h]8118a92e 85c0 test eax,eax8118a930 7407 je nt!CmUnRegisterCallback+0xe5 (8118a939)nt!CmUnRegisterCallback+0xde:8118a932 53 push ebx8118a933 50 push eax8118a934 e8d7e6e5ff call nt!ExFreePoolWithTag (80fe9010)nt!CmUnRegisterCallback+0xe5:8118a939 53 push ebx8118a93a 57 push edi8118a93b e8d0e6e5ff call nt!ExFreePoolWithTag (80fe9010)nt!CmUnRegisterCallback+0xec:8118a940 8b45d8 mov eax,dword ptr [ebp-28h]8118a943 e8753cd9ff call nt!_SEH_epilog4 (80f1e5bd)8118a948 c20800 ret 8nt!CmUnRegisterCallback+0xf7:8118a94b 8555dc test dword ptr [ebp-24h],edx8118a94e 0f852bffffff jne nt!CmUnRegisterCallback+0x2b (8118a87f)nt!CmUnRegisterCallback+0x100:8118a954 8d7708 lea esi,[edi+8]8118a957 f00916 lock or dword ptr [esi],edx8118a95a e8c17aefff call nt!CmpUnlockCallbackList (81082420)8118a95f eb13 jmp nt!CmUnRegisterCallback+0x120 (8118a974)nt!CmUnRegisterCallback+0x10d:8118a961 53 push ebx8118a962 6a04 push 48118a964 8d45dc lea eax,[ebp-24h]8118a967 50 push eax8118a968 8bd6 mov edx,esi8118a96a b908fb0081 mov ecx,offset nt!CallbackListDeleteEvent (8100fb08)8118a96f e8e626caff call nt!ExBlockOnAddressPushLock (80e2d05a)nt!CmUnRegisterCallback+0x120:8118a974 8b06 mov eax,dword ptr [esi]8118a976 8945dc mov dword ptr [ebp-24h],eax8118a979 3d00000080 cmp eax,80000000h8118a97e 75e1 jne nt!CmUnRegisterCallback+0x10d (8118a961)nt!CmUnRegisterCallback+0x12c:8118a980 e899010000 call nt!CmpLockCallbackListExclusive (8118ab1e)8118a985 8b0f mov ecx,dword ptr [edi]8118a987 8b4704 mov eax,dword ptr [edi+4]8118a98a 397904 cmp dword ptr [ecx+4],edi8118a98d 751f jne nt!CmUnRegisterCallback+0x15a (8118a9ae)nt!CmUnRegisterCallback+0x13b:8118a98f 3938 cmp dword ptr [eax],edi8118a991 751b jne nt!CmUnRegisterCallback+0x15a (8118a9ae)nt!CmUnRegisterCallback+0x13f:8118a993 8908 mov dword ptr [eax],ecx8118a995 894104 mov dword ptr [ecx+4],eax8118a998 e8837aefff call nt!CmpUnlockCallbackList (81082420)8118a99d 895dd8 mov dword ptr [ebp-28h],ebxnt!CmUnRegisterCallback+0x14c:8118a9a0 395dd8 cmp dword ptr [ebp-28h],ebx8118a9a3 0f8d34ffffff jge nt!CmUnRegisterCallback+0x89 (8118a8dd)nt!CmUnRegisterCallback+0x155:8118a9a9 e90bd40800 jmp nt! ?? ::NNGAKEGL::`string'+0x7974f (81217db9)nt!CmUnRegisterCallback+0x15a:8118a9ae 6a03 push 38118a9b0 59 pop ecx8118a9b1 cd29 int 29h8118a9b3 cc int 38118a9b4 cc int 38118a9b5 cc int 38118a9b6 cc int 38118a9b7 cc int 38118a9b8 8bff mov edi,edi8118a9ba 55 push ebp8118a9bb 8bec mov ebp,esp8118a9bd 53 push ebx8118a9be 56 push esi8118a9bf 57 push edi8118a9c0 68434d6362 push 62634D43h8118a9c5 6a30 push 30h8118a9c7 6a01 push 18118a9c9 8bfa mov edi,edx8118a9cb 8bd9 mov ebx,ecx8118a9cd e8feefe5ff call nt!ExAllocatePoolWithTag (80fe99d0)8118a9d2 8bf0 mov esi,eax8118a9d4 85f6 test esi,esi8118a9d6 0f8449d50800 je nt! ?? ::NNGAKEGL::`string'+0x798bb (81217f25)nt!CmpRegisterCallbackInternal+0x24:8118a9dc 897604 mov dword ptr [esi+4],esi8118a9df 8d4628 lea eax,[esi+28h]8118a9e2 8936 mov dword ptr [esi],esi8118a9e4 894004 mov dword ptr [eax+4],eax8118a9e7 8900 mov dword ptr [eax],eax8118a9e9 897e18 mov dword ptr [esi+18h],edi8118a9ec 8b7d08 mov edi,dword ptr [ebp+8]8118a9ef c7460800000000 mov dword ptr [esi+8],08118a9f6 895e1c mov dword ptr [esi+1Ch],ebx8118a9f9 68434d6361 push 61634D43h8118a9fe 0fb707 movzx eax,word ptr [edi]8118aa01 66894622 mov word ptr [esi+22h],ax8118aa05 66894620 mov word ptr [esi+20h],ax8118aa09 0fb707 movzx eax,word ptr [edi]8118aa0c 50 push eax8118aa0d 6a01 push 18118aa0f e8bcefe5ff call nt!ExAllocatePoolWithTag (80fe99d0)8118aa14 8bc8 mov ecx,eax8118aa16 894e24 mov dword ptr [esi+24h],ecx8118aa19 85c9 test ecx,ecx8118aa1b 743b je nt!CmpRegisterCallbackInternal+0xa0 (8118aa58)nt!CmpRegisterCallbackInternal+0x65:8118aa1d 0fb707 movzx eax,word ptr [edi]8118aa20 50 push eax8118aa21 ff7704 push dword ptr [edi+4]8118aa24 51 push ecx8118aa25 e82678d8ff call nt!memcpy (80f12250)8118aa2a 8a550c mov dl,byte ptr [ebp+0Ch]8118aa2d 83c40c add esp,0Ch8118aa30 8bce mov ecx,esi8118aa32 e831000000 call nt!CmpInsertCallbackInListByAltitude (8118aa68)8118aa37 8b5510 mov edx,dword ptr [ebp+10h]8118aa3a 8bf8 mov edi,eax8118aa3c 8b4e10 mov ecx,dword ptr [esi+10h]8118aa3f 890a mov dword ptr [edx],ecx8118aa41 8b4e14 mov ecx,dword ptr [esi+14h]8118aa44 894a04 mov dword ptr [edx+4],ecx8118aa47 85ff test edi,edi8118aa49 0f88e0d40800 js nt! ?? ::NNGAKEGL::`string'+0x798c5 (81217f2f)nt!CmpRegisterCallbackInternal+0x97:8118aa4f 8bc7 mov eax,edint!CmpRegisterCallbackInternal+0x99:8118aa51 5f pop edi8118aa52 5e pop esi8118aa53 5b pop ebx8118aa54 5d pop ebp8118aa55 c20c00 ret 0Chnt!CmpRegisterCallbackInternal+0xa0:8118aa58 bf9a0000c0 mov edi,0C000009Ah8118aa5d e9cdd40800 jmp nt! ?? ::NNGAKEGL::`string'+0x798c5 (81217f2f)nt! ?? ::NNGAKEGL::`string'+0x7974f:81217db9 e862a6e6ff call nt!CmpUnlockCallbackList (81082420)81217dbe e97d2bf7ff jmp nt!CmUnRegisterCallback+0xec (8118a940)nt! ?? ::NNGAKEGL::`string'+0x79759:81217dc3 8b06 mov eax,dword ptr [esi]81217dc5 8945dc mov dword ptr [ebp-24h],eax81217dc8 8b4e14 mov ecx,dword ptr [esi+14h]81217dcb e83219c2ff call nt!ObReferenceObjectSafe (80e39702)81217dd0 84c0 test al,al81217dd2 7462 je nt! ?? ::NNGAKEGL::`string'+0x797cc (81217e36)nt! ?? ::NNGAKEGL::`string'+0x7976a:81217dd4 8d46f8 lea eax,[esi-8]81217dd7 8d4808 lea ecx,[eax+8]81217dda 8b11 mov edx,dword ptr [ecx]81217ddc 8955d0 mov dword ptr [ebp-30h],edx81217ddf 8b5104 mov edx,dword ptr [ecx+4]81217de2 8b7dd0 mov edi,dword ptr [ebp-30h]81217de5 394f04 cmp dword ptr [edi+4],ecx81217de8 8b7dd4 mov edi,dword ptr [ebp-2Ch]81217deb 0f85bd2bf7ff jne nt!CmUnRegisterCallback+0x15a (8118a9ae)nt! ?? ::NNGAKEGL::`string'+0x79787:81217df1 390a cmp dword ptr [edx],ecx81217df3 0f85b52bf7ff jne nt!CmUnRegisterCallback+0x15a (8118a9ae)nt! ?? ::NNGAKEGL::`string'+0x7978f:81217df9 8b4dd0 mov ecx,dword ptr [ebp-30h]81217dfc 890a mov dword ptr [edx],ecx81217dfe 895104 mov dword ptr [ecx+4],edx81217e01 8b10 mov edx,dword ptr [eax]81217e03 8b4804 mov ecx,dword ptr [eax+4]81217e06 394204 cmp dword ptr [edx+4],eax81217e09 0f859f2bf7ff jne nt!CmUnRegisterCallback+0x15a (8118a9ae)nt! ?? ::NNGAKEGL::`string'+0x797a5:81217e0f 3901 cmp dword ptr [ecx],eax81217e11 0f85972bf7ff jne nt!CmUnRegisterCallback+0x15a (8118a9ae)nt! ?? ::NNGAKEGL::`string'+0x797ad:81217e17 8911 mov dword ptr [ecx],edx81217e19 894a04 mov dword ptr [edx+4],ecx81217e1c 8b45c8 mov eax,dword ptr [ebp-38h]81217e1f 8d4dc4 lea ecx,[ebp-3Ch]81217e22 890e mov dword ptr [esi],ecx81217e24 894604 mov dword ptr [esi+4],eax81217e27 3908 cmp dword ptr [eax],ecx81217e29 0f857f2bf7ff jne nt!CmUnRegisterCallback+0x15a (8118a9ae)nt! ?? ::NNGAKEGL::`string'+0x797c5:81217e2f 8930 mov dword ptr [eax],esi81217e31 8975c8 mov dword ptr [ebp-38h],esi81217e34 eb04 jmp nt! ?? ::NNGAKEGL::`string'+0x797d0 (81217e3a)nt! ?? ::NNGAKEGL::`string'+0x797cc:81217e36 c645e301 mov byte ptr [ebp-1Dh],1nt! ?? ::NNGAKEGL::`string'+0x797d0:81217e3a 8b75dc mov esi,dword ptr [ebp-24h]81217e3d 8d4728 lea eax,[edi+28h]81217e40 3bf0 cmp esi,eax81217e42 0f857bffffff jne nt! ?? ::NNGAKEGL::`string'+0x79759 (81217dc3)nt! ?? ::NNGAKEGL::`string'+0x797de:81217e48 e9ae2af7ff jmp nt!CmUnRegisterCallback+0xa7 (8118a8fb)nt! ?? ::NNGAKEGL::`string'+0x797e3:81217e4d 8b08 mov ecx,dword ptr [eax]81217e4f 8d55c4 lea edx,[ebp-3Ch]81217e52 395004 cmp dword ptr [eax+4],edx81217e55 0f85532bf7ff jne nt!CmUnRegisterCallback+0x15a (8118a9ae)nt! ?? ::NNGAKEGL::`string'+0x797f1:81217e5b 394104 cmp dword ptr [ecx+4],eax81217e5e 0f854a2bf7ff jne nt!CmUnRegisterCallback+0x15a (8118a9ae)nt! ?? ::NNGAKEGL::`string'+0x797fa:81217e64 894dc4 mov dword ptr [ebp-3Ch],ecx81217e67 895104 mov dword ptr [ecx+4],edx81217e6a 8d70f8 lea esi,[eax-8]81217e6d 8975d0 mov dword ptr [ebp-30h],esi81217e70 8b461c mov eax,dword ptr [esi+1Ch]81217e73 8945b8 mov dword ptr [ebp-48h],eax81217e76 8b4620 mov eax,dword ptr [esi+20h]81217e79 8945bc mov dword ptr [ebp-44h],eax81217e7c 895dfc mov dword ptr [ebp-4],ebx81217e7f 8d45b8 lea eax,[ebp-48h]81217e82 50 push eax81217e83 6a28 push 28h81217e85 ff7718 push dword ptr [edi+18h]81217e88 ff571c call dword ptr [edi+1Ch]81217e8b c745fcfeffffff mov dword ptr [ebp-4],0FFFFFFFEh81217e92 eb13 jmp nt! ?? ::NNGAKEGL::`string'+0x7983d (81217ea7)nt! ?? ::NNGAKEGL::`string'+0x7983d:81217ea7 8b75d0 mov esi,dword ptr [ebp-30h]81217eaa 8b4e1c mov ecx,dword ptr [esi+1Ch]81217ead e89ec3c3ff call nt!ObfDereferenceObject (80e54250)81217eb2 68434d6363 push 63634D43h81217eb7 56 push esi81217eb8 e85311ddff call nt!ExFreePoolWithTag (80fe9010)81217ebd e93e2af7ff jmp nt!CmUnRegisterCallback+0xac (8118a900)nt! ?? ::NNGAKEGL::`string'+0x79858:81217ec2 8d4728 lea eax,[edi+28h]81217ec5 8945d0 mov dword ptr [ebp-30h],eax81217ec8 8bf8 mov edi,eaxnt! ?? ::NNGAKEGL::`string'+0x79860:81217eca e80f2df7ff call nt!CmpLockContextListExclusive (8118abde)81217ecf 8b37 mov esi,dword ptr [edi]81217ed1 8975cc mov dword ptr [ebp-34h],esi81217ed4 e8952cf7ff call nt!CmpUnlockContextList (8118ab6e)81217ed9 3bf7 cmp esi,edi81217edb 7415 je nt! ?? ::NNGAKEGL::`string'+0x79888 (81217ef2)nt! ?? ::NNGAKEGL::`string'+0x79873:81217edd 53 push ebx81217ede 6a04 push 481217ee0 8d45cc lea eax,[ebp-34h]81217ee3 50 push eax81217ee4 8bd7 mov edx,edi81217ee6 b908fb0081 mov ecx,offset nt!CallbackListDeleteEvent (8100fb08)81217eeb e86a51c1ff call nt!ExBlockOnAddressPushLock (80e2d05a)81217ef0 eb03 jmp nt! ?? ::NNGAKEGL::`string'+0x7988b (81217ef5)nt! ?? ::NNGAKEGL::`string'+0x79888:81217ef2 885de3 mov byte ptr [ebp-1Dh],blnt! ?? ::NNGAKEGL::`string'+0x7988b:81217ef5 807de300 cmp byte ptr [ebp-1Dh],081217ef9 75cf jne nt! ?? ::NNGAKEGL::`string'+0x79860 (81217eca)nt! ?? ::NNGAKEGL::`string'+0x79891:81217efb 8b7dd4 mov edi,dword ptr [ebp-2Ch]81217efe e9152af7ff jmp nt!CmUnRegisterCallback+0xc4 (8118a918)nt! ?? ::NNGAKEGL::`string'+0x79899:81217f03 b918fb0081 mov ecx,offset nt!CmpCallbackContextSList (8100fb18)81217f08 e803c1d0ff call nt!ExInterlockedFlushSList (80f24010)81217f0d 8bf0 mov esi,eax81217f0f eb0b jmp nt! ?? ::NNGAKEGL::`string'+0x798b2 (81217f1c)nt! ?? ::NNGAKEGL::`string'+0x798a7:81217f11 8bce mov ecx,esi81217f13 8b36 mov esi,dword ptr [esi]81217f15 53 push ebx81217f16 51 push ecx81217f17 e8f410ddff call nt!ExFreePoolWithTag (80fe9010)nt! ?? ::NNGAKEGL::`string'+0x798b2:81217f1c 85f6 test esi,esi81217f1e 75f1 jne nt! ?? ::NNGAKEGL::`string'+0x798a7 (81217f11)nt! ?? ::NNGAKEGL::`string'+0x798b6:81217f20 e9062af7ff jmp nt!CmUnRegisterCallback+0xd7 (8118a92b)nt! ?? ::NNGAKEGL::`string'+0x798bb:81217f25 b89a0000c0 mov eax,0C000009Ah81217f2a e9222bf7ff jmp nt!CmpRegisterCallbackInternal+0x99 (8118aa51)nt! ?? ::NNGAKEGL::`string'+0x798c5:81217f2f 8b4624 mov eax,dword ptr [esi+24h]81217f32 85c0 test eax,eax81217f34 7408 je nt! ?? ::NNGAKEGL::`string'+0x798d4 (81217f3e)nt! ?? ::NNGAKEGL::`string'+0x798cc:81217f36 6a00 push 081217f38 50 push eax81217f39 e8d210ddff call nt!ExFreePoolWithTag (80fe9010)nt! ?? ::NNGAKEGL::`string'+0x798d4:81217f3e 6a00 push 081217f40 56 push esi81217f41 e8ca10ddff call nt!ExFreePoolWithTag (80fe9010)81217f46 e9042bf7ff jmp nt!CmpRegisterCallbackInternal+0x97 (8118aa4f)
    Win8.1 64 位 CmUnRegisterCallbacklkd> uf CmUnRegisterCallbacknt!CmUnRegisterCallback:fffff803`10797d84 48894c2408 mov qword ptr [rsp+8],rcxfffff803`10797d89 4c8bdc mov r11,rspfffff803`10797d8c 53 push rbxfffff803`10797d8d 56 push rsifffff803`10797d8e 57 push rdifffff803`10797d8f 4154 push r12fffff803`10797d91 4155 push r13fffff803`10797d93 4156 push r14fffff803`10797d95 4157 push r15fffff803`10797d97 4881ec80000000 sub rsp,80hfffff803`10797d9e be0d0000c0 mov esi,0C000000Dhfffff803`10797da3 89b424d8000000 mov dword ptr [rsp+0D8h],esifffff803`10797daa 498363a800 and qword ptr [r11-58h],0fffff803`10797daf 33c0 xor eax,eaxfffff803`10797db1 498943b0 mov qword ptr [r11-50h],raxfffff803`10797db5 498943b8 mov qword ptr [r11-48h],raxfffff803`10797db9 49214380 and qword ptr [r11-80h],raxfffff803`10797dbd e856030000 call nt!CmpLockCallbackListExclusive (fffff803`10798118)fffff803`10797dc2 41be00000080 mov r14d,80000000hnt!CmUnRegisterCallback+0x44:fffff803`10797dc8 4533c0 xor r8d,r8dfffff803`10797dcb 488d542438 lea rdx,[rsp+38h]fffff803`10797dd0 488d0d39f5dbff lea rcx,[nt!CallbackListHead (fffff803`10557310)]fffff803`10797dd7 e85469f1ff call nt!CmListGetNextElement (fffff803`106ae730)fffff803`10797ddc 488bf8 mov rdi,raxfffff803`10797ddf 4889442440 mov qword ptr [rsp+40h],raxfffff803`10797de4 4885c0 test rax,raxfffff803`10797de7 0f845e010000 je nt!CmUnRegisterCallback+0x1c7 (fffff803`10797f4b)nt!CmUnRegisterCallback+0x69:fffff803`10797ded 488b8424c0000000 mov rax,qword ptr [rsp+0C0h]fffff803`10797df5 48394718 cmp qword ptr [rdi+18h],raxfffff803`10797df9 75cd jne nt!CmUnRegisterCallback+0x44 (fffff803`10797dc8)nt!CmUnRegisterCallback+0x77:fffff803`10797dfb 8b4710 mov eax,dword ptr [rdi+10h]fffff803`10797dfe 898424d0000000 mov dword ptr [rsp+0D0h],eaxfffff803`10797e05 85c0 test eax,eaxfffff803`10797e07 0f85c6000000 jne nt!CmUnRegisterCallback+0x14f (fffff803`10797ed3)nt!CmUnRegisterCallback+0x89:fffff803`10797e0d 488b0f mov rcx,qword ptr [rdi]fffff803`10797e10 488b4708 mov rax,qword ptr [rdi+8]fffff803`10797e14 48397908 cmp qword ptr [rcx+8],rdifffff803`10797e18 0f8598bc0900 jne nt! ?? ::NNGAKEGL::`string'+0x84eb6 (fffff803`10833ab6)nt!CmUnRegisterCallback+0x9a:fffff803`10797e1e 483938 cmp qword ptr [rax],rdifffff803`10797e21 0f858fbc0900 jne nt! ?? ::NNGAKEGL::`string'+0x84eb6 (fffff803`10833ab6)nt!CmUnRegisterCallback+0xa3:fffff803`10797e27 488908 mov qword ptr [rax],rcxfffff803`10797e2a 48894108 mov qword ptr [rcx+8],raxfffff803`10797e2e e8116afcff call nt!CmpUnlockCallbackList (fffff803`1075e844)fffff803`10797e33 33f6 xor esi,esifffff803`10797e35 89b424d8000000 mov dword ptr [rsp+0D8h],esint!CmUnRegisterCallback+0xb8:fffff803`10797e3c 488d442450 lea rax,[rsp+50h]fffff803`10797e41 4889442458 mov qword ptr [rsp+58h],raxfffff803`10797e46 488d442450 lea rax,[rsp+50h]fffff803`10797e4b 4889442450 mov qword ptr [rsp+50h],raxfffff803`10797e50 4532f6 xor r14b,r14bfffff803`10797e53 4488b424c8000000 mov byte ptr [rsp+0C8h],r14bfffff803`10797e5b e894030000 call nt!CmpLockContextListExclusive (fffff803`107981f4)fffff803`10797e60 4c8d6740 lea r12,[rdi+40h]fffff803`10797e64 498b1c24 mov rbx,qword ptr [r12]nt!CmUnRegisterCallback+0xe4:fffff803`10797e68 48895c2430 mov qword ptr [rsp+30h],rbxfffff803`10797e6d 493bdc cmp rbx,r12fffff803`10797e70 0f8547bc0900 jne nt! ?? ::NNGAKEGL::`string'+0x84ebd (fffff803`10833abd)nt!CmUnRegisterCallback+0xf2:fffff803`10797e76 e8f1020000 call nt!CmpUnlockContextList (fffff803`1079816c)nt!CmUnRegisterCallback+0xf7:fffff803`10797e7b 488d4c2450 lea rcx,[rsp+50h]fffff803`10797e80 488b442450 mov rax,qword ptr [rsp+50h]fffff803`10797e85 483bc1 cmp rax,rcxfffff803`10797e88 0f85c6bc0900 jne nt! ?? ::NNGAKEGL::`string'+0x84f54 (fffff803`10833b54)nt!CmUnRegisterCallback+0x10a:fffff803`10797e8e 4584f6 test r14b,r14bfffff803`10797e91 0f8549bd0900 jne nt! ?? ::NNGAKEGL::`string'+0x84fe0 (fffff803`10833be0)nt!CmUnRegisterCallback+0x113:fffff803`10797e97 f0ff0deebfd8ff lock dec dword ptr [nt!CmpCallBackCount (fffff803`10523e8c)]fffff803`10797e9e 0f8485bd0900 je nt! ?? ::NNGAKEGL::`string'+0x85029 (fffff803`10833c29)nt!CmUnRegisterCallback+0x120:fffff803`10797ea4 488b4f38 mov rcx,qword ptr [rdi+38h]fffff803`10797ea8 4885c9 test rcx,rcxfffff803`10797eab 7407 je nt!CmUnRegisterCallback+0x130 (fffff803`10797eb4)nt!CmUnRegisterCallback+0x129:fffff803`10797ead 33d2 xor edx,edxfffff803`10797eaf e86cdfd7ff call nt!ExFreePoolWithTag (fffff803`10515e20)nt!CmUnRegisterCallback+0x130:fffff803`10797eb4 33d2 xor edx,edxfffff803`10797eb6 488bcf mov rcx,rdifffff803`10797eb9 e862dfd7ff call nt!ExFreePoolWithTag (fffff803`10515e20)nt!CmUnRegisterCallback+0x13a:fffff803`10797ebe 8bc6 mov eax,esifffff803`10797ec0 4881c480000000 add rsp,80hfffff803`10797ec7 415f pop r15fffff803`10797ec9 415e pop r14fffff803`10797ecb 415d pop r13fffff803`10797ecd 415c pop r12fffff803`10797ecf 5f pop rdifffff803`10797ed0 5e pop rsifffff803`10797ed1 5b pop rbxfffff803`10797ed2 c3 retnt!CmUnRegisterCallback+0x14f:fffff803`10797ed3 4185c6 test r14d,eaxfffff803`10797ed6 0f85ecfeffff jne nt!CmUnRegisterCallback+0x44 (fffff803`10797dc8)nt!CmUnRegisterCallback+0x158:fffff803`10797edc 488d5f10 lea rbx,[rdi+10h]fffff803`10797ee0 f0810b00000080 lock or dword ptr [rbx],80000000hfffff803`10797ee7 e85869fcff call nt!CmpUnlockCallbackList (fffff803`1075e844)nt!CmUnRegisterCallback+0x168:fffff803`10797eec 8b03 mov eax,dword ptr [rbx]fffff803`10797eee 898424d0000000 mov dword ptr [rsp+0D0h],eaxfffff803`10797ef5 413bc6 cmp eax,r14dfffff803`10797ef8 7425 je nt!CmUnRegisterCallback+0x19b (fffff803`10797f1f)nt!CmUnRegisterCallback+0x176:fffff803`10797efa 488364242000 and qword ptr [rsp+20h],0fffff803`10797f00 41b904000000 mov r9d,4fffff803`10797f06 4c8d8424d0000000 lea r8,[rsp+0D0h]fffff803`10797f0e 488bd3 mov rdx,rbxfffff803`10797f11 488d0d08f4dbff lea rcx,[nt!CallbackListDeleteEvent (fffff803`10557320)]fffff803`10797f18 e88313baff call nt!ExBlockOnAddressPushLock (fffff803`103392a0)fffff803`10797f1d ebcd jmp nt!CmUnRegisterCallback+0x168 (fffff803`10797eec)nt!CmUnRegisterCallback+0x19b:fffff803`10797f1f e8f4010000 call nt!CmpLockCallbackListExclusive (fffff803`10798118)fffff803`10797f24 488b0f mov rcx,qword ptr [rdi]fffff803`10797f27 488b4708 mov rax,qword ptr [rdi+8]fffff803`10797f2b 48397908 cmp qword ptr [rcx+8],rdifffff803`10797f2f 7524 jne nt!CmUnRegisterCallback+0x1d1 (fffff803`10797f55)nt!CmUnRegisterCallback+0x1ad:fffff803`10797f31 483938 cmp qword ptr [rax],rdifffff803`10797f34 751f jne nt!CmUnRegisterCallback+0x1d1 (fffff803`10797f55)nt!CmUnRegisterCallback+0x1b2:fffff803`10797f36 488908 mov qword ptr [rax],rcxfffff803`10797f39 48894108 mov qword ptr [rcx+8],raxfffff803`10797f3d e80269fcff call nt!CmpUnlockCallbackList (fffff803`1075e844)fffff803`10797f42 33f6 xor esi,esifffff803`10797f44 89b424d8000000 mov dword ptr [rsp+0D8h],esint!CmUnRegisterCallback+0x1c7:fffff803`10797f4b 85f6 test esi,esifffff803`10797f4d 0f89e9feffff jns nt!CmUnRegisterCallback+0xb8 (fffff803`10797e3c)nt!CmUnRegisterCallback+0x1cf:fffff803`10797f53 eb07 jmp nt!CmUnRegisterCallback+0x1d8 (fffff803`10797f5c)nt!CmUnRegisterCallback+0x1d1:fffff803`10797f55 b903000000 mov ecx,3fffff803`10797f5a cd29 int 29hnt!CmUnRegisterCallback+0x1d8:fffff803`10797f5c e8e368fcff call nt!CmpUnlockCallbackList (fffff803`1075e844)fffff803`10797f61 e958ffffff jmp nt!CmUnRegisterCallback+0x13a (fffff803`10797ebe)nt! ?? ::NNGAKEGL::`string'+0x84eb6:fffff803`10833ab6 b903000000 mov ecx,3fffff803`10833abb cd29 int 29hnt! ?? ::NNGAKEGL::`string'+0x84ebd:fffff803`10833abd 4c8b2b mov r13,qword ptr [rbx]fffff803`10833ac0 4c8d7bf0 lea r15,[rbx-10h]fffff803`10833ac4 498b4f30 mov rcx,qword ptr [r15+30h]fffff803`10833ac8 e8c712abff call nt!ObReferenceObjectSafe (fffff803`102e4d94)fffff803`10833acd 84c0 test al,alfffff803`10833acf 745b je nt! ?? ::NNGAKEGL::`string'+0x84f2c (fffff803`10833b2c)nt! ?? ::NNGAKEGL::`string'+0x84ed1:fffff803`10833ad1 498d4710 lea rax,[r15+10h]fffff803`10833ad5 488b10 mov rdx,qword ptr [rax]fffff803`10833ad8 488b4808 mov rcx,qword ptr [rax+8]fffff803`10833adc 48394208 cmp qword ptr [rdx+8],raxfffff803`10833ae0 756b jne nt! ?? ::NNGAKEGL::`string'+0x84f4d (fffff803`10833b4d)nt! ?? ::NNGAKEGL::`string'+0x84ee2:fffff803`10833ae2 483901 cmp qword ptr [rcx],raxfffff803`10833ae5 7566 jne nt! ?? ::NNGAKEGL::`string'+0x84f4d (fffff803`10833b4d)nt! ?? ::NNGAKEGL::`string'+0x84ee7:fffff803`10833ae7 488911 mov qword ptr [rcx],rdxfffff803`10833aea 48894a08 mov qword ptr [rdx+8],rcxfffff803`10833aee 498b0f mov rcx,qword ptr [r15]fffff803`10833af1 498b4708 mov rax,qword ptr [r15+8]fffff803`10833af5 4c397908 cmp qword ptr [rcx+8],r15fffff803`10833af9 754b jne nt! ?? ::NNGAKEGL::`string'+0x84f46 (fffff803`10833b46)nt! ?? ::NNGAKEGL::`string'+0x84efb:fffff803`10833afb 4c3938 cmp qword ptr [rax],r15fffff803`10833afe 7546 jne nt! ?? ::NNGAKEGL::`string'+0x84f46 (fffff803`10833b46)nt! ?? ::NNGAKEGL::`string'+0x84f00:fffff803`10833b00 488908 mov qword ptr [rax],rcxfffff803`10833b03 48894108 mov qword ptr [rcx+8],raxfffff803`10833b07 488b442458 mov rax,qword ptr [rsp+58h]fffff803`10833b0c 488d4c2450 lea rcx,[rsp+50h]fffff803`10833b11 48890b mov qword ptr [rbx],rcxfffff803`10833b14 48894308 mov qword ptr [rbx+8],raxfffff803`10833b18 488d4c2450 lea rcx,[rsp+50h]fffff803`10833b1d 483908 cmp qword ptr [rax],rcxfffff803`10833b20 751d jne nt! ?? ::NNGAKEGL::`string'+0x84f3f (fffff803`10833b3f)nt! ?? ::NNGAKEGL::`string'+0x84f22:fffff803`10833b22 488918 mov qword ptr [rax],rbxfffff803`10833b25 48895c2458 mov qword ptr [rsp+58h],rbxfffff803`10833b2a eb0b jmp nt! ?? ::NNGAKEGL::`string'+0x84f37 (fffff803`10833b37)nt! ?? ::NNGAKEGL::`string'+0x84f2c:fffff803`10833b2c 41b601 mov r14b,1fffff803`10833b2f 4488b424c8000000 mov byte ptr [rsp+0C8h],r14bnt! ?? ::NNGAKEGL::`string'+0x84f37:fffff803`10833b37 498bdd mov rbx,r13fffff803`10833b3a e92943f6ff jmp nt!CmUnRegisterCallback+0xe4 (fffff803`10797e68)nt! ?? ::NNGAKEGL::`string'+0x84f3f:fffff803`10833b3f b903000000 mov ecx,3fffff803`10833b44 cd29 int 29hnt! ?? ::NNGAKEGL::`string'+0x84f46:fffff803`10833b46 b903000000 mov ecx,3fffff803`10833b4b cd29 int 29hnt! ?? ::NNGAKEGL::`string'+0x84f4d:fffff803`10833b4d b903000000 mov ecx,3fffff803`10833b52 cd29 int 29hnt! ?? ::NNGAKEGL::`string'+0x84f54:fffff803`10833b54 488b08 mov rcx,qword ptr [rax]fffff803`10833b57 488d542450 lea rdx,[rsp+50h]fffff803`10833b5c 48395008 cmp qword ptr [rax+8],rdxfffff803`10833b60 7577 jne nt! ?? ::NNGAKEGL::`string'+0x84fd9 (fffff803`10833bd9)nt! ?? ::NNGAKEGL::`string'+0x84f62:fffff803`10833b62 48394108 cmp qword ptr [rcx+8],raxfffff803`10833b66 7571 jne nt! ?? ::NNGAKEGL::`string'+0x84fd9 (fffff803`10833bd9)nt! ?? ::NNGAKEGL::`string'+0x84f68:fffff803`10833b68 48894c2450 mov qword ptr [rsp+50h],rcxfffff803`10833b6d 488d542450 lea rdx,[rsp+50h]fffff803`10833b72 48895108 mov qword ptr [rcx+8],rdxfffff803`10833b76 488d58f0 lea rbx,[rax-10h]fffff803`10833b7a 48895c2448 mov qword ptr [rsp+48h],rbxfffff803`10833b7f 488b4330 mov rax,qword ptr [rbx+30h]fffff803`10833b83 4889442460 mov qword ptr [rsp+60h],raxfffff803`10833b88 488b4338 mov rax,qword ptr [rbx+38h]fffff803`10833b8c 4889442468 mov qword ptr [rsp+68h],raxfffff803`10833b91 4c8d442460 lea r8,[rsp+60h]fffff803`10833b96 ba28000000 mov edx,28hfffff803`10833b9b 488b4f20 mov rcx,qword ptr [rdi+20h]fffff803`10833b9f ff5728 call qword ptr [rdi+28h]fffff803`10833ba2 eb19 jmp nt! ?? ::NNGAKEGL::`string'+0x84fbd (fffff803`10833bbd)nt! ?? ::NNGAKEGL::`string'+0x84fbd:fffff803`10833bbd 488b4b30 mov rcx,qword ptr [rbx+30h]fffff803`10833bc1 e80a64abff call nt!ObfDereferenceObject (fffff803`102e9fd0)fffff803`10833bc6 ba434d6363 mov edx,63634D43hfffff803`10833bcb 488bcb mov rcx,rbxfffff803`10833bce e84d22ceff call nt!ExFreePoolWithTag (fffff803`10515e20)fffff803`10833bd3 90 nopfffff803`10833bd4 e9a242f6ff jmp nt!CmUnRegisterCallback+0xf7 (fffff803`10797e7b)nt! ?? ::NNGAKEGL::`string'+0x84fd9:fffff803`10833bd9 b903000000 mov ecx,3fffff803`10833bde cd29 int 29hnt! ?? ::NNGAKEGL::`string'+0x84fe0:fffff803`10833be0 e80f46f6ff call nt!CmpLockContextListExclusive (fffff803`107981f4)fffff803`10833be5 4c8d7f40 lea r15,[rdi+40h]fffff803`10833be9 498b1f mov rbx,qword ptr [r15]fffff803`10833bec 48895c2430 mov qword ptr [rsp+30h],rbxfffff803`10833bf1 e87645f6ff call nt!CmpUnlockContextList (fffff803`1079816c)fffff803`10833bf6 493bdf cmp rbx,r15fffff803`10833bf9 7426 je nt! ?? ::NNGAKEGL::`string'+0x85021 (fffff803`10833c21)nt! ?? ::NNGAKEGL::`string'+0x84ffb:fffff803`10833bfb 488364242000 and qword ptr [rsp+20h],0fffff803`10833c01 41b908000000 mov r9d,8fffff803`10833c07 4c8d442430 lea r8,[rsp+30h]fffff803`10833c0c 498bd7 mov rdx,r15fffff803`10833c0f 488d0d0a37d2ff lea rcx,[nt!CallbackListDeleteEvent (fffff803`10557320)]fffff803`10833c16 e88556b0ff call nt!ExBlockOnAddressPushLock (fffff803`103392a0)fffff803`10833c1b 90 nopfffff803`10833c1c e96d42f6ff jmp nt!CmUnRegisterCallback+0x10a (fffff803`10797e8e)nt! ?? ::NNGAKEGL::`string'+0x85021:fffff803`10833c21 4532f6 xor r14b,r14bfffff803`10833c24 e96542f6ff jmp nt!CmUnRegisterCallback+0x10a (fffff803`10797e8e)nt! ?? ::NNGAKEGL::`string'+0x85029:fffff803`10833c29 488d0dd057d2ff lea rcx,[nt!CmpCallbackContextSList (fffff803`10559400)]fffff803`10833c30 e85b51baff call nt!ExpInterlockedFlushSList (fffff803`103d8d90)fffff803`10833c35 488bd8 mov rbx,raxnt! ?? ::NNGAKEGL::`string'+0x85038:fffff803`10833c38 4885db test rbx,rbxfffff803`10833c3b 0f846342f6ff je nt!CmUnRegisterCallback+0x120 (fffff803`10797ea4)nt! ?? ::NNGAKEGL::`string'+0x85041:fffff803`10833c41 488bcb mov rcx,rbxfffff803`10833c44 488b1b mov rbx,qword ptr [rbx]fffff803`10833c47 33d2 xor edx,edxfffff803`10833c49 e8d221ceff call nt!ExFreePoolWithTag (fffff803`10515e20)fffff803`10833c4e ebe8 jmp nt! ?? ::NNGAKEGL::`string'+0x85038 (fffff803`10833c38)
    Win10 32 位 CmUnRegisterCallbackkd> uf CmUnRegisterCallbacknt!CmUnRegisterCallback:81ee7c8f 6a38 push 38h81ee7c91 6880eac881 push offset nt!RtlpSparseBitmapCtxUpdateBits+0x6a49 (81c8ea80)81ee7c96 e8154bcbff call nt!_SEH_prolog4 (81b9c7b0)81ee7c9b 33db xor ebx,ebx81ee7c9d 895dbc mov dword ptr [ebp-44h],ebx81ee7ca0 895dc0 mov dword ptr [ebp-40h],ebx81ee7ca3 895dc4 mov dword ptr [ebp-3Ch],ebx81ee7ca6 895dd0 mov dword ptr [ebp-30h],ebx81ee7ca9 64a124010000 mov eax,dword ptr fs:[00000124h]81ee7caf 66ff883c010000 dec word ptr [eax+13Ch]81ee7cb6 53 push ebx81ee7cb7 33d2 xor edx,edx81ee7cb9 bf9817cb81 mov edi,offset nt!CmpCallbackListLock (81cb1798)81ee7cbe 8bcf mov ecx,edi81ee7cc0 e85b8dc4ff call nt!KeAbPreAcquire (81b30a20)81ee7cc5 8bf0 mov esi,eax81ee7cc7 f00fba2f00 lock bts dword ptr [edi],081ee7ccc 730a jae nt!CmUnRegisterCallback+0x49 (81ee7cd8)nt!CmUnRegisterCallback+0x3f:81ee7cce 57 push edi81ee7ccf 8bd6 mov edx,esi81ee7cd1 8bcf mov ecx,edi81ee7cd3 e82877bbff call nt!ExfAcquirePushLockExclusiveEx (81a9f400)nt!CmUnRegisterCallback+0x49:81ee7cd8 85f6 test esi,esi81ee7cda 7407 je nt!CmUnRegisterCallback+0x54 (81ee7ce3)nt!CmUnRegisterCallback+0x4d:81ee7cdc 8b4610 mov eax,dword ptr [esi+10h]81ee7cdf 804e0e01 or byte ptr [esi+0Eh],1nt!CmUnRegisterCallback+0x54:81ee7ce3 53 push ebx81ee7ce4 8d55d0 lea edx,[ebp-30h]81ee7ce7 b9a017cb81 mov ecx,offset nt!CallbackListHead (81cb17a0)81ee7cec e853cae8ff call nt!CmListGetNextElement (81d74744)81ee7cf1 8bf0 mov esi,eax81ee7cf3 8975dc mov dword ptr [ebp-24h],esi81ee7cf6 85f6 test esi,esi81ee7cf8 0f8496040000 je nt!CmUnRegisterCallback+0x505 (81ee8194)nt!CmUnRegisterCallback+0x6f:81ee7cfe 8b4e10 mov ecx,dword ptr [esi+10h]81ee7d01 3b4d08 cmp ecx,dword ptr [ebp+8]81ee7d04 75dd jne nt!CmUnRegisterCallback+0x54 (81ee7ce3)nt!CmUnRegisterCallback+0x77:81ee7d06 8b4e14 mov ecx,dword ptr [esi+14h]81ee7d09 3b4d0c cmp ecx,dword ptr [ebp+0Ch]81ee7d0c 75d5 jne nt!CmUnRegisterCallback+0x54 (81ee7ce3)nt!CmUnRegisterCallback+0x7f:81ee7d0e 8b4608 mov eax,dword ptr [esi+8]81ee7d11 8945e0 mov dword ptr [ebp-20h],eax81ee7d14 3bc3 cmp eax,ebx81ee7d16 0f8412010000 je nt!CmUnRegisterCallback+0x19f (81ee7e2e)nt!CmUnRegisterCallback+0x8d:81ee7d1c b800000080 mov eax,80000000h81ee7d21 8545e0 test dword ptr [ebp-20h],eax81ee7d24 75bd jne nt!CmUnRegisterCallback+0x54 (81ee7ce3)nt!CmUnRegisterCallback+0x97:81ee7d26 8d7e08 lea edi,[esi+8]81ee7d29 f00907 lock or dword ptr [edi],eax81ee7d2c 8b0d9817cb81 mov ecx,dword ptr [nt!CmpCallbackListLock (81cb1798)]81ee7d32 8bc1 mov eax,ecx81ee7d34 83e0f0 and eax,0FFFFFFF0h81ee7d37 83f810 cmp eax,10h81ee7d3a 8d51f0 lea edx,[ecx-10h]81ee7d3d 7702 ja nt!CmUnRegisterCallback+0xb2 (81ee7d41)nt!CmUnRegisterCallback+0xb0:81ee7d3f 8bd3 mov edx,ebxnt!CmUnRegisterCallback+0xb2:81ee7d41 f6c102 test cl,281ee7d44 7512 jne nt!CmUnRegisterCallback+0xc9 (81ee7d58)nt!CmUnRegisterCallback+0xb7:81ee7d46 8bc1 mov eax,ecx81ee7d48 be9817cb81 mov esi,offset nt!CmpCallbackListLock (81cb1798)81ee7d4d f00fb116 lock cmpxchg dword ptr [esi],edx81ee7d51 3bc1 cmp eax,ecx81ee7d53 8b75dc mov esi,dword ptr [ebp-24h]81ee7d56 740a je nt!CmUnRegisterCallback+0xd3 (81ee7d62)nt!CmUnRegisterCallback+0xc9:81ee7d58 b99817cb81 mov ecx,offset nt!CmpCallbackListLock (81cb1798)81ee7d5d e81e87bbff call nt!ExfReleasePushLock (81aa0480)nt!CmUnRegisterCallback+0xd3:81ee7d62 b99817cb81 mov ecx,offset nt!CmpCallbackListLock (81cb1798)81ee7d67 e8f488c4ff call nt!KeAbPostRelease (81b30660)81ee7d6c 648b0d24010000 mov ecx,dword ptr fs:[124h]81ee7d73 0fbf813c010000 movsx eax,word ptr [ecx+13Ch]81ee7d7a 40 inc eax81ee7d7b 6689813c010000 mov word ptr [ecx+13Ch],ax81ee7d82 6685c0 test ax,ax81ee7d85 752a jne nt!CmUnRegisterCallback+0x122 (81ee7db1)nt!CmUnRegisterCallback+0xf8:81ee7d87 8d4170 lea eax,[ecx+70h]81ee7d8a 3900 cmp dword ptr [eax],eax81ee7d8c 7423 je nt!CmUnRegisterCallback+0x122 (81ee7db1)nt!CmUnRegisterCallback+0xff:81ee7d8e 6639993e010000 cmp word ptr [ecx+13Eh],bx81ee7d95 751a jne nt!CmUnRegisterCallback+0x122 (81ee7db1)nt!CmUnRegisterCallback+0x108:81ee7d97 e8707abbff call nt!KiCheckForKernelApcDelivery (81a9f80c)81ee7d9c eb13 jmp nt!CmUnRegisterCallback+0x122 (81ee7db1)nt!CmUnRegisterCallback+0x10f:81ee7d9e 53 push ebx81ee7d9f 6a04 push 481ee7da1 8d45e0 lea eax,[ebp-20h]81ee7da4 50 push eax81ee7da5 8bd7 mov edx,edi81ee7da7 b9a817cb81 mov ecx,offset nt!CallbackListDeleteEvent (81cb17a8)81ee7dac e8c715c1ff call nt!ExBlockOnAddressPushLock (81af9378)nt!CmUnRegisterCallback+0x122:81ee7db1 8b07 mov eax,dword ptr [edi]81ee7db3 8945e0 mov dword ptr [ebp-20h],eax81ee7db6 3d00000080 cmp eax,80000000h81ee7dbb 75e1 jne nt!CmUnRegisterCallback+0x10f (81ee7d9e)nt!CmUnRegisterCallback+0x12e:81ee7dbd 64a124010000 mov eax,dword ptr fs:[00000124h]81ee7dc3 66ff883c010000 dec word ptr [eax+13Ch]81ee7dca 53 push ebx81ee7dcb 33d2 xor edx,edx81ee7dcd b99817cb81 mov ecx,offset nt!CmpCallbackListLock (81cb1798)81ee7dd2 e8498cc4ff call nt!KeAbPreAcquire (81b30a20)81ee7dd7 8bf8 mov edi,eax81ee7dd9 b89817cb81 mov eax,offset nt!CmpCallbackListLock (81cb1798)81ee7dde f00fba2800 lock bts dword ptr [eax],081ee7de3 730a jae nt!CmUnRegisterCallback+0x160 (81ee7def)nt!CmUnRegisterCallback+0x156:81ee7de5 50 push eax81ee7de6 8bd7 mov edx,edi81ee7de8 8bc8 mov ecx,eax81ee7dea e81176bbff call nt!ExfAcquirePushLockExclusiveEx (81a9f400)nt!CmUnRegisterCallback+0x160:81ee7def 85ff test edi,edi81ee7df1 7407 je nt!CmUnRegisterCallback+0x16b (81ee7dfa)nt!CmUnRegisterCallback+0x164:81ee7df3 8b4710 mov eax,dword ptr [edi+10h]81ee7df6 804f0e01 or byte ptr [edi+0Eh],1nt!CmUnRegisterCallback+0x16b:81ee7dfa 8b0e mov ecx,dword ptr [esi]81ee7dfc 8b4604 mov eax,dword ptr [esi+4]81ee7dff 397104 cmp dword ptr [ecx+4],esi81ee7e02 7525 jne nt!CmUnRegisterCallback+0x19a (81ee7e29)nt!CmUnRegisterCallback+0x175:81ee7e04 3930 cmp dword ptr [eax],esi81ee7e06 7521 jne nt!CmUnRegisterCallback+0x19a (81ee7e29)nt!CmUnRegisterCallback+0x179:81ee7e08 8908 mov dword ptr [eax],ecx81ee7e0a 894104 mov dword ptr [ecx+4],eax81ee7e0d 8b0d9817cb81 mov ecx,dword ptr [nt!CmpCallbackListLock (81cb1798)]81ee7e13 8bc1 mov eax,ecx81ee7e15 83e0f0 and eax,0FFFFFFF0h81ee7e18 83f810 cmp eax,10h81ee7e1b 8d51f0 lea edx,[ecx-10h]81ee7e1e 7702 ja nt!CmUnRegisterCallback+0x193 (81ee7e22)nt!CmUnRegisterCallback+0x191:81ee7e20 8bd3 mov edx,ebxnt!CmUnRegisterCallback+0x193:81ee7e22 bf9817cb81 mov edi,offset nt!CmpCallbackListLock (81cb1798)81ee7e27 eb2d jmp nt!CmUnRegisterCallback+0x1c7 (81ee7e56)nt!CmUnRegisterCallback+0x19a:81ee7e29 6a03 push 381ee7e2b 59 pop ecx81ee7e2c cd29 int 29hnt!CmUnRegisterCallback+0x19f:81ee7e2e 8b0e mov ecx,dword ptr [esi]81ee7e30 8b4604 mov eax,dword ptr [esi+4]81ee7e33 397104 cmp dword ptr [ecx+4],esi81ee7e36 75f1 jne nt!CmUnRegisterCallback+0x19a (81ee7e29)nt!CmUnRegisterCallback+0x1a9:81ee7e38 3930 cmp dword ptr [eax],esi81ee7e3a 75ed jne nt!CmUnRegisterCallback+0x19a (81ee7e29)nt!CmUnRegisterCallback+0x1ad:81ee7e3c 8908 mov dword ptr [eax],ecx81ee7e3e 894104 mov dword ptr [ecx+4],eax81ee7e41 8b0d9817cb81 mov ecx,dword ptr [nt!CmpCallbackListLock (81cb1798)]81ee7e47 8bc1 mov eax,ecx81ee7e49 83e0f0 and eax,0FFFFFFF0h81ee7e4c 83f810 cmp eax,10h81ee7e4f 8d51f0 lea edx,[ecx-10h]81ee7e52 7702 ja nt!CmUnRegisterCallback+0x1c7 (81ee7e56)nt!CmUnRegisterCallback+0x1c5:81ee7e54 8bd3 mov edx,ebxnt!CmUnRegisterCallback+0x1c7:81ee7e56 f6c102 test cl,281ee7e59 750a jne nt!CmUnRegisterCallback+0x1d6 (81ee7e65)nt!CmUnRegisterCallback+0x1cc:81ee7e5b 8bc1 mov eax,ecx81ee7e5d f00fb117 lock cmpxchg dword ptr [edi],edx81ee7e61 3bc1 cmp eax,ecx81ee7e63 7407 je nt!CmUnRegisterCallback+0x1dd (81ee7e6c)nt!CmUnRegisterCallback+0x1d6:81ee7e65 8bcf mov ecx,edi81ee7e67 e81486bbff call nt!ExfReleasePushLock (81aa0480)nt!CmUnRegisterCallback+0x1dd:81ee7e6c 8bcf mov ecx,edi81ee7e6e e8ed87c4ff call nt!KeAbPostRelease (81b30660)81ee7e73 648b0d24010000 mov ecx,dword ptr fs:[124h]81ee7e7a 0fbf813c010000 movsx eax,word ptr [ecx+13Ch]81ee7e81 40 inc eax81ee7e82 6685c0 test ax,ax81ee7e85 6689813c010000 mov word ptr [ecx+13Ch],ax81ee7e8c 7515 jne nt!CmUnRegisterCallback+0x214 (81ee7ea3)nt!CmUnRegisterCallback+0x1ff:81ee7e8e 8d4170 lea eax,[ecx+70h]81ee7e91 3900 cmp dword ptr [eax],eax81ee7e93 740e je nt!CmUnRegisterCallback+0x214 (81ee7ea3)nt!CmUnRegisterCallback+0x206:81ee7e95 6639993e010000 cmp word ptr [ecx+13Eh],bx81ee7e9c 7505 jne nt!CmUnRegisterCallback+0x214 (81ee7ea3)nt!CmUnRegisterCallback+0x20f:81ee7e9e e86979bbff call nt!KiCheckForKernelApcDelivery (81a9f80c)nt!CmUnRegisterCallback+0x214:81ee7ea3 895dd4 mov dword ptr [ebp-2Ch],ebx81ee7ea6 8d45c8 lea eax,[ebp-38h]81ee7ea9 8945cc mov dword ptr [ebp-34h],eax81ee7eac 8945c8 mov dword ptr [ebp-38h],eax81ee7eaf 885de7 mov byte ptr [ebp-19h],bl81ee7eb2 64a124010000 mov eax,dword ptr fs:[00000124h]81ee7eb8 66ff883c010000 dec word ptr [eax+13Ch]81ee7ebf 53 push ebx81ee7ec0 33d2 xor edx,edx81ee7ec2 bf9c17cb81 mov edi,offset nt!CmpContextListLock (81cb179c)81ee7ec7 8bcf mov ecx,edi81ee7ec9 e8528bc4ff call nt!KeAbPreAcquire (81b30a20)81ee7ece 8bc8 mov ecx,eax81ee7ed0 894dd0 mov dword ptr [ebp-30h],ecx81ee7ed3 f00fba2f00 lock bts dword ptr [edi],081ee7ed8 730d jae nt!CmUnRegisterCallback+0x258 (81ee7ee7)nt!CmUnRegisterCallback+0x24b:81ee7eda 57 push edi81ee7edb 8bd1 mov edx,ecx81ee7edd 8bcf mov ecx,edi81ee7edf e81c75bbff call nt!ExfAcquirePushLockExclusiveEx (81a9f400)81ee7ee4 8b4dd0 mov ecx,dword ptr [ebp-30h]nt!CmUnRegisterCallback+0x258:81ee7ee7 85c9 test ecx,ecx81ee7ee9 7407 je nt!CmUnRegisterCallback+0x263 (81ee7ef2)nt!CmUnRegisterCallback+0x25c:81ee7eeb 8b4110 mov eax,dword ptr [ecx+10h]81ee7eee 80490e01 or byte ptr [ecx+0Eh],1nt!CmUnRegisterCallback+0x263:81ee7ef2 8d4628 lea eax,[esi+28h]81ee7ef5 8b38 mov edi,dword ptr [eax]81ee7ef7 3bf8 cmp edi,eax81ee7ef9 0f8485000000 je nt!CmUnRegisterCallback+0x2f5 (81ee7f84)nt!CmUnRegisterCallback+0x270:81ee7eff 8b07 mov eax,dword ptr [edi]81ee7f01 8945d0 mov dword ptr [ebp-30h],eax81ee7f04 8b4f14 mov ecx,dword ptr [edi+14h]81ee7f07 e85430c4ff call nt!ObReferenceObjectSafe (81b2af60)81ee7f0c 84c0 test al,al81ee7f0e 7462 je nt!CmUnRegisterCallback+0x2e3 (81ee7f72)nt!CmUnRegisterCallback+0x281:81ee7f10 8d47f8 lea eax,[edi-8]81ee7f13 8d4808 lea ecx,[eax+8]81ee7f16 8b11 mov edx,dword ptr [ecx]81ee7f18 8955e0 mov dword ptr [ebp-20h],edx81ee7f1b 8b5104 mov edx,dword ptr [ecx+4]81ee7f1e 8b75e0 mov esi,dword ptr [ebp-20h]81ee7f21 394e04 cmp dword ptr [esi+4],ecx81ee7f24 8b75dc mov esi,dword ptr [ebp-24h]81ee7f27 0f85fcfeffff jne nt!CmUnRegisterCallback+0x19a (81ee7e29)nt!CmUnRegisterCallback+0x29e:81ee7f2d 390a cmp dword ptr [edx],ecx81ee7f2f 0f85f4feffff jne nt!CmUnRegisterCallback+0x19a (81ee7e29)nt!CmUnRegisterCallback+0x2a6:81ee7f35 8b4de0 mov ecx,dword ptr [ebp-20h]81ee7f38 890a mov dword ptr [edx],ecx81ee7f3a 895104 mov dword ptr [ecx+4],edx81ee7f3d 8b10 mov edx,dword ptr [eax]81ee7f3f 8b4804 mov ecx,dword ptr [eax+4]81ee7f42 394204 cmp dword ptr [edx+4],eax81ee7f45 0f85defeffff jne nt!CmUnRegisterCallback+0x19a (81ee7e29)nt!CmUnRegisterCallback+0x2bc:81ee7f4b 3901 cmp dword ptr [ecx],eax81ee7f4d 0f85d6feffff jne nt!CmUnRegisterCallback+0x19a (81ee7e29)nt!CmUnRegisterCallback+0x2c4:81ee7f53 8911 mov dword ptr [ecx],edx81ee7f55 894a04 mov dword ptr [edx+4],ecx81ee7f58 8b45cc mov eax,dword ptr [ebp-34h]81ee7f5b 8d4dc8 lea ecx,[ebp-38h]81ee7f5e 890f mov dword ptr [edi],ecx81ee7f60 894704 mov dword ptr [edi+4],eax81ee7f63 3908 cmp dword ptr [eax],ecx81ee7f65 0f85befeffff jne nt!CmUnRegisterCallback+0x19a (81ee7e29)nt!CmUnRegisterCallback+0x2dc:81ee7f6b 8938 mov dword ptr [eax],edi81ee7f6d 897dcc mov dword ptr [ebp-34h],edi81ee7f70 eb04 jmp nt!CmUnRegisterCallback+0x2e7 (81ee7f76)nt!CmUnRegisterCallback+0x2e3:81ee7f72 c645e701 mov byte ptr [ebp-19h],1nt!CmUnRegisterCallback+0x2e7:81ee7f76 8b7dd0 mov edi,dword ptr [ebp-30h]81ee7f79 8d4628 lea eax,[esi+28h]81ee7f7c 3bf8 cmp edi,eax81ee7f7e 0f857bffffff jne nt!CmUnRegisterCallback+0x270 (81ee7eff)nt!CmUnRegisterCallback+0x2f5:81ee7f84 8b0d9c17cb81 mov ecx,dword ptr [nt!CmpContextListLock (81cb179c)]81ee7f8a 8bc1 mov eax,ecx81ee7f8c 83e0f0 and eax,0FFFFFFF0h81ee7f8f 83f810 cmp eax,10h81ee7f92 8d51f0 lea edx,[ecx-10h]81ee7f95 7702 ja nt!CmUnRegisterCallback+0x30a (81ee7f99)nt!CmUnRegisterCallback+0x308:81ee7f97 8bd3 mov edx,ebxnt!CmUnRegisterCallback+0x30a:81ee7f99 bf9c17cb81 mov edi,offset nt!CmpContextListLock (81cb179c)81ee7f9e f6c102 test cl,281ee7fa1 750a jne nt!CmUnRegisterCallback+0x31e (81ee7fad)nt!CmUnRegisterCallback+0x314:81ee7fa3 8bc1 mov eax,ecx81ee7fa5 f00fb117 lock cmpxchg dword ptr [edi],edx81ee7fa9 3bc1 cmp eax,ecx81ee7fab 7407 je nt!CmUnRegisterCallback+0x325 (81ee7fb4)nt!CmUnRegisterCallback+0x31e:81ee7fad 8bcf mov ecx,edi81ee7faf e8cc84bbff call nt!ExfReleasePushLock (81aa0480)nt!CmUnRegisterCallback+0x325:81ee7fb4 8bcf mov ecx,edi81ee7fb6 e8a586c4ff call nt!KeAbPostRelease (81b30660)81ee7fbb 648b0d24010000 mov ecx,dword ptr fs:[124h]81ee7fc2 0fbf813c010000 movsx eax,word ptr [ecx+13Ch]81ee7fc9 40 inc eax81ee7fca 6689813c010000 mov word ptr [ecx+13Ch],ax81ee7fd1 6685c0 test ax,ax81ee7fd4 7515 jne nt!CmUnRegisterCallback+0x35c (81ee7feb)nt!CmUnRegisterCallback+0x347:81ee7fd6 8d4170 lea eax,[ecx+70h]81ee7fd9 3900 cmp dword ptr [eax],eax81ee7fdb 740e je nt!CmUnRegisterCallback+0x35c (81ee7feb)nt!CmUnRegisterCallback+0x34e:81ee7fdd 6639993e010000 cmp word ptr [ecx+13Eh],bx81ee7fe4 7505 jne nt!CmUnRegisterCallback+0x35c (81ee7feb)nt!CmUnRegisterCallback+0x357:81ee7fe6 e82178bbff call nt!KiCheckForKernelApcDelivery (81a9f80c)nt!CmUnRegisterCallback+0x35c:81ee7feb 8d4dc8 lea ecx,[ebp-38h]81ee7fee 8b45c8 mov eax,dword ptr [ebp-38h]81ee7ff1 3bc1 cmp eax,ecx81ee7ff3 747c je nt!CmUnRegisterCallback+0x3e2 (81ee8071)nt!CmUnRegisterCallback+0x366:81ee7ff5 8b08 mov ecx,dword ptr [eax]81ee7ff7 8d55c8 lea edx,[ebp-38h]81ee7ffa 395004 cmp dword ptr [eax+4],edx81ee7ffd 0f8526feffff jne nt!CmUnRegisterCallback+0x19a (81ee7e29)nt!CmUnRegisterCallback+0x374:81ee8003 394104 cmp dword ptr [ecx+4],eax81ee8006 0f851dfeffff jne nt!CmUnRegisterCallback+0x19a (81ee7e29)nt!CmUnRegisterCallback+0x37d:81ee800c 894dc8 mov dword ptr [ebp-38h],ecx81ee800f 895104 mov dword ptr [ecx+4],edx81ee8012 8d48f8 lea ecx,[eax-8]81ee8015 894de0 mov dword ptr [ebp-20h],ecx81ee8018 8b411c mov eax,dword ptr [ecx+1Ch]81ee801b 8945bc mov dword ptr [ebp-44h],eax81ee801e 8b4120 mov eax,dword ptr [ecx+20h]81ee8021 8945c0 mov dword ptr [ebp-40h],eax81ee8024 895dfc mov dword ptr [ebp-4],ebx81ee8027 8d45bc lea eax,[ebp-44h]81ee802a 50 push eax81ee802b 6a28 push 28h81ee802d ff7618 push dword ptr [esi+18h]81ee8030 ff561c call dword ptr [esi+1Ch]81ee8033 c745fcfeffffff mov dword ptr [ebp-4],0FFFFFFFEh81ee803a eb18 jmp nt!CmUnRegisterCallback+0x3c5 (81ee8054)nt!CmUnRegisterCallback+0x3c5:81ee8054 8b4de0 mov ecx,dword ptr [ebp-20h]81ee8057 8b491c mov ecx,dword ptr [ecx+1Ch]81ee805a e8713bc4ff call nt!ObfDereferenceObject (81b2bbd0)81ee805f 68434d6363 push 63634D43h81ee8064 ff75e0 push dword ptr [ebp-20h]81ee8067 e8b49fdaff call nt!ExFreePoolWithTag (81c92020)81ee806c e97affffff jmp nt!CmUnRegisterCallback+0x35c (81ee7feb)nt!CmUnRegisterCallback+0x3e2:81ee8071 807de700 cmp byte ptr [ebp-19h],081ee8075 0f84d4000000 je nt!CmUnRegisterCallback+0x4c0 (81ee814f)nt!CmUnRegisterCallback+0x3ec:81ee807b 8d4628 lea eax,[esi+28h]81ee807e 8945d0 mov dword ptr [ebp-30h],eax81ee8081 8bf0 mov esi,eaxnt!CmUnRegisterCallback+0x3f4:81ee8083 64a124010000 mov eax,dword ptr fs:[00000124h]81ee8089 66ff883c010000 dec word ptr [eax+13Ch]81ee8090 53 push ebx81ee8091 33d2 xor edx,edx81ee8093 8bcf mov ecx,edi81ee8095 e88689c4ff call nt!KeAbPreAcquire (81b30a20)81ee809a 8bc8 mov ecx,eax81ee809c 894dd0 mov dword ptr [ebp-30h],ecx81ee809f f00fba2f00 lock bts dword ptr [edi],081ee80a4 730d jae nt!CmUnRegisterCallback+0x424 (81ee80b3)nt!CmUnRegisterCallback+0x417:81ee80a6 57 push edi81ee80a7 8bd1 mov edx,ecx81ee80a9 8bcf mov ecx,edi81ee80ab e85073bbff call nt!ExfAcquirePushLockExclusiveEx (81a9f400)81ee80b0 8b4dd0 mov ecx,dword ptr [ebp-30h]nt!CmUnRegisterCallback+0x424:81ee80b3 85c9 test ecx,ecx81ee80b5 7407 je nt!CmUnRegisterCallback+0x42f (81ee80be)nt!CmUnRegisterCallback+0x428:81ee80b7 8b4110 mov eax,dword ptr [ecx+10h]81ee80ba 80490e01 or byte ptr [ecx+0Eh],1nt!CmUnRegisterCallback+0x42f:81ee80be 8b06 mov eax,dword ptr [esi]81ee80c0 8945d8 mov dword ptr [ebp-28h],eax81ee80c3 8b0d9c17cb81 mov ecx,dword ptr [nt!CmpContextListLock (81cb179c)]81ee80c9 8bc1 mov eax,ecx81ee80cb 83e0f0 and eax,0FFFFFFF0h81ee80ce 83f810 cmp eax,10h81ee80d1 8d51f0 lea edx,[ecx-10h]81ee80d4 7702 ja nt!CmUnRegisterCallback+0x449 (81ee80d8)nt!CmUnRegisterCallback+0x447:81ee80d6 8bd3 mov edx,ebxnt!CmUnRegisterCallback+0x449:81ee80d8 f6c102 test cl,281ee80db 750a jne nt!CmUnRegisterCallback+0x458 (81ee80e7)nt!CmUnRegisterCallback+0x44e:81ee80dd 8bc1 mov eax,ecx81ee80df f00fb117 lock cmpxchg dword ptr [edi],edx81ee80e3 3bc1 cmp eax,ecx81ee80e5 7407 je nt!CmUnRegisterCallback+0x45f (81ee80ee)nt!CmUnRegisterCallback+0x458:81ee80e7 8bcf mov ecx,edi81ee80e9 e89283bbff call nt!ExfReleasePushLock (81aa0480)nt!CmUnRegisterCallback+0x45f:81ee80ee 8bcf mov ecx,edi81ee80f0 e86b85c4ff call nt!KeAbPostRelease (81b30660)81ee80f5 648b0d24010000 mov ecx,dword ptr fs:[124h]81ee80fc 0fbf813c010000 movsx eax,word ptr [ecx+13Ch]81ee8103 40 inc eax81ee8104 6689813c010000 mov word ptr [ecx+13Ch],ax81ee810b 6685c0 test ax,ax81ee810e 7515 jne nt!CmUnRegisterCallback+0x496 (81ee8125)nt!CmUnRegisterCallback+0x481:81ee8110 8d4170 lea eax,[ecx+70h]81ee8113 3900 cmp dword ptr [eax],eax81ee8115 740e je nt!CmUnRegisterCallback+0x496 (81ee8125)nt!CmUnRegisterCallback+0x488:81ee8117 6639993e010000 cmp word ptr [ecx+13Eh],bx81ee811e 7505 jne nt!CmUnRegisterCallback+0x496 (81ee8125)nt!CmUnRegisterCallback+0x491:81ee8120 e8e776bbff call nt!KiCheckForKernelApcDelivery (81a9f80c)nt!CmUnRegisterCallback+0x496:81ee8125 3975d8 cmp dword ptr [ebp-28h],esi81ee8128 7415 je nt!CmUnRegisterCallback+0x4b0 (81ee813f)nt!CmUnRegisterCallback+0x49b:81ee812a 53 push ebx81ee812b 6a04 push 481ee812d 8d45d8 lea eax,[ebp-28h]81ee8130 50 push eax81ee8131 8bd6 mov edx,esi81ee8133 b9a817cb81 mov ecx,offset nt!CallbackListDeleteEvent (81cb17a8)81ee8138 e83b12c1ff call nt!ExBlockOnAddressPushLock (81af9378)81ee813d eb03 jmp nt!CmUnRegisterCallback+0x4b3 (81ee8142)nt!CmUnRegisterCallback+0x4b0:81ee813f 885de7 mov byte ptr [ebp-19h],blnt!CmUnRegisterCallback+0x4b3:81ee8142 807de700 cmp byte ptr [ebp-19h],081ee8146 0f8537ffffff jne nt!CmUnRegisterCallback+0x3f4 (81ee8083)nt!CmUnRegisterCallback+0x4bd:81ee814c 8b75dc mov esi,dword ptr [ebp-24h]nt!CmUnRegisterCallback+0x4c0:81ee814f 83c8ff or eax,0FFFFFFFFh81ee8152 f00fc105b87ecb81 lock xadd dword ptr [nt!CmpCallBackCount (81cb7eb8)],eax81ee815a 48 dec eax81ee815b 751d jne nt!CmUnRegisterCallback+0x4eb (81ee817a)nt!CmUnRegisterCallback+0x4ce:81ee815d b9b817cb81 mov ecx,offset nt!CmpCallbackContextSList (81cb17b8)81ee8162 e809a5cbff call nt!ExInterlockedFlushSList (81ba2670)81ee8167 8bf8 mov edi,eax81ee8169 eb0b jmp nt!CmUnRegisterCallback+0x4e7 (81ee8176)nt!CmUnRegisterCallback+0x4dc:81ee816b 8bcf mov ecx,edi81ee816d 8b3f mov edi,dword ptr [edi]81ee816f 53 push ebx81ee8170 51 push ecx81ee8171 e8aa9edaff call nt!ExFreePoolWithTag (81c92020)nt!CmUnRegisterCallback+0x4e7:81ee8176 85ff test edi,edi81ee8178 75f1 jne nt!CmUnRegisterCallback+0x4dc (81ee816b)nt!CmUnRegisterCallback+0x4eb:81ee817a 8b4624 mov eax,dword ptr [esi+24h]81ee817d 85c0 test eax,eax81ee817f 7407 je nt!CmUnRegisterCallback+0x4f9 (81ee8188)nt!CmUnRegisterCallback+0x4f2:81ee8181 53 push ebx81ee8182 50 push eax81ee8183 e8989edaff call nt!ExFreePoolWithTag (81c92020)nt!CmUnRegisterCallback+0x4f9:81ee8188 53 push ebx81ee8189 56 push esi81ee818a e8919edaff call nt!ExFreePoolWithTag (81c92020)81ee818f 8b45d4 mov eax,dword ptr [ebp-2Ch]81ee8192 eb67 jmp nt!CmUnRegisterCallback+0x56c (81ee81fb)nt!CmUnRegisterCallback+0x505:81ee8194 8b0d9817cb81 mov ecx,dword ptr [nt!CmpCallbackListLock (81cb1798)]81ee819a 8bc1 mov eax,ecx81ee819c 83e0f0 and eax,0FFFFFFF0h81ee819f 83f810 cmp eax,10h81ee81a2 8d51f0 lea edx,[ecx-10h]81ee81a5 7702 ja nt!CmUnRegisterCallback+0x51a (81ee81a9)nt!CmUnRegisterCallback+0x518:81ee81a7 8bd3 mov edx,ebxnt!CmUnRegisterCallback+0x51a:81ee81a9 f6c102 test cl,281ee81ac 750a jne nt!CmUnRegisterCallback+0x529 (81ee81b8)nt!CmUnRegisterCallback+0x51f:81ee81ae 8bc1 mov eax,ecx81ee81b0 f00fb117 lock cmpxchg dword ptr [edi],edx81ee81b4 3bc1 cmp eax,ecx81ee81b6 7407 je nt!CmUnRegisterCallback+0x530 (81ee81bf)nt!CmUnRegisterCallback+0x529:81ee81b8 8bcf mov ecx,edi81ee81ba e8c182bbff call nt!ExfReleasePushLock (81aa0480)nt!CmUnRegisterCallback+0x530:81ee81bf 8bcf mov ecx,edi81ee81c1 e89a84c4ff call nt!KeAbPostRelease (81b30660)81ee81c6 648b0d24010000 mov ecx,dword ptr fs:[124h]81ee81cd 0fbf813c010000 movsx eax,word ptr [ecx+13Ch]81ee81d4 40 inc eax81ee81d5 6689813c010000 mov word ptr [ecx+13Ch],ax81ee81dc 6685c0 test ax,ax81ee81df 7515 jne nt!CmUnRegisterCallback+0x567 (81ee81f6)nt!CmUnRegisterCallback+0x552:81ee81e1 8d4170 lea eax,[ecx+70h]81ee81e4 3900 cmp dword ptr [eax],eax81ee81e6 740e je nt!CmUnRegisterCallback+0x567 (81ee81f6)nt!CmUnRegisterCallback+0x559:81ee81e8 6639993e010000 cmp word ptr [ecx+13Eh],bx81ee81ef 7505 jne nt!CmUnRegisterCallback+0x567 (81ee81f6)nt!CmUnRegisterCallback+0x562:81ee81f1 e81676bbff call nt!KiCheckForKernelApcDelivery (81a9f80c)nt!CmUnRegisterCallback+0x567:81ee81f6 b80d0000c0 mov eax,0C000000Dhnt!CmUnRegisterCallback+0x56c:81ee81fb e8f545cbff call nt!_SEH_epilog4 (81b9c7f5)81ee8200 c20800 ret 8
    Win10 64 位 CmUnRegisterCallbackkd> uf CmUnRegisterCallbacknt!CmUnRegisterCallback:fffff800`a0a5b718 4c8bdc mov r11,rspfffff800`a0a5b71b 49894b08 mov qword ptr [r11+8],rcxfffff800`a0a5b71f 53 push rbxfffff800`a0a5b720 56 push rsifffff800`a0a5b721 57 push rdifffff800`a0a5b722 4154 push r12fffff800`a0a5b724 4155 push r13fffff800`a0a5b726 4156 push r14fffff800`a0a5b728 4157 push r15fffff800`a0a5b72a 4881ec80000000 sub rsp,80hfffff800`a0a5b731 498363a800 and qword ptr [r11-58h],0fffff800`a0a5b736 33c0 xor eax,eaxfffff800`a0a5b738 498943b0 mov qword ptr [r11-50h],raxfffff800`a0a5b73c 498943b8 mov qword ptr [r11-48h],raxfffff800`a0a5b740 49214380 and qword ptr [r11-80h],raxfffff800`a0a5b744 e8a318f6ff call nt!CmpLockCallbackListExclusive (fffff800`a09bcfec)fffff800`a0a5b749 be00000080 mov esi,80000000hnt!CmUnRegisterCallback+0x36:fffff800`a0a5b74e 4533c0 xor r8d,r8dfffff800`a0a5b751 488d542438 lea rdx,[rsp+38h]fffff800`a0a5b756 488d0d83cfd1ff lea rcx,[nt!CallbackListHead (fffff800`a07786e0)]fffff800`a0a5b75d e8ba6aefff call nt!CmListGetNextElement (fffff800`a095221c)fffff800`a0a5b762 488bf8 mov rdi,raxfffff800`a0a5b765 4889442440 mov qword ptr [rsp+40h],raxfffff800`a0a5b76a 4885c0 test rax,raxfffff800`a0a5b76d 0f84c8020000 je nt!CmUnRegisterCallback+0x323 (fffff800`a0a5ba3b)nt!CmUnRegisterCallback+0x5b:fffff800`a0a5b773 488b8c24c0000000 mov rcx,qword ptr [rsp+0C0h]fffff800`a0a5b77b 48394818 cmp qword ptr [rax+18h],rcxfffff800`a0a5b77f 75cd jne nt!CmUnRegisterCallback+0x36 (fffff800`a0a5b74e)nt!CmUnRegisterCallback+0x69:fffff800`a0a5b781 8b4810 mov ecx,dword ptr [rax+10h]fffff800`a0a5b784 898c24d0000000 mov dword ptr [rsp+0D0h],ecxfffff800`a0a5b78b 8bc1 mov eax,ecxfffff800`a0a5b78d 85c0 test eax,eaxfffff800`a0a5b78f 7464 je nt!CmUnRegisterCallback+0xdd (fffff800`a0a5b7f5)nt!CmUnRegisterCallback+0x79:fffff800`a0a5b791 85c6 test esi,eaxfffff800`a0a5b793 75b9 jne nt!CmUnRegisterCallback+0x36 (fffff800`a0a5b74e)nt!CmUnRegisterCallback+0x7d:fffff800`a0a5b795 488d5f10 lea rbx,[rdi+10h]fffff800`a0a5b799 f0810b00000080 lock or dword ptr [rbx],80000000hfffff800`a0a5b7a0 e80b92ebff call nt!CmpUnlockCallbackList (fffff800`a09149b0)nt!CmUnRegisterCallback+0x8d:fffff800`a0a5b7a5 8b03 mov eax,dword ptr [rbx]fffff800`a0a5b7a7 898424d0000000 mov dword ptr [rsp+0D0h],eaxfffff800`a0a5b7ae 3bc6 cmp eax,esifffff800`a0a5b7b0 7425 je nt!CmUnRegisterCallback+0xbf (fffff800`a0a5b7d7)nt!CmUnRegisterCallback+0x9a:fffff800`a0a5b7b2 488364242000 and qword ptr [rsp+20h],0fffff800`a0a5b7b8 41b904000000 mov r9d,4fffff800`a0a5b7be 4c8d8424d0000000 lea r8,[rsp+0D0h]fffff800`a0a5b7c6 488bd3 mov rdx,rbxfffff800`a0a5b7c9 488d0d20cfd1ff lea rcx,[nt!CallbackListDeleteEvent (fffff800`a07786f0)]fffff800`a0a5b7d0 e8934fb1ff call nt!ExBlockOnAddressPushLock (fffff800`a0570768)fffff800`a0a5b7d5 ebce jmp nt!CmUnRegisterCallback+0x8d (fffff800`a0a5b7a5)nt!CmUnRegisterCallback+0xbf:fffff800`a0a5b7d7 e81018f6ff call nt!CmpLockCallbackListExclusive (fffff800`a09bcfec)fffff800`a0a5b7dc 488b0f mov rcx,qword ptr [rdi]fffff800`a0a5b7df 488b4708 mov rax,qword ptr [rdi+8]fffff800`a0a5b7e3 48397908 cmp qword ptr [rcx+8],rdifffff800`a0a5b7e7 7505 jne nt!CmUnRegisterCallback+0xd6 (fffff800`a0a5b7ee)nt!CmUnRegisterCallback+0xd1:fffff800`a0a5b7e9 483938 cmp qword ptr [rax],rdifffff800`a0a5b7ec 7421 je nt!CmUnRegisterCallback+0xf7 (fffff800`a0a5b80f)nt!CmUnRegisterCallback+0xd6:fffff800`a0a5b7ee b903000000 mov ecx,3fffff800`a0a5b7f3 cd29 int 29hnt!CmUnRegisterCallback+0xdd:fffff800`a0a5b7f5 488b0f mov rcx,qword ptr [rdi]fffff800`a0a5b7f8 488b4708 mov rax,qword ptr [rdi+8]fffff800`a0a5b7fc 48397908 cmp qword ptr [rcx+8],rdifffff800`a0a5b800 0f852e020000 jne nt!CmUnRegisterCallback+0x31c (fffff800`a0a5ba34)nt!CmUnRegisterCallback+0xee:fffff800`a0a5b806 483938 cmp qword ptr [rax],rdifffff800`a0a5b809 0f8525020000 jne nt!CmUnRegisterCallback+0x31c (fffff800`a0a5ba34)nt!CmUnRegisterCallback+0xf7:fffff800`a0a5b80f 488908 mov qword ptr [rax],rcxfffff800`a0a5b812 48894108 mov qword ptr [rcx+8],raxfffff800`a0a5b816 e89591ebff call nt!CmpUnlockCallbackList (fffff800`a09149b0)fffff800`a0a5b81b 4533ff xor r15d,r15dfffff800`a0a5b81e 4489bc24d8000000 mov dword ptr [rsp+0D8h],r15dfffff800`a0a5b826 488d442450 lea rax,[rsp+50h]fffff800`a0a5b82b 4889442458 mov qword ptr [rsp+58h],raxfffff800`a0a5b830 488d442450 lea rax,[rsp+50h]fffff800`a0a5b835 4889442450 mov qword ptr [rsp+50h],raxfffff800`a0a5b83a 4032f6 xor sil,silfffff800`a0a5b83d 4088b424c8000000 mov byte ptr [rsp+0C8h],silfffff800`a0a5b845 e86a900000 call nt!CmpLockContextListExclusive (fffff800`a0a648b4)fffff800`a0a5b84a 4c8d6740 lea r12,[rdi+40h]fffff800`a0a5b84e 498b1c24 mov rbx,qword ptr [r12]nt!CmUnRegisterCallback+0x13a:fffff800`a0a5b852 48895c2430 mov qword ptr [rsp+30h],rbxfffff800`a0a5b857 493bdc cmp rbx,r12fffff800`a0a5b85a 0f8497000000 je nt!CmUnRegisterCallback+0x1df (fffff800`a0a5b8f7)nt!CmUnRegisterCallback+0x148:fffff800`a0a5b860 4c8b2b mov r13,qword ptr [rbx]fffff800`a0a5b863 4c8d73f0 lea r14,[rbx-10h]fffff800`a0a5b867 498b4e30 mov rcx,qword ptr [r14+30h]fffff800`a0a5b86b e85017aeff call nt!ObReferenceObjectSafe (fffff800`a053cfc0)fffff800`a0a5b870 84c0 test al,alfffff800`a0a5b872 745b je nt!CmUnRegisterCallback+0x1b7 (fffff800`a0a5b8cf)nt!CmUnRegisterCallback+0x15c:fffff800`a0a5b874 498d4610 lea rax,[r14+10h]fffff800`a0a5b878 488b10 mov rdx,qword ptr [rax]fffff800`a0a5b87b 488b4808 mov rcx,qword ptr [rax+8]fffff800`a0a5b87f 48394208 cmp qword ptr [rdx+8],raxfffff800`a0a5b883 756b jne nt!CmUnRegisterCallback+0x1d8 (fffff800`a0a5b8f0)nt!CmUnRegisterCallback+0x16d:fffff800`a0a5b885 483901 cmp qword ptr [rcx],raxfffff800`a0a5b888 7566 jne nt!CmUnRegisterCallback+0x1d8 (fffff800`a0a5b8f0)nt!CmUnRegisterCallback+0x172:fffff800`a0a5b88a 488911 mov qword ptr [rcx],rdxfffff800`a0a5b88d 48894a08 mov qword ptr [rdx+8],rcxfffff800`a0a5b891 498b0e mov rcx,qword ptr [r14]fffff800`a0a5b894 498b4608 mov rax,qword ptr [r14+8]fffff800`a0a5b898 4c397108 cmp qword ptr [rcx+8],r14fffff800`a0a5b89c 754b jne nt!CmUnRegisterCallback+0x1d1 (fffff800`a0a5b8e9)nt!CmUnRegisterCallback+0x186:fffff800`a0a5b89e 4c3930 cmp qword ptr [rax],r14fffff800`a0a5b8a1 7546 jne nt!CmUnRegisterCallback+0x1d1 (fffff800`a0a5b8e9)nt!CmUnRegisterCallback+0x18b:fffff800`a0a5b8a3 488908 mov qword ptr [rax],rcxfffff800`a0a5b8a6 48894108 mov qword ptr [rcx+8],raxfffff800`a0a5b8aa 488b442458 mov rax,qword ptr [rsp+58h]fffff800`a0a5b8af 488d4c2450 lea rcx,[rsp+50h]fffff800`a0a5b8b4 48890b mov qword ptr [rbx],rcxfffff800`a0a5b8b7 48894308 mov qword ptr [rbx+8],raxfffff800`a0a5b8bb 488d4c2450 lea rcx,[rsp+50h]fffff800`a0a5b8c0 483908 cmp qword ptr [rax],rcxfffff800`a0a5b8c3 751d jne nt!CmUnRegisterCallback+0x1ca (fffff800`a0a5b8e2)nt!CmUnRegisterCallback+0x1ad:fffff800`a0a5b8c5 488918 mov qword ptr [rax],rbxfffff800`a0a5b8c8 48895c2458 mov qword ptr [rsp+58h],rbxfffff800`a0a5b8cd eb0b jmp nt!CmUnRegisterCallback+0x1c2 (fffff800`a0a5b8da)nt!CmUnRegisterCallback+0x1b7:fffff800`a0a5b8cf 40b601 mov sil,1fffff800`a0a5b8d2 4088b424c8000000 mov byte ptr [rsp+0C8h],silnt!CmUnRegisterCallback+0x1c2:fffff800`a0a5b8da 498bdd mov rbx,r13fffff800`a0a5b8dd e970ffffff jmp nt!CmUnRegisterCallback+0x13a (fffff800`a0a5b852)nt!CmUnRegisterCallback+0x1ca:fffff800`a0a5b8e2 b903000000 mov ecx,3fffff800`a0a5b8e7 cd29 int 29hnt!CmUnRegisterCallback+0x1d1:fffff800`a0a5b8e9 b903000000 mov ecx,3fffff800`a0a5b8ee cd29 int 29hnt!CmUnRegisterCallback+0x1d8:fffff800`a0a5b8f0 b903000000 mov ecx,3fffff800`a0a5b8f5 cd29 int 29hnt!CmUnRegisterCallback+0x1df:fffff800`a0a5b8f7 e8d0910000 call nt!CmpUnlockContextList (fffff800`a0a64acc)nt!CmUnRegisterCallback+0x1e4:fffff800`a0a5b8fc 488d4c2450 lea rcx,[rsp+50h]fffff800`a0a5b901 488b442450 mov rax,qword ptr [rsp+50h]fffff800`a0a5b906 483bc1 cmp rax,rcxfffff800`a0a5b909 0f848c000000 je nt!CmUnRegisterCallback+0x283 (fffff800`a0a5b99b)nt!CmUnRegisterCallback+0x1f7:fffff800`a0a5b90f 488b08 mov rcx,qword ptr [rax]fffff800`a0a5b912 488d542450 lea rdx,[rsp+50h]fffff800`a0a5b917 48395008 cmp qword ptr [rax+8],rdxfffff800`a0a5b91b 7577 jne nt!CmUnRegisterCallback+0x27c (fffff800`a0a5b994)nt!CmUnRegisterCallback+0x205:fffff800`a0a5b91d 48394108 cmp qword ptr [rcx+8],raxfffff800`a0a5b921 7571 jne nt!CmUnRegisterCallback+0x27c (fffff800`a0a5b994)nt!CmUnRegisterCallback+0x20b:fffff800`a0a5b923 48894c2450 mov qword ptr [rsp+50h],rcxfffff800`a0a5b928 488d542450 lea rdx,[rsp+50h]fffff800`a0a5b92d 48895108 mov qword ptr [rcx+8],rdxfffff800`a0a5b931 488d58f0 lea rbx,[rax-10h]fffff800`a0a5b935 48895c2448 mov qword ptr [rsp+48h],rbxfffff800`a0a5b93a 488b4330 mov rax,qword ptr [rbx+30h]fffff800`a0a5b93e 4889442460 mov qword ptr [rsp+60h],raxfffff800`a0a5b943 488b4338 mov rax,qword ptr [rbx+38h]fffff800`a0a5b947 4889442468 mov qword ptr [rsp+68h],raxfffff800`a0a5b94c 4c8d442460 lea r8,[rsp+60h]fffff800`a0a5b951 ba28000000 mov edx,28hfffff800`a0a5b956 488b4f20 mov rcx,qword ptr [rdi+20h]fffff800`a0a5b95a ff5728 call qword ptr [rdi+28h]fffff800`a0a5b95d eb1a jmp nt!CmUnRegisterCallback+0x261 (fffff800`a0a5b979)nt!CmUnRegisterCallback+0x261:fffff800`a0a5b979 488b4b30 mov rcx,qword ptr [rbx+30h]fffff800`a0a5b97d e87e2da7ff call nt!ObfDereferenceObject (fffff800`a04ce700)fffff800`a0a5b982 ba434d6363 mov edx,63634D43hfffff800`a0a5b987 488bcb mov rcx,rbxfffff800`a0a5b98a e87126c5ff call nt!ExFreePoolWithTag (fffff800`a06ae000)fffff800`a0a5b98f e968ffffff jmp nt!CmUnRegisterCallback+0x1e4 (fffff800`a0a5b8fc)nt!CmUnRegisterCallback+0x27c:fffff800`a0a5b994 b903000000 mov ecx,3fffff800`a0a5b999 cd29 int 29hnt!CmUnRegisterCallback+0x283:fffff800`a0a5b99b 4084f6 test sil,silfffff800`a0a5b99e 7442 je nt!CmUnRegisterCallback+0x2ca (fffff800`a0a5b9e2)nt!CmUnRegisterCallback+0x288:fffff800`a0a5b9a0 e80f8f0000 call nt!CmpLockContextListExclusive (fffff800`a0a648b4)fffff800`a0a5b9a5 4c8d7740 lea r14,[rdi+40h]fffff800`a0a5b9a9 498b1e mov rbx,qword ptr [r14]fffff800`a0a5b9ac 48895c2430 mov qword ptr [rsp+30h],rbxfffff800`a0a5b9b1 e816910000 call nt!CmpUnlockContextList (fffff800`a0a64acc)fffff800`a0a5b9b6 493bde cmp rbx,r14fffff800`a0a5b9b9 7422 je nt!CmUnRegisterCallback+0x2c5 (fffff800`a0a5b9dd)nt!CmUnRegisterCallback+0x2a3:fffff800`a0a5b9bb 488364242000 and qword ptr [rsp+20h],0fffff800`a0a5b9c1 41b908000000 mov r9d,8fffff800`a0a5b9c7 4c8d442430 lea r8,[rsp+30h]fffff800`a0a5b9cc 498bd6 mov rdx,r14fffff800`a0a5b9cf 488d0d1acdd1ff lea rcx,[nt!CallbackListDeleteEvent (fffff800`a07786f0)]fffff800`a0a5b9d6 e88d4db1ff call nt!ExBlockOnAddressPushLock (fffff800`a0570768)fffff800`a0a5b9db ebbe jmp nt!CmUnRegisterCallback+0x283 (fffff800`a0a5b99b)nt!CmUnRegisterCallback+0x2c5:fffff800`a0a5b9dd 4032f6 xor sil,silfffff800`a0a5b9e0 ebb9 jmp nt!CmUnRegisterCallback+0x283 (fffff800`a0a5b99b)nt!CmUnRegisterCallback+0x2ca:fffff800`a0a5b9e2 83c8ff or eax,0FFFFFFFFhfffff800`a0a5b9e5 f00fc105732ad2ff lock xadd dword ptr [nt!CmpCallBackCount (fffff800`a077e460)],eaxfffff800`a0a5b9ed 83f801 cmp eax,1fffff800`a0a5b9f0 7523 jne nt!CmUnRegisterCallback+0x2fd (fffff800`a0a5ba15)nt!CmUnRegisterCallback+0x2da:fffff800`a0a5b9f2 488d0d0766d2ff lea rcx,[nt!CmpCallbackContextSList (fffff800`a0782000)]fffff800`a0a5b9f9 e8d29db6ff call nt!ExpInterlockedFlushSList (fffff800`a05c57d0)fffff800`a0a5b9fe 488bd8 mov rbx,raxnt!CmUnRegisterCallback+0x2e9:fffff800`a0a5ba01 4885db test rbx,rbxfffff800`a0a5ba04 740f je nt!CmUnRegisterCallback+0x2fd (fffff800`a0a5ba15)nt!CmUnRegisterCallback+0x2ee:fffff800`a0a5ba06 488bcb mov rcx,rbxfffff800`a0a5ba09 488b1b mov rbx,qword ptr [rbx]fffff800`a0a5ba0c 33d2 xor edx,edxfffff800`a0a5ba0e e8ed25c5ff call nt!ExFreePoolWithTag (fffff800`a06ae000)fffff800`a0a5ba13 ebec jmp nt!CmUnRegisterCallback+0x2e9 (fffff800`a0a5ba01)nt!CmUnRegisterCallback+0x2fd:fffff800`a0a5ba15 488b4f38 mov rcx,qword ptr [rdi+38h]fffff800`a0a5ba19 4885c9 test rcx,rcxfffff800`a0a5ba1c 7407 je nt!CmUnRegisterCallback+0x30d (fffff800`a0a5ba25)nt!CmUnRegisterCallback+0x306:fffff800`a0a5ba1e 33d2 xor edx,edxfffff800`a0a5ba20 e8db25c5ff call nt!ExFreePoolWithTag (fffff800`a06ae000)nt!CmUnRegisterCallback+0x30d:fffff800`a0a5ba25 33d2 xor edx,edxfffff800`a0a5ba27 488bcf mov rcx,rdifffff800`a0a5ba2a e8d125c5ff call nt!ExFreePoolWithTag (fffff800`a06ae000)fffff800`a0a5ba2f 418bc7 mov eax,r15dfffff800`a0a5ba32 eb11 jmp nt!CmUnRegisterCallback+0x32d (fffff800`a0a5ba45)nt!CmUnRegisterCallback+0x31c:fffff800`a0a5ba34 b903000000 mov ecx,3fffff800`a0a5ba39 cd29 int 29hnt!CmUnRegisterCallback+0x323:fffff800`a0a5ba3b e8708febff call nt!CmpUnlockCallbackList (fffff800`a09149b0)fffff800`a0a5ba40 b80d0000c0 mov eax,0C000000Dhnt!CmUnRegisterCallback+0x32d:fffff800`a0a5ba45 4881c480000000 add rsp,80hfffff800`a0a5ba4c 415f pop r15fffff800`a0a5ba4e 415e pop r14fffff800`a0a5ba50 415d pop r13fffff800`a0a5ba52 415c pop r12fffff800`a0a5ba54 5f pop rdifffff800`a0a5ba55 5e pop rsifffff800`a0a5ba56 5b pop rbxfffff800`a0a5ba57 c3 ret
    2 留言 2019-03-27 13:02:47
显示 75 到 90 ,共 15 条
eject