pwn/
context.rs

1//! The global (to a given thread) context. Used to set global settings which are used internally by several functions.
2//! # Examples
3//! ```
4//! use pwn::{context, I386};
5//! use pwn::Bits::ThirtyTwo;
6//! context::set_arch(I386);
7//! assert_eq!(context::get_arch(), I386);
8//! assert_eq!(context::get_bits(), ThirtyTwo)
9//! ```
10//! # Warning
11//! `context` is local to each thread. Context values may need to be re-set when using multi-threaded code.
12#![allow(dead_code)]
13
14use crate::context::Bits::{SixtyFour, ThirtyTwo};
15use crate::context::Endianness::Little;
16
17use std::cell::RefCell;
18
19/// The word endianness of a given [`Arch`]
20#[derive(Copy, Clone, Debug, PartialEq)]
21#[allow(missing_docs)]
22pub enum Endianness {
23    Little,
24    Big,
25}
26
27/// The word size of a given [`Arch`]
28#[derive(Copy, Clone, Debug, PartialEq)]
29#[repr(u8)]
30#[allow(missing_docs)]
31pub enum Bits {
32    Eight = 8,
33    Sixteen = 16,
34    ThirtyTwo = 32,
35    SixtyFour = 64,
36}
37
38/// An architecture, identified by its endianness and word size
39#[derive(Copy, Clone, Debug, PartialEq)]
40#[allow(missing_docs)]
41pub struct Arch {
42    pub endian: Endianness,
43    pub bits: Bits,
44}
45
46/// The 64-bit version of x86
47pub const AMD64: Arch = Arch {
48    endian: Little,
49    bits: SixtyFour,
50};
51
52/// The 32-bit version of x86
53pub const I386: Arch = Arch {
54    endian: Little,
55    bits: ThirtyTwo,
56};
57
58/// The current context, used by most functions for runtime
59/// behaviour modification
60#[derive(Copy, Clone, Debug, PartialEq)]
61#[allow(missing_docs)]
62pub struct Context {
63    arch: Arch,
64}
65
66impl Default for Context {
67    fn default() -> Self {
68        Self { arch: I386 }
69    }
70}
71
72thread_local! {
73    /** The default `Context`.
74    * Arch: [`I386`],
75    * Log Level: [`Info`]
76     **/
77    static CONTEXT: RefCell<Context> = Default::default();
78}
79
80// Setters
81/// Set the context's architecture
82pub fn set_arch(a: Arch) {
83    CONTEXT.with(|c| c.borrow_mut().arch = a)
84}
85/// Set the context's endianess
86pub fn set_endianess(e: Endianness) {
87    CONTEXT.with(|c| c.borrow_mut().arch.endian = e)
88}
89/// Set the context's word size
90pub fn set_bits(b: Bits) {
91    CONTEXT.with(|c| c.borrow_mut().arch.bits = b)
92}
93// Getters
94/// Get the context's architecture
95pub fn get_arch() -> Arch {
96    CONTEXT.with(|c| c.borrow().arch)
97}
98/// Get the context's endianess
99pub fn get_endianess() -> Endianness {
100    CONTEXT.with(|c| c.borrow().arch.endian)
101}
102/// Get the context's word size
103pub fn get_bits() -> Bits {
104    CONTEXT.with(|c| c.borrow().arch.bits)
105}