找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 17846|回复: 14

求助拦截DLL加载问题

[复制链接]

9

主题

32

回帖

0

精华

铜牌会员

积分
162
发表于 2013-6-7 20:42:02 | 显示全部楼层 |阅读模式
我在 PsSetLoadImageNotifyRoutine 中拦截DLL的加载,修改PIAMGE_INFO 镜像入口地址总是不成功,直接RtlCopyMemory pEntryPoint 前5个字节就蓝屏,使用MDL 修改无效果,没办法,求大虾们指点一下!

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2013-6-7 23:03:02 | 显示全部楼层
随便贴一段我原创的禁止加载DLL的代码给你,最早是为WIN64AST所写的,你要用的话需要稍微修改一下代码,记得要在SystemThread里执行
  1. void DenyLoadDll(PSIZE_T data)
  2. {
  3.         PEPROCESS dld_ep=(PEPROCESS)(data[0]);
  4.         PVOID DriverEntry=(PVOID)(data[1]);
  5.         UCHAR fuck64[]="\xB8\x00\x00\x00\x00\xC3";
  6.         UCHAR fuck32[]="\xB8\x00\x00\x00\x00\xC2\x08\x00";
  7.         PVOID BaseAddress=DriverEntry;
  8.         ULONG OldProtect;
  9.         SIZE_T RegionSize;
  10.         NTSTATUS st;
  11.         KAPC_STATE ks={0};
  12.         if((ULONG64)DriverEntry<(ULONG64)0x7FFFFFFF)
  13.         {
  14.                 RegionSize=sizeof(fuck32);
  15.         }
  16.         else
  17.         {
  18.                 RegionSize=sizeof(fuck64);
  19.         }
  20.         KeStackAttachProcess(dld_ep,&ks);
  21.         st=NtProtectVirtualMemory((HANDLE)-1,&BaseAddress,&RegionSize,PAGE_EXECUTE_READWRITE,&OldProtect);
  22.         if(NT_SUCCESS(st))
  23.         {
  24.                 __try
  25.                 {
  26.                         if((ULONG64)DriverEntry<(ULONG64)0x7FFFFFFF)
  27.                         {
  28.                                 memcpy(DriverEntry,fuck32,sizeof(fuck32));
  29.                         }
  30.                         else
  31.                         {
  32.                                 memcpy(DriverEntry,fuck64,sizeof(fuck64));
  33.                         }
  34.                 }
  35.                 __except(1)
  36.                 {
  37.                         ;
  38.                 }
  39.         }
  40.         KeUnstackDetachProcess(&ks);
  41.         PsTerminateSystemThread(STATUS_SUCCESS);
  42. }
复制代码

9

主题

32

回帖

0

精华

铜牌会员

积分
162
 楼主| 发表于 2013-6-8 11:34:41 | 显示全部楼层
Tesla.Angela 发表于 2013-6-7 23:03
随便贴一段我原创的禁止加载DLL的代码给你,最早是为WIN64AST所写的,你要用的话需要稍微修改一下代码,记 ...

问下代码中的 NtProtectVirtualMemory 使用
MmGetSystemRoutineAddress 获取到的是0X00000000,方法不对吗?

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2013-6-8 19:47:32 | 显示全部楼层
xiaoc1026 发表于 2013-6-8 11:34
问下代码中的 NtProtectVirtualMemory 使用
MmGetSystemRoutineAddress 获取到的是0X00000000,方法不对 ...

NtProtectVirtualMemory的地址不能直接用MmGetSystemRoutineAddress获得,要从SSDT里取得。

如果你不懂如何从SSDT里取NT系列函数地址,那我就无话可说了。

9

主题

32

回帖

0

精华

铜牌会员

积分
162
 楼主| 发表于 2013-6-9 09:57:41 | 显示全部楼层
Tesla.Angela 发表于 2013-6-8 19:47
NtProtectVirtualMemory的地址不能直接用MmGetSystemRoutineAddress获得,要从SSDT里取得。

如果你不懂 ...

SSDT……,那在X64上就不兼容了。

9

主题

32

回帖

0

精华

铜牌会员

积分
162
 楼主| 发表于 2013-6-9 09:58:25 | 显示全部楼层
Tesla.Angela 发表于 2013-6-8 19:47
NtProtectVirtualMemory的地址不能直接用MmGetSystemRoutineAddress获得,要从SSDT里取得。

如果你不懂 ...

这个地方不能用MDL 来修改的吗?我修改的好像无效果,不知道是不是不能用MDL 修改?

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2013-6-9 15:37:48 | 显示全部楼层
xiaoc1026 发表于 2013-6-9 09:57
SSDT……,那在X64上就不兼容了。

