(转载)CreateRemoteThread (代码注入)
2009-03-20 11:41
627 查看
转载自:http://win32.mvps.org/processes/remthread.html
CreateRemoteThread
Update 12-Dec-00: Keith Brown drew my attention to some weird
behaviour. If incremental linking is on, and if a wstrstream is used to convert
a string to a numeric PID, then the remote thread will crash the target process,
and I have not the faintest idea why. (OK, so I have an idea, but it's all
speculation.) In consequence, I removed all references to the standard C++
library.
Update 21-Nov-99: Tomas Restrepo found a bug, and one of an
unbelievably horrible kind, too -- I used VirtualFree() instead of VirtualFreeEx(),
meaning that I not only leaked memory in the target process, but also freed
something I never allocated in the remthread process. The bug has been fixed,
and I owe Tomas a big thank-you.
This sample demonstrates how to get the command line another process was
started with. To this end, it performs the following steps:
There are other methods, too, for code injection, most notably hooks. ICK!
Not only does a hook not hook all processes, it usually includes a ton of bloat.
I know people who write global hooks in VB and drag megabytes and megabytes of
dead fish into every process their hook touches.
A few caveats apply:
The code you copy into the target should not call any functions
besides those in kernel32.dll; only kernel32.dll is guaranteed to be present
(and at the same load address) in both the local and the target processes. If
you need more or other library routines, pass the addresses of LoadLibrary() and
GetProcAddress(), both of which are in kernel32.dll, to the injected code, and
let it go and get the rest itself.
Do not call subroutines. If you must, then copy each routine individually,
and supply a table to the new addresses of the copied routines in your data
area. Why? Because the linker is free to reorder functions; if you define
functions in the order first(), second(), ..., last(), after_last() and copy the
code between &first and &after_last, you may find that the linker has
moved second() elsewhere, and you are missing it. You can, however,
supply the linker with a text file listing the ordering of the functions; doing
that will allow you to copy a block of memory from first() to
after_last().
Tread lightly. Loading DLLs always may have unexpected side effects; try to
stick with Windows-supplied DLLs, and the fewer the better.
Don't bother the target process. Interference is not only impolite, it is
downright risky, as the target, in all likelihood, is unaware of your intrusion.
If you produce a debug build, remember to remove the /GZ switch from the
project options!( If you forget, the compiler generates calls to a routine that
checks the stack for munging -- calls to a routine that is not there.
remthread.dsw, 4 KB: workspace file,
not that you need it ...
remthread.dsp, 1 KB: project file.
remthread.cpp,
6 KB: the meat of this sample. The rest is salad.
stdafx.cpp, 1 KB; stdafx.h,
1 KB: these two generate the precompiled header.
remthread.zip,
61 KB: all of the above, plus a ready-to-run executable.
CreateRemoteThread
Update 12-Dec-00: Keith Brown drew my attention to some weird
behaviour. If incremental linking is on, and if a wstrstream is used to convert
a string to a numeric PID, then the remote thread will crash the target process,
and I have not the faintest idea why. (OK, so I have an idea, but it's all
speculation.) In consequence, I removed all references to the standard C++
library.
Update 21-Nov-99: Tomas Restrepo found a bug, and one of an
unbelievably horrible kind, too -- I used VirtualFree() instead of VirtualFreeEx(),
meaning that I not only leaked memory in the target process, but also freed
something I never allocated in the remthread process. The bug has been fixed,
and I owe Tomas a big thank-you.
This sample demonstrates how to get the command line another process was
started with. To this end, it performs the following steps:
opens the target process | |
allocates two chunks of memory in the target process' address space; one is executable, the other one for data | |
copies a function from the local address space to the first piece of memory in the target | |
initializes the allocated data area in the target | |
calls CreateRemoteThread() to get the copied code going | |
waits on the thread handle until the newly created thread is done | |
copies the (now filled-in) data area back into the local address space |
Not only does a hook not hook all processes, it usually includes a ton of bloat.
I know people who write global hooks in VB and drag megabytes and megabytes of
dead fish into every process their hook touches.
A few caveats apply:
The code you copy into the target should not call any functions
besides those in kernel32.dll; only kernel32.dll is guaranteed to be present
(and at the same load address) in both the local and the target processes. If
you need more or other library routines, pass the addresses of LoadLibrary() and
GetProcAddress(), both of which are in kernel32.dll, to the injected code, and
let it go and get the rest itself.
Do not call subroutines. If you must, then copy each routine individually,
and supply a table to the new addresses of the copied routines in your data
area. Why? Because the linker is free to reorder functions; if you define
functions in the order first(), second(), ..., last(), after_last() and copy the
code between &first and &after_last, you may find that the linker has
moved second() elsewhere, and you are missing it. You can, however,
supply the linker with a text file listing the ordering of the functions; doing
that will allow you to copy a block of memory from first() to
after_last().
Tread lightly. Loading DLLs always may have unexpected side effects; try to
stick with Windows-supplied DLLs, and the fewer the better.
Don't bother the target process. Interference is not only impolite, it is
downright risky, as the target, in all likelihood, is unaware of your intrusion.
If you produce a debug build, remember to remove the /GZ switch from the
project options!( If you forget, the compiler generates calls to a routine that
checks the stack for munging -- calls to a routine that is not there.
remthread.dsw, 4 KB: workspace file,
not that you need it ...
remthread.dsp, 1 KB: project file.
remthread.cpp,
6 KB: the meat of this sample. The rest is salad.
stdafx.cpp, 1 KB; stdafx.h,
1 KB: these two generate the precompiled header.
remthread.zip,
61 KB: all of the above, plus a ready-to-run executable.
相关文章推荐
- 利用CreateRemoteThread进行远程代码注入的技术在64位机上可能遇到的问题
- CreateRemoteThread 直接注入代码执行一文拾遗
- CreateRemoteThread 远程注入代码实现
- 使用CreateRemoteThread把代码远程注入指定exe执行
- CreateRemoteThread 直接注入代码执行
- 使用CreateRemoteThread把代码远程注入指定exe执行
- Delphi利用CreateRemoteThread远程注入 详细 (非dll注入,是代码注入)
- CreateRemoteThread_远程CALL调用代码实现原理。
- 轻松玩转CreateRemoteThread,让你的代码长出翅膀
- Dll注入:X86/X64 远程线程CreateRemoteThread 注入
- 轻松玩转CreateRemoteThread,让你的代码长出翅膀(转)
- Delphi利用CreateRemoteThread远程注入
- 利用CreateRemoteThread注入
- CreateRemoteThread的使用(转载)
- 轻松玩转CreateRemoteThread (转载
- 在Delphi中利用CreateRemoteThread远程注入例子
- 进程注入失败,CreateRemoteThread 失败,错误码5
- CreateRemoteThread注入DLL
- DLL注入之CreateRemoteThread
- 进程注入方法之 CreateRemoteThread