Guest Article - Introduction to Registry Filtering in Vista (Part I) (By: The NT Insider, Vol 15, Issue 1, March- April 2008 | Published: 28-May-08| Modified: 28-May-08)By Jerry KelleyThe Registry Filtering Model (RFM) provides the developer with a framework to develop registry filters quickly and safely. Before the RFM, filter developers had to resort to potentially unsafe hacks to hook the registry service calls. With the RFM, a skeleton filter can be assembled in short order by anyone with any familiarity of filtering. This is the first of two articles which will present a whirlwind tour of the RFM in Vista. In this article, I'll show you how to put together a simple filter from which you can build upon to add functionality to suit your needs.What can it do for me? Let's get started by going over what the RFM actually does for the developer. It provides a framework whereby a driver can be developed that provides callbacks for registry IO that it's interested in. These callbacks are registered with the RFM and are called whenever specific registry IO is processed. All of the RFM interfaces that the driver uses are provided by the Configuration Manager (CM). In addition to managing the callbacks, the RFM also provides for three types of contexts that a driver can use to associate private information with an object or operation. Those who know the file system Filter Manager should already be acquainted with these features. The Filter Manager does provide a broader API than the RFM but, to be fair, it's been out there longer and file system filters are among the hardest drivers to develop so a lot of effort has gone into the Filter Manager to ease their burden.Not exactly the new kid in town You may have noticed that the RFM has been around since XP. The API was very limited in XP and expanded in Server 2003. The biggest change in Server 2003 was that the RFM added support for pre and post operation callbacks meaning the driver gets a callback before and after the CM processes an operation. (In XP, only a single operation callback is available which just announces the IO). Vista added callbacks for key flush, load, and unload as well as key security query and set.Altitude is everything Registry filters are assigned altitudes by the type of application they perform. An altitude arranges the layering of filters so that no matter when they load, they'll load within a pre-determined level based on their function. The altitude categories are the same as those for the file system minifilters and vendors who already have altitudes for their minifilters will use them for their registry filters as well. Altitudes can be requested from Microsoft via the WHDC Minifilter Altitude Allocation Web site.Callbacks, of course Before we discuss registering with CM for callbacks, let's take a look at the format of the callback routines. All of the callbacks are of the PEX_CALLBACK_FUNCTION type definition in WDM.H. The three input values represent, respectively, the registration context, the operation type, and a pointer to the operation's information structure. The PEX_CALLBACK_FUNCTION is shown in Figure 1.typedef NTSTATUS (*PEX_CALLBACK_FUNCTION)(IN PVOID CallbackContext,IN PVOID Argument1,IN PVOID Argument2);The callback context is really a registration context created when a filter registers with CM (This will be discussed further when we talk about registration). When a filter registers at an altitude it can set a private context that the filter can use to identify a specific registration. Argument1 is not really a pointer but an enumeration value of the REG_NOTIFY_CLASS type. This value indicates the specific registry operation. Sample enumeration values include RegNtPreDeleteKey, RegNtPostDeleteKey, RegNtPreCreateKeyEx, and RegNtPostCreateKeyEx. Be sure to treat it as an enumeration and not a pointer since it'll never hold a valid pointer value.Argument2 is a pointer to an operation-specific structure. There are distinct pre-op and post-op structures that your filter will have to deal with. The pre-op structure depends on the operation. As an example, consider pre-create (CreateKeyEx), Argument2 is a REG_CREATE_KEY_INFORMATION pointer (See Figure 2).typedef struct _REG_CREATE_KEY_INFORMATION {PUNICODE_STRING CompleteName;PVOID RootObject;PVOID ObjectType;ULONG CreateOptions;PUNICODE_STRING Class;PVOID SecurityDescriptor;PVOID SecurityQualityOfService;ACCESS_MASK DesiredAccess;ACCESS_MASK GrantedAccess;PULONG Disposition;PVOID *ResultObject;PVOID CallContext;PVOID Reserved;} REG_CREATE_KEY_INFORMATION, REG_OPEN_KEY_INFORMATION,*PREG_CREATE_KEY_INFORMATION, *PREG_OPEN_KEY_INFORMATION;Figure 2 - REG_CREATE_KEY_INFORMATION Structure In the pre-query key callback Argument2 provides a pointer to a REG_QUERY_KEY_INFORMATION structure (See Figure 3).typedef struct _REG_QUERY_KEY_INFORMATION {PVOID Object;KEY_INFORMATION_CLASS KeyInformationClass;PVOID KeyInformation;ULONG Length;PULONG ResultLength;PVOID CallContext;PVOID ObjectContext;PVOID Reserved;} REG_QUERY_KEY_INFORMATION, *PREG_QUERY_KEY_INFORMATION;Figure 3 - REG_QUERY_KEY_INFORMATION Structure
You'll notice that REG_OPEN_KEY_INFORMATION is the same as REG_CREATE_KEY_INFORMATION. The pre-op structure for create-key and open-key are overloaded but the pre-op structures for the rest of the operations are not. These structures are defined in WDM.H and documented in the WDK documentation.The pre-op structures all contain several common members that help the filter identify the target of the operation. Some contain only these values because nothing else is needed. Take delete-key for example. In Figure 4, the REG_DELETE_KEY _INFORMATION structure has only three members (ignoring Reserved) and this is all that's required to define the key to be deleted.typedef struct _REG_DELETE_KEY_INFORMATION {PVOID Object;PVOID CallContext;PVOID ObjectContext;PVOID Reserved;} REG_DELETE_KEY_INFORMATION, *PREG_DELETE_KEY_INFORMATION;Figure 4 - REG_DELETE_KEY_INFORMATION Structure
The first three parameters are common to all pre-op structures except for create and open. To be exact, CallContext is used in all structures including create and open but Object does not exist until the create (or open) completes and ObjectContext is not valid unless it has been set on the registry object. Other pre-op structures may have more members but they all will have at least these three.All post-op routines are passed a pointer to a REG_POST_OPERATION_INFORMATION structure providing common completion information regardless of the operation type. Figure 5 contains the definition of the REG_POST_OPERATION_INFORMATION structure.typedef struct _REG_POST_OPERATION_INFORMATION {PVOID Object;NTSTATUS Status;PVOID PreInformation;NTSTATUS ReturnStatus;PVOID CallContext;PVOID ObjectContext;PVOID Reserved;} REG_POST_OPERATION_INFORMATION,*PREG_POST_OPERATION_INFORMATION;Figure 5 - REG_POST_OPERATION_INFORMATION StructureNotice the three primary fields discussed previously - Object, CallContext, and ObjectContext. These give us the registry object and context information we need to properly identify the operation target. The Status field is the actual status from CM for the operation while ReturnStatus is what will be returned to the caller. Because a filter may choose to return a status other than Status the ReturnStatus member is where the filter can set the status it wants returned to the caller. This is covered in the section on completion processing. The PreInformation member is a pointer to the pre-op structure and provides the post-op routine with the original values defining the operation.There's one more callback to cover, the context cleanup callback. This callback must be provided if your filter sets contexts on registry objects. This callback is executed when a registry object's handle is closed or the filter unregisters. In the unregister case, the filter will get a callback for every outstanding registry context assignment. This callback is where the filter releases any registry context resources. It is a PEX_CALLBACK_FUNCTION just like the rest of the other callbacks.Callback templates The callbacks have been discussed as far as their function prototype and structures passed so now we'll look at a template for a pre-op callback and then a post-op callback. For these examples I'm using CreateKeyEx but the template applies to any operation. The pre-op template shown in Figure 6 breaks down to enclosing the buffer access in a try/except block, casting Argument2 to a REG_CREATE_KEY_INFORMATION pointer, processing it and returning.NTSTATUS PreCreateKeyExCallback(IN PVOID CallbackContext,IN PVOID Argument1,IN PVOID Argument2){__try{PREG_CREATE_KEY_INFORMATION pPreInfo =(PREG_CREATE_KEY_INFORMATION)pInfo;//// perform pre-op processing//}__except(EXCEPTION_EXECUTE_HANDLER){NTSTATUS Status = GetExceptionCode();//// handle the exception as required//}return STATUS_SUCCESS;}Figure 6 - Pre-Op TemplateThe post-op template in Figure 7 is similar to the pre-op template but adds an extra step where a pointer to the pre-op structure is extracted to a local as a shortcut. The processing is left to the filter implementation.NTSTATUS PostCreateKeyExCallback(IN PVOID CallbackContext,IN PVOID Argument1,IN PVOID Argument2){NTSTATUS Status = STATUS_SUCCESS;__try{PREG_POST_OPERATION_INFORMATION pPostInfo =(PREG_POST_OPERATION_INFORMATION)pInfo;PREG_CREATE_KEY_INFORMATION pPreInfo =(PREG_CREATE_KEY_INFORMATION)pPostInfo->PreInformation;//// perform post-op processing//}__except(EXCEPTION_EXECUTE_HANDLER){Status = GetExceptionCode();//// handle the exception as required//}return STATUS_SUCCESS;}Figure 7 - Post-Op TemplateThe pre and post-op callbacks have to be careful when using the buffer pointer in Argument2 since this can be a user-space pointer. With that in mind, all access to the buffer must take place in a try/except block. The processing depends on the filter's application, so just remember to use the Argument2 pointer safely.The power of the registry IO handler Now that we've looked at the callback templates and the structures used, we can take that a step further and talk about what a registry filter can do - or to be more precise - what a registry IO handler can do. In this case, the term handler refers to the pre-op and post-op callback pair. A handler considers the pre and post routines as a unit which processes a single registry IO operation. With that model in mind, we can quickly describe the primary functions of a registry filter; monitoring, blocking, and modifying.The monitoring filter is passive in that it does not interfere with any of the registry IO other than to "sniff" it and possibly record it for an application. This is a common use of registry filtering and is found in many applications. The blocking filter uses criteria to determine if registry IO should be allowed. In this type of filter, the pre-op routine does the vast majority of the work since the idea is to stop IO before it can be passed on to CM. The criteria could be user, process, operation type, and so on. The final type of filter considered is one that modifies operations. There can be modifications made to the target of the operation or to the data itself. A typical modification is to the target in order to redirect the operation somewhere else in the registry. Another example is modifying the data of a value to encrypt or decrypt it.What the Ex? CreateKeyEx (and OpenKey by reference) were used in previous examples and we are discussing the Vista RFM implementation but let's diverge just for a moment to see just how different the "Ex" versions are from their predecessors. The "Ex" versions appeared in Server 2003 and replaced the "non-Ex" versions in XP. These "Ex" versions live up to their name by adding a wealth of new parameters describing the create or open. We've seen the REG_CREATE_KEY_I NFORMATION structure already; now let's look back at the REG_PRE_CREATE_KEY_INFORMATION used by CreateKey in Figure 8.typedef struct _REG_PRE_CREATE_KEY_INFORMATION {PUNICODE_STRING CompleteName;} REG_PRE_CREATE_KEY_INFORMATION, *PREG_PRE_CREATE_KEY_INFORMATION;Figure 8 - REG_PRE_CREATE_KEY_INFORMATION Structure
It's quite a bit thinner than REG_CREATE_KEY_ INFORMATION and the same is true for the structure used by OpenKey when compared to OpenKeyEx. The other thing about these older routines is that they have their own post-op structures. Figure 9 shows the REG_POST_CREATE_KEY_ INFORMATION structure.typedef struct _REG_POST_CREATE_KEY_INFORMATION {PUNICODE_STRING CompleteName;PVOID Object;NTSTATUS Status;} REG_POST_CREATE_KEY_INFORMATION, *PREG_POST_CREATE_KEY_INFORMATION;Figure 9 - _POST_CREATE_KEY_INFORMATION StructureCompare REG_POST_CREATE_KEY_INFORMATION with REG_POST_OPERATION_INFORMATION and you'll again see that the "Ex" API's provide much more information to the filter.Be sure to get registered Once your callbacks have been defined you're almost ready to register with CM to start receiving notifications. The registration routine takes a PEX_CALLBACK_ FUNCTION that it calls for all registry IO sent to your filter. This callback is the central point from which you'll pass on the calls to your IO callbacks which we have discussed so far. Using a single dispatch callback is relatively easy to implement. To begin with, define an array of PEX_CALLBACK_ FUNCTION entries that'll contain pointers to each operation callback you have implemented. The array definition is shown in Figure 10.PEX_CALLBACK_FUNCTION g_pCallbackFcns[MaxRegNtNotifyClass];Figure 10 - Defining the Callback ArrayInitialize the array such that each callback pointer is located based on its REG_NOTIFY_CLASS enumeration value. Figure 11 shows the initialization for a filter that only monitors creates, opens, and deletes. Your filter can use whatever combination of operation monitoring it needs for your application.memset(g_pCallbackFcns, 0, sizeof(g_pCallbackFcns));g_pCallbackFcns[RegNtPreCreateKeyEx] = PreCreateKeyExCallback;g_pCallbackFcns[RegNtPostCreateKeyEx] = PostCreateKeyExCallback;g_pCallbackFcns[RegNtPreOpenKeyEx] = PreOpenKeyEx;g_pCallbackFcns[RegNtPostOpenKeyEx] = PostOpenKeyEx;g_pCallbackFcns[RegNtPreDeleteKey] = PreDeleteKeyCallback;g_pCallbackFcns[RegNtPostDeleteKey] = PostDeleteKeyCallback;Figure 11 - Initializing the Callback ArrayWith the array defined, the dispatch callback simply has to cast Argument1 to a USHORT and use it as an index into the array to obtain the callback pointer. Be sure to check for a NULL entry in the array before attempting to use the callback. Figure 12 shows how the dispatch callback could be implemented.NTSTATUS DispatchCallback(IN PVOID CallbackContext,IN PVOID Argument1,IN PVOID Argument2){USHORT Class = (USHORT)Argument1;if (NULL == g_pCallbackFcns[Class]){return STATUS_SUCCESS;}return (*(g_pCallbackFcns[Class]))(CallbackContext, Argument1, Argument2);}Figure 12 - The Dispatch Callback FunctionIf you don't handle a specific type of IO (the array entry is NULL) you must return STATUS_SUCCESS. This is required because the operation must continue and should not be interrupted just because your filter doesn't care about a particular type of IO.We're now ready to notify CM that we want to filter registry IO. You can register your filter whenever makes the most sense for your application. Many filters will register in DriverEntry while others will register later. When you register, it's for all registry IO since you provide a single callback to CM. Therefore, the callback array should have NULL entries for any IO class (operation) you don't care about. This is why the dispatch callback must check for NULL entries (besides being a prudent practice anyway).In addition to a pointer to the dispatch callback, the registration API takes a string description of the altitude, a pointer to the filter's driver object, a pointer to a registration context for the filter, and a pointer to a variable to receive a special cookie identifying the registration. The string description of the altitude is simply a UNICODE_STRING of the altitude. The registration context is optional and opaque to CM. It is a means for the filter to associate information regarding a particular registration. This context is passed into each callback in the CallbackContext parameter. The cookie is a LARGE_INTEGER that is opaque to the filter and used by CM to identify a registration. It is required by certain CM routines and thus the filter must maintain this value. A typical usage of CmRegisterCallbackEx is shown in Figure 13.RtlInitUnicodeString(&altitudeString, L"360055");NTSTATUS Status = CmRegisterCallbackEx(DispatchCallback,(PCUNICODE_STRING)&altitudeString,pDriver,&g_RegistrationContext1,&g_RegistrationContext1.Cookie,Null);Figure 13 - Calling CmRegisterCallbackExA filter can register at more than one altitude provided it has been assigned multiple altitudes. It's up to the filter designer to determine how to differentiate IO at each altitude. You can still use the same dispatch callback and callback array but specify a different registration context for each altitude registered. When any of the callbacks are called, the altitude is determined by the callback using the registration context. Of course, a filter could define a separate dispatch callback and set of callbacks for each altitude but, depending on the application, this may result in a lot of duplicate code and more code to be debugged and maintained.When the filter no longer needs to filter registry IO it must unregister with CM. This would typically be done in the driver's unload routine but depending on the functionality of the filter it could occur anywhere. A filter unregisters by calling CmUnRegisterCallback. This routine takes only the cookie that the filter received when it registered with CM. Continuing our example from Figure 13; Figure 14 depicts unregistering the same filter.NTSTATUS Status = CmUnRegisterCallback(g_RegistrationContext1.Cookie)Figure 14 - Calling CmUnRegisterCallbackAs covered so far, there are several types of contexts available to a filter. Contexts allow a driver to associate private information with a distinct object or operation that is typically managed by another subsystem such as a service in the operating system. This means, for example, a driver can allocate and initialize a private blob of information that it attaches to an object, like a registry object in this case, and (nearly) every time the driver gets the object from operating system the context comes with it. So why is this useful? Well, those of us who developed file system filters prior to the Filter Manager can attest to the magnitude of overhead necessary to, say, track all open file and stream objects. Once we had context support it was so much easier to just allocate our private contexts and attach them to file system objects. Anytime we processed IO we just had to retrieve our contexts and we had the information that we used to have to track ourselves in trees or lists.There are three types of contexts available to a registry filter:
- Registration
- Registry object
- Registry operation
When we looked at registration earlier you'll recall we could pass a pointer to our initialized registration context. A filter uses this context to store per-registration information. This context is passed as the first parameter to every callback. This gives all callbacks access to the filter's private registration context to use as determined by the filter.A registry filter can set a context on a registry object with a call to CmSetCallbackObjectContext (See Figure 15 for the prototype). This is very useful because registry objects are the central focus of registry IO (surprise) and with a context on each object the filter can easily track per-object information and status. For example, a registry object context could store the root and path, create/open options and the process and thread that created/opened it. The context is typically set in the create/open post-op if the create/open was successful. However, CmSetCallbackObjectContext can be called anytime from post-create (or post-open) to prior to the handle close pre-op to set the context. Once the context has been successfully set on the object, the filter will receive a RegNtCallbackObjectContextCleanup notification when the object's handle has been closed or the filter has unregistered. Therefore, if you're going to use object contexts you must register a context cleanup callback that releases your resources for the context.NTSTATUS CmSetCallbackObjectContext(IN OUT PVOID Object,IN PLARGE_INTEGER Cookie,IN PVOID NewContext,OUT OPTIONAL PVOID *OldContext);Figure 15 - CmSetCallbackObjectContext PrototypeThe filter can track the context but it is passed to every pre-op callback in the ObjectContext member of the REG_Xxx_KEY_INFORMATION structure. If a filter registers at more than one altitude, different contexts for the same registry object can be assigned for each registration by using the cookies to delineate the assignments. CmSetCallbackObjectContext also lets you replace a context on a registry object. If you call CmSetCallbackObjectContext and a context already exists, it will remove the old context, attach the new one, and return a pointer to the old one in OldContext. If OldContext comes back non-NULL the filter is responsible for cleaning it up.The registry operation context covers the scope between the pre-op and the post-op callbacks. It is passed from the pre-op to the post-op of a single operation. It does not span across operations and is not propagated beyond the operation by CM. The filter uses this context to pass private information from a pre-op to a post-op routine. This means the filter will allocate a context in the pre-op and free it in the post-op. The context is set in the CallContext member of REG_Xxx_KEY_ INFORMATION in the pre-op and retrieved from the CallContext member of REG_POST_OPERATION_ INFORMATION in the post-op.Modification of Registry IO Calls We're almost done with this discussion of registry filters but we have an important subject left to cover: modifying registry IO calls. There are generally four distinct areas of modifications and they can be combined:
- Input parameters
- Output parameters
- Return value
- Completion processing
The filter's pre-op callback can modify input parameters in the REG_Xxx_KEY_INFORMATION structure and pass the new value(s) on. Likewise, the post-op callback can alter values in REG_POST_OPERATION_INFORMATION and return the modified information (Think of redirection as an example). In the case where the filter's post-op wants to change the return value to the caller, it sets the ReturnStatus member of REG_POST_OPERATION_INFORMATION with the status value that it wants the caller to receive and returns STATUS_CALLBACK_BYPASS. This halts further processing on the operation and immediately returns ReturnStatus to the caller. The caveat here is that the filter is responsible for cleanup of any CM objects if the status is changed from a success to a failure. If it is changed from failure to success the filter will need to provide proper parameter values in REG_POST_OPERATION_ INFORMATION. If the filter wants to fail the operation, it sets ReturnStatus to the error status to be returned to the caller and returns an error status other than STATUS_CALLBACK_BYPASS (STATUS_CALLBACK_ BYPASS is defined as an error value by the way).A filter can handle the operation completely and bypass the intended operation path. To do this, the pre-op callback processes the operation however it wants and returns STATUS_CALLBACK_BYPASS. The post-op callback is not called in this case because CM will immediately return STATUS_SUCCESS to the caller without calling any other registry filters or CM routines beyond what is necessary to complete the operation. The filter must set the corresponding REG_Xxx_KEY_INFORMATION structure with proper parameters to be returned to the caller.More to Come This article has covered a lot of material in a relatively short amount of space. The WDK provides fairly good coverage of this information but there are some crucial elements left out - I know because I had to fill in a lot of these holes to get my first registry filter working. I have tried to provide enough coverage for a developer to become familiar with the concepts and components of a registry filter. The next article will cover transactions and how to build a non-durable resource manager since the RFM doesn?t provide one (Your filter will need one to support transactions and there is no known public documentation on how to build one).Jerry Kelley is a file system filter driver developer working on software virtualization systems for a major security software corporation in the U.S. He has twenty-five years of development experience including embedded systems with the last nine years in filter development. He can be reached at jerryjkelley@msn.com.Figure 1 - Callback Routine Template
相关推荐
注册表R0监控
函数//注册一个可监控注册表操作的函数 CmRegisterCallback(回调函数地址,NULL,&返回的handle);//或CmRegisterCallbackEx,可设置高度NTSTATUS MyRegistryCallback( __in PVOID CallbackContext, __in_opt PVOID Argument1,//标识操作类型 REG_NOTIFY_CLA
RegistryCallback routine(CmRegisterCallback 注册表操作监控介绍)
RegistryCallback routine 过滤器驱动程序的常规RegistryCallback可以监视,阻止或修改一个注册表操作。 句法 C ++ EX_CALLBACK_FUNCTION RegistryCallback; NTSTATUS RegistryCallback( 标签:APIWinHTTP PVO
深入注册表监控
注册表是windows的重要数据库,存放了很多重要的信息以及一些应用的设置,对注册表进行监控并防止篡改是十分有必要的。在64位系统下微软提供了这个回调函数来实时监控注册表的操作,那么既然这里微软提供了这么一个方便的接口,病毒木马自然也会利用,这里我们就来探究其实现的原理和如何利用这个回调函数进行对抗。
Windows内核沙盒原理详解
沙盒 在计算机领域指一种虚拟技术,它实际上是一种安全体系,且多用于计算机安全技术。其原理是通过重定向技术,把程序生成和修改的文件定向到自身文件夹中。本文主要探讨沙盒的内核实现原理
ntoskrnl.exe.c 导出函数 常用2000 个内核函数名
//CmRegisterCallback 监控注册表 //CmRegisterCallbackEx 监控注册表 //PsRemoveCreateThreadNotifyRoutine //取消线程拦截 取消线程监控 //PsRemoveLoadImageNotifyRoutine //取消模块拦截 取消模块监控 //PsRestoreImpersonation //PsResumeProcess //PsReturnPoolQuota //PsReturnProcessNonPagedPoolQuota //PsReturnProcessPagedPoolQuota //PsRevertThreadToSelf //PsRevertToSelf //PsSetContextThread //设置线程环境 //PsSetCreateProcessNotifyRoutine //拦截进程 //PsSetCreateProcessNotifyRoutineEx //拦截进程 进程监控 //PsSetCreateThreadNotifyRoutine //线程监控 线程拦截 //PsSetCurrentThreadPrefetching //PsSetJobUIRestrictionsClass //PsSetLegoNotifyRoutine //PsSetLoadImageNotifyRoutine 拦截模块加载 //PsSetProcessPriorityByClass
原创_新魔百和CM201-1鸿蒙架构当贝乐家语音安卓9线刷固件包刷机教程可救砖rom刷机包
不用担心变砖,因为系统内核会自动判断分区及CPU等级,假设你CPU是高于S905L3的那么。7.adb功能支持,系统增加开机自启功能,添加老人桌面模式,默认为年轻化桌面;所以我发的这个固件可适用于_cw_ys_zg_zn代工上生产的盒子进行刷机;5.CPU及GPU算法更改,当观看4K片源时,AI智能会自动优化系统后台进程,正如我所说,本固件是采用安卓公版镜像制作而成,那么代工厂也是使用的公版镜像,1.移植鸿蒙架构代码,完美融合安卓系统,增加系统的稳定性;刷机的时候 他会自动短接链接,所以不存在变砖。
windows驱动 - 注册表回调
0x00 函数 CmRegisterCallbackEx() //回调函数绑定 CmUnRegisterCallback() //注销注册表回调 NTSTATUS ExCallbackFunction(PVOID CallbackContext,PVOID Argument1,PVOID Argument2) //注册表回调,具体内容看文档 0x01 代码 #include <ntifs.h> #include <ntddk.h> #include <wdm...
图像相似度的评价指标 : FID(Fréchet Inception Distance)
FID(Fréchet Inception Distance) 是用来计算真实图像与生成图像的特征向量间距离的一种度量。如果FID值越小,则相似程度越高。最好情况即是FID=0,两个图像相同。 实际计算: 参考链接:https://machinelearningmastery.com/how-to-implement-the-frechet-inception-distance-fid-from-scratch/ # example of calculating the frechet inceptio
利用CmRegisterCallback函数在Windows下保护注册表项
<br />一般在Windows下保护注册表有以下几种方法:<br /> <br />1. Ring3 hook <br /> 实现简单。可利用微软的Detour库,第三方的mhook库,或者自己实现。<br /> 但是如果是做产品的话不得不考虑兼容性的问题,纵使周知,大量的病毒、木马和恶意程序使用同样的方法来隐藏或者保护自身<br /> 的注册表项和键值,基本上所有基于行为监控的安全类软件都会向用户报告此类程序为恶意程序。<br />2. Ring0 hook<br /> 原理和Ring3 hook基本上
IMU、INS、GNSS与组合导航:从原理到工程实践全解析
在自动驾驶、无人机和机器人等智能系统的定位方案中,IMU、INS、GNSS和组合导航常被混为一谈,但它们在硬件层级、数据特性和误差机制上截然不同。IMU作为惯性测量单元,以百赫兹以上频率输出加速度和角速度;INS基于IMU完成姿态、速度与位置的递推解算,却因积分累积误差而随时间漂移;GNSS提供绝对位置,但易受遮挡和干扰。组合导航通过卡尔曼滤波将两者融合,实现短期不飘、长期不偏的连续定位,这正是高精度导航系统的技术底座。工程落地时,从IMU标定、Allan方差分析到相机/LiDAR与IMU外参标定,再到松耦
【BAAS】基于supabase的知识库详细设计
为满足快速开发需要和减少开发及维护成本,使用BAAS(Backend-as-a-Service)模式可以很好的降低我们的后端维护成本,并提高前端对接效率。一般来说,BAAS是一种云服务模式,BaaS供应商会为提供一些通用的能力,例如用户身份验证、数据库管理、远程更新和推送通知(针对移动应用程序),以及云存储和自托管。BaaS最主流的是Google的firebase,具有相当完善的功能和集成方案,但他是收费的,而且在我们实际项目中,可能需要私有化部署,这时就需要一些开源的替代方案,例如主流的。
注册表回调笔记
NTSTATUS CmRegisterCallbackEx( PEX_CALLBACK_FUNCTION Function,//回调函数 PCUNICODE_STRING Altitude,//高度 PVOID Driver, PVOID Context, PLARGE_INTEGER C...
3.1 快速启动Flink集群
在本实战中,我们将快速启动Apache Flink 1.13.0集群,并在Hadoop集群环境中提交作业。首先,我们会在本地下载Flink安装包并上传至云主机,解压并配置环境变量。接着,我们将启动Flink集群,通过访问Web UI进行监控管理。然后,我们会配置集群,将Flink分发到从节点,并在集群上提交作业。最后,我们将通过命令行提交作业,并在Web UI上查看任务节点的输出结果。这个过程涵盖了Flink集群的部署、配置和作业提交,为大数据处理提供了一个完整的实战经验。
电脑老蓝屏
电脑蓝屏 终止代码:REGISTRY_FILTER_DRIVER_EXCEPTION 失败的操作:hotfixplatform.sys。
Python 爬虫实战:爬取今日头条文章与阅读量数据
本文详细介绍了基于Python爬取今日头条文章与阅读量数据的完整方案。通过分析今日头条API接口,采用Requests+正则表达式技术实现数据抓取,重点解决加密参数构造、请求头模拟、反爬规避等核心问题。文章包含文章列表获取、详情数据提取、互动数据采集等完整流程,并提供数据存储与基础分析方法。同时强调合规使用爬虫技术,控制爬取频率,避免干扰平台运营。该方案可为内容传播分析、用户兴趣研究提供数据支持,但需注意接口参数更新和反爬机制变化,适时调整代码实现。
092、Python在芯片验证中的应用:从脚本小子到验证架构师
Python在芯片验证中的高效应用 本文通过实际案例展示了Python在芯片验证中的关键作用。凌晨三点的调试场景揭示了传统方法的局限,Python脚本能在20分钟内分析80GB波形数据定位FIFO指针问题。文章重点介绍了两个核心工具: 智能日志分析系统:通过正则表达式和上下文分析,自动分类百万行验证日志中的错误,生成可视化报告,效率远超传统grep方法。 寄存器模型生成器:将Excel表格自动转换为UVM寄存器模型代码,将原本需要两周的手工工作缩短至两小时,同时保证零错误。 文章还展示了Python与Sys
Windows内核
这就是PNP_INITIALIZE_BAD_CRITICAL_DRIVERS和PNP_INITIALIZE_BAD_DRIVERS策略之间的主要区别:后者允许加载所有驱动程序,包括已知为恶意的非关键驱动程序。因此,在这个阶段对驱动程序的保护不是很有效。在 Windows 内核加载阶段,控制权会移交给Windows加载器Winload.exe,它会加载必要的内核文件如Ntoskrnl.exe,在此时会加载注册表中配置为 引导启动类型(Boot Start Type)的驱动程序,包括ELAM模块。
【24届数字IC秋招总结】正式批面试经验汇总6——禾赛
15、ahb写或者读的数据存储起来了嘛,ahb读的话,apb这边是怎样的。19、覆盖率收集的时候有没有哪些是很难收集到的,然后写了定向测试。2、C++有学过嘛 还记得C++的什么内容 C++成绩多少。12、config_db机制用过嘛 四个参数的含义。8、脚本语言有学过嘛 简单学过 简单是指代码数少嘛。13、run_phase和mian_phase的区别。10、覆盖机制的创建方法 ,是不是覆盖用的很少。6、call_back机制记得哪些细节的东西。9、uvm实战学了哪些章节 印象深刻的章节。
RegistryCallback routine
RegistryCallback routine A filter driver's RegistryCallback routine can monitor, block, or modify a registry operation. Syntax C++ EX_CALLBACK_FUNCTION RegistryCallba
LinePhone3.2.7(android端最新版本) sip客户端
SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/
深度学习工具包 DeepLearningToolbox
深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[](https://bitdeli.com/free "Bitdeli Badge")
内核回调函数
Kernel Callback Functions
Devexpress16.2.6破解工具
Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具
Moving to Windows Vista x64(codeproject)
Moving to Windows Vista x64 By Daniel Pistelli. An article about x64 and Windows Vista. GenericWindo
复分析 阿尔福斯(Ahlfors) 第三版答案 英文
答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案
Windows下CmRegisterCallback简单分析
IDA看一下 进入Internal函数 signed __int64 __fastcall CmpRegisterCallbackInternal(__int64 Function, __int64 Context, const void **CmLegacyAltitude, char c_1, _QWORD *Cookie) { __int64 _Context; // rsi __int6...
【Python】成功解决NameError: name ‘os‘ is not defined
【🐍Python小妙招】拯救你的代码!告别NameError: name 'os' is not defined 🚫 😲初遇NameError,你是否一脸懵圈? 🤔为何os总是未定义?原来你没导入它! 💡深入理解import语句,让模块为你所用。 🔍排查NameError,不再被小错误绊倒。 📚掌握技巧,轻松避免NameError的尴尬。 💼os模块实战应用,文件操作更高效! 🎓总结经验,成为Python编程高手! 不再让NameError阻挡你的编程之路,轻松掌握Python os模
Registry Filter
本文使用驱动机制,可以实现对注册表操作进行拦截,而且拦截的路径可以自定义。就像杀毒软件的注册表监控一样。 同样,本程序只能运行在管理员权限下。若想要在非管理员权限下运行,则须写一个服务程序,并且在服务程序里加载这个驱动即可,不过我没有写。谁若要有兴趣,可以继续完善一下。 我的邮箱: qqliuyong007@163.com 源代码下载地址:
发一注册表监控驱动代码
该代码利用微软提供的注册表回调函数CmRegisterCallback,无需任何SSDT hook不仅能够进行注册表监控,还可以拦截。驱动完整代码如下:#define NTDDI_WINXPSP2 0x05010200#define OSVERSION_MASK 0xFFFF0000#define SPVERSION_MASK 0x00...
774



被折叠的 条评论
为什么被折叠?