不兼容个毛。
我是叫你从SSDT取地址,不是叫你HOOK SSDT。

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2013-6-9 15:38:13 | 显示全部楼层
xiaoc1026 发表于 2013-6-9 09:58
这个地方不能用MDL 来修改的吗?我修改的好像无效果,不知道是不是不能用MDL 修改? ...

这个是R3的内存,貌似不能用MDL来修改。

9

主题

32

回帖

0

精华

铜牌会员

积分
162
 楼主| 发表于 2013-6-9 17:19:20 | 显示全部楼层

  1. PVOID RetrieveFuncAddrInSSDT(IN CHAR FuncName[])
  2. {
  3.         PVOID  FuncAddr=NULL;
  4.         ULONG  ServiceID=0;
  5.         PSYSTEM_SERVICE_TABLE pTable = NULL;

  6. #if defined(_WIN64)
  7.         pTable = (PSYSTEM_SERVICE_TABLE)GetKeServiceDescriptorTable64();
  8. #else
  9.         pTable = &KeServiceDescriptorTable;
  10. #endif

  11.         if(FuncName==NULL)
  12.         {
  13.                 return NULL;
  14.         }
  15.         if(FindFuncInfoInNtdll(FuncName,&ServiceID)!=NULL)
  16.         {
  17.                 FuncAddr=*(PULONG*)((PUCHAR)pTable->ServiceTableBase+4*ServiceID);
  18.         }
  19.         return FuncAddr;
  20. }

  21. PVOID FindFuncInfoInNtdll(IN CHAR FuncName[],IN PULONG ServiceID)
  22. {
  23.         NTSTATUS                                        Status = STATUS_SUCCESS;
  24.         ULONG                                            ulModuleNum,ulLen,ulRetLen;
  25.         PSYSTEM_MODULE_INFORMATION                        SystemModuleInfo = NULL;
  26.         PVOID                                            Buffer=0;
  27.         ULONG                                            ulIndex=0;   
  28.         PVOID                                            FuncAddr=NULL;

  29.         if (FuncName==NULL || ServiceID==NULL)
  30.         {
  31.                 return NULL;
  32.         }

  33.         *ServiceID=0;

  34.         ZwQuerySystemInformation(SystemModuleInformation,NULL,0,&ulLen);
  35.         Buffer=ExAllocatePoolWithTag(NonPagedPool,ulLen,'_Hi_');
  36.         if (Buffer==NULL)
  37.         {
  38.                 return NULL;
  39.         }
  40.         Status=ZwQuerySystemInformation(SystemModuleInformation,Buffer,ulLen,&ulRetLen);
  41.         if (!NT_SUCCESS(Status))
  42.         {
  43.                 return NULL;
  44.         }
  45.         SystemModuleInfo=(PSYSTEM_MODULE_INFORMATION)((PULONG)Buffer+1);
  46.         ulModuleNum=*(PULONG)Buffer;
  47.         for (ulIndex=0;ulIndex<ulModuleNum;ulIndex++)
  48.         {
  49.                 PCHAR    CurModuleName=CurModuleName=SystemModuleInfo->ImageName + SystemModuleInfo->ModuleNameOffset;
  50.                 if(_stricmp(CurModuleName,"ntdll.dll")==0)
  51.                 {
  52.                         PVOID    ModuleAddr=SystemModuleInfo->Base;        
  53.                         ulIndex=ulModuleNum;

  54.                         {
  55.                                 PIMAGE_DOS_HEADER        ImgDosHdr=NULL;
  56.                                 PIMAGE_NT_HEADERS        ImgNtHdrs=NULL;
  57.                                 PIMAGE_EXPORT_DIRECTORY ImgExpDir=NULL;

  58.                                 ImgDosHdr=(PIMAGE_DOS_HEADER)ModuleAddr;
  59.                                 ImgNtHdrs=(PIMAGE_NT_HEADERS)(ImgDosHdr->e_lfanew+(PUCHAR)ModuleAddr);
  60.                                 ImgExpDir=(PIMAGE_EXPORT_DIRECTORY)((PUCHAR)ModuleAddr+ImgNtHdrs->OptionalHeader.DataDirectory[0].VirtualAddress);

  61.                                 {
  62.                                         ULONG    ulIndex;   
  63.                                         ULONG    *ulFuncNameRVA=(ULONG    *)((PUCHAR)ModuleAddr+ImgExpDir->AddressOfNames);
  64.                                         ULONG    *ulFuncAddrRVA=(ULONG    *)((PUCHAR)ModuleAddr+ImgExpDir->AddressOfFunctions);
  65.                                         USHORT    *usFuncOrdiRVA=(USHORT    *)((PUCHAR)ModuleAddr+ImgExpDir->AddressOfNameOrdinals);
  66.                                         UCHAR    *ExpFuncNmae=NULL;
  67.                                         for (ulIndex=0;ulIndex<ImgExpDir->NumberOfNames ;ulIndex++)
  68.                                         {
  69.                                                 ExpFuncNmae=(PUCHAR)ModuleAddr+ulFuncNameRVA[ulIndex];
  70.                                                 if(_stricmp(ExpFuncNmae,FuncName)==0)
  71.                                                 {
  72.                                                         FuncAddr=(PVOID)((PUCHAR)ModuleAddr+ulFuncAddrRVA[usFuncOrdiRVA[ulIndex]]);
  73.                                                         *ServiceID=*(PULONG)((PUCHAR)FuncAddr+1);
  74.                                                         ulIndex=ImgExpDir->NumberOfNames;
  75.                                                 }                    
  76.                                         }
  77.                                 }
  78.                         }
  79.                 }        
  80.                 else
  81.                 {
  82.                         SystemModuleInfo++;
  83.                 }        
  84.         }
  85.         ExFreePoolWithTag(Buffer,'_Hi_');
  86.         return FuncAddr;
  87. }

  88. VOID DenyLoadDll(PVOID pParam)
  89. {
  90.         PDenyLoadDllParam pContext = NULL;
  91.         UCHAR fuck64[]="\xB8\x00\x00\x00\x00\xC3";
  92.         UCHAR fuck32[]="\xB8\x00\x00\x00\x00\xC2\x08\x00";
  93.         PEPROCESS pEprocess = NULL;
  94.         KAPC_STATE ks = {0};
  95.         SIZE_T RegionSize;
  96.         PIMAGE_DOS_HEADER dos = NULL;
  97.         PIMAGE_NT_HEADERS nth = NULL;
  98.         PIMAGE_OPTIONAL_HEADER poh = NULL;
  99.         PVOID pOEP = NULL;
  100.         PVOID pImageBase = NULL;
  101.         NTSTATUS status;
  102.         PVOID BaseAddress = NULL;
  103.         ULONG OldProtect;

  104.         do
  105.         {
  106.                 if( !pParam )
  107.                 {
  108.                         break;
  109.                 }

  110.                 pContext = (PDenyLoadDllParam)pParam;

  111.                 if( pContext->hProcessId == NULL || !pContext->pImageInfo )
  112.                 {
  113.                         break;
  114.                 }

  115.                 if( !NT_SUCCESS(PsLookupProcessByProcessId( pContext->hProcessId, &pEprocess )) )
  116.                 {
  117.                         break;
  118.                 }

  119.                 if( !NtProtectVirtualMemory )
  120.                 {
  121.                         NtProtectVirtualMemory = (NtProtectVirtualMemory_)RetrieveFuncAddrInSSDT("NtProtectVirtualMemory");
  122.                 }

  123.                 if( !NtProtectVirtualMemory )
  124.                 {
  125.                         break;
  126.                 }

  127.                 //attach the process
  128.                 KeStackAttachProcess(pEprocess, &ks);

  129.                 pImageBase = pContext->pImageInfo->ImageBase;

  130.                 dos = (PIMAGE_DOS_HEADER) pImageBase;
  131.                 nth = (PIMAGE_NT_HEADERS) (dos->e_lfanew + (char *)pImageBase);
  132.                 poh = (PIMAGE_OPTIONAL_HEADER) &nth->OptionalHeader;

  133.                 // "MZ" "PE\0\0"
  134.                 if( (dos->e_magic != 0x5a4d) || (nth->Signature != 0x4550) )
  135.                 {
  136.                         break;
  137.                 }

  138.                 pOEP = (PVOID)( poh->AddressOfEntryPoint + (char *)pImageBase );
  139.                 BaseAddress = pOEP;


  140.                 if((ULONG64)pOEP<(ULONG64)0x7FFFFFFF)
  141.                 {
  142.                         RegionSize=sizeof(fuck32);
  143.                 }
  144.                 else
  145.                 {
  146.                         RegionSize=sizeof(fuck64);
  147.                 }       

  148.                 status = NtProtectVirtualMemory((HANDLE)-1,&BaseAddress,&RegionSize,PAGE_EXECUTE_READWRITE,&OldProtect);

  149.                 if(NT_SUCCESS(status))
  150.                 {
  151.                         __try
  152.                         {
  153.                                 if((ULONG64)pOEP<(ULONG64)0x7FFFFFFF)
  154.                                 {                               
  155.                                         RtlCopyMemory(pOEP,fuck32,sizeof(fuck32));
  156.                                         //SafeMemCopy(pOEP,fuck32,sizeof(fuck32));
  157.                                 }
  158.                                 else
  159.                                 {
  160.                                         RtlCopyMemory(pOEP,fuck64,sizeof(fuck64));
  161.                                         //SafeMemCopy(pOEP,fuck64,sizeof(fuck64));
  162.                                 }
  163.                         }
  164.                         __except(1)
  165.                         {
  166.                                 ;
  167.                         }
  168.                 }

  169.                 ObDereferenceObject(pEprocess);
  170.                 KeUnstackDetachProcess(&ks);
  171.                


  172.         } while (FALSE);

  173.         PsTerminateSystemThread(STATUS_SUCCESS);
  174. }
