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 内核的 4 大 IO 调度算法

    https://cloud.tencent.com/developer/article/1615744 Linux 内核包含4个IO调度器,分别是 Noop IO scheduler.Anticipa ...

  2. [转帖]decimal and numeric (Transact-SQL)

    https://learn.microsoft.com/en-us/sql/t-sql/data-types/decimal-and-numeric-transact-sql?view=sql-ser ...

  3. [转帖]Steam内存测试工具【转】

      转自:https://www.cnblogs.com/iouwenbo/p/14377478.html Stream测试是内存测试中业界公认的内存带宽性能测试基准工具. Stream安装 官方源码 ...

  4. 金蝶Cosmic虚拟机简单使用与总结

    背景 知己知彼 简单学习下友商发出来的测试软件 看看有否对自己现在的工作有所指导 也看看对方的部署方式有啥优缺点 当然了仅是测试, 不是生产软件可能有失真. 注意 我没有测试序列号, 登录系统耗时很久 ...

  5. vue 路由守卫是否携带token

    //整个实例出来 配置路由守卫 const router = new Router({ //这里面是路由配置哈 }) router.beforeEach((to, from, next) => ...

  6. es6默认传参 es5的默认传参

    在默认传参在实际中座中还是用的比较多的. 它可以用来解决,用户没有给定值的时候,默认给一个指定的值. es6默认传参 es5的默认传参 //es6 function say(a = 4) { cons ...

  7. 使用 NuGet.Server 创建和部署 ASP.NET Web 应用程序搭建私有Nuget服务器

    使用 NuGet.Server 创建和部署 ASP.NET Web 应用程序搭建私有Nuget服务器 在Visual Studio中,选择"新建>文件>"Project ...

  8. python代码的tab和空格缩进互转

    代码规范 在我们项目中python代码使用tab缩进,并统一大家的编辑器设置. 如果同一个python文件中即有空格又有tab缩进,那么运行此文件会报错. 关于使用空格还是tab,这里就不展开讨论了, ...

  9. 通过URL载入ShellCode代码

    将生成的shellcode放到web服务器上,本地不保存恶意代码,本地只负责加载到内存运行,这样可以很好的躲过查杀. 生成shellcode msfvenom -a x86 --platform Wi ...

  10. C/C++ Qt 使用JSON解析库 [修改篇]

    JSON是一种轻量级的数据交换格式,它是基于ECMAScript的一个子集,使用完全独立于编程语言的文本格式来存储和表示数据,简洁清晰的的层次结构使得JSON成为理想的数据交换语言,Qt库为JSON的 ...