分享
 
 
 

windows 远程线程介绍

王朝system·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

远程线程指把当前进程部分代码注入到其他进程做为线程执行,虽然钩子程序能挂钩其他程序的消息,但钩子程序退出,注入的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 即得到了代码的实际地址和汇编地址之间的偏差,所以在需要重定位的代码上加上这个偏移值即可。

远程线程代码

远程线程小例子

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

;sample write by ameng, http://ameng.tianyablog.com

;使用远程线程注入到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

KnlWinExecStrdb 'WinExec',0

KnlGetModuleHandleStrdb 'GetModuleHandleA',0

KnlGetProcAddressStrdb 'GetProcAddress',0

FileNamedb 'nodead.exe',0

szDllKerneldb 'Kernel32.dll',0

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

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

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

szDesktopClassdb 'Progman',0

szDesktopWindowdb 'Program Manager',0

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

.data?

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

KnlOpenProcessdd?

KnlWaitForSingleObjectdd?

KnlWinExecdd?

KnlGetModuleHandledd?

KnlGetProcAddressdd?

dwProcessIDdd?

dwThreadIDdd?

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

.code

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

include RemoteCode.asm

Start:

invokeGetModuleHandle,addr szDllKernel

mov ebx,eax

invokeGetProcAddress,ebx,offset KnlOpenProcessStr

movKnlOpenProcess,eax

invokeGetProcAddress,ebx,offset KnlWaitForObjectStr

movKnlWaitForSingleObject,eax

invokeGetProcAddress,ebx,offset KnlWinExecStr

movKnlWinExec,eax

invokeGetProcAddress,ebx,offset KnlGetProcAddressStr

movKnlGetProcAddress,eax

invokeGetProcAddress,ebx,offset KnlGetModuleHandleStr

movKnlGetModuleHandle,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

addedi,offset Protect2kProc - offset REMOTE_CODE_START

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

invoke CloseHandle,ebx

invoke Sleep,100h

invokeMessageBoxA,0,offset FileName,offset FileName,0

OpenProcessError:

invoke ExitProcess,0

end Start

macro.inc

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

; 将参数列表的顺序翻转

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

reverseArgsmacroarglist:VARARG

localtxt,count

txtTEXTEQU<>

count= 0

fori,

count= count + 1

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

endm

ifcount GT 0

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

endif

exitmtxt

endm

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

; 建立一个类似于 invoke 的 Macro

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

_invokemacro_Proc,args:VARARG

localcount

count= 0

%fori,< reverseArgs( args ) >

count= count + 1

pushi

endm

calldword ptr _Proc

endm

RemoteThread.asm

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

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

;sample code write by ameng

;http://ameng.tianyablog.com

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

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

REMOTE_CODE_STARTequ this byte

_KnlOpenProcessdd?

_KnlWaitForSingleObject dd?

_KnlWinExecdd?

_KnlGetModuleHandledd?

_KnlGetProcAddressdd?

_KnlSleepdd?

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

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

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

_hInstancedd?

_KnlFindWindowdd?

_KnlMessageBoxdd?

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

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

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

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

_szDllUserdb'user32.dll',0

_szDllKerneldb'kernel32.dll',0

szFindWindowdb'FindWindowA',0

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

szSleepdb'Sleep',0,0

Protect2kProc proc uses ebx edi esi

localhModuleUser

localhModuleKernel

call @F

@@:

pop ebx

sub ebx,offset @B

_invoke[ebx+ _KnlGetModuleHandle],NULL

testeax,eax

jzExitProtectProc

mov[ebx+ _hInstance],eax

leaeax,[ebx+ offset _szDllUser]

_invoke[ebx+_KnlGetModuleHandle],eax

movhModuleUser,eax

leaesi,[ebx+offset szFindWindow]

leaedi,[ebx+offset _KnlFindWindow]

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

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

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

.whileTRUE

_invoke[ebx+_KnlGetProcAddress],hModuleUser,esi

mov[edi],eax

addedi,4

@@:

lodsb

oral,al

jnz@B

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

.endw

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

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

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

leaeax,[ebx+ offset _szDllKernel]

_invoke[ebx+_KnlGetModuleHandle],eax

movhModuleKernel,eax

leaesi,[ebx+offset szSleep]

leaedi,[ebx+offset _KnlSleep]

.whileTRUE

_invoke[ebx+_KnlGetProcAddress],hModuleKernel,esi

mov[edi],eax

addedi,4

@@:

lodsb

oral,al

jnz@B

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

.endw

call_WinMain

ExitProtectProc:

ret

Protect2kProc endp

_WinMainproc uses ebx esi edi

call@F

@@:

popebx

subebx,@B

leaedi,[ebx+ offset _ErrorMsg]

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

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

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

.whileTRUE

leaesi,[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

_WinMainendp

REMOTE_CODE_ENDequ this byte

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

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

;长度可以使用此参数

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

REMOTE_CODE_LENGTHequ 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- 王朝網路 版權所有