Suspend: 挂起指定的线程

备注:不要永远挂起线程, 因为在Win32中,进程堆是线程安全的对象,并且由于在不访问堆的情况下很难在Win32中完成很多工作,因此在Win32中挂起线程极有可能使进程死锁。


那么,为什么首先还要有SuspendThread函数呢?

调试器在调试过程中使用它冻结进程中的所有线程。调试器还可以使用它冻结进程中除一个线程之外的所有线程,因此您一次只能专注于一个线程。由于调试器是一个独立的进程,因此不会在调试器中创建死锁。

Link: Why you should never suspend a thread

并且我们不应该用来Suspend­Thread同步两个线程,因为没有实际的同步保证。发生的是Suspend­Thread信号通知调度程序挂起线程并立即返回。如果调度程序正忙于执行其他操作,则它可能无法立即处理挂起请求,因此被挂起的线程将在借来的时间上运行,直到调度器处理挂起请求为止,此时它实际上已被挂起。

如果要确保线程确实被挂起,则需要执行同步操作,该操作取决于线程被挂起的事实。因为这是操作的先决条件,并且由于操作是同步的,所以这会强制处理该暂停请求,您知道在返回时肯定已经发生了暂停。

传统的做法是调用Get­Thread­Context,因为这需要内核从被挂起的线程的上下文中读取,这首先需要将上下文保存在该位置,而该前提是必须先将线程挂起。


一些代码:

#pragma pack(push, 1)
struct myByteCode
{
BYTE push;
DWORD pushValue;
BYTE call;
INT32 callOffset;
BYTE ret;
};
#pragma pack(pop) // allocate executable page for shellcode
struct myByteCode* mem = (struct myByteCode*) VirtualAlloc(0, sizeof(struct myByteCode), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!mem)
{
// error handling...
} // copy shellcode to page
mem->push = 0x68;
mem->pushValue = (DWORD) ThreadCallbackParameter;
mem->call = 0xE8;
mem->callOffset = ((INT_PTR)ThreadCallback) - ((INT_PTR)(&mem->ret));
mem->ret = 0xC3; DWORD ignored;
if (!VirtualProtect(mem, sizeof(struct myByteCode), PAGE_EXECUTE, &ignored))
{
// error handling...
} FlushInstructionCache(GetCurrentProcess(), mem, sizeof(struct myByteCode)); // redirect thread to shellcode
...

需要FlushInstructionCache()在执行分配的内存之前先对其进行调用。而且,您还应该READ/WRITE(用VirtualProtect)从内存中删除这些标志,以避免恶意代码劫持您的Shell代码来执行其他操作。

Link: Redirecting thread to another function

