ring0 恢复SSDTHook
原理:
用ZwQuerySystemInformation 功能号为11(SystemModuleInformation) 得到所有系统模块的地址 遍历搜索得到ntos模块的基地址
读Ntos模块到System进程空间中
在ntos中找到函数真正地址
将地址转换为ssdt的索引
//X64版本
#include "ResumeSSDTHook.h" #define SEC_IMAGE 0x1000000 PVOID __NtosModuleBaseAddress = NULL;
ULONG64 __NtosModuleLength = ;
PVOID __SSDTAddress = ;
ULONG32 __NtOpenProcessIndex = ; NTSTATUS
DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegisterPath)
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
int i = ;
char FunctionName[] = "NtOpenProcess";
char ModuleName[] = "ntoskrnl.exe"; UNICODE_STRING DeviceName;
UNICODE_STRING LinkName; RtlInitUnicodeString(&DeviceName,DEVICE_NAME);
RtlInitUnicodeString(&LinkName,LINK_NAME); //创建设备对象; Status = IoCreateDevice(DriverObject,,
&DeviceName,FILE_DEVICE_UNKNOWN,,FALSE,&DeviceObject);
if (!NT_SUCCESS(Status))
{
return Status;
} Status = IoCreateSymbolicLink(&LinkName,&DeviceName); for (i = ; i<IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = DefaultPassThrough;
} DriverObject->DriverUnload = UnloadDriver;
//得Ntos
if (GetSystemMoudleInfoBySystemModuleName(ModuleName,
&__NtosModuleBaseAddress, &__NtosModuleLength) == FALSE)
{
return Status;
} DbgPrint("Win7 Ntos模块地址:%p\r\n", __NtosModuleBaseAddress);
DbgPrint("Win7 Ntos模块大小:%x\r\n", __NtosModuleLength);
//得ssdt
if (GetSSDTAddress(&__SSDTAddress) == FALSE)
{
return Status;
}
DbgPrint("Win7 SSDT地址:%p\r\n", __SSDTAddress);
//得需要hook的函数的索引
if (GetSSDTFunctionIndexFromNtdllExportTableByFunctionName(FunctionName,
&__NtOpenProcessIndex) == FALSE)
{
return STATUS_UNSUCCESSFUL;
}
DbgPrint("Win7 __NtOpenProcessIndex地址:%d\r\n", __NtOpenProcessIndex); //
if (ResumeSSDT(__SSDTAddress, __NtosModuleBaseAddress, __NtOpenProcessIndex, ) == TRUE)
{
DbgPrint("恢复成功\r\n");
} #ifdef WIN64
DbgPrint("WIN64: ResumeSSDTHook IS RUNNING!!!");
#else
DbgPrint("WIN32: ResumeSSDTHook SIS RUNNING!!!"); #endif return STATUS_SUCCESS;
} NTSTATUS
DefaultPassThrough(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = ;
IoCompleteRequest(Irp,IO_NO_INCREMENT); return STATUS_SUCCESS;
} VOID
UnloadDriver(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING LinkName;
PDEVICE_OBJECT NextDeviceObject = NULL;
PDEVICE_OBJECT CurrentDeviceObject = NULL;
RtlInitUnicodeString(&LinkName,LINK_NAME); IoDeleteSymbolicLink(&LinkName);
CurrentDeviceObject = DriverObject->DeviceObject;
while (CurrentDeviceObject != NULL)
{ NextDeviceObject = CurrentDeviceObject->NextDevice;
IoDeleteDevice(CurrentDeviceObject);
CurrentDeviceObject = NextDeviceObject;
} DbgPrint("ResumeSSDTHook IS STOPPED!!!");
} BOOLEAN GetSystemMoudleInfoBySystemModuleName(char* ModuleName,
PVOID* ModuleBase, ULONG64* ModuleLength)
{
int i = ;
NTSTATUS Status = STATUS_SUCCESS;
PVOID BufferData = NULL;
ULONG ReturnLength = ;
//功能号为11,先获取所需的缓冲区大小 得大小
Status = ZwQuerySystemInformation(SystemModuleInformation, NULL, , &ReturnLength); //SSDT
if (Status != STATUS_INFO_LENGTH_MISMATCH) //没有内存
{
return FALSE;
} //申请内存
BufferData = ExAllocatePool(PagedPool, ReturnLength); //PagedPool(数据段 置换到磁盘) NonPagedPool(代码段 不置换到磁盘) if (BufferData == NULL)
{
return FALSE;
} //再次调用 得数据
Status = ZwQuerySystemInformation(SystemModuleInformation, BufferData, ReturnLength, &ReturnLength);
if (!NT_SUCCESS(Status))
{
ExFreePool(BufferData);
return FALSE;
} for (i = ; i < ((PSYSTEM_MODULES_INFO)BufferData)->NumberOfModules; i++)
{
if (strstr(((PSYSTEM_MODULES_INFO)BufferData)->Modules[i].ModuleFullPathData,
ModuleName) != NULL) //Ntoskernel.exe
{
*ModuleBase = ((PSYSTEM_MODULES_INFO)BufferData)->Modules[i].ModuleBase;
*ModuleLength = ((PSYSTEM_MODULES_INFO)BufferData)->Modules[i].ModuleLength; if (BufferData != NULL)
{
ExFreePool(BufferData);
BufferData = NULL;
}
return TRUE;
}
}
if (BufferData != NULL)
{
ExFreePool(BufferData);
BufferData = NULL;
} return FALSE;
} BOOLEAN ResumeSSDT(ULONG64 SSDTAddress, ULONG64 ModuleBase, ULONG32 SSDTFunctionIndex, ULONG32 ParameterCount)
{
int i = ;
PUINT8 RVAOfSSDT = ;
WCHAR FileFullPathData[] = L"\\SystemRoot\\System32\\ntoskrnl.exe";
PIMAGE_DOS_HEADER DosHeader = NULL;
PIMAGE_NT_HEADERS NtHeader = NULL;
PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;
PIMAGE_SECTION_HEADER SectionHeader = NULL;
PVOID PresupporseImageBase = ; //优先加载地址
PVOID BaseOfSSDTInFile = ; //文件基地址
PVOID v1 = ; //函数真正地址
ULONG32 v2 = ; //SSDT[Offset]
char v3;
CHAR Bits[] = { }; PVOID BufferData = NULL;
//获得SSDT与ntos模块基地址RVA
RVAOfSSDT = ((PUINT8)(((PSERVER_SERVICE_DESCRIPTOR_TABLE)SSDTAddress)->Unknow0)) - (PUINT8)ModuleBase; //读Ntos模块到System进程空间中 (FileAlign)
if (ReadingFileInRing0Space(FileFullPathData, &BufferData) == FALSE)
{
return FALSE;
} DosHeader = (PIMAGE_DOS_HEADER)BufferData;
NtHeader = (PIMAGE_NT_HEADERS)(DosHeader->e_lfanew + (PUINT8)BufferData);
OptionalHeader = &(NtHeader->OptionalHeader);
PresupporseImageBase = OptionalHeader->ImageBase; //优先加载的地址 SectionHeader = (PIMAGE_SECTION_HEADER)((PUINT8)NtHeader + sizeof(IMAGE_NT_HEADERS)); for (i = ; i<NtHeader->FileHeader.NumberOfSections; i++)
{
if (RVAOfSSDT >= SectionHeader[i].VirtualAddress && RVAOfSSDT <
(SectionHeader[i].VirtualAddress + SectionHeader[i].SizeOfRawData))
{
//SSDT的文件偏移
BaseOfSSDTInFile = (PVOID)((PUINT8)BufferData + (RVAOfSSDT - (PUINT8)(SectionHeader[i].VirtualAddress)) + SectionHeader[i].PointerToRawData);
break;
}
} //NtOpenProcess 文件中ssdt索引对应的函数地址 - 模块加载基地址 + ntos模块的基地址
v1 = (PUINT8)(((PULONG64)BaseOfSSDTInFile)[SSDTFunctionIndex]) - (PUINT8)PresupporseImageBase + (PUINT8)ModuleBase;
//偏移
v1 = (PUINT8)v1 - (PUINT8)(((PSERVER_SERVICE_DESCRIPTOR_TABLE)SSDTAddress)->Unknow0);
v1 = (ULONG32)v1 << ; //处理参数个数
if (ParameterCount>)
{
ParameterCount = ParameterCount - ;
}
else
{
ParameterCount = ;
} //处理低四位,填写参数个数 如果一个函数的参数为5 那么dwTemp的低4位就是 0001 如果参数是6 就是0002 因为 6要减4
#define SETBIT(x,y) x|=(1<<y) //将X的第Y位置1
#define CLRBIT(x,y) x&=~(1<<y) //将X的第Y位清0
#define GETBIT(x,y) (x & (1 << y)) //取X的第Y位,返回0或非0 memcpy(&v3, &v1, );
for (i = ; i<; i++) //一个16进制 4个二进制 0000
{
Bits[i] = GETBIT(ParameterCount, i);
if (Bits[i])
{
SETBIT(v3, i);
}
else
{
CLRBIT(v3, i);
}
}
memcpy(&v1, &v3, ); //获得真实的数据了 //获得当前的数据
v2 = ((PULONG32)(((PSERVER_SERVICE_DESCRIPTOR_TABLE)SSDTAddress)->Unknow0))[SSDTFunctionIndex];
if (v1 != v2)
{
WPOFF();
((PULONG32)(((PSERVER_SERVICE_DESCRIPTOR_TABLE)SSDTAddress)->Unknow0))[SSDTFunctionIndex] = (ULONG32)v1;
WPON();
} if (BufferData != NULL)
{
ExFreePool(BufferData);
BufferData = NULL;
}
return TRUE;
} VOID WPOFF()
{
_disable();
__writecr0(__readcr0() & (~(0x10000))); }
VOID WPON()
{
__writecr0(__readcr0() ^ 0x10000);
_enable();
} BOOLEAN GetSSDTAddress(ULONG64* SSDTAddress)
{
//kd> rdmsr c0000082
PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082);
PUCHAR EndSearchAddress = StartSearchAddress + PAGE_SIZE;
PUCHAR i = NULL;
UCHAR v1 = , v2 = , v3 = ;
INT64 Offset = ; //002320c7
ULONG64 VariableAddress = ;
*SSDTAddress = NULL;
for (i = StartSearchAddress; i < EndSearchAddress; i++)
{
if (MmIsAddressValid(i) && MmIsAddressValid(i + ) && MmIsAddressValid(i + ))
{
v1 = *i;
v2 = *(i + );
v3 = *(i + );
if (v1 == 0x4c && v2 == 0x8d && v3 == 0x15)
{
memcpy(&Offset, i + , );
*SSDTAddress = Offset + (ULONG64)i + ;
break;
}
}
}
//如果是Win32 导出表 搜索 KeServiceDescriptorTable
if (*SSDTAddress == NULL)
{
return FALSE;
} return TRUE;
}
BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionName(CHAR* FunctionName, ULONG32* SSDTFunctionIndex)
{
ULONG i;
BOOLEAN IsOk = FALSE;
WCHAR FileFullPath[] = L"\\SystemRoot\\System32\\ntdll.dll"; //C:\Windows\
SIZE_T MappingViewSize = ;
PVOID MappingBaseAddress = NULL;
PIMAGE_EXPORT_DIRECTORY ImageExportDirectory = NULL;
PIMAGE_NT_HEADERS NtHeader = NULL;
UINT32* AddressOfFunctions = NULL;
UINT32* AddressOfNames = NULL;
UINT16* AddressOfNameOrdinals = NULL;
CHAR* v1 = NULL;
ULONG32 FunctionOrdinal = ;
PVOID FunctionAddress = ;
ULONG32 Offset_SSDTFunctionIndex = ;
//将Ntdll.dll映射 当前的空间中 *SSDTFunctionIndex = -;
IsOk = MappingPEFileInRing0Space(FileFullPath, &MappingBaseAddress, &MappingViewSize);
if (IsOk == FALSE)
{
return FALSE;
}
else
{
__try {
NtHeader = RtlImageNtHeader(MappingBaseAddress); //extern
if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
{
ImageExportDirectory = (IMAGE_EXPORT_DIRECTORY*)((UINT8*)MappingBaseAddress +
NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); AddressOfFunctions = (UINT32*)((UINT8*)MappingBaseAddress + ImageExportDirectory->AddressOfFunctions);
AddressOfNames = (UINT32*)((UINT8*)MappingBaseAddress + ImageExportDirectory->AddressOfNames);
AddressOfNameOrdinals = (UINT16*)((UINT8*)MappingBaseAddress + ImageExportDirectory->AddressOfNameOrdinals);
for (i = ; i < ImageExportDirectory->NumberOfNames; i++)
{
v1 = (char*)((ULONG64)MappingBaseAddress + AddressOfNames[i]); //获得函数名称
if (_stricmp(FunctionName, v1) == )
{
FunctionOrdinal = AddressOfNameOrdinals[i];
FunctionAddress = (PVOID)((UINT8*)MappingBaseAddress + AddressOfFunctions[FunctionOrdinal]); *SSDTFunctionIndex = *(ULONG32*)((UINT8*)FunctionAddress + Offset_SSDTFunctionIndex);
break;
}
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
;
}
} ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress); //解除映射 if (*SSDTFunctionIndex == -)
{
return FALSE;
} return TRUE;
}
BOOLEAN MappingPEFileInRing0Space(WCHAR* FileFullPath, PVOID* MappingBaseAddress, PSIZE_T MappingViewSize)
{ NTSTATUS Status;
UNICODE_STRING v1;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle = NULL;
HANDLE SectionHandle = NULL; if (!FileFullPath &&MmIsAddressValid(FileFullPath))
{
return FALSE;
} if (!MappingBaseAddress&&MmIsAddressValid(MappingBaseAddress))
{
return FALSE;
} RtlInitUnicodeString(&v1, FileFullPath);
InitializeObjectAttributes(&ObjectAttributes,
&v1,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL
); //获得文件句柄
Status = IoCreateFile(&FileHandle,
GENERIC_READ | SYNCHRONIZE,
&ObjectAttributes, //文件绝对路径
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
,
CreateFileTypeNone,
NULL,
IO_NO_PARAMETER_CHECKING
);
if (!NT_SUCCESS(Status))
{
return FALSE;
} ObjectAttributes.ObjectName = NULL;
Status = ZwCreateSection(&SectionHandle,
SECTION_QUERY | SECTION_MAP_READ,
&ObjectAttributes,
NULL,
PAGE_WRITECOPY,
SEC_IMAGE, //内存对齐 0x1000
FileHandle
);
ZwClose(FileHandle);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
Status = ZwMapViewOfSection(SectionHandle,
NtCurrentProcess(), //映射到当前进程的内存空间中
MappingBaseAddress,
,
,
,
MappingViewSize,
ViewUnmap,
,
PAGE_WRITECOPY
);
ZwClose(SectionHandle);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
return TRUE;
}
BOOLEAN ReadingFileInRing0Space(WCHAR* FileFullPathData, PVOID* BufferData)
{ NTSTATUS Status;
LARGE_INTEGER ReturnLength = { , };
UNICODE_STRING v1;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE FileHandle;
IO_STATUS_BLOCK IoStatusBlock;
FILE_STANDARD_INFORMATION v2 = { };
if (FileFullPathData == NULL&&*BufferData != NULL)
{
return FALSE;
} RtlInitUnicodeString(&v1, FileFullPathData);
InitializeObjectAttributes(&ObjectAttributes, &v1, OBJ_CASE_INSENSITIVE, NULL, NULL); //获取文件句柄
Status = ZwCreateFile(&FileHandle,
SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
);
if (!NT_SUCCESS(Status))
{
return FALSE;
} //计算文件长度 Status = ZwQueryInformationFile(FileHandle,
&IoStatusBlock,
&v2,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation);
if (!NT_SUCCESS(Status))
{
ZwClose(FileHandle);
return FALSE;
} //动态申请内存
*BufferData = ExAllocatePool(PagedPool, v2.EndOfFile.LowPart);
if (*BufferData == NULL)
{
ZwClose(FileHandle);
return FALSE;
} //读取文件到内存 Status = ZwReadFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
*BufferData,
v2.EndOfFile.LowPart,
&ReturnLength,
NULL); if (!NT_SUCCESS(Status))
{
ExFreePool(*BufferData);
ZwClose(FileHandle);
return FALSE;
}
ZwClose(FileHandle); return TRUE;
}
#include <ntifs.h>
#include <ntimage.h>
#ifndef CXX_ResumeSSDTHook_H
#define CXX_ResumeSSDTHook_H #define DEVICE_NAME L"\\Device\\ResumeSSDTHookDevice"
#define LINK_NAME L"\\??\\ResumeSSDTHookLink"
#define SystemModuleInformation 0xB typedef struct SYSTEM_MODULE_INFO
{
UINT32 Unknow0[];
UINT64 ModuleBase;
UINT32 ModuleLength;
UINT32 Flags;
UINT64 Unknow1;
char ModuleFullPathData[];
} SYSTEM_MODULE_INFO, *PSYSTEM_MODULE_INFO; typedef struct _SYSTEM_MODULES_INFO
{
UINT32 NumberOfModules;
SYSTEM_MODULE_INFO Modules[];
}SYSTEM_MODULES_INFO, *PSYSTEM_MODULES_INFO; typedef struct _SERVER_SERVICE_DESCRIPTOR_TABLE_
{
PVOID Unknow0;
PVOID Unknow1;
PVOID Unknow2;
PVOID Unknow3;
}SERVER_SERVICE_DESCRIPTOR_TABLE, *PSERVER_SERVICE_DESCRIPTOR_TABLE; extern
PIMAGE_NT_HEADERS
NTAPI
RtlImageNtHeader(PVOID BaseAddress); extern
NTSTATUS
ZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength); VOID
UnloadDriver(PDRIVER_OBJECT DriverObject); BOOLEAN GetSystemMoudleInfoBySystemModuleName(char * ModuleName, PVOID * ModuleBase, ULONG64 * ModuleLength); BOOLEAN ResumeSSDT(ULONG64 SSDTAddress, ULONG64 ModuleBase, ULONG32 SSDTFunctionIndex, ULONG32 ParameterCount); VOID WPOFF(); VOID WPON(); BOOLEAN GetSSDTAddress(ULONG64 * SSDTAddress); BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionName(CHAR * FunctionName, ULONG32 * SSDTFunctionIndex); BOOLEAN MappingPEFileInRing0Space(WCHAR * FileFullPath, PVOID * MappingBaseAddress, PSIZE_T MappingViewSize); BOOLEAN ReadingFileInRing0Space(WCHAR * FileFullPathData, PVOID * BufferData); NTSTATUS
DefaultPassThrough(PDEVICE_OBJECT DeviceObject,PIRP Irp); #endif
ring0 恢复SSDTHook的更多相关文章
- ring0 关于SSDTHook使用的绕过页面写保护的原理与实现
原博:http://www.cnblogs.com/hongfei/archive/2013/06/18/3142162.html 为了安全起见,Windows XP及其以后的系统将一些重要的内存页设 ...
- ring0 SSDTHook
SSDT 的全称是 System Services Descriptor Table,系统服务描述符表.这个表就是一个把 Ring3 的 Win32 API 和 Ring0 的内核 API 联系起来. ...
- ring0 SSDTHook 实现x64/x86
#include "HookSSDT.h" #include <ntimage.h> #define SEC_IMAGE 0x001000000 ULONG32 __N ...
- SSDTHook实例--编写稳定的Hook过滤函数
解说怎样写Hook过滤函数,比方NewZwOpenProcess.打开进程. 非常多游戏保护都会对这个函数进行Hook. 因为我们没有游戏保护的代码,无法得知游戏公司是怎样编写这个过滤函数. 我看到非 ...
- ring0 与 ring3 层之间的交互
在进行Windows的ring0层开发时,必不可免的要与 ring3 层进行交互.进行数据间的相互传输.可用的方法有DeviceIoCntrol,ReadFile.我平常都是用的DeviceIoCon ...
- RING0到RING3
在前一篇文章里面,我们将了CPU保护模式中的几种特权RING0,RING1,RING2,RING3!操作系统通常运行在RING0,应用程序通常运行在RING3. CPU如何从RING0到RING3 先 ...
- 64位内核开发第十二讲,进程监视,ring3跟ring0事件同步.
一丶同步与互斥详解,以及实现一个进程监视软件. 1.用于线程同步的 KEVENT 事件很简单分别分为 事件状态. 以及事件类别. 事件状态: 有信号 Signaled 无信号 Non-signaled ...
- X86驱动:恢复SSDT内核钩子
SSDT 中文名称为系统服务描述符表,该表的作用是将Ring3应用层与Ring0内核层,两者的API函数连接起来,起到承上启下的作用,SSDT并不仅仅只包含一个庞大的地址索引表,它还包含着一些其它有用 ...
- Hook集合----SSDTHook(x86 Win7)
最近在学习Ring0层Hook的一些知识点,很久就写完SSDTHook的代码了,但是一直没有整理成笔记,最近有时间也就整理整理. 介绍: SSDTHook 实质是利用Ntoskrnl.exe 中全局导 ...
随机推荐
- webgoat环境搭建
链接: https://pan.baidu.com/s/1gfEKIyB 密码: 5zdq 1:配置Java环境变量,过程请找度娘 2:解压下载好的tomcat 3:将webgoat-containe ...
- docker 启动容器报错
2018-10-24 报错信息: /usr/bin/docker-current: Error response from daemon: driver failed programming exte ...
- 论文笔记 | Self-organized Text Detection with Minimal Post-processing via Border Learning
论文链接:http://openaccess.thecvf.com/content_ICCV_2017/papers/Wu_Self-Organized_Text_Detection_ICCV_201 ...
- moment.js(moment-in-node.js)获取本月最后一天 不指定
http://tommyhu.cn/moment-in-nodejs/ //获取本月最后一天 to=using.moment(日期).endOf('month').format("YYYY- ...
- (转)DB2 db2diag.log 日志分析
DB2 db2diag.log 日志分析 原文:http://blog.csdn.net/lyjiau/article/details/52129997 db2diag.log是用来记录DB2数据库运 ...
- [转]一种可以避免数据迁移的分库分表scale-out扩容方式
原文地址:http://jm-blog.aliapp.com/?p=590 目前绝大多数应用采取的两种分库分表规则 mod方式 dayofweek系列日期方式(所有星期1的数据在一个库/表,或所有?月 ...
- 队列同步器AbstractQueuedSynchronizer
AQS是用来构建锁或者其它同步组件的基础框架,它使用一个int变量来表示同步状态,通过内置的FIFO队列来完成获取线程的排队工作,concurrent包的作者Doug Lea期望它能称为实现大部分同步 ...
- import java.util.Collections类
Collections类提供了一些操作集合的方法 下面介绍几个方法 1.将集合变为线程安全的 三个方法分别对应了ArrayList,HashMap,HashSet: Collections.sync ...
- 机器学习——GBDT
基础概念 GBDT(Gradient Boosting Decision Tree) 全称梯度提升决策树,是一种迭代的决策树算法.GBDT是集成学习Boosting的家族成员,GBDT中的树是回归树, ...
- python pickle命令执行与marshal 任意代码执行
1.python pickle反序列化漏洞 自己的理解: 由于在类的__reduce__方法中提供了我们可以自定义程序如何去解序列化的方法,因此如果应用程序接受了不可信任的序列化的数据,那么就可能导致 ...