用类对象(可调用对象)创建线程的手法(学习)

本文探讨了C++中创建线程的多种方法,包括使用类对象、lambda表达式等,分析了线程对象的生命周期,拷贝构造及析构过程,并讨论了detach()函数的使用及其对主线程与子线程的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

其他创建线程的手法:
用类对象(可调用对象),就会执行operator这个函数。

这样的程序每次执行结果都不一样。
//线程中使用了主线程的局不变量,主线程执行结束后,i内存被回收。子线程还在使用i的引用,会出现不可知的情况。
一旦调用detach(),主线程的TA对象还在吗?
答:这个对象不在了,但是没有关系,因为这个对象是被复制到了子线程中去。
执行完主线程ta会被销毁,但是复制的对象依旧存在。
所以,只要子线程中没引用或者指针,那么就不会出什么问题。

class TA
{
public:
    void operator()()
    {
        cout<<"我的线程开始执行了"<<endl;
        cout<<"我的线程结束了"<<endl;
    }

};

int main()
{
   TA ta;
   thraed my_th(ta);//可调用对象
   my_th.join();
   
   cout<<"I LOve CHNIA"<<endl;
   return 0;

}


-------------------------------------------------


class TA
{
public:
    TA(int i):m_i(i){
        cout<<"TA构造函数执行"<<endl;
    }
    TA(const TA ta):m_i(ta.m_i)
    {
        cout<<"拷贝构造函数执行"<<endl;    
    }
    
    ~TA()
    {
        cout<<"TA析构函数执行"<<endl;
    }
    void operator()()
    {
        cout<<"m_i:"<<m_i<<endl;
        cout<<"m_i:"<<m_i<<endl;
        cout<<"m_i:"<<m_i<<endl;
        cout<<"m_i:"<<m_i<<endl;
    }
    int m_i;

};

int main()
{
   int i=6;
   TA ta(i);
   thraed my_th(ta);//可调用对象,拷贝了
   my_th.detach();
   
   cout<<"I LOve CHNIA"<<endl;
   return 0;

}


使用:lambda表达式创建线程

int main()
{
    auto mylambda = []
    {
    cout<<"我的线程开始执行了"<<endl;
    
    
    
    cout<<"我的线程结束了"<<endl;

    };
    thread myth(mylambda);
     myth.jion();
    cout<<"I LOve CHNIA"<<endl;
    return ;
}

 

### 关于内核远程线程注入的技术细节 #### Windows 平台下的内核远程线程注入 在 Windows 系统中,内核远程线程注入是一种高级技术,通常用于动态链接库 (DLL) 的加载或其他恶意行为。以下是其实现的关键技术和细节: 1. **API 函数的作用** - `VirtualAllocEx` 和 `CreateRemoteThread` 是 NT 内核模式下常用的 API 函数[^1]。这些函数允许分配目标进程的内存空间,并在其上下文中创建一个新的线程。 - 在更深层次上,`CreateRemoteThread` 调用了未公开的内核函数 `RtlCreateUserThread`,而后者实际上是基于 `NtCreateThreadEx` 或 `ZwCreateThreadEx` 实现的[^2]。 2. **具体实现流程** - 首先,使用 `OpenProcess` 打开目标进程句柄。 - 接着,利用 `VirtualAllocEx` 分配一段可写、可执行的目标进程地址空间。 - 将要执行的代码(通常是 DLL 加载路径)写入到上述分配的空间中,通过 `WriteProcessMemory` 完成数据传输。 - 使用 `CreateRemoteThread` 创建一个新线程,其入口点指向 `LoadLibrary`,参数则设置为目标 DLL 的路径字符串指针。 - 当线程运行时,它会在目标进程中调用 `LoadLibrary` 来加载指定的 DLL 文件。 3. **内核层面的具体机制** - 在内核级别,`CreateRemoteThread` 最终依赖于 `ZwCreateThreadEx` 来完成实际操作[^3]。这意味着任何对远程线程的操作都可以追溯至这一核心功能。 - 此外,为了绕过某些安全限制(如 Session 0 隔离),可能还需要额外处理权限提升或令牌伪造等问题。 4. **注意事项** - 上述方法仅适用于 Windows 操作系统环境中的用户模式程序交互;对于其他平台或者更高层次的安全防护措施,则需采用不同的策略和技术手段加以应对。 --- #### Linux 平台下的内核远程线程注入 Linux 下不存在像 Windows 中那样显式的远程线程注入接口,但由于其开源特性和灵活的设计理念,仍然可以通过一些间接途径达成类似效果: 1. **ptrace 工具的应用** - Ptrace 是一种强大的调试工具,能够监控甚至修改另一个正在运行的过程状态信息。借助 ptrace 可以向目标进程中注入自定义指令序列从而达到控制目的。 ```c long ret = ptrace(PTRACE_ATTACH, pid, NULL, NULL); // Attach to target process if(ret != 0){ perror("PTRACE_ATTACH failed"); exit(EXIT_FAILURE); } wait(NULL); // Wait until the process stops struct user_regs_struct regs; ptrace(PTRACE_GETREGS, pid, NULL, &regs); // Get current register values void *addr = mmap(0, sizeof(shellcode), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); // Allocate memory for shellcode memcpy(addr, shellcode, sizeof(shellcode)); // Copy shellcode into allocated space regs.rip = (unsigned long) addr; // Set instruction pointer to our code location ptrace(PTRACE_SETREGS, pid, NULL, &regs); // Apply changes back to registers ptrace(PTRACE_CONT, pid, NULL, NULL); // Resume execution of modified program flow ``` 2. **共享对象预加载技巧** - 利用 LD_PRELOAD 环境变量可以强制让某个特定应用程序优先加载我们自己编写的 so 库文件而不是标准库版本。这种方法虽然简单有效但也容易被检测发现所以并不推荐作为隐蔽攻击手法之一。 3. **模块化扩展支持** - 如果拥有超级管理员特权的话还可以考虑编写 kernel module 插件形式来进行更加深入级别的干预动作比如挂钩 syscalls 表项等等不过这已经超出了常规意义上的“线程注入”的范畴了属于完全改变操作系统行为特征的行为应该谨慎对待以免造成不可预料后果影响整个系统的稳定性可靠性等方面表现情况恶化加剧风险程度提高很多倍数以上不建议轻易尝试除非必要情况下才去实施此类方案设计思路规划布局安排部署落实到位才行哦! --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aFakeProgramer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值