XP下为何不能把系统DLL考出来再使用? ( 积分: 20 )

  • 主题发起人 主题发起人 sy0116
  • 开始时间 开始时间
S

sy0116

Unregistered / Unconfirmed
GUEST, unregistred user!
为了防止被别人Hook API我想把系统的kernel32.dll拷贝一份命名为old.dll放在原system32目录下,但是我发现拷贝出来的old.dll中的API不能正常工作,具体表现为我调用里面的CreateProcessW函数时进程并没有被创建,但函数又返回了True,没有任何错误提示,我在Vista下也试了一下,发现可以实现我想要的功能,不知道为什么在XP下不行
 
实在是反HOOK API的高招 有创意!
 
貌似XP有某种保护机制,但在Vista下却可以正常使用,奇怪<br>这不仅仅是可以反API&nbsp;Hook,同时也可以用来解决陷阱式API&nbsp;Hook的重入问题
 
还用,面这段代码也会有一些奇怪的问题:我想用下面的代码来把kernel32.dll拷贝到内存中,然后通过计算来得到CreateProcessW的入口地址,再通过这个地址来调用CreateProcessW,这个方法在XP下确实成功了,但问题是,这段代码在一些电脑上执行时会出错,提示XXX不能为Read,我也没找到出错的电脑的共同特征,但如果我把KdllAddr:=MapViewOfFile(maphd,FILE_MAP_ALL_ACCESS,0,0,0);这一句换成KdllAddr:=VirtualAllocEx(GetCurrentProcess,nil,KdllInfo.SizeOfImage,MEM_COMMIT,PAGE_EXECUTE_READWRITE);<br>则在那些不能运行的电脑上也可以正常运行了,不知是何原因。<br><br>function&nbsp;GetNewCreateProcessW:Pointer;<br>var<br>&nbsp;&nbsp;OldCreateProcAddr:Pointer;<br>&nbsp;&nbsp;kdllhd:THandle;<br>&nbsp;&nbsp;maphd:THandle;<br>begin<br>&nbsp;&nbsp;if&nbsp;KdllAddr=nil&nbsp;then<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;kdllhd:=LoadLibrary('kernel32.dll');<br>&nbsp;&nbsp;&nbsp;&nbsp;GetModuleInformation(GetCurrentProcess,kdllhd,@KdllInfo,SizeOf(KdllInfo));<br>&nbsp;&nbsp;&nbsp;&nbsp;OldCreateProcAddr:=GetProcAddress(kdllhd,'CreateProcessW');<br>&nbsp;&nbsp;&nbsp;&nbsp;maphd:=OpenFileMapping(FILE_MAP_ALL_ACCESS,True,'ddd_sy');<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;maphd=0&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maphd:=CreateFileMapping($FFFFFFFF,nil,PAGE_EXECUTE_READWRITE,0,KdllInfo.SizeOfImage,'ddd_sy');<br>&nbsp;&nbsp;&nbsp;&nbsp;KdllAddr:=MapViewOfFile(maphd,FILE_MAP_ALL_ACCESS,0,0,0);<br>&nbsp;&nbsp;&nbsp;&nbsp;//KdllAddr:=VirtualAllocEx(GetCurrentProcess,nil,KdllInfo.SizeOfImage,MEM_COMMIT,PAGE_EXECUTE_READWRITE);<br>&nbsp;&nbsp;&nbsp;&nbsp;WriteProcessMemory(GetCurrentProcess,KdllAddr,KdllInfo.lpBaseOfDll,KdllInfo.SizeOfImage,crd);<br>&nbsp;&nbsp;&nbsp;&nbsp;SendMessage(FindWindow('tform1',nil),16442,Cardinal(KdllAddr),0);<br>&nbsp;&nbsp;&nbsp;&nbsp;Result:=Pointer(Cardinal(OldCreateProcAddr)-cardinal(KdllInfo.lpBaseOfDll)+cardinal(KdllAddr));<br>&nbsp;&nbsp;end<br>&nbsp;&nbsp;else<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;Result:=KdllAddr;<br>&nbsp;&nbsp;end;<br>end;
 
