能力值:
( LV2,RANK:10 )
|
-
-
2 楼
通过“目标窗口”获得“目标窗口”的hWnd->通过hWnd获得“目标进程”的ID(ProcessID)->根据ProcessID打开“目标进程”获得进程句柄hProcess->利用hProcess在“目标进程”new出一块或多块空间(使用函数VirtualAllocEx)用于填放自己的代码和传入参数,假设预先new出的代码空间地址为pCodeRemote,参数空间地址为pParamRemote->把自己的参数和代码copy到上述new出的空间(使用WriteProcessMemory)->OK创建线程就可以了(使用CreateRemoteThread)。
思路有了,但是还是有很多要注意的地方的,注意点很容易造成致命错误而直接导致“目标进程”挂掉。
首先是你如何知道在“目标进程”该为自己的pCodeRemote分配多大的空间?
//------------------------------------------------------test
假设我是这样写的这个结构:
#include <windows.h>
//
Void WINAPI RemoteFunc(PVOID pParam)
{
…….
}
Void Injector()
{
…….
}
Void main()
{
Injector();
}
//----------------------------------------------------------
我就犯了这个错误:pCodeRemote =Injector-RemoteFunc;这样是不对的
如上图:貌似编译后函数线性地址的前后顺序都变了,所以肯定不行了。。。
(估计熟悉线性地址的老牛们不会看这篇文章了。。。所以,关于线性地址:就是反汇编时工具上写的那个地址,由于当前WIN32早已经不使用CS+EIP做线性地址了(所以EIP就是线性地址了,不用额外计算),当然CS另有它用,用做 “段描述符selector”,好像所有的”段寄存器”都用来做selector了,但我发现各个”段寄存器”的值在运行时是不同的,所以猜测是指向不同index的”段描述符”了,这些都无所谓OS的事情。。。)
既然那样不行咋办? 。。。自己看着办吧。。。调试时去数数到底占多大空间应该不错。。哈
当前问题解决了,还有问题。。。你注意一下你的RemoteFunc里面都在干什么,看有没有调用API呀,只要你调用基本绝对会引起目标进程挂掉。。。奇怪了?
有人想了,很多API来自于系统的DLL文件,难道是线性地址在不同进程中不同?对于这一点,到底所有的系统DLL加载到不同进程的线性地址是否不同,俺也不知道(望大牛指点),当然它的线性地址在同一个程序的空间中式绝对不能变的了,要变了的话,你的EXE调用这个”系统DLL”中包含的API可就挂了啊,不过这里并不是几句简单的话能解决的,即使是变化的一样也有办法定位的。看下面吧:
调用个Sleep(…);做个试验
看下Sleep的VC反汇编代码,call [0042a268H]。。。汗,原来0042a268H位置的内容才是Sleep的真正地址 ,转到地址0x7C802446发现原来这才是Sleep函数。。。恩,原来0x0042a268只是一个函数指针,0x0042a268是存放Sleep的地址的内存块的地址,所以问题出现了,我们不能确定”目标进程”的0x0042a268位置存放的就是Sleep的地址0x7C802446,甚至这块内存根本就是无效的。。。调试”目标进程”, 发现这块内存的确是无效的,当然会出错了。。。
下面再看下目标进程中Sleep在什么位置(当然为了调试方便,”目标进程”也是俺自己写的一个小程序,所以直接在代码里加个Sleep就可以查看了) 恩,同样是这样的形式call [41F30CH],找到地址0x0041F30C,发现 ,函数地址依然是0x7c802446,OK,问题解决了,因此你要是需要在嵌入上述”目标进程”中的函数RemoteFunc中调用Sleep函数有2种方式:
1.
2710H是给Sleep传入的那一个参数,这里要注意的是push 2710H后你不需要在call Sleep后恢复栈,因为几乎所有的API调用方式都是__stdcall,栈由被调用者恢复。
2. // int 3
push eax
mov eax, 7c802446H
push 2710H
call eax
pop eax
关于上述代码可以直接嵌入你的RemoteFunc,一般情况下是完全可以执行的。
最后关注一下 ,有没发现call dword ptr [__imp__Sleep@4 (41F30CH)]前面的__imp__Sleep@4,看这个意思正好吻合imp。。是指image map吧。。。,所以估计这正是win的机制。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
楼上的大哥,我是想要挂起注入后的程序本身的线程,而不是为自己创建自己本身的线程,也就是听说有一个可以玫举线程的结构体,来得到线程的句柄,不知怎么使用,希望有此类代码出现
|
能力值:
(RANK:170 )
|
-
-
4 楼
发个挂起目标进程所有线程的代码,是否挂起成功没判断
BOOL SuspendProcThread (DWORD dwTargetPid)
{
HANDLE hThreadSnap = NULL;
BOOL bRet = FALSE;
THREADENTRY32 te32 = {0};
DWORD dwOwnerPID = GetCurrentProcessId();
HANDLE hThread = NULL;
if (dwTargetPid == dwOwnerPID)
{
return (FALSE);
}
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hThreadSnap == INVALID_HANDLE_VALUE)
{
return (FALSE);
}
te32.dwSize = sizeof(THREADENTRY32);
// 遍历所有该PID的线程
if (Thread32First(hThreadSnap, &te32))
{
do
{
if (hThread)
{
CloseHandle(hThread);
hThread = NULL;
}
if (te32.th32OwnerProcessID == dwTargetPid)
{
hThread = OpenThread(THREAD_ALL_ACCESS,FALSE,te32.th32ThreadID);
if (!hThread) continue;
SuspendThread(hThread);
}
}
while (Thread32Next(hThreadSnap, &te32));
bRet = TRUE;
}
else
{
bRet = FALSE;
}
// 清理
CloseHandle (hThreadSnap);
return (bRet);
}
|
|
|