王朝网络
分享
 
 
 

使用远程线程制作不死进程

王朝other·作者佚名  2006-12-13
宽屏版  字体: |||超大  

远程线程指把当前进程部分代码注入到其他进程做为线程执行,虽然钩子程序能挂钩其他程序的消息,但钩子程序退出,注入的dll也就退出了,而远程线程不会 随着本地进程退出而结束。而且可以处理更多的事情,而不局限于消息。由于98不支持所以只能在nt内核上运行,下面是制作远程线程需要使用的api。

获取进程句柄方法之一是使用GetWindowThreadProcessId函数,这个函数可以从一个窗口句柄获得创建窗口进程的id,而获得一个窗口句柄可以用FindWindow轻易得到。

HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName);

lpClassName, // 窗口类名称,可以指定为NULL,光指定窗口名称即可

lpWindowName // 窗口名称。

如果两个参数都为0,则获得最顶层窗口的句柄。

DWORD GetWindowThreadProcessId(HWND hWnd,LPDWORD lpdwProcessId);

Hwnd 进程拥有的窗口句柄

LpdwProcessID 指向用来存放进程ID的变量

得到进程ID 之后,可以使用 OpenProcess函数来获得进程句柄

HANDLE OpenProcess(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwProcessId);

DwDesiredAccess,对打开的进程的访问权限,可以是下列值的组合:

PROCESS_ALL_ACCESS--------------------等于下面所有权限的组合

PROCESS_CREATE_THREAD-----------------允许创建远程线程

PROCESS_DUP_HANDLE--------------------允许进程句柄被复制

PROCESS_QUERY_INFORMATION-------------允许使用GetExitCodeProcess函数查询和GetProrityClass 查询进程信息

PROCESS_SET_INFORMATION---------------允许使用SetPriorityClass函数设置进程的优先级

PROCESS_TERMINATE----------------------允许结束进程

PROCESS_VM_OPERATION-------------------允许使用WriteProcessMemory函数或者VirtualProtectEx来修改进程的地址空间

PROCESS_VM_READ------------------------允许对读取进程地址空间

PROCESS_VM_WRITE-----------------------允许使用写入进程地址空间

BInheritHandle参数,指定返回的进程句柄是否可以被当前进程的子进程继承

DwProcessId 参数指定目标进程的进程ID

还有一种方法是使用CreateToolhelp32Snapshot(快照)函数来获得进程句柄,上面的方法进程必须要有窗口,而快照函数不需要进程拥有窗口,暂不介绍

下面是读写进程数据的两个api函数:

