这里讨论5个字节跳转的。
1) 被NOP掉的指令可以重复执行而不影响效果,那意味着不能有PUSH POP之类的指令存在
2) 写入指令时不被打断,如果是8个字节内的,可以用INTERLOCK,大于8个字节的可以用IRQL + DPC。
3) 被替换的指令中需要有一条指令的长度大于或等于5个字节。
记录记得的点滴
这里讨论5个字节跳转的。
1) 被NOP掉的指令可以重复执行而不影响效果,那意味着不能有PUSH POP之类的指令存在
2) 写入指令时不被打断,如果是8个字节内的,可以用INTERLOCK,大于8个字节的可以用IRQL + DPC。
3) 被替换的指令中需要有一条指令的长度大于或等于5个字节。
1)不要被当前诱惑所限制,如果你走得足够远,爬得足够高,再回头,很多现在认为重要的事其实不再重要,事情在我们心中的重要性是会随着我们的经历所改变的,我们的认知是会变得,感觉也是会变得,一切取决于你有什么样的经历和顿悟。不要让诱惑阻碍或者改变你前进的步伐。看得远一些,在一些事情上要沉得住气。不争,不比。
2)起点不好,方向对了,也会很拥挤。我们努力首先是得找个方向,其次是得有个好起点。跑过步的人都知道500米谁都能跑,但5000米不是谁都跑得了,这需要你是否能坚持得住,是否有不断的训练。在一个好的方向上,前面500米的人很多很挤,你应该要努力挤过这500米。人生是一趟长长的旅途,前500米人会很多很挤,这个时候你是无法领略风景的,这时候你会拼得头破血流,但未来终究是美好的。
3)不专注,想法太多,没有执行力,那你将一事无成,不少人花了许多时间在选择上,而不是在实践上。收获总是在途中,不要迷失在别人的言语里,同样走一条路,收获和感觉不同人会是不同的,但别人告诉你不要走了,我走过了,确实这条路不怎样?你是否就毫不犹豫地放弃了呢?不要活在别人的结论里,有些事情要自己亲身经历才会懂得。
4)及早放弃不想要的。那些年里面女主
写驱动的人知道,蓝屏了设置个DUMP可以帮助定位信息。只需要设置一下,那下次机器蓝屏时就会生成DUMP文件。相关的注册表信息是存储在
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CrashControl
其中
CrashDumpEnabled 设置为 00000002表示KERNEL DUMP
DumpFile 设置为生成DUMP全路径
Overwrite 表示覆盖原有的文件。
那怎么废掉安全软件呢?就是
DumpFile 设置为安全软件的TRAY文件的全路径。
然后强制结束系统进程,重启后就88了。
纯粹娱乐。 比较暴力,也没啥用
兼容的目标就是:保证你的改动不影响别人的改动,对别人是透明的。
一般来说改动遵守俩个原则:添加新功能,修复内部BUG。
有了目标,有了原则,一切就变得简单了。
1) 如果使用静态LIB成本不高的化,尽量使用静态LIB
2) 在写基础框架,或者基础库的时候,就考虑好应用可能的场景,尽量一次性提供所需的功能接口。当然很多时候开始无法把事情考虑完美,那在设计的时候需要思考“我如何保证扩展性,如果后续有新的功能加入,对已经暴露的东西有何影响”。
3) 给别人使用的头文件一定要仔细琢磨。暴露最少的数据结构,接口定义不变,向后兼容。保证对这个头文件的改动只仅仅是添加新的功能定义。原有的东西一概不能变动。
4)尽量不要导出一个指向结构体的指针,比如你的模块提供几个函数给外面的人使用。
struct stInterface
{
EXPORT_DEF_FUNC pfnxxxx_0;
EXPORT_DEF_FUNC pfnxxxx_1;
}
不要直接导出指向stInterface的指针。而应该是使用Query的方式。很多东西都可以采用Query方式来避免直接暴露结构体信息。通过偏移量来访问结构数据成员是不太明智的。
5) 设计接口或者数据结构时,除非保证你已经很清楚他们的用途不
驱动程序中通过一个驱动对象名来获取对应的驱动对象通常是调用ObReferenceObjectByName,ObReferenceObjectByName的声明如下
NTSTATUS
ObReferenceObjectByName (
__in PUNICODE_STRING ObjectName,
__in ULONG Attributes,
__in_opt PACCESS_STATE AccessState,
__in_opt ACCESS_MASK DesiredAccess,
__in POBJECT_TYPE ObjectType,
__in KPROCESSOR_MODE AccessMode,
__inout_opt PVOID ParseContext,
__out PVOID *Object
)
对象管理器就会根据ObjectName去遍历对应对象目录下的所有对象,看哪些对象的名字跟ObjectName匹配。那驱动对象的名字是存储在哪里呢?答案就是在
OBJECT_HEADER_NAME_INFO里面。
typedef struct _OBJECT_HEADER_NAME_INFO {
POBJECT_DIRECTORY Directory; //对象所属的路径
UNICODE_STRING Name;//对象名
ULONG QueryReferences;
} OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;
那这样修改对象名,那通过ObReferenceObjectByName就无法获取到正确的驱动对象了。下面介绍如何隐藏IRP DISPATCH HOOK。
1) 调用ObReferenceObjectByName获取\FileSystem\ntfs对应的驱动对象的指针pDrvObj
2)替换掉你想要替换的DISPACTH指针
3)修改\FileSystem\ntfs这个名字
OBJECT_HEADER* lpObjectHeader = NUL
下面的代码比较简单,能实现下面俩个功能
1)代码行数统计,只需要PDB就可以,而且统计出来的行数是有效行数,那些空行的不包括在内。
2)函数的局部变量占用空间统计,对驱动程序来讲,堆栈是宝贵资源。
HRESULT
SymGetFunctionInfo(
IN PCSTR FunctionName,
OUT ULONG64 *Offset,
OUT ULONG *Size,
OUT ULONG *Locals, OPTIONAL
OUT ULONG *Params, OPTIONAL
OUT ULONG *cbFrame, OPTIONAL
OUT BOOLEAN *fHasSEH OPTIONAL
)
{
HRESULT hr = S_FALSE;
ULONG Type = 0;
ULONG64 tmpOffset = 0;
FPO_DATA Fpo = { 0 };
IMAGE_FUNCTION_ENTRY FucEntry = { 0 };
if( FunctionName == NULL || Offset == NULL || Size == NULL )
goto __EXIT0;
hr = gDpVar.Control->GetActualProcessorType(&Type);
if( FAILED(&
以前做流量控制的时候需要用到PING,因为精确的流量控制在每建立一条TCP链接的时候,需要PING一下获取数据包的返回时间。(需要了解下TCP/IP协议)
#include "precomp.h"
#include "packet.h"
#pragma hdrstop
#pragma pack(1)//内存对齐,使内存紧凑
/* IPv4 header structure */
typedef struct _IPv4_HEADER
{
unsigned char IHL:4;
unsigned char Version:4;
unsigned char TOS;
unsigned short Length;
unsigned short Id;
unsigned short FragFlags;
unsigned char TTL;
unsigned char Protocol;
unsigned short Checksum;
unsigned int SrcAddress;
unsigned int DstAddress;
} IPv4_HEADER, *PIPv4_HEADER;
/* ICMP echo request/reply header structure */
typedef struct _ICMP_HEADER
{
unsigned char Type;
unsigned char Code;
unsigned short Checksum;
unsigned short Id;
unsigned&n
bp nt!NtTestAlert "r $t0 = @@c++( ((nt!_EPROCESS*)@$proc)->ActiveThreads );.if(@$t0==1){r $t1=@@c++( ((nt!_ETHREAD*)@$thread)->Win32StartAddress);.printf\"Win32StartAddress:\%x\\n\",@$t1;bp /p @$proc @$t1;g;}.else{g;}"
*** An Access Violation occurred in C:\Windows\system32\services.exe: The instruction at 76EE32CC tried to write to a NULL pointer *** enter .exr 00BCF5B0 for the exception record
*** enter .cxr 00BCF5CC for the context
*** then kb to get the faulting stack Break instruction exception - code 80000003 (first chance)
ntdll!DbgBreakPoint:
001b:774e7dfe cc int 3 kd> u 76ee32cc
RPCRT4!RpcpStrictAlpcToRpcStatus+0x13:
76ee32cc 890d00000000 mov dword ptr ds:[0],ecx
76ee32d2 b8e6060000 mov eax,6E6h 而RPC只接受下面的固定错误返回值
kd> dd 76430750
76430750 00000000 00000000 c0000037 000006be
76430760 c0000703 000006be c0000017 0000000e
76430770 c0000040 0000000e c0000097 0000000e
76430780 c000009a 0000000e c00000a1 0000000e
76430790 c0000007 0000000e c000012d 0000000e
764307a0 c0000702 000006be c0000022 000006be
另外拒绝也不能简单返回DENY