关于createremoteprocess的一个疑问?(50分)

I

iamfly

Unregistered / Unconfirmed
GUEST, unregistred user!
不知有大家有没有看过今年6月份的&lt;&lt;电脑高手&gt;&gt;其中在“WINDOWS API揭密”这一栏,有<br>如下一段C++的代码:<br>#include&lt;windows.h&gt;<br>bool SafeClose(HANDLE hProcess,UINT uExitCode)<br>{<br>&nbsp;DWORD dwTID,dwCode,dwErr=0;<br>&nbsp;HANDLE hProcessDup=INVALID_HANDLE_VALUE;<br>&nbsp;HANDLE hRt=NULL;<br>&nbsp;HINSTANCE hKernel=GetModuleHandle("Kernel32");<br>&nbsp;BOOL bSuccess=FALSE;<br>&nbsp;BOOL bDup=DuplicateHandle(GetCurrentProcess(),hProcess,GetCurrentProcess(),<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&amp;hProcessDup,PROCESS_ALL_ACCESS,FALSE,0);<br>&nbsp;if(GetexitCodeProcess((bDup)?hProcessDup:hProcess,&amp;dwCode)&amp;&amp;(dwCode==STILL_ACTIVE))<br>&nbsp;{ FARPROC pfnExitProc;<br>&nbsp; &nbsp;pfnExitProc=GetProcAddress(hKernel,"ExitProcess");<br>&nbsp; &nbsp;hRt=CreateRemoteThread((bDup)?hProcessDup:hProcess,NULL,0,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (LPTHREAD_START_ROUTINE)pfnExitProc,(PVOID)uExitCode,0&amp;dwTID);<br>&nbsp; &nbsp;if (hRt==NULL)<br>&nbsp; &nbsp; &nbsp; dwErr=GetLastError();<br>&nbsp;}<br>&nbsp;else<br>&nbsp;{dwErr=ERROR_PROCESS_ABORTED;<br>&nbsp;}<br>&nbsp;if(hRt)<br>&nbsp;{ WaitForSingleObject((bDup)?hProcessDup:hProcess,INFINITE);<br>&nbsp; &nbsp;CloseHandle(hRt);<br>&nbsp; &nbsp;bSuccess=TRUE;<br>&nbsp;}<br>&nbsp;if(bDup)<br>&nbsp; &nbsp;CloseHandle(hProcessDup);<br>&nbsp;if(!bSuccess)<br>&nbsp; &nbsp;setlasterror(dwErr);<br>&nbsp;return bSuccess;<br>}<br>现在我的疑问是:在createremotethread这,(pvoid)uexitcode有什么用呢?我应该传递<br>什么exitcode呢?其它的代码,我都已经转成了DELPHI的,就是这儿不是很明白,暂时<br>还无法调用这个函数。who can help me:)
 
不是吧,连看都没人看???:(
 
莫非,又要我自己去查MSDN?
 
找了半天的MSDN,终于找到了可能可以的答案:)<br>我传了个1过去,HPROCESS那将OPENPROCESS返回的PROCESS HANDLE传过去,OK了:)<br>版主,我能把分给回自己吗? &nbsp;
 
我要将这个问题放到直到我明白为什么再结束:P[:D]
 
CreateRemoteThread函数在Delphi下的调用原型:<br>CreateRemoteThread(hProcess,ThreadAttributes^,StackSize,StartAddress^,Parameter^,CreationFlags,ThreadId);<br>其中hProcess一般调用OpenProcess()获得<br>&nbsp; &nbsp; ThreadAttributes^则一般默认NIL<br>&nbsp; &nbsp; StackSize初始值默认为0<br>&nbsp; &nbsp; StartAddress^往往由GetProcAddress()得到<br>&nbsp; &nbsp; Parameter^则由VirtualAllocEx()获得<br>&nbsp; &nbsp; CreationFlags默认赋值为0<br>&nbsp; &nbsp; ThreadId为dword类型 &nbsp; &nbsp;<br>其作用就是在另一进程中建立线程。引申点就是可以在将自己的线程加入到别人的进程中去 ^_^<br>如:<br>pRemoteThread:=CreateRemoteThread(pRemoteProcess,NIL,0,pfnStartAddr,pFileRemote,0,p); <br>接下来你可以利用WaitForSingleObject()等待event,最后利用函数TerminateThread()即可结束线程!<br><br>照自己的理解说了一通,不知道是否清楚? 希望能对你有所帮助!<br>(无意中在一张帖子里看到你的回帖,深有感触,就特意找来你的帖子看看!)<br>才疏学浅,若有不当,还望多多交流,不吝赐教!
 
在MSDN里PARAMETER这一个参数里是这样说的:<br>Specifies a single value passed to the thread function<br>可能是和SENDMESSAGE里的WPARAM与LPARAM两个参数类似,要根据具体的不同来传递不同的<br>参数。<br>Parameter^则由VirtualAllocEx()获得?这个函数不是用来分配内存的吗?<br>望YB_UNIQUE兄能指点迷津:)<br>P.S 兄所说的用TERMINATETHREAD来结束线程的方法我不赞同,因为这样造成的可能后果在<br>MSDN里已经有很好的说明。<br>AND 我的程序在2000下已经运行通过了,在98下不行,因为Windows 95/98: Unsupported.<br>
 
