• 同步对象和远程注入实现


    1. 内核同步对象(信号和互斥体)

    1.1 信号

     控制多线程等待数量问题

    HANDLE CreateSemaphore(

      LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,   安全控制,一般直接传入NULL。

      LONG lInitialCount,  初始资源数量

      LONG lMaximumCount, 最大并发数量

      LPCTSTR lpName 信号量的名称,传入NULL表示匿名信号量

    );

    作用跨进程使用信号灯

    HANDLE OpenSemaphore(

      DWORD dwDesiredAccess, 访问权限,对一般传入SEMAPHORE_ALL_ACCESS

      BOOL bInheritHandle, 句柄继承性,一般传入TRUE即可。

      LPCTSTR lpName 名称,不同进程中的各线程可以通过名称来确保它们访问同一个信号量。

    );

    增加线程并发数量

    BOOL ReleaseSemaphore(

      HANDLE hSemaphore, 信号量的句柄。

      LONG lReleaseCount,  增加个数,必须大于0且不超过最大资源数量。

      LPLONG lpPreviousCount 可以用来传出先前的资源计数,设为NULL表示不需要传出

    );

          信号量:

     WaitForSingleObject -- 等待成功,个数减一,

    //等待可用的信号, 如果成功,则可用信号的个数减一

    WaitForSingleObject(g_hSemphore, INFINITE);

     信号量的个数为0,信号量处于no-signale状态

     ReleaseSem释放信号 个数加一

        //释放可用信号

        ReleaseSemaphore(g_hSemphore, 1, NULL);

    多用于处理多个线程共享多于一个资源的情况,常见于池技术

    1.2 互斥体

    互斥体实现了“互相排斥”(mutual exclusion)同步的简单形式(所以名为互斥体(mutex))。互斥体禁止多个线程同时进入受保护的代码“临界区critical section)。

    HANDLE CreateMutex(

    LPSECURITY_ATTRIBUTESlpMutexAttributes, // 指向安全属性的指针

    BOOLbInitialOwner, // 初始化互斥对象的所有者

    LPCTSTRlpName // 指向互斥对象名的指针

    );

          多个线程使用互斥体,只有一个线程拥有互斥体的权限,即只有一个线程能够执行

          WaitForSingleObject(hMutex, INFINITE);  -- 获取互斥体的使用权,并修改互斥体的状态为no-signal

           ReleaseMutex(hMutex);  --释放互斥体的使用权

      1.3

         三环(用户模式):原子操作, 关键段

         内核同步对象:事件, 信号, 互斥体

         三环的同步手段,效率明显高于内核同步对象

    2. 远程线程注入

    通过调用进程api函数传递参数到达调用函数实现自己的目的

       注入 -- 别的进程执行自己的代码

       如果让别的进程执行自己的dll代码?

    获取进程句柄

    HANDLE  hProcess = GetProcessByName("Calc.exe");

    Calc.exe  进程名

    1) 获取LoadLiabrary的地址

    HMODULE hModKer32 = GetModuleHandle("kernel32");

     LPVOID pLoadLibrary = GetProcAddress(hModKer32, "LoadLibraryA");  

    LPTHREAD_START_ROUTINE addr = (LPTHREAD_START_ROUTINE)GetProcAddress(modHandle, "LoadLibraryA");

    LoadLibraryA        调用函数

    2) 在目标进程申请内存,写入dll的路径

    目标进程中申请一块内存

    LPVOID pDllPathOfDstProc =

        VirtualAllocEx(

          hProces,

          NULL, //系统自动分配地址

          0x1000, //申请内存大小

          MEM_COMMIT, //物理映射

          PAGE_READWRITE //可读可写

          );

     char szBuff[] = { "Dll.dll" };

      DWORD dwBytestToWrite = 0;

      BOOL bRet = WriteProcessMemory(

        hProces,

        pDllPathOfDstProc,   申请内存地址

        szBuff, 写入的地址

        sizeof(szBuff), 大小

    &dwBytestToWrite);

    Dll.dll  自己要注入dll的全路径

    3) 创建远程线程

     m_hRemoteThread = CreateRemoteThread(

        hProces,

        NULL,

        0,

        (LPTHREAD_START_ROUTINE)pLoadLibrary, //在目标进程中的回调函数的地址 远程调用这个函数

        pDllPathOfDstProc, 将参数传进LoadLibrary函数

        0,

        NULL);

       

      卸载:

    1) 获取模块句柄

     HANDLE hRemoteDll = NULL;

      GetExitCodeThread(m_hRemoteThread, (DWORD*)&hRemoteDll);

    2) 获取freelibrary的地址

      HMODULE hModKer32 = GetModuleHandle("kernel32");

      LPVOID pfnFreeLibrary = GetProcAddress(hModKer32, "FreeLibrary");

    3) 创建远程线程

     

      UINT dwProcId = GetDlgItemInt(EDT_PROCID);

      HANDLE hProces = OpenProcess(

        PROCESS_ALL_ACCESS,

        FALSE,

    dwProcId);

      m_hRemoteThread = CreateRemoteThread(

        hProces,

        NULL,

        0,

        (LPTHREAD_START_ROUTINE)pfnFreeLibrary, //在目标进程中的回调函数的地址

        hRemoteDll,

        0,

        NULL);

    对象

    数据类型

    描述

    Event(事件)

    KEVENT

    阻塞一个线程直到其它线程检测到某事件发生

    Semaphore(信号灯)

    KSEMAPHORE

    与事件对象相似,但可以满足任意数量的等待

    Mutex(互斥)

    KMUTEX

    执行到关键代码段时,禁止其它线程执行该代码段

    Timer(定时器)

    KTIMER

    推迟线程执行一段时期

    Thread(线程)

    KTHREAD

    阻塞一个线程直到另一个线程结束

    学如逆水行舟,不进则退。 博客园技术交流群 群 号:1073255314 (本群没人,刚刚建立 -_-!!! )
  • 相关阅读:
    [IMX6]Android6.0移植和分析
    Android设计原则和设计模式
    Linux内核源码目录
    Android源码博客目录
    Android应用博客目录
    imx6的kernel3.4.15启动流程
    dd命令
    shell
    i.mx6 Android5.1.1 build解析
    git总结
  • 原文地址:https://www.cnblogs.com/Mj-NaijAm/p/13615453.html
Copyright © 2020-2023  润新知