简单说说SSDT

驱动开发笔记3—SSDT表详解 SSDT表 SSDT的全称是"System Services Descriptor Table",即系统服务描述表,在内核中的实际名称是KeServiceDescriptorTable,这个表由ntoskrnl.exe导出(在x64里不导出)。 SSDT用于处理应用层通过Kernel32.dll下发的各个API操作请求。ntdll.dll中的API是一个简单的包装函数,当Kernel32.dll中的API通过Ntdll.dll时,会先完成对参数的检查,再调用一个中断(int 2Eh 或者 SysEnter指 阅读详情

Author: 云舒
http://www.ph4nt0m.org
Date: 2007-06-11


论技术,我还差得远,而且网上关于SSDT的文章也多不胜数。但是还是想自己写一下,因为我想试试我能不能用最简单的语言来描述SSDT——这个对一般来人来说比较神秘的属于内核的地带。引用EVA说的一句话,“以为写个驱动就是内核,还远着了”——大概是这么个意思,记得不是很清楚。

关于SSDT,描述得最清楚的应该算《SSDT Hook的妙用-对抗ring0 inline hook》一文了,作者是堕落天才。这里引用一下他写的开头部分,略有个别字符的修改:

内核中有两个系统服务描述符表,一个是KeServiceDescriptorTable,由ntoskrnl.exe导出,一个是 KeServieDescriptorTableShadow,没有导出。这两者都是一个结构体,结构下面会给出。他们的区别是, KeServiceDescriptorTable仅有 ntoskrnel一项,而KeServieDescriptorTableShadow则包含了ntoskrnel和win32k。一般的Native API的服务地址由KeServiceDescriptorTable分派,而gdi.dll和
user.dll的内核API调用服务地址,由 KeServieDescriptorTableShadow分派。还有要清楚一点的是win32k.sys只有在GUI线程中才加载,一般情况下是不加载的。

他们的结构如下:

typedef struct _SYSTEM_SERVICE_TABLE
{
    PVOID ServiceTableBase;    
//这个指向系统服务函数地址表
    PULONG ServiceCounterTableBase;
    ULONG NumberOfService;     
//服务函数的个数,NumberOfService*4 就是整个地址表的大小
    ULONG ParamTableBase;
}SYSTEM_SERVICE_TABLE,
*PSYSTEM_SERVICE_TABLE;

typedef 
struct _SERVICE_DESCRIPTOR_TABLE
{
    SYSTEM_SERVICE_TABLE ntoskrnel;    
//ntoskrnl.exe的服务函数
    SYSTEM_SERVICE_TABLE win32k;    //win32k.sys的服务函数,(gdi.dll/user.dll的内核支持)
    SYSTEM_SERVICE_TABLE NotUsed1;
    SYSTEM_SERVICE_TABLE NotUsed2;
}SYSTEM_DESCRIPTOR_TABLE,
*PSYSTEM_DESCRIPTOR_TABLE; 


当系统需要使用一个本机API的时候,就会去查找SYSTEM_DESCRIPTOR_TABLE这个表,也就是由ntoskrnl.exe导出的KeServiceDescriptorTable:
nt!RtlpBreakWithStatusInstruction:
80527fc8 cc              
int     3
kd
> dd KeServiceDescriptorTable
80553380  805021fc 00000000 0000011c 80502670
80553390  00000000 00000000 00000000 00000000
805533a0  
00000000 00000000 00000000 00000000
805533b0  
00000000 00000000 00000000 00000000
805533c0  
00002710 bf80c227 00000000 00000000
805533d0  f9e6da80 f963a9e0 816850f0 806e0f40
805533e0  
00000000 00000000 00000000 00000000
805533f0  97c5ac40 01c7abf5 
00000000 00000000 


可以看到,KeServiceDescriptorTable的地址是80553380。现在看看这个地址保存的是什么,因为这个地址的值就是 SYSTEM_SERVICE_TABLE的起始地址。好了,我们看到这个地址保存的是805021fc,那么也就是说,系统服务的地址表起始地址为 805021fc了。看看这个表是些什么鬼东西:
kd> dd 805021fc
805021fc  
80599746 805e6914 805ea15a 805e6946
8050220c  805ea194 805e697c 805ea1d8 805ea21c
8050221c  8060b880 8060c5d2 805e1cac 805e1904
8050222c  805ca928 805ca8d8 8060bea6 805ab334
8050223c  8060b4be 8059dbbc 805a5786 805cc406
8050224c  804ffed0 8060c5c4 8056be64 805353f2
8050225c  80604b90 805b19c0 805ea694 80619a56
8050226c  805eeb86 80599e34 80619caa 805996e6 


这个过程是这样的,最开始是SYSTEM_DESCRIPTOR_TABLE(80553380)保存了SYSTEM_SERVICE_TABLE的地址(805021fc),SYSTEM_SERVICE_TABLE的地址(805021fc)又保存了很多地址,这个地址就是系统服务的地址了,类似 NtOpenProcess这样的ring0的函数地址。这样,系统就可以方便的找到每一个ring0函数去调用。

我们先看看第一个地址80599746是个什么函数,反汇编一下:
kd> u 80599746
nt
!NtAcceptConnectPort:
80599746 689c000000      push    9Ch
8059974b 6820a14d80      push    offset nt
!_real+0x128 (804da120)
80599750 e8abebf9ff      call    nt!_SEH_prolog (80538300)
80599755 64a124010000    mov     eax,dword ptr fs:[00000124h]
8059975b 8a8040010000    mov     al,
byte ptr [eax+140h]
80599761 884590          mov     byte ptr [ebp-70h],al
80599764 84c0            test    al,al
80599766 0f84b9010000    je      nt!NtAcceptConnectPort+0x1df (80599925) 


原来是NtAcceptConnectPort函数,第二个805e6914呢?我们也看一下,
kd> u 805e6914
nt
!NtAccessCheck:
805e6914 8bff            mov     edi,edi
805e6916 
55              push    ebp
805e6917 8bec            mov     ebp,esp
805e6919 33c0            xor     eax,eax
805e691b 
50              push    eax
805e691c ff7524          push    dword ptr [ebp
+24h]
805e691f ff7520          push    dword ptr [ebp+20h]
805e6922 ff751c          push    dword ptr [ebp
+1Ch] 


原来是NtAccessCheck函数。

这样我们可以清楚的看到,在这个起始地址为0x805021fc的表中,保存了各个ring0函数的地址。下面我来做个简单的比喻。

从前有一个很大的帮派,名字叫做Windows,功能很多并且很强大。因为这些各方面的能力由各个专人负责,他们一个人做一件事情。随着人员增多,帮主发现联系起来越来越困了。有一天帮主要找竟然NtOpenProcess来调查一下他的一个手下是不是别的帮派派来的间谍,但是他发现 NtOpenProcess跑不见了。

于是军师就想出了一个好办法来解决这个问题:先建立一个封闭的密室,这个密室只有八袋长老以上的人才能进去。密室中间有一张纸条,上面写着一个地址——温家堡,还有这个地址放着多少人的联系信息等内容。这个密室就是Ntdll.dll,这个纸条就是 SYSTEM_DESCRIPTOR_TABLE,上写的地址就是SYSTEM_SERVICE_TABLE,也就是温家堡了。这个温家堡是一个有很多大房间的地方,每个房子有个房间号
,房间里面又放着一张纸条,上面写着各个手下的住所。比如说编号为7A的房间,里面放的是NtOpenProcess的家庭住址。

这样一来,帮主要找人就容易了。先去密室找到纸条,看看上面写的是温家堡还是白云城,那个地方有多少个人的联系信息等。如果是温家堡就跑到那里去,看看要找谁,找NtOpenProcess就去7A房间。在这个房间里一看,啊,里面写着NtOpenProcess现在就住在密室的旁边……搞定。

这里就有一个新的问题,帮主假设这个里面写的东西都是正确的,没有被人改过。于是就有了别派的间谍发现了,偷偷溜进密室,然后根据纸条的内容,又跑到温家堡。进到7A房间,神不知鬼不觉的把里面记录的NtOpenProcess的地址改成了自己的家。于是,帮主再找人,发现找到对头家里去了。这个就是传说中的SSDT Hook了。

攻击者进入ring0之后,找到KeServiceDescriptorTable地址的值,即 SYSTEM_SERVICE_TABLE的地址(进入密室,找到纸条写的地址——温家堡)。然后改写SYSTEM_SERVICE_TABLE中一个特定函数的地址为自己定义的函数入口处,截获了系统调用(来到温家堡,改掉7A房间里面写的住所,改成自己家)。一次HOOK就完成了。

下面我给一段简单的代码,演示怎么样让一个特定的PID不会被杀死。这段代码基本和《SSDT Hook的妙用-对抗ring0 inline hook》一文一样,我只是注释了一下而已,另外在MyNtOpenProcess处加了个判断是不是某个特定PID的功能。
/*
演示HOOK系统服务调用表中的NtOpenProcess函数,保护需要保护的进程被,防止被杀掉
*/

#include
<ntddk.h>

/*
KeServiceDescriptorTable仅有ntoskrnel一项,没有包含win32k,而且后面的两个字段都没有使用,所

以为了简便直接把SystemServiceDescriptorTable定义成SYSTEM_SERVICE_TABLE,免得访问多个结构体的

字段,麻烦。这里明白就行了。
*/
typedef 
struct _SystemServiceDescriptorTable
{
    PVOID    ServiceTableBase;
    PULONG    ServiceCounterTableBase;
    ULONG    NumberOfService;
    ULONG    ParamTableBase;
}SystemServiceDescriptorTable,
*PSystemServiceDescriptorTable;

// KeServiceDescriptorTable为ntoskrnl.exe导出
extern    PSystemServiceDescriptorTable    KeServiceDescriptorTable;

// 定义一下NtOpenProcess的原型,下面如果用汇编调用就不用定义了,但是我想尽量不用汇编
typedef    NTSTATUS    (__stdcall *NTOPENPROCESS)( OUT PHANDLE ProcessHandle,
                                                

IN ACCESS_MASK AccessMask,
                                                

IN POBJECT_ATTRIBUTES ObjectAttributes,
                                                

IN PCLIENT_ID ClientId
                                                

);

NTOPENPROCESS    RealNtOpenProcess;

// 定义函数原型
VOID Hook();
VOID Unhook();
VOID OnUnload(IN PDRIVER_OBJECT DriverObject);

// 真实的函数地址,我们会在自定义的函数中调用
ULONG    RealServiceAddress;

// 需要被驱动保护的进程ID
HANDLE    MyPID;

// 自定义的NtOpenProcess函数
NTSTATUS __stdcall MyNtOpenProcess( OUT    PHANDLE ProcessHandle,
                    IN    ACCESS_MASK DesiredAccess,
                    IN    POBJECT_ATTRIBUTES ObjectAttributes,
                    IN    PCLIENT_ID ClientId )
{
    NTSTATUS    rc;
    ULONG        PID;
    
    
//DbgPrint( "NtOpenProcess() called./n" );
    
    rc 
= (NTSTATUS)(NTOPENPROCESS)RealNtOpenProcess( ProcessHandle, DesiredAccess,

ObjectAttributes, ClientId );
    
    
if( (ClientId != NULL) )
    {
        PID 
= (ULONG)ClientId->UniqueProcess;
        
//DbgPrint( "%d was opened,Handle is %d./n", PID, (ULONG)ProcessHandle );
        
        
// 如果进程PID是1520,直接返回权限不足,并将句柄设置为空
        if( PID == 1520 )
        {
            DbgPrint( 
"Some want to open pid 1520!/n" );
            
            ProcessHandle 
= NULL;
                        
            rc 
= STATUS_ACCESS_DENIED;
        }
    }
    
    
return rc;
}

// 驱动入口
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath )
{
    DriverObject
->DriverUnload = OnUnload;

    Hook();
    
    
return STATUS_SUCCESS;
}

