zjjmj2002 - 2007-2-28 21:30:00
对乐,修改导入表还有个问题,如下面的代码直接在内存中搜寻 GetProcAddress() API函数地址。
moveax, [esp]
andeax, 0FFFF0000h
@@chk:
cmpdword ptr [eax], 00905A4Dh; 比较一下…… 5A4D就是文件头'MZ'
je@@fnd; 找到了文件头基址了!
subeax, 1000h; faint,找不到,减少1000h作为跨度
jmp@@chk; Go on!
@@fnd:
push ebp
push ebx
push esi
push edi
movebp, eax ;eax中为文件头基址
addeax, [eax][IMAGE_DOS_HEADER.e_lfanew] ;现在eax=[eax+3Ch],也就是PE文件头处
movedi, [eax][IMAGE_NT_HEADERS.OptionalHeader.DataDirectory]
addedi, ebp
movesi, [edi][IMAGE_EXPORT_DIRECTORY.AddressOfNames]
addesi, ebp
;在 kernel32.dll 里面查找 GetProcAddress 这个 API 的线形地址:
xoredx, edx
@@name:
moveax, [esi]
addeax, ebp
@@chgp:; GetProcAddress()
cmpdword ptr [eax+00h], "PteG"; GetP
jne@@next
cmpdword ptr [eax+04h], "Acor"; rocA
jne@@next
cmpdword ptr [eax+08h], "erdd"; ddre
jne@@next
cmpword ptr [eax+0Ch], "ss"; ss
jne@@next
moveax, [edi][IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals]
addeax, ebp
movzx ebx, word ptr [edx*2+eax]
moveax, [edi][IMAGE_EXPORT_DIRECTORY.AddressOfFunctions]
addeax, ebp
moveax, [ebx*4+eax]
addeax, ebp
;找到了,储存起来:
mov[_GetProcAddress], eax
@@next:
addesi, 4
incedx
cmpedx, [edi][IMAGE_EXPORT_DIRECTORY.NumberOfNames]
jne@@name
zjjmj2002 - 2007-3-1 9:12:00
其实在NT系统中TerminateProcess函数最终还是通过调用NtTerminateProcess来实现的,由于这个程序很模块化,只需要把源文件中
DllName1 db "ntdll.dll",0
ApiName1 db "NtTerminateProcess",0
如此修改一下就可以拦截NtTerminateProcess了。
但还是有很多程序不通过这些函数来结束进程,所以请高手多提意见,看结束进程的方法到底有多少!
闪电风暴 - 2007-3-1 19:00:00
| 引用: |
【zjjmj2002的贴子】其实在NT系统中TerminateProcess函数最终还是通过调用NtTerminateProcess来实现的,由于这个程序很模块化,只需要把源文件中 DllName1 db "ntdll.dll",0 ApiName1 db "NtTerminateProcess",0 如此修改一下就可以拦截NtTerminateProcess了。 但还是有很多程序不通过这些函数来结束进程,所以请高手多提意见,看结束进程的方法到底有多少!
……………… |
ntdll.dll中的NtTerminateProcess并不是ntoskrnl.exe中的系统服务NtTerminateProcess,不信你用IceSword看看.
画个图:
代码中直接调用 API ======>导入表 =========>相关DLL(如CreateFileA对应kernel32.dll) ==========>NTDLL接口
以上是用户态,也就是ring3部分.然后由NTDLL进入ring0
NTDLL ===========>NtCreateFile============>一系列系统服务函数调用(相当多,包括检查权限等)
zjjmj2002 - 2007-3-1 19:30:00
据俺所知嘛,熊猫烧香不感染如下目录里的文件
Microsoft Frontpage
Movie Maker
MSN Gamin Zone
Common Files
Windows NT
Recycled
System Volume Information
Documents and Settings
这就是为什么熊猫不感染系统文件的原因。
至于俺为什么不HOOK ntdll.dll中的NtTerminateProcess。那是因为正常进程退出时ExitProcess最终也需要调用这个函数,如果因此造成内存未被及时释放就糟糕乐。
熊猫烧香感染PE文件的方法真的很搞笑,俺估计作者对PE文件头格式可能不熟,至于特征码嘛,其实*.sys *.dll *.fon *.vxd 还有屏保之类等文件都是PE文件,猫猫为什么不感染?
zjjmj2002 - 2007-3-1 20:07:00
ntdll.dll中的NtTerminateProcess当然不是ntoskrnl.exe中的系统服务NtTerminateProcess
ntdll.dll只是提供一个接口,具体代码在ntoskrnl.exe中实现。这个俺知道,不过俺不会去HOOK ntoskrnl.exe的,来个高手干脆把IDT HOOK了得了,呵呵
zjjmj2002 - 2007-3-2 10:04:00
其实修改SSDT来HOOK native Api并不是什么高深莫测的技术。
俺以前经常编个*.sys文件通过Hook ZwQuerySystemInformation函数来隐藏进程。代码也很简单,只可惜后来大家都知道这个秘密了,现在这个技术也就能骗骗Windows的任务管理器、卡卡上网安全助手之类的啦,icesword里给你现个大大的红字,呵呵:
HookFunction proc
pushad
mov eax, [KeServiceDescriptorTable]
mov esi, [eax]
mov esi, [esi]
mov eax,ZwQuerySystemInformation
inc eax
inc eax
mov eax,[eax]
mov eax,[eax]
inc eax
movzx ecx,byte ptr[eax]
sal ecx,2
add esi,ecx
mov dwAddr,esi
mov edi,dword ptr[esi]
mov dwOldNtQuerySystemInformation,edi
mov edi,offset NewNtQuerySystemInformation
cli
mov dword ptr[esi],edi
sti
popad
mov eax, STATUS_SUCCESS
ret
HookFunction endp
zjjmj2002 - 2007-3-2 10:44:00
貌似SSDT是MS公司专门为Hooker准备的一样,内核程序通过修改这张表指向自己的处理程序就可以实现Hook,而内核程序自己调用NT*函数根本就用不着这张表,也就是说内核程序自己调用这些函数的话连恢复SSDT表这一步都可以省了,呵呵!
zjjmj2002 - 2007-3-6 15:43:00
花了点时间把软件保护程序For Win9X版编出来了!
原理基本和前几天的ForXp版本一样,还是修改Kernel32.dll模块中的TerminateProcess函数前几个字节jmp到自己的代码段达到Hook的目的(据说这叫Inline Hook,faint!)。但由于该死的MS把Kernel32.dll放在了BFF70000h处(可恨呀,那里是系统内存,Ring3的应用程序没有权限修改!这就是为什么俺以前那个ForXp的程序在Win9X下不起作用的原因。不过喜得好在Win9X下进入Ring0并不是什么难事,呵呵!)
程序下载:http://b.py99.net/zip/f?v=20073/61321259.zip
源代码如下:
.586
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include macros.asm
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
Call32 macro Selector,Offsetv
db 09ah
dd Offsetv
dw Selector
endm
.data
aKernel32 db 'Kernel32.dll',0
aUser32 db 'User32.dll',0
AddrKernel32 dd ?
aTerminateProcess db 'TerminateProcess',0
AddrTerminate dd ?
aMessageboxA db 'MessageBoxA',0
AddrMessage dd ?
aExitProcess db 'ExitProcess',0
AddrExitProcess dd ?
lpMappedObject dd ?
;;-----------------------------------------
.code
Start:
invoke GetModuleHandle,addr aKernel32
mov AddrKernel32,eax
invoke GetProcAddress,eax,addr aTerminateProcess
mov AddrTerminate,eax
detect:
cmp word ptr[eax+5],90c3h
jz _ErrHooked
invoke GetProcAddress,AddrKernel32,addr aExitProcess
mov AddrExitProcess,eax
invoke GetModuleHandle,addr aUser32
invoke GetProcAddress,eax,addr aMessageboxA
mov AddrMessage,eax
mov eax,080000000h-1000h
Try_next:
add eax,1000h
cmp eax,(-1-1000h)
jae _ErrCantAlloc
push eax
invoke VirtualAlloc,eax,1000h,MEM_COMMIT,PAGE_EXECUTE_READWRITE
test eax,eax
xchg eax,ebx
pop eax
je Try_next
mov lpMappedObject, eax
push offset MyProc
call ToRing0Code
cld
mov edi,lpMappedObject
mov esi,offset Addr0Proc
mov ecx,Addr0ProcLength+1
rep movsb
invoke MessageBox,0,CTXT("软件已成功运行!"),CTXT("SUCCESS"),MB_ICONWARNING
jmp Exit
_ErrCantAlloc:
invoke MessageBox,0,CTXT("不能分配内存!"),CTXT("ERROR"),0
jmp Exit
_ErrHooked:
invoke MessageBox,0,CTXT("程序已经运行过了!"),CTXT("ERROR"),MB_ICONWARNING
Exit:
invoke ExitProcess,0
;-----------------------------------------
MyProc proc
;进入Ring0了,当然要先叫一声庆祝庆祝!
pushad
mov al,0B6h
out 43h,al
mov al,04h
out 42h,al
out 42h,al
in al,61h
or al,3
out 61h,al
mov ecx,2000000h ;延时
loop $
and al,0FCh ;关声音
out 61h,al
popad
;开始对Kernel32.dll动手术了!
push esi
push edi
lea esi,AddrMessage
lea edi,bAddrMessage
movsd
lea esi,AddrTerminate
lea edi,bTerminate
movsd
lea esi,lpMappedObject
lea edi,blpMappedObject
movsd
mov esi,AddrTerminate
lea edi,OldBytes
xor ecx,ecx
mov cl,7
rep movsb
mov eax,AddrTerminate
mov byte ptr[eax],68h
m2m dword ptr[eax+1],lpMappedObject
mov word ptr[eax+5],90c3h
pop edi
pop esi
retf
MyProc endp
Addr0Proc:
push ebx
push esi
push edi
jmp next
align 4
Caution db '注意',0
Text db '有程序妄图终止其它进程',0dh,0ah
db '阻止吗?',0
bAddrMessage dd ?
bTerminate dd ?
blpMappedObject dd ?
next:
call tmp
tmp:
pop esi
mov eax,offset tmp-offset Addr0Proc
sub esi,eax
push MB_YESNOCANCEL or MB_ICONWARNING
mov ecx, offset Caution-offset Addr0Proc
add ecx,esi
push ecx
mov ecx, offset Text-offset Addr0Proc
add ecx,esi
push ecx
push dword ptr 0
mov ecx, offset bAddrMessage-offset Addr0Proc
add ecx,esi
call dword ptr[ecx]
.if eax==IDYES
pop edi
pop esi
pop ebx
mov eax,0
ret 8
.elseif eax==IDCANCEL
mov ecx,offset Restore-offset Addr0Proc
add ecx,esi
push ecx
mov ecx,offset ToRing0Code-offset Addr0Proc
add ecx,esi
call ecx
pop edi
pop esi
pop ebx
mov eax,0
ret 8
.endif
mov ecx,offset Restore-offset Addr0Proc
add ecx,esi
push ecx
mov ecx,offset ToRing0Code-offset Addr0Proc
add ecx,esi
call ecx
mov ecx,dword ptr[esp+5*4]
mov edx,dword ptr[esp+4*4]
push ecx
push edx
mov ecx,offset bTerminate-offset Addr0Proc
add ecx,esi
mov edx,offset Back-offset Addr0Proc
add edx,esi
push edx
push dword ptr[ecx]
ret
OldBytes db 7 dup(90h)
Back:
push eax
mov ecx,offset ReChange-offset Addr0Proc
add ecx,esi
push ecx
mov ecx,offset ToRing0Code-offset Addr0Proc
add ecx,esi
call ecx
pop eax
pop edi
pop esi
pop ebx
ret 8
ReChange:
mov ecx,offset bTerminate-offset Addr0Proc
add ecx,esi
mov eax,[ecx]
mov byte ptr[eax],68h
mov ecx,offset blpMappedObject-offset Addr0Proc
add ecx,esi
m2m dword ptr[eax+1],[ecx]
mov word ptr[eax+5],90c3h
retf
Restore:
push esi
push edi
mov edi,offset bTerminate-offset Addr0Proc
add edi,esi
mov edi,dword ptr[edi]
mov ecx,offset OldBytes-offset Addr0Proc
add esi,ecx
mov ecx,7
cld
rep movsb
pop edi
pop esi
retf
ToRing0Code proc Ring0Proc:DWORD;生成调用门并调用Ring0子程序Ring0Proc
LOCAL Temp,Temp1
callGetLdtAddress;取出LDT的地址,返回结果在eax中
movecx,[eax];保存LDT第一个描述符
mov[Temp],ecx;
movecx,[eax+4];
mov[Temp1],ecx;
movedx,Ring0Proc;把调用门的内容写入LDT
mov[eax],dx;偏移量的低16位
movword ptr [eax+2],28h;段选择子
movword ptr [eax+4],0ec00h;属性
shredx,16;偏移量的高16位
mov[eax+6],dx;
pusheax
Call327,0;调用 Ring0 子程序
popebx
movedx,[Temp];恢复LDT第一个描述符
mov[ebx],edx;
movedx,[Temp1];
mov[ebx+4],edx;
ret
ToRing0Code endp
GetLdtAddress proc;取LDT的地址
pushebx;先要取GDT的地址
sgdt[esp-2];
popebx;
sldtax;取LDT内容
andeax,0fff8H;屏蔽掉低3位、eax的高16位清0
addebx,eax;算出LDT描述符的位置
moveax,[ebx+2];从描述符中取出LDT的地址
movdl,[ebx+7];
shledx,24;
andeax,0ffffffh;
oreax,edx;
ret
GetLdtAddress endp
Addr0ProcLength =$-Addr0Proc
END Start
zjjmj2002 - 2007-3-6 16:57:00
俺都测试过,Win9X这个还不错,因为在Win9X下想绕过TerminateProcess这个API函数来终止进程很难(Post一个WM_CLOSE?)!但可惜的是现在很少有人用Win9X了。
XP下那个就实在不怎么样了,因为现在调用NtTerminateProcess来结束进程好象更流行,有些甚至于在内核下调用,连SSDT都不过,faint呀!微软的Windows。不过尽然编出来了就发表吧,呵呵!
zjjmj2002 - 2007-3-6 17:19:00
据闪电风暴老兄说还有个PspTerminateProcess,可惜他又不说怎么用,俺到网上Google了一下,有人介绍说在ntoskrnl模块里搜,于是俺从804D8000h地址开始搜,又用Unicode,又用Ansi,都还是没搜到,又有人说可以硬编码,但不说编码号是多少,跟没说一样,faint!
© 2000 - 2026 Rising Corp. Ltd.