libmwemu 0.24.5

x86 32/64bits and system internals emulator, for securely emulating malware and other stuff.
Documentation
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;

use crate::eflags::Eflags;
use crate::flags::Flags;
use crate::regs_aarch64::RegsAarch64;
use crate::regs64::Regs64;
use crate::serialization::fpu::SerializableFPU;
use crate::threading::context::{ArchThreadState, ThreadContext};

#[derive(Serialize, Deserialize)]
pub enum SerializableThreadArch {
    X86 {
        regs: Regs64,
        pre_op_regs: Regs64,
        post_op_regs: Regs64,
        flags: Flags,
        pre_op_flags: Flags,
        post_op_flags: Flags,
        eflags: Eflags,
        fpu: SerializableFPU,
        seh: u64,
        veh: u64,
        uef: u64,
        eh_ctx: u64,
        tls32: Vec<u32>,
        tls64: Vec<u64>,
        fls: Vec<u32>,
        fs: BTreeMap<u64, u64>,
        call_stack: Vec<(u64, u64)>,
    },
    AArch64 {
        regs: RegsAarch64,
        pre_op_regs: RegsAarch64,
        post_op_regs: RegsAarch64,
    },
}

#[derive(Serialize, Deserialize)]
pub struct SerializableThreadContext {
    pub id: u64,
    pub suspended: bool,
    pub wake_tick: usize,
    pub blocked_on_cs: Option<u64>,
    pub handle: u64,
    pub arch: SerializableThreadArch,
}

impl From<&ThreadContext> for SerializableThreadContext {
    fn from(thread: &ThreadContext) -> Self {
        match &thread.arch {
            ArchThreadState::X86 {
                regs, pre_op_regs, post_op_regs,
                flags, pre_op_flags, post_op_flags,
                eflags, fpu, seh, veh, uef, eh_ctx,
                tls32, tls64, fls, fs, call_stack,
            } => SerializableThreadContext {
                id: thread.id,
                suspended: thread.suspended,
                wake_tick: thread.wake_tick,
                blocked_on_cs: thread.blocked_on_cs,
                handle: thread.handle,
                arch: SerializableThreadArch::X86 {
                    regs: *regs,
                    pre_op_regs: *pre_op_regs,
                    post_op_regs: *post_op_regs,
                    flags: *flags,
                    pre_op_flags: *pre_op_flags,
                    post_op_flags: *post_op_flags,
                    eflags: eflags.clone(),
                    fpu: fpu.clone().into(),
                    seh: *seh,
                    veh: *veh,
                    uef: *uef,
                    eh_ctx: *eh_ctx,
                    tls32: tls32.clone(),
                    tls64: tls64.clone(),
                    fls: fls.clone(),
                    fs: fs.clone(),
                    call_stack: call_stack.clone(),
                },
            },
            ArchThreadState::AArch64 {
                regs,
                pre_op_regs,
                post_op_regs,
            } => SerializableThreadContext {
                id: thread.id,
                suspended: thread.suspended,
                wake_tick: thread.wake_tick,
                blocked_on_cs: thread.blocked_on_cs,
                handle: thread.handle,
                arch: SerializableThreadArch::AArch64 {
                    regs: *regs,
                    pre_op_regs: *pre_op_regs,
                    post_op_regs: *post_op_regs,
                },
            },
        }
    }
}

impl From<SerializableThreadContext> for ThreadContext {
    fn from(serialized: SerializableThreadContext) -> Self {
        ThreadContext {
            id: serialized.id,
            suspended: serialized.suspended,
            wake_tick: serialized.wake_tick,
            blocked_on_cs: serialized.blocked_on_cs,
            handle: serialized.handle,
            arch: match serialized.arch {
                SerializableThreadArch::X86 {
                    regs,
                    pre_op_regs,
                    post_op_regs,
                    flags,
                    pre_op_flags,
                    post_op_flags,
                    eflags,
                    fpu,
                    seh,
                    veh,
                    uef,
                    eh_ctx,
                    tls32,
                    tls64,
                    fls,
                    fs,
                    call_stack,
                } => ArchThreadState::X86 {
                    regs,
                    pre_op_regs,
                    post_op_regs,
                    flags,
                    pre_op_flags,
                    post_op_flags,
                    eflags,
                    fpu: fpu.into(),
                    seh,
                    veh,
                    uef,
                    eh_ctx,
                    tls32,
                    tls64,
                    fls,
                    fs,
                    call_stack,
                },
                SerializableThreadArch::AArch64 {
                    regs,
                    pre_op_regs,
                    post_op_regs,
                } => ArchThreadState::AArch64 {
                    regs,
                    pre_op_regs,
                    post_op_regs,
                },
            },
        }
    }
}