求助拦截DLL加载问题
我在 PsSetLoadImageNotifyRoutine 中拦截DLL的加载,修改PIAMGE_INFO 镜像入口地址总是不成功,直接RtlCopyMemory pEntryPoint 前5个字节就蓝屏,使用MDL 修改无效果,没办法,求大虾们指点一下! 随便贴一段我原创的禁止加载DLL的代码给你,最早是为WIN64AST所写的,你要用的话需要稍微修改一下代码,记得要在SystemThread里执行。void DenyLoadDll(PSIZE_T data){
PEPROCESS dld_ep=(PEPROCESS)(data);
PVOID DriverEntry=(PVOID)(data);
UCHAR fuck64[]="\xB8\x00\x00\x00\x00\xC3";
UCHAR fuck32[]="\xB8\x00\x00\x00\x00\xC2\x08\x00";
PVOID BaseAddress=DriverEntry;
ULONG OldProtect;
SIZE_T RegionSize;
NTSTATUS st;
KAPC_STATE ks={0};
if((ULONG64)DriverEntry<(ULONG64)0x7FFFFFFF)
{
RegionSize=sizeof(fuck32);
}
else
{
RegionSize=sizeof(fuck64);
}
KeStackAttachProcess(dld_ep,&ks);
st=NtProtectVirtualMemory((HANDLE)-1,&BaseAddress,&RegionSize,PAGE_EXECUTE_READWRITE,&OldProtect);
if(NT_SUCCESS(st))
{
__try
{
if((ULONG64)DriverEntry<(ULONG64)0x7FFFFFFF)
{
memcpy(DriverEntry,fuck32,sizeof(fuck32));
}
else
{
memcpy(DriverEntry,fuck64,sizeof(fuck64));
}
}
__except(1)
{
;
}
}
KeUnstackDetachProcess(&ks);
PsTerminateSystemThread(STATUS_SUCCESS);
} Tesla.Angela 发表于 2013-6-7 23:03 static/image/common/back.gif
随便贴一段我原创的禁止加载DLL的代码给你,最早是为WIN64AST所写的,你要用的话需要稍微修改一下代码,记 ...
问下代码中的 NtProtectVirtualMemory 使用
MmGetSystemRoutineAddress 获取到的是0X00000000,方法不对吗? xiaoc1026 发表于 2013-6-8 11:34 static/image/common/back.gif
问下代码中的 NtProtectVirtualMemory 使用
MmGetSystemRoutineAddress 获取到的是0X00000000,方法不对 ...
NtProtectVirtualMemory的地址不能直接用MmGetSystemRoutineAddress获得,要从SSDT里取得。
如果你不懂如何从SSDT里取NT系列函数地址,那我就无话可说了。 Tesla.Angela 发表于 2013-6-8 19:47 static/image/common/back.gif
NtProtectVirtualMemory的地址不能直接用MmGetSystemRoutineAddress获得,要从SSDT里取得。
如果你不懂 ...
SSDT……,那在X64上就不兼容了。 Tesla.Angela 发表于 2013-6-8 19:47 static/image/common/back.gif
NtProtectVirtualMemory的地址不能直接用MmGetSystemRoutineAddress获得,要从SSDT里取得。
如果你不懂 ...
这个地方不能用MDL 来修改的吗?我修改的好像无效果,不知道是不是不能用MDL 修改? xiaoc1026 发表于 2013-6-9 09:57 static/image/common/back.gif
SSDT……,那在X64上就不兼容了。
不兼容个毛。
我是叫你从SSDT取地址,不是叫你HOOK SSDT。 xiaoc1026 发表于 2013-6-9 09:58 static/image/common/back.gif
这个地方不能用MDL 来修改的吗?我修改的好像无效果,不知道是不是不能用MDL 修改? ...
这个是R3的内存,貌似不能用MDL来修改。
PVOID RetrieveFuncAddrInSSDT(IN CHAR FuncName[])
{
PVOIDFuncAddr=NULL;
ULONGServiceID=0;
PSYSTEM_SERVICE_TABLE pTable = NULL;
#if defined(_WIN64)
pTable = (PSYSTEM_SERVICE_TABLE)GetKeServiceDescriptorTable64();
#else
pTable = &KeServiceDescriptorTable;
#endif
if(FuncName==NULL)
{
return NULL;
}
if(FindFuncInfoInNtdll(FuncName,&ServiceID)!=NULL)
{
FuncAddr=*(PULONG*)((PUCHAR)pTable->ServiceTableBase+4*ServiceID);
}
return FuncAddr;
}
PVOID FindFuncInfoInNtdll(IN CHAR FuncName[],IN PULONG ServiceID)
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG ulModuleNum,ulLen,ulRetLen;
PSYSTEM_MODULE_INFORMATION SystemModuleInfo = NULL;
PVOID Buffer=0;
ULONG ulIndex=0;
PVOID FuncAddr=NULL;
if (FuncName==NULL || ServiceID==NULL)
{
return NULL;
}
*ServiceID=0;
ZwQuerySystemInformation(SystemModuleInformation,NULL,0,&ulLen);
Buffer=ExAllocatePoolWithTag(NonPagedPool,ulLen,'_Hi_');
if (Buffer==NULL)
{
return NULL;
}
Status=ZwQuerySystemInformation(SystemModuleInformation,Buffer,ulLen,&ulRetLen);
if (!NT_SUCCESS(Status))
{
return NULL;
}
SystemModuleInfo=(PSYSTEM_MODULE_INFORMATION)((PULONG)Buffer+1);
ulModuleNum=*(PULONG)Buffer;
for (ulIndex=0;ulIndex<ulModuleNum;ulIndex++)
{
PCHAR CurModuleName=CurModuleName=SystemModuleInfo->ImageName + SystemModuleInfo->ModuleNameOffset;
if(_stricmp(CurModuleName,"ntdll.dll")==0)
{
PVOID ModuleAddr=SystemModuleInfo->Base;
ulIndex=ulModuleNum;
{
PIMAGE_DOS_HEADER ImgDosHdr=NULL;
PIMAGE_NT_HEADERS ImgNtHdrs=NULL;
PIMAGE_EXPORT_DIRECTORY ImgExpDir=NULL;
ImgDosHdr=(PIMAGE_DOS_HEADER)ModuleAddr;
ImgNtHdrs=(PIMAGE_NT_HEADERS)(ImgDosHdr->e_lfanew+(PUCHAR)ModuleAddr);
ImgExpDir=(PIMAGE_EXPORT_DIRECTORY)((PUCHAR)ModuleAddr+ImgNtHdrs->OptionalHeader.DataDirectory.VirtualAddress);
{
ULONG ulIndex;
ULONG *ulFuncNameRVA=(ULONG *)((PUCHAR)ModuleAddr+ImgExpDir->AddressOfNames);
ULONG *ulFuncAddrRVA=(ULONG *)((PUCHAR)ModuleAddr+ImgExpDir->AddressOfFunctions);
USHORT *usFuncOrdiRVA=(USHORT *)((PUCHAR)ModuleAddr+ImgExpDir->AddressOfNameOrdinals);
UCHAR *ExpFuncNmae=NULL;
for (ulIndex=0;ulIndex<ImgExpDir->NumberOfNames ;ulIndex++)
{
ExpFuncNmae=(PUCHAR)ModuleAddr+ulFuncNameRVA;
if(_stricmp(ExpFuncNmae,FuncName)==0)
{
FuncAddr=(PVOID)((PUCHAR)ModuleAddr+ulFuncAddrRVA]);
*ServiceID=*(PULONG)((PUCHAR)FuncAddr+1);
ulIndex=ImgExpDir->NumberOfNames;
}
}
}
}
}
else
{
SystemModuleInfo++;
}
}
ExFreePoolWithTag(Buffer,'_Hi_');
return FuncAddr;
}
VOID DenyLoadDll(PVOID pParam)
{
PDenyLoadDllParam pContext = NULL;
UCHAR fuck64[]="\xB8\x00\x00\x00\x00\xC3";
UCHAR fuck32[]="\xB8\x00\x00\x00\x00\xC2\x08\x00";
PEPROCESS pEprocess = NULL;
KAPC_STATE ks = {0};
SIZE_T RegionSize;
PIMAGE_DOS_HEADER dos = NULL;
PIMAGE_NT_HEADERS nth = NULL;
PIMAGE_OPTIONAL_HEADER poh = NULL;
PVOID pOEP = NULL;
PVOID pImageBase = NULL;
NTSTATUS status;
PVOID BaseAddress = NULL;
ULONG OldProtect;
do
{
if( !pParam )
{
break;
}
pContext = (PDenyLoadDllParam)pParam;
if( pContext->hProcessId == NULL || !pContext->pImageInfo )
{
break;
}
if( !NT_SUCCESS(PsLookupProcessByProcessId( pContext->hProcessId, &pEprocess )) )
{
break;
}
if( !NtProtectVirtualMemory )
{
NtProtectVirtualMemory = (NtProtectVirtualMemory_)RetrieveFuncAddrInSSDT("NtProtectVirtualMemory");
}
if( !NtProtectVirtualMemory )
{
break;
}
//attach the process
KeStackAttachProcess(pEprocess, &ks);
pImageBase = pContext->pImageInfo->ImageBase;
dos = (PIMAGE_DOS_HEADER) pImageBase;
nth = (PIMAGE_NT_HEADERS) (dos->e_lfanew + (char *)pImageBase);
poh = (PIMAGE_OPTIONAL_HEADER) &nth->OptionalHeader;
// "MZ" "PE\0\0"
if( (dos->e_magic != 0x5a4d) || (nth->Signature != 0x4550) )
{
break;
}
pOEP = (PVOID)( poh->AddressOfEntryPoint + (char *)pImageBase );
BaseAddress = pOEP;
if((ULONG64)pOEP<(ULONG64)0x7FFFFFFF)
{
RegionSize=sizeof(fuck32);
}
else
{
RegionSize=sizeof(fuck64);
}
status = NtProtectVirtualMemory((HANDLE)-1,&BaseAddress,&RegionSize,PAGE_EXECUTE_READWRITE,&OldProtect);
if(NT_SUCCESS(status))
{
__try
{
if((ULONG64)pOEP<(ULONG64)0x7FFFFFFF)
{
RtlCopyMemory(pOEP,fuck32,sizeof(fuck32));
//SafeMemCopy(pOEP,fuck32,sizeof(fuck32));
}
else
{
RtlCopyMemory(pOEP,fuck64,sizeof(fuck64));
//SafeMemCopy(pOEP,fuck64,sizeof(fuck64));
}
}
__except(1)
{
;
}
}
ObDereferenceObject(pEprocess);
KeUnstackDetachProcess(&ks);
} while (FALSE);
PsTerminateSystemThread(STATUS_SUCCESS);
}我修改了一下你的代码,在执行到 NtProtectVirtualMemory 的时候卡住了,求教。 “卡住了”是什么意思?
找不到NtProtectVirtualMemory的地址?
NtProtectVirtualMemory的地址有错?
NtProtectVirtualMemory返回失败?
执行NtProtectVirtualMemory的线程死锁了?
执行到NtProtectVirtualMemory蓝屏了? Tesla.Angela 发表于 2013-6-9 18:07 static/image/common/back.gif
“卡住了”是什么意思?
找不到NtProtectVirtualMemory的地址?
NtProtectVirtualMemory的地址有错?
NtProtectVirtualMemory地址获取到了,
NtProtectVirtualMemory 也执行了
NtProtectVirtualMemory 退不出来了,我不知道是不是它里面死锁了。
系统没有蓝屏 xiaoc1026 发表于 2013-6-9 18:16 static/image/common/back.gif
NtProtectVirtualMemory地址获取到了,
NtProtectVirtualMemory 也执行了
NtProtectVirtualMemory 退不出 ...
你确定地址没有找错?
如果没有错,但是卡住的话,那我就不知道什么原因了。
最后多嘴一句,写代码要理解代码的意思,感觉你的相关知识欠缺很多,啥相关知识都不知道,就想搞出相应的功能是不可能的。
另外,你检查一下你获取SSDT函数地址的代码是否可靠,我曾经在论坛上发过一份可靠的代码。 Tesla.Angela 发表于 2013-6-9 18:53 static/image/common/back.gif
你确定地址没有找错?
如果没有错,但是卡住的话,那我就不知道什么原因了。
恶补了一下,NtProtectVirtualMemory调用失败是因为传入地址是内核地址,还需要另外申请R3内存做转换,传入。
后来我又用之前MDL 的方法修改,之前MDL无效是因为 MmProbeAndLockPages 的第三个参数传入的可写属性,这里应该先传入IoReadAccess只读属性,再在 MmProtectMdlSystemAddress 修改为可写。
最后修改成功了,但是不是我要的效果……,DLL是被拦截的,同时进程也起不来了。。。
我的目的只是想让DLL加载失败,进程还是可以起来的,我方法用错了吗?有别的方法实现我这个功能吗? xiaoc1026 发表于 2013-6-11 13:42 static/image/common/back.gif
恶补了一下,NtProtectVirtualMemory调用失败是因为传入地址是内核地址,还需要另外申请R3内存做转换,传 ...
你拦截的是不是程序必须用到的DLL???
如果是的话进程能跑起来才怪。
比如一个VB程序,你如果拦截了msvbvm60.dll,你认为此程序还能跑起来么? Tesla.Angela说DenyLoadDll需要在SystemThread中执行, 但是等到SystemThread执行时,dll已经被加载了, 再改dll入口点已经没有意义了, 如果在LoadImageNotifyRoutine回调函数中用KeWaitForSingleObject等待SystemThread修改入口点成功, 不知道为什么线程会死锁, Tesla.Angela能不能给解释一下, 这种情况怎么处理?
页:
[1]