// 驱动卸载
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
    Unhook( );
}

//  此处修改SSDT中的NtOpenProcess服务地址
VOID Hook()
{
    ULONG            Address;
    
    
// 0x7A为Winxp+SP2下NtOpenProcess服务ID号
    
// Adress是个地址A,这个地址的数据还是一个地址B,这个地址B就是NtOpenProcess的地址了
    
// (ULONG)KeServiceDescriptorTable->ServiceTableBase就是温家堡的第一个房间
    
// Address是第7A个房间。
    Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;

    
// 取得地址A的值,也就是NtOpenProcess服务的地址了,保存原来NtOpenProcess的地址以后恢

复用
    RealServiceAddress 
= *(ULONG*)Address;
    
    RealNtOpenProcess 
= (NTOPENPROCESS)RealServiceAddress;
    
    DbgPrint( 
"Address of Real NtOpenProcess: 0x%08X/n", RealServiceAddress );

    DbgPrint(
" Address of MyNtOpenProcess: 0x%08X/n", MyNtOpenProcess );

    
// 去掉内存保护
    __asm
    {
        cli
        mov    eax, cr0
        and    eax, not 10000h
        mov    cr0, eax
    }
    
    
// 修改SSDT中NtOpenProcess服务的地址
   *((ULONG*)Address) = (ULONG)MyNtOpenProcess;

    
// 恢复内存保护
    __asm
    {
        mov    eax, cr0
        or    eax, 10000h
        mov    cr0, eax
        sti
    }
}

