原理:

用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的更多相关文章

  1. ring0 关于SSDTHook使用的绕过页面写保护的原理与实现

    原博:http://www.cnblogs.com/hongfei/archive/2013/06/18/3142162.html 为了安全起见,Windows XP及其以后的系统将一些重要的内存页设 ...

  2. ring0 SSDTHook

    SSDT 的全称是 System Services Descriptor Table,系统服务描述符表.这个表就是一个把 Ring3 的 Win32 API 和 Ring0 的内核 API 联系起来. ...

  3. ring0 SSDTHook 实现x64/x86

    #include "HookSSDT.h" #include <ntimage.h> #define SEC_IMAGE 0x001000000 ULONG32 __N ...

  4. SSDTHook实例--编写稳定的Hook过滤函数

    解说怎样写Hook过滤函数,比方NewZwOpenProcess.打开进程. 非常多游戏保护都会对这个函数进行Hook. 因为我们没有游戏保护的代码,无法得知游戏公司是怎样编写这个过滤函数. 我看到非 ...

  5. ring0 与 ring3 层之间的交互

    在进行Windows的ring0层开发时,必不可免的要与 ring3 层进行交互.进行数据间的相互传输.可用的方法有DeviceIoCntrol,ReadFile.我平常都是用的DeviceIoCon ...

  6. RING0到RING3

    在前一篇文章里面,我们将了CPU保护模式中的几种特权RING0,RING1,RING2,RING3!操作系统通常运行在RING0,应用程序通常运行在RING3. CPU如何从RING0到RING3 先 ...

  7. 64位内核开发第十二讲,进程监视,ring3跟ring0事件同步.

    一丶同步与互斥详解,以及实现一个进程监视软件. 1.用于线程同步的 KEVENT 事件很简单分别分为 事件状态. 以及事件类别. 事件状态: 有信号 Signaled 无信号 Non-signaled ...

  8. X86驱动:恢复SSDT内核钩子

    SSDT 中文名称为系统服务描述符表,该表的作用是将Ring3应用层与Ring0内核层,两者的API函数连接起来,起到承上启下的作用,SSDT并不仅仅只包含一个庞大的地址索引表,它还包含着一些其它有用 ...

  9. Hook集合----SSDTHook(x86 Win7)

    最近在学习Ring0层Hook的一些知识点,很久就写完SSDTHook的代码了,但是一直没有整理成笔记,最近有时间也就整理整理. 介绍: SSDTHook 实质是利用Ntoskrnl.exe 中全局导 ...

随机推荐

  1. wx.getLocation和show-location定位点不符

    发现开发者工具未发现此类问题,到了真机上预览,观察到wx.getLocation的经纬度和show-location定位点的位置不符合.该怎么解决? 开发者工具上: 真机上: 解决方法: getLoc ...

  2. python 文件处理(基础字符)

    基于字符read & write 最基本的文件操作当然就是在文件中读写数据.这也是很容易掌握的.现在打开一个文件以进行写操作: 1. fileHandle = open ( 'test.txt ...

  3. PIE SDK栅格拉伸渲染

    1. 功能简介 栅格数据拉伸渲染是对指定的波段进行图像拉伸,并设置拉伸之后的颜色带,根据像元值和颜色带进行数据渲染. 2. 功能实现说明 2.1. 实现思路及原理说明 第一步 实例化拉伸渲染对象示例 ...

  4. PDFJs 在线预览插件

    0.A.到官网 https://mozilla.github.io/pdf.js/getting_started/#download 下载最新版本B 部署到IIS 中访问 pdf.js/web/vie ...

  5. resty-limit-multiple-strategy.lua

    --[[ 执行过载限流策略 --]] -- 当执行限流时,Nginx 返回的状态码 err_code = local limit_config = { user_limit = {rate = , b ...

  6. oracle执行update语句卡住不动

    一.问题探究 开发的时候debug到一条update的sql语句时程序就不动了,然后我就在plsql上试了一下,发现plsql一直在显示正在执行,等了好久也不出结果.但是奇怪的是执行其他的select ...

  7. Oracle RAC集群搭建(末篇)--dbca建库

    一,环境配置检测 当前位置oracle用户 二,dbca建库 运行命令dbca 根据实际情况配置 等待完成 本次内容教程完成 查看IP信息

  8. 【C#】隐式类型var

    在.NET 3.0后微软引入了隐式类型var,编译器可以自动判断变量的类型,通过var这个隐式类型,可以提高开发人员的开发效率,很多时候可以不考虑对象的类型,编译器会自动帮我们判断 使用隐式类型和使用 ...

  9. java中的各种修饰符作用范围

    访问修饰符: private 缺省 protected public 作用范围: 访问修饰符\作用范围 所在类 同一包内其他类 其他包内子类 其他包内非子类 private 可以访问 不可以 不可以 ...

  10. TOJ 4119 Split Equally

    描述 Two companies cooperatively develop a project, but they don’t like working with one another. In o ...