win32 - 将线程重定向到另一个函数(附带Suspend的解释)的更多相关文章

  1. 线程模型、pthread 系列函数 和 简单多线程服务器端程序

    一.线程有3种模型,分别是N:1用户线程模型,1:1核心线程模型和N:M混合线程模型,posix thread属于1:1模型. (一).N:1用户线程模型 “线程实现”建立在“进程控制”机制之上,由用 ...

  2. posix 线程(一):线程模型、pthread 系列函数 和 简单多线程服务器端程序

    posix 线程(一):线程模型.pthread 系列函数 和 简单多线程服务器端程序 一.线程有3种模型,分别是N:1用户线程模型,1:1核心线程模型和N:M混合线程模型,posix thread属 ...

  3. Android Handler机制 (一个Thead中可以建立多个Hander,通过msg.target保证MessageQueue中的每个msg交由发送message的handler进行处理 ,但是 每个线程中最多只有一个Looper,肯定也就一个MessageQuque)

    转载自http://blog.csdn.net/stonecao/article/details/6417364 在android中提供了一种异步回调机制Handler,使用它,我们可以在完成一个很长 ...

  4. Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量

    Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量 一丶线程的理论知识 什么是线程:    1.线程是一堆指令,是操作系统调度 ...

  5. jni不通过线程c回调java的函数 --总结

    1.JNIEnv类型是一个指向全部JNI方法的指针.该指针只在创建它的线程有效,不能跨线程传递 2.JavaVM是虚拟机在JNI中的表示,一个JVM中只有一个JavaVM对象,这个对象是线程共享的. ...

  6. STM32—重定向printf和getchar函数到串口

    在STM32测试串口的时候经常需要在开发板和上位机之间传输数据,我们可以用c语言中的printf()函数和getchar()函数来简化传输. 以printf()为例: printf()函数实际上是一个 ...

  7. ytu 1050:写一个函数,使给定的一个二维数组(3×3)转置,即行列互换(水题)

    1050: 写一个函数,使给定的一个二维数组(3×3)转置,即行列互换 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 154  Solved: 112[ ...

  8. 假如现在有一堆长度大于3小于9的电话号码,用座机呼叫,如果出现这样的号码【123和12345】那么12345将永远不会被拨出,因为拨到123的时候电话已经呼出了,试写一个函数输出所有不能被呼出的电话号码(java实现)

    解题: 假如现在有一堆长度大于3小于9的电话号码,用座机呼叫,如果出现这样的号码[123和12345]那么12345将永远不会被拨出,因为拨到123的时候电话已经呼出了,试写一个函数输出所有不能被呼出 ...

  9. Java-集合(没做出来)第四题 (List)写一个函数reverseList,该函数能够接受一个List,然后把该List 倒序排列。 例如: List list = new ArrayList(); list.add(“Hello”); list.add(“World”); list.add(“Learn”); //此时list 为Hello World Learn reverseL

    没做出来 第四题 (List)写一个函数reverseList,该函数能够接受一个List,然后把该List 倒序排列. 例如: List list = new ArrayList(); list.a ...

  10. 面试题-->写一个函数,返回一个数组中所有元素被第一个元素除的结果

    package com.rui.test; import java.util.Random; /** * @author poseidon * @version 1.0 * @date:2015年10 ...

随机推荐

  1. [转帖]linux将大目录等分切割成多个小目录

    https://www.jianshu.com/p/6f9e6743a1dc 需求:有一个目录存放了数十万个文件,现在需要将这个目录上传,如果整个目录上传,中间因为某些故障断开连接了,可能又要从头开始 ...

  2. [转帖]Prometheus监控系统存储容量优化攻略,让你的数据安心保存!

    云原生监控领域不可撼动,Prometheus 是不是就没缺点?显然不是. 一个软件如果什么问题都想解决,就会导致什么问题都解决不好.所以Prometheus 也存在不足,广受诟病的问题就是 单机存储不 ...

  3. 参照DefenseGrid在Unity中实现合理的塔防寻路机制

    前言 在一款TD游戏中,最重要的单位就两大类:防御塔(Tower)和敌人单位(Enemy).在处理敌人单位的AI行为时,最基本也是最重要的就是自动寻路.在各式TD游戏中,防御塔的攻击方式以及敌人单位的 ...

  4. 最小的 $x$ 满足 $L\le x\bmod P\le R$

    设 \(G(L, R, D, P)\) 为 \(y P+L \leq x D \leq y P+R\) ,满足 \(1 \leq L \leq R<P, D<P\) ,其中 \(x\) 的 ...

  5. 重新学习一下new Date()

    new Date()你知道多少 很多小伙伴可能都知道, Date是js中的一个内置对象,用于处理日期和时间. 当你调用 new Date() 时,它会创建一个新的日期(Date) 对象. 表示当前本地 ...

  6. 如何给所有的 await async 函数添加try/catch?

    如何给所有的 await async 函数添加try/catch?做全局捕获异常. 面试官:如何给所有的 await async 函数添加try/catch?做全局捕获异常. 我们可以使用 windo ...

  7. 微信小程序-页面生命周期

    官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/page-life-cycle.html

  8. 声明式API和命令式API的区别

    声明式API 声明式和命令式的对比 Kubernetes 声明式 API 的工作原理 参考 声明式API 声明式和命令式的对比 命令式 命令式有时也称为指令式,命令式的场景下,计算机只会机械的完成指定 ...

  9. 重写JSON.stringify与JSON.parse使其支持解析function类型

    const JSONStringify = (option) => { return JSON.stringify(option, (key, val) => { // 处理函数丢失问题 ...

  10. 编译Assimp时出现“warning C4819”的解决方案

      最近又重新捣鼓起了OpenGL, 使用Assimp库加载3D模型,最新(2023/12/9)的版本是5.3.1. 使用cmake编译本是一件简单的事情: cmake . cmake --build ...