//////////////////////////////////////////////////////
VOID Unhook()
{
   ULONG   Address;
   Address 
= (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;

    __asm
    {
        cli
        mov    eax, cr0
        and    eax, not 10000h
        mov    cr0, eax
    }

    
// 还原SSDT
    *((ULONG*)Address) = (ULONG)RealServiceAddress;
    
    __asm
    {
        mov    eax, cr0
        or    eax, 10000h
        mov    cr0, eax
        sti
    }

    DbgPrint(
"Unhook");
} 
 
SSDT Hook实现内核级的进程保护 SSDT Hook效果图 加载驱动并成功Hook  NtTerminateProcess函数: 当对 指定的进程进行保护后,尝试使用“任务管理器”结束进程的时候,会弹出“拒绝访问”的窗口,说明,我们的目的已经达到: SSDT简介 SSDT 的全称是 System Services Descriptor Table,系统服务描述符表。 这个表 阅读详情

相关推荐

R0层获取ShadowSSDT函数原始地址实例

本实例由VS2008开发,在提供了一套驱动开发框架的同时,又演示了如何获取Shadow SSDT表函数原始地址的办法。 主要函数:ULONG GetShadowSSDT_Function_OriAddr(ULONG index); 原理说明: 根据特征码搜索导出函数KeAddSystemServiceTable来获取Shadow SSDT基址,以及通过ZwQuerySystemInformation()函数获取win32k.sys基址,然后解析PE定位到Shadow SSDT在win32k.sys的偏移地址,并通过进一步计算来得到Shadow SSDT表函数的原始地址。 这里只测试了三个函数:(460)NtUserMessageCall、(475)NtUserPostMessage和(502)NtUserSendInput,具体使用时可以举一反三,网上完整的源代码实例并不太多,希望可以帮到真正有需要的朋友。 系统环境: 在WinXP SP3系统 + 瑞星杀毒软件 打印输出: [ LemonInfo : Loading Shadow SSDT Original Address Driver... ] [ LemonInfo : 创建“设备”值为:0 ] [ LemonInfo : 创建“设备”成功... ] [ LemonInfo : 创建“符号链接”状态值为:0 ] [ LemonInfo : 创建“符号链接”成功... ] [ LemonInfo : 驱动加载成功... ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP 开始... ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP Enter IRP_MJ_DEVICE_CONTROL... ] [ LemonInfo : 获取ShadowSSDT表 (460)NtUserMessageCall 函数的“当前地址”为:0xB83ECFC4,“起源地址”为:0xBF80EE6B ] [ LemonInfo : 获取ShadowSSDT表 (475)NtUserPostMessage 函数的“当前地址”为:0xB83ECFA3,“起源地址”为:0xBF8089B4 ] [ LemonInfo : 获取ShadowSSDT表 (502)NtUserSendInput 函数的“当前地址”为:0xBF8C31E7,“起源地址”为:0xBF8C31E7 ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP_MJ_DEVICE_CONTROL 成功执行... ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP 结束... ] [ LemonInfo : UnLoading Shadow SSDT Original Address Driver... ] [ LemonInfo : 删除“符号链接”成功... ] [ LemonInfo : 删除“设备”成功... ] [ LemonInfo : 驱动卸载成功... ]

初探SSDT

SSDT 的全称是 System Services Descriptor Table,系统服务描述符表。这个表就是一个把 Ring3 的 Win32 API 和 Ring0 的内核 API 联系起来。SSDT 并不仅仅只包含一个庞大的地址索引表,它还包含着一些其它有用的信息,诸如地址索引的基地址、服务函数个数等。通过修改此表的函数地址可以对常用 Windows 函数及 API 进行 Hook,从而实现对一些关心的系统动作进行过滤、监控的目的。一些 HIPS、防毒软件、系统监控、注册表监控软件往往会采用此接.

hongduilanjun的博客 2732

matlab安装libsvm常见问题

matlab安装libsvm常见问题 libsvm的官网链接:LIBSVM -- A Library for Support Vector Machines.

cqujcy的博客 1535

驱动保护:挂接SSDT内核钩子(1)

SSDT 中文名称为系统服务描述符表,该表的作用是将Ring3应用层与Ring0内核层,两者的API函数连接起来,起到承上启下的作用,SSDT并不仅仅只包含一个庞大的地址索引表,它还包含着一些其它有用的信息,诸如地址索引的基址、服务函数个数等,SSDT 通过修改此表的函数地址可以对常用 Windows 函数进行内核级的Hook,从而实现对一些核心的系统动作进行过滤、监控的目的,接下来将演...

weixin_30790841的博客 661

别再手动下单了!用Python+EasyTrader+同花顺,5分钟搞定你的第一个自动化交易机器人

本文详细介绍了如何使用Python和EasyTrader结合同花顺客户端快速构建自动化交易机器人。从环境配置到实战脚本编写,涵盖自动打新、条件单、跟单策略等核心功能,并分享性能优化与风险控制技巧,帮助投资者高效实现自动化交易。

weixin_30381317的博客 398

2.4G射频微带线阻抗匹配设计实战(WiFi/BLE)

本文深入探讨了2.4G射频微带线阻抗匹配在WiFi/BLE产品开发中的关键作用。文章详细解析了共面波导微带线结构,提供了基于SI9000工具的阻抗计算实战指南,并总结了不同PCB板厚下的设计参数对照表。同时,文章分享了PCB布局布线、与板厂沟通以及天线匹配调试等核心避坑经验,旨在帮助硬件工程师构建从射频芯片到天线的稳定高效传输通道。

j0k1l2m3n的博客 369

【SSDT】SSDT hook技术

通过修改此表的函数地址可以对常用Windows函数及API进行Hook,从而实现对一些关心的系统动作进行过滤、监控等目的。在NT4.0 以上的Windpws 操作系统中,默认存在两个系统服务描述表,两个调度表对应两类不同的系统服务。要Hook SSDT表,首选需要这个表是可写的,但是在XP之后的系统都是只读的,有三种方式修改内存保护机制。其中第1位叫做保护属性位,控制着页的读或写属性。如果为0,则只能读/执行。SSDT,IDT(中断描述符表)的页属性在默认情况下只读,可执行,但不能写。例如进程保护(驱动)

dr0op's blog 2784

Altium Concord Pro 的应用范围,安装,和使用范围

Altium Concord Pro 的应用范围,安装,和使用范围。保证满足两者软件的最低安装要求。 Altium Concord Pro 是配合Digapcb,和MCAD,Altium 和相应机械设计软件的基础和交换桥梁

hanzhaos的博客 1122

SQL Server Data Tools (SSDT)入门教程

SQL Server Data Tools (SSDT) 是一种集成开发环境 (IDE),用于设计SQL Server数据库对象并实现数据库的持续集成与持续交付 (CI/CD)。数据库项目的开发和版本控制架构比较和同步数据库测试和部署支持T-SQL、SSIS、SSRS和SSAS的开发SSDT是SQL Server开发的强大工具,集成了数据库项目管理、架构同步、自动化部署和单元测试等功能,极大地提升了数据库开发的效率和可靠性。

qq_43535970的博客 5217

OpenClaw(Clawdbot/Moltbot)如何正确的配置浏览器,实现对浏览器的自动化操作功能(浏览器状态为running:false怎么办)

OpenClaw(Clawdbot/Moltbot)浏览器自动化功能无效?🤖 本文详细介绍如何解决这个问题🔧,让你的OpenClaw(Clawdbot/Moltbot)真正具备"睁眼看世界"的能力,支持网页搜索、点击操作和截图等功能 ✅

XiaoqiangClub的博客 8112

完整的 Python 数据分析案例:新能源汽车续航里程预测

随着新能源汽车的普及,续航里程成为消费者关注的重要指标。准确预测新能源汽车的续航里程,有助于车企优化电池管理系统、提升车辆性能,也能帮助消费者合理规划出行。本案例将基于新能源汽车的各项参数,如电池容量、行驶速度、环境温度等,构建续航里程预测模型。通过以上改进,可以提高数据处理的准确性、模型的性能和可视化的效果。

daqsdfas的博客 1588

SSDT详解

本文对于SSDT的原理和作用进行细致入微的解释和说明,并且配以大量实例,相信您定会有所收获!什么是SSDT?什么是SSDT?自然,这个是我必须回答的问题。不过在此之前,请你打开命令行(cmd.exe)窗口,并输入“dir”并回车——好了,列出了当前目录下的所有文件和子目录。那么,以程序员的视角来看,整个过程应该是这样的:由用户输入dir命令。 cmd.exe获取用户输入

yxyhack's blog 8202

fatal: unable to access ‘https://github.com/xxx.git/‘ OpenSSL SSL_connect: SSL_ERROR_SYSCALL 解决方案

 本文主要介绍了fatal: unable to access ‘https://github.com/xxx.git/’: OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443解决方案,希望能对使用git的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 24万+

修改SSDT做简单的进程保护

*By 炉子[0GiNr]http://atleast.blog.cfan.com.cnhttp://0ginr.com*/M$真是照顾菜鸟 居然会给个SSDT,而且居然还把KSDT(KeServiceDescrīptorTable)导出了(当然,不排除这是M$的无奈之举,因为M$是不推荐programmer Hook他的API的,但是如果不对API做hook,那么许多事情都很难完成,这使得M$不

1938

基于Simulink的智能车辆电子稳定控制(ESC)仿真

本文完成了基于 Simulink 的智能车辆电子稳定控制(ESC),实现了:✅ 构建含轮胎非线性的车辆动力学模型✅ 设计滑模横摆稳定性控制器✅ 实现四轮制动力分配逻辑✅ 验证在双移线低附着场景下的卓越稳定性✅ 为主动安全控制系统开发提供完整范式。

xiaoheshang_123的博客 82

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

城里城外看SSDT

原文链接:http://www.titilima.cn/?action=show&id=201点这里下载本文的配套代码引子2006年,中国互联网上的斗争硝烟弥漫。这时的战场上,先前颇为流行的窗口挂钩、API挂钩、进程注入等技术已然成为昨日黄花,大有逐渐淡出之势;取而代之的,则是更狠毒、更为赤裸裸的词汇:驱动、隐藏进程、Rootkit……前不久,我不经意翻出自己2005年9月写下

马说@优快云 6272

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

简单易懂的SSDT学习心得

在这篇心得开始,说点其他的。之前参加百度校园招聘的时候,面试官问我什么是SSDT,已经HOOK SSDT的实现过程。自己明明知道,可是我一下答上来,所以我找出来以前学习的心得,贴出来,好备份吧!我这篇心得呢!是代码与文字一起加载在一起的,学习就想读书的时候一样,书看到哪里笔记就做到哪里。这样方便理解。如果代价复制黏贴来学,不会影响的,一边看代码一边看笔记哟!其实我平时写代码不是这样的……都是规范化

fsjaky的专栏 3189

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

DSDT与SSDT提取

先来个提取 至于修改后面慢慢跟新此方法是在MAC下直接操作 工具MACiASL是提取和修改的一个工具。后期修改是会用到的 双击打开点击文件   提取  选择DSDT其实这个也可以提取SSDT但是会有多个  等会会有一个简单的方式提取一个的SSDT点击提取后会另外跳出一个页面 点击新出的页面还是点击文件   另存为  名称修改为DSDT.后缀在修改A...

hehyyoulan的博客 7345
上一篇: Radmin的抓屏和显屏API代码部分分析
下一篇: 逆向分析点滴
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值