zoukankan      html  css  js  c++  java
  • 常见注入手法第二讲,APC注入

                      常见注入手法第二讲,APC注入

    转载注明出处

    首先,我们要了解下什么是APC

    APC 是一个简称,具体名字叫做异步过程调用,我们看下MSDN中的解释,异步过程调用,属于是同步对象中的函数,所以去同步对象中查看.

    首先介绍一下APC,会了正想开发就会逆向注入

    首先第一个函数

    QueueUserApc: 函数作用,添加制定的异步函数调用(回调函数)到执行的线程的APC队列中

    APCproc:   函数作用: 回调函数的写法.

    我们首先要知道异步函数调用的原理,

    异步过程调用是一种能在特定线程环境中异步执行的系统机制。

    往线程APC队列添加APC,系统会产生一个软中断。在线程下一次被调度的时候,就会执行APC函数,APC有两种形式,由系统产生的APC称为内核模式APC,由应用程序产生的APC被称为用户模式APC

    这里介绍一下应用程序的APC

    APC是往线程中插入一个回调函数,但是用的APC调用这个回调函数是有条件的.我们看下Msdn怎么写

    MSDN说,要使用SleepEx,signalObjectAndWait.....等等这些函数才会触发

    那么使用APC场合的注入就有了,

    1.必须是多线程环境下

    2.注入的程序必须会调用上面的那些同步对象.

    那么我们可以注入APC,注意下条件,也不是所有都能注入的.

    注入方法的原理:

    1.当对面程序执行到某一个上面的等待函数的时候,系统会产生一个中断

    2.当线程唤醒的时候,这个线程会优先去Apc队列中调用回调函数

    3.我们利用QueueUserApc,往这个队列中插入一个回调

    4.插入回调的时候,把插入的回调地址改为LoadLibrary,插入的参数我们使用VirtualAllocEx申请内存,并且写入进去

    使用方法:

    1.利用快照枚举所有的线程

    2.写入远程内存,写入的是Dll的路径

    3.插入我们的DLL即可

    ①丶首先先写一个测试程序.

    编写一个MFC程序,这个程序的作用就是调用上面的SleepEx.

    这个程序啥也不干,就是调用等待,注意第二个参数给TRUE,第二个参数决定了你的APC是否调用

    ②.编写一个简单的DLL用作注入使用

    直接生成一个简单的带有DllMain的入口的DLL即可.

    在DLL附加的时候,调用一个MessageBox

    ③丶编写注入程序

     我们要注入的是MFC,也就是写的测试程序,那么现在我们直接打开进程,打开线程,然后插入APC即可

     

    在按钮下面写入我们的代码.

     //1.查找窗口
      HWND hWnd = ::FindWindow(NULL, TEXT("APCTest"));
      if (NULL == hWnd)
      {
        return;
      }
      /*2.获得进程的PID,当然通用的则是你把进程PID当做要注入的程序,这样不局限
      于窗口了.这里简单编写,进程PID可以快照遍历获取
      */
      DWORD dwPid = 0;
      DWORD dwTid = 0;
      dwTid = GetWindowThreadProcessId(hWnd, &dwPid);
    
      //3.打开进程
      HANDLE hProcess = NULL;
      hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
      if (NULL == hProcess)
      {
        return;
      }
      //4.成功了,申请远程内存
      void *lpAddr = NULL;
      lpAddr = VirtualAllocEx(hProcess, 0, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
      if (NULL == lpAddr)
      {
        return;
      }
      //5.写入我们的DLL路径,这里我写入当前根目录下的路径
      char szBuf[] = "MyDll.dll";
      BOOL bRet = WriteProcessMemory(hProcess, lpAddr, szBuf, strlen(szBuf) + 1, NULL);
      if (!bRet)
      {
        return;
      }
      //6.根据线程Tid,打开线程句柄
      HANDLE hThread = NULL;
      hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, dwTid);
      if (NULL == hThread)
      {
        return;
      }
      //7.给APC队列中插入回调函数
      QueueUserAPC((PAPCFUNC)LoadLibraryA, hThread, (ULONG_PTR)lpAddr);
    
      CloseHandle(hThread);
      CloseHandle(hProcess);

    代码很简单,就这几行,其实可以遍历进程快照,获取线程的TID,然后判断快照中的进程PID是否和注入程序的PID相等,相等的话就可以注入了.

    这里我写死了,按理说根据PID就和TID就可以注入,这里我偷懒,根据窗口找进程的TID和PID

    看下程序结果

    注意,我偷懒了,这几个程序要放在一起,主要是DLL,要和被注入的程序放在一起

     

    ,打开注入程序和被注入程序,被注入程序要点击按钮,让其执行SleepEX

    DLL功能被执行了,我们用PCHunter看下被注入程序是否多了一个DLL

    原创不易,如果你认为写的还好,请推荐加评论,好人一生平安,如果不太懂,可以评论,看到会回复.

    课堂资料:

    链接:http://pan.baidu.com/s/1bo1M6BH 密码:tcu8

    博客园IBinary原创  博客连接:http://www.cnblogs.com/iBinary/

    转载请注明出处,谢谢

  • 相关阅读:
    1_Selenium环境搭建
    python functools
    python 参数注解inspect
    python 堆排序
    python functools
    python 装饰器
    python 柯里化
    python 高阶函数
    python 树
    python 函数销毁
  • 原文地址:https://www.cnblogs.com/iBinary/p/7574055.html
Copyright © 2011-2022 走看看