这样并不能反&nbsp;Hook.
 
什么东西,没看懂
 
楼上是哪里没看懂?
 
hook是根据模块来的吧,楼主这样做应该有一定的效果。
 
效果小得可怜,最简单直接hook&nbsp;ntAPI就行了。
 
现在的问题是如何解决复制出的DLL不能用的问题,或者是我的第二个问题,Hook&nbsp;NtAPI&nbsp;确实可以,但我现在只需要防住别人对kernel32的Hook就可以了
 
那Hook住WriteProcessMemory就可以了。现在95%得Hook都是用这个的&nbsp;。
 
你的第二个问题是不是因为kdllhd:=LoadLibrary('kernel32.dll');没有释放加载造成的哟。
 
楼上的老兄认为应该在何处释放?我要等到下周3才可能测试,因为在我自己的电脑上这段程序完全正常,但在学校机房里就不行
 
FreeLibrary(kdllhd);
 
问题是:free掉了后还怎么用dll中的函数呢?
 
XP&nbsp;SP2以后的系统为了防止缓冲区溢出攻击,如果执行代码申请的内存不是可执行的话会报错.<br>所以你VirtualAllocEx分配的时候最后一个参数给PAGE_EXECUTE_READWRITE,就是分配一块可执行的内存,在XP&nbsp;SP2以上的系统才不会报错.<br>这个防缓冲区溢出攻击的功能还要CPU配合.<br>所以你的代码MapViewOfFile在支持的CPU+XP&nbsp;SP2的计算机上运行才会出错.
 
