进程和线程/线程上下文 简单介绍

进程和线程/线程上下文 简单介绍

  • 引言
  • 进程
  • 线程
  • 线程上下文
    • CONTEXT 结构

引言

进程是资源分配的最小单位,线程是CPU调度的最小单位。
上面这句话是抄的,是的,我粘贴来的,因为说的确实是对的,虽然很笼统。
搞过高并发的都用过线程,因为在JAVA中基本没有人使用多进程的方式,Python倒是有一部分人用多进程。

之前写过相关的文章,小白可以先入个门。
函数调用过程小白文了解一下
VEH HOOK。

进程

进程是系统分配资源的单位,一个进程并不能让程序真正的“跑”起来,当你运行一个程序的时候,启动了一个进程,随之附带的还有这个进程的主线程,进程中包含虚拟内存空间,堆信息(包含在PEB中)等等。

如果启动这个进程后,我们将主线程暂停,那么这个进程就完全没有任何用处,它并没有在工作。

线程

线程是CPU调度的最小单位,什么意思呢?当这个进程中有线程的情况下,CPU才会分配时间片,这个程序才真正的开始工作。
函数调用过程小白文了解一下
在CPU分配的时间片内,线程才真正处于工作状态,一个进程可以有很多个线程,那么这些线程是如何切换的,我们需要了解线程上下文,那么线程上下文是什么呢?

线程上下文

我最早看见线程上下文有关的东西是在《Windows核心编程》中,这本书很不错,推荐看。
GetThreadContext 可以用于获取线程上下文,如果你设置了VEH异常捕获,在回调函数中上下文会包含在异常中。可以看看这VEH HOOK。

CONTEXT 结构

typedef struct _CONTEXT {

    //
    // The flag values within this flag control the contents of
    // a CONTEXT record.
    //
    // If the context record is used as an input parameter, then
    // for each portion of the context record controlled by a flag
    // whose value is set, it is assumed that that portion of the
    // context record contains valid context. If the context record
    // is being used to modify a thread's context, only that
    // portion of the thread's context will be modified.
    //
    // If the context record is used as an IN OUT parameter to capture
    // the context of a thread, only those portions of the thread's
    // context corresponding to set flags will be returned.
    //
    // The context record is never used as an OUT only parameter.
    //

    DWORD ContextFlags;

    //
    // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
    // set in ContextFlags. Note that CONTEXT_DEBUG_REGISTERS is NOT
    // included in CONTEXT_FULL.
    //

    DWORD   Dr0;
    DWORD   Dr1;
    DWORD   Dr2;
    DWORD   Dr3;
    DWORD   Dr6;
    DWORD   Dr7;

    //
    // This section is specified/returned if the
    // ContextFlags word contains the flag CONTEXT_FLOATING_POINT.
    //

    FLOATING_SAVE_AREA FloatSave;

    //
    // This section is specified/returned if the
    // ContextFlags word contains the flag CONTEXT_SEGMENTS.
    //

    DWORD   SegGs;
    DWORD   SegFs;
    DWORD   SegEs;
    DWORD   SegDs;

    //
    // This section is specified/returned if the
    // ContextFlags word contains the flag CONTEXT_INTEGER.
    //

    DWORD   Edi;
    DWORD   Esi;
    DWORD   Ebx;
    DWORD   Edx;
    DWORD   Ecx;
    DWORD   Eax;

    //
    // This section is specified/returned if the
    // ContextFlags word contains the flag CONTEXT_CONTROL.
    //

    DWORD   Ebp;
    DWORD   Eip;
    DWORD   SegCs;              // MUST BE SANITIZED
    DWORD   EFlags;             // MUST BE SANITIZED
    DWORD   Esp;
    DWORD   SegSs;

    //
    // This section is specified/returned if the ContextFlags word
    // contains the flag CONTEXT_EXTENDED_REGISTERS.
    // The format and contexts are processor specific
    //

    BYTE    ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];

} CONTEXT;

其中Drx是和硬件调试器有关的,本篇文章不讲硬断和软中断。
我们看见线程上下文中包含了很多寄存器,这在第一篇函数调用过程小白文里有,其中最主要的就是这些:

DWORD Edi;
DWORD Esi;
DWORD Ebx;
DWORD Edx;
DWORD Ecx;
DWORD Eax;
DWORD Ebp;
DWORD Eip;
DWORD EFlags; // MUST BE SANITIZED
DWORD Esp;

Eflags是标志寄存器,也叫程序状态字。具体VEH那篇文章有简单介绍。为什么捕获到异常程序可以继续运行下去,这就和Eflags有很大关系。

线程在进行切换时,会保存当前上下文,在切换回来的时候会通过上下文确定EIP地址,让程序继续运行下去。

通过这个上下文其实能干很多事情,反调试,调试,HOOK等等。

你可能感兴趣的:(C/C++)