复制代码
我修改了一下你的代码,在执行到 NtProtectVirtualMemory 的时候卡住了,求教。

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2013-6-9 18:07:54 | 显示全部楼层
“卡住了”是什么意思?
找不到NtProtectVirtualMemory的地址?
NtProtectVirtualMemory的地址有错?
NtProtectVirtualMemory返回失败?
执行NtProtectVirtualMemory的线程死锁了?
执行到NtProtectVirtualMemory蓝屏了?

9

主题

32

回帖

0

精华

铜牌会员

积分
162
 楼主| 发表于 2013-6-9 18:16:27 | 显示全部楼层
Tesla.Angela 发表于 2013-6-9 18:07
“卡住了”是什么意思?
找不到NtProtectVirtualMemory的地址?
NtProtectVirtualMemory的地址有错?

NtProtectVirtualMemory地址获取到了,
NtProtectVirtualMemory 也执行了
NtProtectVirtualMemory 退不出来了,我不知道是不是它里面死锁了。

系统没有蓝屏

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2013-6-9 18:53:30 | 显示全部楼层
xiaoc1026 发表于 2013-6-9 18:16
NtProtectVirtualMemory地址获取到了,
NtProtectVirtualMemory 也执行了
NtProtectVirtualMemory 退不出 ...


你确定地址没有找错?
如果没有错,但是卡住的话,那我就不知道什么原因了。

