win7 64bit下远程线程注入技术(进程劫持入门技术)

http://blog.csdn.net/arvon2012/article/details/7766439

本文是配合上文学习和使用的。上文中,最后,我们生成了可以hook api的dll,那么怎么把它发射到其他进程中,让其他进程调用运行我们的dll呢?

远程线程注入技术可以解决这个问题。

原理:

远程线程注入是这样的,首先在当前运行的进程中找到目标进程,然后将我们的dll的内容写入目标进程的私有空间中,最后通过关键的API:CreateRemoteThread创建线程。该线程只执行一个任务:loadlibrary加载我们的dll。

下面通过实例解释,例子中注入的进程是“explorer.exe”(个人认为玩弄这个进程异常的舒爽~~吼吼吼吼~~~~)

具体实现:
1.找到目标
原理简单,我们首先获得目前时刻正在运行的进程的列表,然后通过遍历搜索,找到列表中我们想要的进程,然后记录下进程的ID号。
hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
这个函数用来获得当前进程的快照。(啪!说人话!)哦,就是获得当前进程的列表啊。

然后通过下面的代码按顺序遍历这个列表,通过字符串对比,找到我们的目标:explorer.exe。上代码!

[cpp] view plaincopy

//获取目标进程的ID  
 if(Process32First(hProcessSnap,&pe32))   //获取第一个进程   
 {   
  do{   
   char te[MAX_PATH];   
   strcpy(te,pe32.szExeFile);   
   if(strcmp(te, INJECT_PROCESS_NAME) == 0)  
   {   
    dwRemoteProcessId=pe32.th32ProcessID;   
    printf("%d\n",dwRemoteProcessId);  
    break;   
   }       
  }       
  while(Process32Next(hProcessSnap,&pe32));//获取下一个进程   
 }   
 else   
 {   
  return   -1;   
 }   

找到目标进程后,用dwRemoteProcessId记录下进程ID。还是一样,大家不用深究看不懂的变量(毕竟变量搞懂也没大意思),先看清原理,完整的代码会在最后给出下载地址。
上面这个代码段中关键函数分别是Process32First,Process32Next两个可以沿着列表搜索的函数还有一个字符串对比函数strcmp核对当前搜索的进程对象的名称是不是explorer.exe。

2.打开进程,把我们的dll写进去!
(1)打开
在上一步获得目标进程的id后我们就可以打开进程,然后对进程进行操作。打开进程如下:
hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwProcessId);
参数中的第一个是表明我们在打开进程的时候想要获得的权限,第三个是目标进程的ID。成功打开后,我们用hProcess存放打开的句柄。句柄嘛,大家都懂的,windows里都是用句柄访问和操作对象的嘛~~

(2)写入
既然要往目标进程的私有空间写入数据,我们就要先在目标进程中申请和我们的dll一样大,或者更大的空间。申请如下:
pszLibRemoteFile = VirtualAllocEx(hProcess,NULL,cb,MEM_COMMIT,PAGE_READWRITE);
参数中的cb是我们想要申请的尺寸,最后一个参数是读写权限。
我们怎么获得cb呢?look:
[cpp] view plaincopy

int   cch   =   1   +   lstrlenW(lpwLibFile); //这里的lpwLibFile其实就是我们的dll  
int   cb   =   cch   *   sizeof(WCHAR);   

上面第一步得到的是我们dll的文件尺寸,单位是“个”,代表我们的文件有cch个字符。
第二步得到真正的字节大小,我们把字符数乘以每一个宽字符所占的字节空间即可。这里为什么是宽字符?是windows文件都是宽字符形式吗?还是。。。不也不懂,大家一起查查,知道了别忘告诉我下,先谢过各位亲~~~

空间申请好了,空间的首地址用pszLibRemoteFile存着,然后就可以写数据了:
WriteProcessMemory(hProcess, pszLibRemoteFile,(PVOID)lpwLibFile, cb, &dwWritten);
这个没啥好解释的,就是一个写内存的API。

至此在目标进程中已经有了我们dll邪恶的身影,最后当然是逼着目标进程加载我们的dll(不加载就是垃圾数据占空间来的,难道占空间也是一种攻击方式???额。。。)

3.加载
windows允许我们做什么,我们就以什么为突破口。
windows提供给我们一个API叫做CreateRemoteThread。。。。说实话,微软为什么要给程序员这中完全不安全的API,我不能猜到内幕。只能坏笑着说“微软~~~你真坏”
不过这里要说下,win7没那么好欺负,直接调用CreateRemoteThread好像不行,我没有认真研究具体是哪里被拒绝了,不过网上找到资料,这个函数最终会调用NtCreateThreadEx。
呵呵,各位菜鸟朋友们,当大家看到nt开头的函数应该很兴奋吧,对windows来说,对几乎所有的API调用最后都会调用对应nt开头的API,这些是底层的函数,既然win7不让我们创建线程,那我们自己强行调用这个nt函数。
这里真的有点像hook api里的操作:
找到NtCreateThreadEx所在dll,然后从这个dll中获得NtCreateThreadEx的位置,然后定义一个返回值和参数表和NtCreateThreadEx一样的函数的指针存放NtCreateThreadEx的地址,直接调用指针指向的位置里存放的代码(废话一堆。。其实就是用地址调用了NtCreateThreadEx)。
程序如下:
[cpp] view plaincopy

pFunc = GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtCreateThreadEx");    
  //下面就是用地址执行了NtCreateThreadEx  
  ((PFNTCREATETHREADEX)pFunc)(  
   &hThread,   
   0x1FFFFF,    
   NULL,    
   hProcess,    
   pThreadProc,    
   pRemoteBuf,    
   FALSE,    
   NULL,    
   NULL,    
   NULL,    
   NULL);    

OK,目前线程能创建了,那么别忘了我们付给这个线程的艰巨使命:出卖它所属的进程,调用我们的dll库(这是拟人的修辞手法啊有木有!)
回头看下这个创建线程的函数,里面有个参数叫做pThreadProc,呵呵,能猜到吧,这里放的就是线程起来后负责运行的程序。我们果断把这个值附成LoadLibrary,然后在哪里传入LoadLibrary的参数呢?pRemoteBuf!新的线程会从这里读取它要执行的函数的参数。我们前面在写入dll数据的时候不是记录了一个地址吗?那个地址变量不也是Buff吗?把那个变量放到这个参数的位置就OK了。
我的程序里这样创建线程:
MyCreateRemoteThread(hProcess, pfnThreadRnt,pszLibRemoteFile);
第二个参数在前面有个处理:
pfnThreadRnt = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L”Kernel32”), “LoadLibraryW”);
懂了吧?嘿嘿。。
第三个参数是存了我们dll的buff头指针。
当这个函数顺利执行完的时候,我们dll的工作也顺利完成了。

提醒下广大和我一样的菜鸟朋友,如果要把你的dll注入64位系统的explorer.exe,别忘了把dll编程成x64的,然后这个注入程序也编译生成x64的可执行文件哦,否则会发现注入了木有任何反应哦~亲~得意

本文的源码在http://download.csdn.net/detail/arvon2012/4441040

你可能感兴趣的:(win7 64bit下远程线程注入技术(进程劫持入门技术))