同步对象和远程注入实现

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 (本群没人,刚刚建立 -_-!!! )
原文地址:https://www.cnblogs.com/Mj-NaijAm/p/13615453.html