BOOL ReadProcessMemory(

HANDLE hProcess, // 进程句柄

LPCVOID lpBaseAddress, // 要读取的目标进程起始内存

LPVOID lpBuffer, // 本地进程用来存放读取内容的数据缓冲区

SIZE_T nSize, // 要从目标进程读取得数据长度

SIZE_T * lpNumberOfBytesRead // 要读出的到本地的数量,为NULL则忽略这个参数

BOOL WriteProcessMemory(

HANDLE hProcess, // handle to process

LPVOID lpBaseAddress, // base of memory area

LPVOID lpBuffer, // data buffer

SIZE_T nSize, // count of bytes to write

SIZE_T * lpNumberOfBytesWritten // count of bytes written

);

要注入远程线程,必须要在目标进程中开辟一段空间,来存放远程线程代码。

LPVOID VirtualAllocEx(

HANDLE hProcess, // 要开辟内存的进程

LPVOID lpAddress, // 从进程那个地址开始分配,为NULL,则系统决定

SIZE_T dwSize, // 要分配的空间大小

DWORD flAllocationType, // 分配的类型,一般用 MEM_COMMIT即可

DWORD flProtect // 这段内存访问的权限,PAGE_EXECUTE_READWRITE,远程线程所处空间必须可读可执行

);

下面是注入远程线程的需要使用的函数:

HANDLE CreateRemoteThread(

HANDLE hProcess, // 要写入远程线程进程句柄

LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程安全属性

DWORD dwStackSize, // 初始化堆栈大小

LPTHREAD_START_ROUTINE lpStartAddress, // 远程线程函数

LPVOID lpParameter, // 远程线程参数

DWORD dwCreationFlags, // 标志,可以创建挂起的线程等等

LPDWORD lpThreadId // 用来返回线程ID的指针

);

代码重定位

有 了这些函数就可以把一段代码插入到目标进程,这段代码将作为目标进程中一个独立的线程运行。但是代码编译时,全局变量、Api函数等等,将被编译为地址形 式,这是地址对于本地进程是可读可执行的,对于目标进程,读取这些地址是非法的,windows这样做,可以保证每个进程都拥有自己独立的4GB空间,而 不互相干扰(处于ring3的进程互相访问是非法的)。对于所有的高级语言,包括C语言,根本不能解决重定位问题,程序只能先写一个dll文件,然后用 CreateRemoteThread 把LoadLibrary 函数注入到目标进程中。LoadLibrary 函数调用dll 文件,执行自己想要的功能,不过这样用一些进程工具可以看到目标进程多了一个dll。重定位是汇编语言的拿手好戏。

Call @F

@@:

pop ebx

sub ebx,offset @B

现在 ebx 即得到了代码的实际地址和汇编地址之间的偏差,所以在需要重定位的代码上加上这个偏移值即可。

远程线程小例子

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;使用远程线程注入到explorer中,避免出现在win2k任务管理器中,并实现看护win2k进程,发现进程退出

;马上启动同样的另一个进程

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 使用 nmake 或下列命令进行编译和链接:

; ml /c /coff RemoteThread.asm

; rc RemoteThread.rc

; Link /subsystem:windows RemoteThread.obj RemoteThread.res

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

.386

.model flat,stdcall

option casemap:none

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

include \masm32\include\windows.inc

include \masm32\include\user32.inc

include \masm32\include\kernel32.inc

includelib \masm32\lib\user32.lib

includelib \masm32\lib\kernel32.lib

include macro.inc

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

.data

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

KnlOpenProcessStr db 'OpenProcess',0

KnlWaitForObjectStr db 'WaitForSingleObject',0

KnlWinExecStr db 'WinExec',0

KnlGetModuleHandleStr db 'GetModuleHandleA',0

KnlGetProcAddressStr db 'GetProcAddress',0

FileName db 'nodead.exe',0

szDllKernel db 'Kernel32.dll',0

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;下面两个变量是explorer.exe 进程窗口的类名(RegisterClassA参数中设定的)和进程标题名字

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

szDesktopClass db 'Progman',0

szDesktopWindow db 'Program Manager',0

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

.data?

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

KnlOpenProcess dd ?

KnlWaitForSingleObject dd ?

KnlWinExec dd ?

KnlGetModuleHandle dd ?

KnlGetProcAddress dd ?

dwProcessID dd ?

dwThreadID dd ?

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

.code

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

include RemoteCode.asm

Start:

invoke GetModuleHandle,addr szDllKernel

mov ebx,eax

invoke GetProcAddress,ebx,offset KnlOpenProcessStr

mov KnlOpenProcess,eax

invoke GetProcAddress,ebx,offset KnlWaitForObjectStr

mov KnlWaitForSingleObject,eax

invoke GetProcAddress,ebx,offset KnlWinExecStr

mov KnlWinExec,eax

invoke GetProcAddress,ebx,offset KnlGetProcAddressStr

mov KnlGetProcAddress,eax

invoke GetProcAddress,ebx,offset KnlGetModuleHandleStr

mov KnlGetModuleHandle,eax

invoke FindWindow,addr szDesktopClass,addr szDesktopWindow

invoke GetWindowThreadProcessId,eax,offset dwProcessID

mov dwThreadID,eax

invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,dwProcessID

test eax,eax

jz OpenProcessError

mov ebx,eax

invoke VirtualAllocEx,ebx,NULL,REMOTE_CODE_LENGTH,MEM_COMMIT,PAGE_EXECUTE_READWRITE

or eax,eax

jz OpenProcessError

mov edi,eax

push eax

invoke WriteProcessMemory,ebx,edi,offset REMOTE_CODE_START,REMOTE_CODE_LENGTH,NULL

invoke WriteProcessMemory,ebx,edi,offset KnlOpenProcess,sizeof dword * 5,NULL

add edi,offset Protect2kProc - offset REMOTE_CODE_START

invoke CreateRemoteThread,ebx,NULL,0,edi,0,0,NULL

invoke CloseHandle,ebx

invoke Sleep,100h

invoke MessageBoxA,0,offset FileName,offset FileName,0

OpenProcessError:

invoke ExitProcess,0

end Start

macro.inc

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 将参数列表的顺序翻转

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

reverseArgs macro arglist:VARARG

local txt,count

txt TEXTEQU <>

count = 0

for i,

count = count + 1

txt TEXTEQU @CatStr(i,,<%txt>)

endm

if count GT 0

txt SUBSTR txt,1,@SizeStr(%txt)-1

endif

exitm txt

endm

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 建立一个类似于 invoke 的 Macro

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

_invoke macro _Proc,args:VARARG

local count

count = 0

% for i,< reverseArgs( args ) >

count = count + 1

push i

endm

call dword ptr _Proc

endm

RemoteThread.asm

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 注入远程进程执行的代码

;equ this [:类型],则变量包含的段和偏移地址都和下一句相同,类型指变量类型

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

REMOTE_CODE_START equ this byte

_KnlOpenProcess dd ?

_KnlWaitForSingleObject dd ?

_KnlWinExec dd ?

_KnlGetModuleHandle dd ?

_KnlGetProcAddress dd ?

_KnlSleep dd ?

_Error2 db 'overflow2',0;循环把这个字符串覆盖了?

_FileName db 'c:\wap32.exe',0; 要看护的进程路径

_WinName db 'Our First Dialog Box',0;要看护的进程窗口名字

_hInstance dd ?

_KnlFindWindow dd ?

_KnlMessageBox dd ?

_ErrorMsg db 'overflow',0 ;循环把这个字符串覆盖了?

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 要从User32 中提取使用的api函数名称

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

_szDllUser db 'user32.dll',0

_szDllKernel db 'kernel32.dll',0

szFindWindow db 'FindWindowA',0

szMessageBox db 'MessageBoxA',0,0 ;多一个0用于结束循环

szSleep db 'Sleep',0,0

Protect2kProc proc uses ebx edi esi

local hModuleUser

local hModuleKernel

call @F

@@:

pop ebx

sub ebx,offset @B

_invoke [ebx+ _KnlGetModuleHandle],NULL

test eax,eax

jz ExitProtectProc

mov [ebx+ _hInstance],eax

lea eax,[ebx+ offset _szDllUser]

_invoke [ebx+_KnlGetModuleHandle],eax

mov hModuleUser,eax

lea esi,[ebx+offset szFindWindow]

lea edi,[ebx+offset _KnlFindWindow]

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 从User32.dll中取api函数地址的循环

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

.while TRUE

_invoke [ebx+_KnlGetProcAddress],hModuleUser,esi

mov [edi],eax

add edi,4

@@:

lodsb

or al,al

jnz @B

.break .if ! byte ptr [esi+1]

.endw

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 从Kernel32.dll中取api函数地址的循环

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

lea eax,[ebx+ offset _szDllKernel]

_invoke [ebx+_KnlGetModuleHandle],eax

mov hModuleKernel,eax

lea esi,[ebx+offset szSleep]

lea edi,[ebx+offset _KnlSleep]

.while TRUE

_invoke [ebx+_KnlGetProcAddress],hModuleKernel,esi

mov [edi],eax

add edi,4

@@:

lodsb

or al,al

jnz @B

.break .if ! byte ptr [esi+1]

.endw

call _WinMain

ExitProtectProc:

ret

Protect2kProc endp

_WinMain proc uses ebx esi edi

call @F

@@:

pop ebx

sub ebx,@B

lea edi,[ebx+ offset _ErrorMsg]

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 看护循环,发现进程退出马上重启一个

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

.while TRUE

lea esi,[ebx+offset _WinName]

_invoke [ebx+_KnlFindWindow],NULL,esi

.if ! eax

lea esi,[ebx+ offset _FileName]

_invoke [ebx+_KnlWinExec],esi,SW_SHOWNORMAL

.endif

_invoke [ebx+_KnlSleep],110h

.endw

ret

_WinMain endp

REMOTE_CODE_END equ this byte

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;REMOTE_CODE_LENGTH 获取整个插入代码的长度,在nodead.asm中,VirtualAllocEx 中制定远程线程

;长度可以使用此参数

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

REMOTE_CODE_LENGTH equ offset REMOTE_CODE_END - offset REMOTE_CODE_START

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有