最后多嘴一句,写代码要理解代码的意思,感觉你的相关知识欠缺很多,啥相关知识都不知道,就想搞出相应的功能是不可能的。
另外,你检查一下你获取SSDT函数地址的代码是否可靠,我曾经在论坛上发过一份可靠的代码。

9

主题

32

回帖

0

精华

铜牌会员

积分
162
 楼主| 发表于 2013-6-11 13:42:34 | 显示全部楼层
Tesla.Angela 发表于 2013-6-9 18:53
你确定地址没有找错?
如果没有错,但是卡住的话,那我就不知道什么原因了。

恶补了一下,NtProtectVirtualMemory调用失败是因为传入地址是内核地址,还需要另外申请R3内存做转换,传入。
后来我又用之前MDL 的方法修改,之前MDL无效是因为 MmProbeAndLockPages 的第三个参数传入的可写属性,这里应该先传入IoReadAccess只读属性,再在 MmProtectMdlSystemAddress 修改为可写。

最后修改成功了,但是不是我要的效果……,DLL是被拦截的,同时进程也起不来了。。。
我的目的只是想让DLL加载失败,进程还是可以起来的,我方法用错了吗?有别的方法实现我这个功能吗?

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2013-6-11 20:29:08 | 显示全部楼层
xiaoc1026 发表于 2013-6-11 13:42
恶补了一下,NtProtectVirtualMemory调用失败是因为传入地址是内核地址,还需要另外申请R3内存做转换,传 ...

你拦截的是不是程序必须用到的DLL???
如果是的话进程能跑起来才怪。
比如一个VB程序,你如果拦截了msvbvm60.dll,你认为此程序还能跑起来么?

0

主题

10

回帖

0

精华

铜牌会员

积分
42
发表于 2015-12-15 11:57:57 | 显示全部楼层
Tesla.Angela说DenyLoadDll需要在SystemThread中执行, 但是等到SystemThread执行时,dll已经被加载了, 再改dll入口点已经没有意义了, 如果在LoadImageNotifyRoutine回调函数中用KeWaitForSingleObject等待SystemThread修改入口点成功, 不知道为什么线程会死锁, Tesla.Angela能不能给解释一下, 这种情况怎么处理?
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表