我学校机房的是赛扬D+XP&nbsp;SP2的,应该不支持吧,我自己的电脑是T5200+XP&nbsp;SP2,我在其他很多同学的电脑上测试(XP&nbsp;SP2)大部分都没有问题,但也有一两台有问题的,我写了一个程序用来检查错问题,还修改了一下代码,将分配到的内存的属性显示出来,发现这块内存并非PAGE_EXECUTE_READWRITE,而是PAGE_READWRITE,不知道是什么原因影响了CreateFilemapping函数,加上VirtualProtect再看还是一样,不能设置成PAGE_EXECUTE_READWRITE而是自动变成了PAGE_READWRITE,但是当我是用VirtualAlloc时却可以设置成PAGE_EXECUTE_READWRITE<br>function&nbsp;GetNewCreateProcessW:Pointer;<br>var<br>&nbsp;&nbsp;OldCreateProcAddr:Pointer;<br>&nbsp;&nbsp;kdllhd:THandle;&nbsp;<br>&nbsp;&nbsp;maphd:THandle;<br>&nbsp;&nbsp;{$IF&nbsp;Defined(DEBUG)}<br>&nbsp;&nbsp;tmpstruct:TJump;&nbsp;&nbsp;//debug<br>&nbsp;&nbsp;{$IFEND}<br>begin<br>&nbsp;&nbsp;if&nbsp;KdllAddr=nil&nbsp;then<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;kdllhd:=LoadLibrary('kernel32.dll');<br>&nbsp;&nbsp;&nbsp;&nbsp;GetModuleInformation(GetCurrentProcess,kdllhd,@KdllInfo,SizeOf(KdllInfo));<br>&nbsp;&nbsp;&nbsp;&nbsp;OldCreateProcAddr:=GetProcAddress(kdllhd,'CreateProcessW');<br>&nbsp;&nbsp;&nbsp;&nbsp;maphd:=OpenFileMapping(FILE_MAP_ALL_ACCESS,True,'AntiAutoRun_sy');<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;maphd=0&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maphd:=CreateFileMapping($FFFFFFFF,nil,PAGE_EXECUTE_READWRITE,0,KdllInfo.SizeOfImage,'AntiAutoRun_sy');<br>&nbsp;&nbsp;&nbsp;&nbsp;//GetMem(KdllAddr,KdllInfo.SizeOfImage);<br>&nbsp;&nbsp;&nbsp;&nbsp;KdllAddr:=MapViewOfFile(maphd,FILE_MAP_ALL_ACCESS,0,0,0);<br>&nbsp;&nbsp;&nbsp;&nbsp;//KdllAddr:=VirtualAlloc(nil,KdllInfo.SizeOfImage,MEM_COMMIT,PAGE_EXECUTE_READWRITE);<br>&nbsp;&nbsp;&nbsp;&nbsp;//virtualprotect(kdlladdr,KdllInfo.SizeOfImage,Page_execute_readwrite,crd);<br>&nbsp;&nbsp;&nbsp;&nbsp;//messagebox(0,pchar(inttostr(getlasterror)),'hhhhh',0);<br>&nbsp;&nbsp;&nbsp;&nbsp;VirtualQuery(KdllAddr,Debug_protect,SizeOf(Debug_protect));<br>&nbsp;&nbsp;&nbsp;&nbsp;{$IF&nbsp;Defined(DEBUG)}<br>&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendDebugInfo(SY_DEBUG_BEGIN);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendDebugInfo(SY_DEBUG,True,'检查内存分配是否正确');<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendDebugInfo(SY_DEBUG,True,'Protect:',Debug_protect.AllocationProtect);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendDebugInfo(SY_DEBUG,True,'MEM&nbsp;State:',Debug_protect.State);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendDebugInfo(SY_DEBUG,False,'大小:',Debug_protect.RegionSize);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendDebugInfo(SY_DEBUG,False,'kernel32.dll大小:',KdllInfo.SizeOfImage);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendDebugInfo(SY_DEBUG_END);<br>&nbsp;&nbsp;&nbsp;&nbsp;end;<br>&nbsp;&nbsp;&nbsp;&nbsp;{$IFEND}<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;debug_protect.Protect=$40&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WriteProcessMemory(GetCurrentProcess,KdllAddr,KdllInfo.lpBaseOfDll,KdllInfo.SizeOfImage,crd);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Result:=Pointer(Cardinal(OldCreateProcAddr)-cardinal(KdllInfo.lpBaseOfDll)+cardinal(KdllAddr));<br>&nbsp;&nbsp;&nbsp;&nbsp;end<br>&nbsp;&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;Result:=nil;<br>&nbsp;&nbsp;end&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;else<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;Result:=KdllAddr;<br>&nbsp;&nbsp;end;<br>&nbsp;&nbsp;{$IF&nbsp;Defined(DEBUG)}<br>&nbsp;&nbsp;ReadProcessMemory(GetCurrentProcess,KdllAddr,@tmpStruct,8,crd);&nbsp;&nbsp;//debug<br>&nbsp;&nbsp;{$IFEND}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//dubug<br>end;
 
我查阅了部分资料,对于你说的问题也分析实验了一下,<br>你的'kernel32.dll'入口是7C800000,调用NTDLL.DLL在7C800290处,而真正调用自身地址偏移到7C800049处,DTDLL.DLL在7C800290,你调用的部分函数内的方法不是直接实现的,有的是调用NTDLL.DLL内的函数,真正的函数输出口在7C804B63到7C8092A5段,再有你的调用函数只是系统三核心文件的共享块,虚拟页会偏移改变。<br>也许我还有未考虑到的地方,你也可以参看《WIN2000核心技术》和《WINXP核心技术》书做下比较可能会对你有更大的帮助。
 
记得在winnt系统下&nbsp;kernel32.dll,ntdll.dll,user32.dll&nbsp;这三个库文件总是载入到固定地址的,不允许重定位。
 
谢谢楼上两位的回答,可我还有一点不明白的,为什么用我第二个问题中的方法却可以实现调用Kernel32.dll中的函数呢?
 

Similar threads

后退
顶部