DLL注入 之线程劫持

  大家好,我是FISH ,以下代码只是属于思路,都是我自己KEY进去的,有错误很抱歉,我尽量注意,

 内容来自Greg hoglund 的<<exploiting online games>> .

    给应用程序注入新的代码,最常用的技巧是DLL注入,使用这个方法,可以让远线程加载到你自己

设计的DLL. DLL本身的功能可以是挂钩函数,修改目标程序的内存空间,DLL注入是很隐藏,很方便的

注入手段,(实际上,该方法很容易被发现,有不少常规方法可以发现注入的DLL).
 
   DLL注入的技巧是让目标进程中已存在的一个线程跳到某个代码片段,该代码片段调用

Loadlibiary 来加载模块,这样的思路有很多种实现方法. 比如:使用CreateRemoteThread创建

新的远程线程,这里介绍的技巧没有创建新线程,而是劫持现有的线程进行加载操作.

   首先,需要将加载的DLL代码写到远程进程.定义代码如下:

 char InjectedcodePage[4096]=
 { 0xb8 ,00,00,00,00
 //mov EAX,0h | Pointer to LoadlibraryA() (DWORD)
 0xBB,00,00,00,00
 //mov EBX,0h | DLLname to inject(DWORD)
 0x53,   //push EBX
 0xff, 0xD0, //call EAX
 0x5b,  //pop ebx
 0xcc    /int 3h
 //dll name string will be placed here
 };
 int length_of_injection_code=15;

  上述代码有一些占位字节用来填充LoadlibraryA()和需要加载的DLL名指针地址.

对于LoadLibraryA的地址,代码简单的假设被注入远程的LoadLibraryA地址和现在的进程地址相同

作者没有遇到过不同的情况,所以假设这样做是安全的.[评: 实际上,目前对不少游戏这样操作不

能得到正确的地址,原因是KERNEL32.dll]位置被移动了.]

 farproc loadlibproc=getprocaddress(
 getmodulehandle("kernel32.dll"),
 LoadLibraryA};

  对于dll名称,可以将DLL名直接写在上述的代码段之后,即代码中偏移为15的地方.下面要计算所有

要用到的偏移.

 char *Dllname;
 Dword *EAX, *EBX;
 
 DLLname=((char*)((dword)injectedcodepage
 +length_of_inject_code);
 Eax=(dowrd)(injectedcodepage+1);
 ebx=(dword)(injectedcodepage+6);

这样就得到了两处占位字节序列的地址和将要填写的dll名地址. 需要将代码写到远端进程才能

填写这几个地址,因为代码将要在远端执行,而不是本地.

 内嵌在代码段中的INT3指令用于和调试器交互,内嵌断点通知调试器,注入代码执行完毕

现在不管这些,先了解一下如何查找dll代码位置.

  下面的代码,假设已经打开调试器并发送初始调试信号,如果该操作为附加操作,将会为初始

断点事件创建线程.代码将劫持该线程并利用该线程运行注入的代码片段,在调试时间循环中,使用

如下代码获取线程句柄.

 Hthread=fopenthread(
 thread_all_access,
 false,
 dbg_ent.dwthreadtd);

记得使用句柄后关闭句柄

 dll名称为dll文件的全路径, hprocess为被调试的团段进程,hmodulebase可以从调试事件循环中

获取,或者可以假定为0x400000 为基地址,(绝大多数情况都是这样).从调试时间循环获取的方法为:

 if (dbg_evt.dwdebugEventcode==create_process_debug_event)
 {
  Hmodulebase=dng_evt.u.createprocessinfo.lpbaseofimage;
 }
 
 注入的下一不走为定位远程进程的有效的可执行代码段. 这需要解析pe文件头,查找DOS头:

 res=readprocessmemory(
 hprocess,
 hmodulebase,
 &dosdhr,
 sizeof(doshdr),
 &read);
 if ((!res)||(read!=sizeof(doshdr)))
 {
 printf("could not get dos header/n");
 return false;
 }
 
 现在通过mz字符串检查文件是否为DOS头.

 if (doshdr.e_magic(!=image_dos_signature)
 {
 printf("could not find mz for dos header/n")'
 return false;
 }

 通过dos头信息查找nt头信息
 
 //get nt header
 res=readprocessmemory(
 hprocess,
 (void*)((dword)hmodulebase+
 &NThdr,
 sizeof(nthdr),
 &read);
 if (!res)||(READ!=sizeof(nyhdr)))
 printf("could not get nt header/n")'

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值