VirtualAllocEx()函数可以为线程申请内存,在上例中是分配远程进程的地址空间中的内存。<br>这样你才可以利用WriteProcessMemory()函数将DLL的路径名复制到远程进程的内存空间 <br>臭名昭著的SirCAM病毒(Delphi写的)就利用了上面的原理!<br>至于TerminateThread()函数的问题,早有耳闻。但我觉得作为线程终止运行时发生的操作,<br>只要注意释放线程所占用的资源一般不会引发异常(尤其是多线程)!<br><br>现在这年头,一些未公开的技术传播得越快,好像非但造福苍生,反而变成唯恐天下不乱[:(]<br>实在是。。。唉!在国外HACK网站看到用Delphi写的病毒木马越来越多,就越是迷惘!<br>这些本非Delphi所长,但居然也被发扬光大,实在令人感慨!
 
“至于TerminateThread()函数的问题,早有耳闻。但我觉得作为线程终止运行时发生的操<br>作,只要注意释放线程所占用的资源一般不会引发异常(尤其是多线程)!”<br>如果是自己写的程序中的线程,释放资源还是不难,可是,对于别的进程的线程来说,就不<br>对了吧。别的线程占用了什么资源我们怎么知道呢?又怎么去在强行中止它时释放呢?<br>关于PARAMTER^此参数,我想应该是作为StartAddress^所指向的函数的函数的:)<br>为此,再查了下MSDN,发现是这样的:<br>VOID ExitProcess(<br>&nbsp; UINT uExitCode &nbsp; // exit code for all threads<br>);<br>因为我并不用将一个DLL路径名复制到远程进程的地址空间(USER32.DLL已经是在每一个进程<br>的地址空间里了),只需要将一个API函数插进它的空间去,并运行这个API函数,所以用不<br>到VirtualAllocEx()。在DFW看过一个在2000下把一个DLL插入另一个进程的空间的例子。<br>因为目前机上没装2000,所以试不了。YB_UNIQUE兄说的应该就是和那个贴差不多的意思吧:)<br>其实目前的很多病毒都算不上真正的病毒,只能说是蠕虫。。。<br>有很多蠕虫、木马用DELPHI来编是件好事,起码说明DELPHI也能做到:)<br><br><br><br>
 
既然兄弟有如此雅兴,呵呵!我们就再来聊聊 CreateRemoteThread() 的威力有多大! <br>Function CreateRemoteThread (processHandle : cardinal;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;threadAttr &nbsp; &nbsp;: PSecurityAttributes;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;stackSize &nbsp; &nbsp; : integer;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;startAddr &nbsp; &nbsp; : pointer;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;params &nbsp; &nbsp; &nbsp; &nbsp;: pointer;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;creationFlags : cardinal;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var threadID &nbsp;: cardinal &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) : cardinal; stdcall; <br>CreateRemoteThread()作为一个NT格式下的强力函数,在另一进程中建立自己的线程。<br>(程序在2000下已经运行通过了,在98下不行,因为Windows 95/98: Unsupported),其实通过改写扩展以后,<br>该函数完全可以在所有的32bit的OS下运行!这是我在一国外论坛上看到的!<br>(USER32.DLL已经是在每一个进程的地址空间里了,所以只需将一个API函数插进它的空间去)<br>注意两个开始地址和参数在目标进程里必须为有效!为了在进程里得到有效的开始地址要将所需的函数插入!<br>(关于PARAMTER^此参数,我想应该是作为StartAddress^所指向的函数的函数的)<br>对于PARAMTER^参数,一般是利用VirtualAllocEx()获得;<br>也可以先用AllocMemEx()分配Buffer,然后WriteProcessMemory()给赋初值即可。 <br>(其实目前的很多病毒都算不上真正的病毒,只能说是蠕虫。。。)<br>说得不错,大部分只能说是蠕虫,但对于网络而言,这不是危害更大吗?何况很多还是复合型的!<br>(有很多蠕虫、木马用DELPHI来编是件好事,起码说明DELPHI也能做到:))<br>Delphi的强大不是依靠蠕虫、木马来体现的,这也本非其所长。<br>如果有一天微软愿意公布其所有操作系统的源码,不知道那会是什么样? 没有秘密,谁都可以做到!
 
"其实通过改写扩展以后,该函数完全可以在所有的32bit的OS下运行!这是我在一国外论坛<br>上看到的!"<br>很想知道如何做到的:)<br>“注意两个开始地址和参数在目标进程里必须为有效!为了在进程里得到有效的开始地址要<br>将所需的函数插入!”<br>不是很明这句话,两个开始地址,startAddr和哪一个呢?有效的开始地址是指远地进程的<br>开始地址还是本进程的开始地址?将所需的函数插入就能得到这个开始地址,无论什么函数<br>都行吗?<br>“对于PARAMTER^参数,一般是利用VirtualAllocEx()获得;<br>也可以先用AllocMemEx()分配Buffer,然后WriteProcessMemory()给赋初值即可。 ”<br>能给个可行的例子看看吗:)<br>谢了,YB兄^_^<br><br><br>
 
例子:先分配Buffer,然后WriteProcessMemory()给赋初值即可<br><br>Var <br>ProcessId : integer; <br>ThreadId : integer; <br>buf : PChar; <br>HandleWindow : Integer; <br>write : cardinal; <br><br>Const <br>WindowTitle = 'MY test'; <br>Address = $41D090; <br>PokeValue = $32; <br>NumberOfBytes = 1; <br><br>ThreadId := GetWindowThreadProcessId(FindWindow(nil,WindowTitle),@ProcessId); <br>HandleWindow := OpenProcess(PROCESS_ALL_ACCESS,False,ProcessId); &nbsp; //当前进程<br>GetMem(buf,1); <br>buf^ := Chr(PokeValue); <br>WriteProcessMemory(HandleWindow,ptr(Address),buf,NumberOfBytes,write); //ptr(Address)指向线程地址<br>FreeMem(buf);<br><br>上面的AllocMemEx原型是<br>function AllocMemEx(size:cardinal;processHandle:cardinal=0):pointer;stdcall;<br>是GetMem的加强版(自定义的^_^)!
 
接受答案了.
 
顶部