Skip to content

Commit

Permalink
updates from back to the future
Browse files Browse the repository at this point in the history
  • Loading branch information
n3k committed Jun 23, 2023
1 parent 4211e24 commit 7a7953b
Show file tree
Hide file tree
Showing 69 changed files with 8,675 additions and 716 deletions.
21 changes: 21 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 IOActive

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
22 changes: 22 additions & 0 deletions PlatboxClient/PlatboxClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,28 @@ void parse_bus_device_function(char *line, UINT *bus, UINT *device, UINT *functi
free(subargs);
}


void read_msr(int argc, char **argv) {
/* rdmsr <msr> */
if (argc == 2) {
UINT msr = strtoul(argv[1], NULL, 16);
enable_debug_mode();
do_read_msr(msr, NULL);
restore_debug_mode();
}
}

void write_msr(int argc, char **argv) {
/* wrmsr <msr> <value> */
if (argc == 3) {
UINT msr = strtoul(argv[1], NULL, 16);
UINT64 value = strtoull(argv[2], NULL, 16);
enable_debug_mode();
do_write_msr(msr, value);
restore_debug_mode();
}
}

void parse_handle_pci_operation(int argc, char **argv) {
// pci r 0:2:0 -> reads the configuration space
// pci rb 0:2:0 1 -> reads a byte from offset
Expand Down
57 changes: 52 additions & 5 deletions PlatboxDrv/linux/driver/kernetix.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "kernetix.h"

#include <linux/efi.h>
#include <asm/io.h>

///////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -76,7 +77,8 @@ static long int kernetix_ioctl(struct file *file, unsigned int cmd, unsigned lon
void __user * p = (void __user *)carg;

struct _kernel_write *kwrite = NULL;
struct _kernel_read *kread = NULL;
struct _kernel_read *kread = NULL;
IO_PORT_CALL _io;
unsigned long _cr3;

printk(KERN_ALERT "==> The IOCTL for %#08x was called\n", cmd);
Expand Down Expand Up @@ -154,9 +156,7 @@ static long int kernetix_ioctl(struct file *file, unsigned int cmd, unsigned lon

printk(KERN_ALERT "Value of rbx --> %llx\n", swsmi_call->rbx );

__u16 b2b3 = ((swsmi_call->SwSmiData << 8) | swsmi_call->SwSmiNumber);
_swsmi(b2b3, swsmi_call->rax, swsmi_call->rbx,
swsmi_call->rcx, swsmi_call->rdx, swsmi_call->rsi, swsmi_call->rdi);
_swsmi(swsmi_call);

kfree(swsmi_call);
break;
Expand Down Expand Up @@ -392,7 +392,54 @@ static long int kernetix_ioctl(struct file *file, unsigned int cmd, unsigned lon
//printk(KERN_ALERT "efi_memmap: %016lx --> addr_result:[%016lx]\n", &efi.memmap, addr_result);
put_user( (long unsigned int *) &efi.memmap, (unsigned long **)addr_result );

break;
break;

case IOCTL_READ_IO_PORT:
if (copy_from_user(&_io, p, sizeof(IO_PORT_CALL))) {
return -EINVAL;
}

_io.data = 0;

switch(_io.size) {
case IO_SIZE_BYTE:
_io.data = inb(_io.port);
break;
case IO_SIZE_WORD:
_io.data = inw(_io.port);
break;
case IO_SIZE_DWORD:
_io.data = inl(_io.port);
break;
default:
return -EINVAL;
}

if (copy_to_user(p, &_io, sizeof(IO_PORT_CALL))) {
pr_err("copy_to_user error!!\n");
}
break;

case IOCTL_WRITE_IO_PORT:
if (copy_from_user(&_io, p, sizeof(IO_PORT_CALL))) {
return -EINVAL;
}

switch(_io.size) {
case IO_SIZE_BYTE:
outb((uint8_t) _io.data, _io.port);
break;
case IO_SIZE_WORD:
outw((uint16_t) _io.data, _io.port);
break;
case IO_SIZE_DWORD:
outl(_io.data, _io.port);
break;
default:
return -EINVAL;
}

break;
}

return 0;
Expand Down
89 changes: 75 additions & 14 deletions PlatboxDrv/linux/driver/low_level_functions.asm
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,88 @@ global _wrmsr

section .text

; void _swsmi( smi_code_data, rax_value, rbx_value, rcx_value, rdx_value, rsi_value, rdi_value);
; void _swsmi(SW_SMI_CALL *smi_call);
_swsmi:
push r15
push r14
push r13
push r12
push r11
push r10
push r9
push r8
push rsi
push rdx
push rbx

; RAX will get partially overwritten (AX) by _smi_code_data (which is passed in RCX)
; RDX will get partially overwritten (DX) by the value of APMC port (= 0x00B2)
mov rax, rsi ; rax_value
mov ax, di ; smi_code_data
mov rbx, rdx ; rbx value
; rcx already in its right value
mov rdx, r8 ; rdx value
mov rsi, r9 ; rsi value
mov rdi, [rsp + 010h] ; rdi_value
mov dx, 0B2h

push rcx
push rdi

; set registers to state of provided structure
mov r15, [rdi + 080h]
mov r14, [rdi + 078h]
mov r13, [rdi + 070h]
mov r12, [rdi + 068h]
mov r11, [rdi + 060h]
mov r10, [rdi + 058h]
mov r9, [rdi + 050h]
mov r8, [rdi + 048h]
; rdi handled later
mov rsi, [rdi + 038h]
mov rdx, [rdi + 030h]
mov rcx, [rdi + 028h]
mov rbx, [rdi + 020h]

; The trigger port might be different than 0xB2 in AMD
mov dx, [rdi + 010h]

mov rax, [rdi + 08h]
shl rax, 8
or rax, [rdi]

mov rdi, [rdi + 040h] ; get rdi value just before the OUT instruction
; this OUT instruction will write WORD value (smi_code_data) to ports 0xB2 and 0xB3 (SW SMI control and data ports)
out dx, ax

;; write to structure the changes that could have happened in SMM

push rax; save return RAX from SMI
mov rax, [rsp + 08h]; rax points to original RDI

mov [rax + 080h], r15
mov [rax + 078h], r14
mov [rax + 070h], r13
mov [rax + 068h], r12
mov [rax + 060h], r11
mov [rax + 058h], r10
mov [rax + 050h], r9
mov [rax + 048h], r8
mov [rax + 040h], rdi
mov [rax + 038h], rsi
mov [rax + 030h], rdx
mov [rax + 028h], rcx
mov [rax + 020h], rbx

pop r15 ; retrieve original rax
mov [rax + 018h], r15

pop rdi
pop rcx
pop rbx
ret
pop rdx
pop rsi
pop r8
pop r9
pop r10
pop r11
pop r12
pop r13
pop r14
pop r15

xor rax, rax

ret

; _read_pci_compatible_configuration_space(UINT8 Bus, UINT8 Device, UINT8 Function, PVOID pOut)
; Reads the 256 bytes of PCI Configuration data from a BDF into pOut
Expand Down
34 changes: 25 additions & 9 deletions PlatboxDrv/linux/include/kernetix.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ struct _kernel_write
void *old_value;
};



typedef unsigned short USHORT;
typedef USHORT UINT16;
typedef unsigned int UINT;
typedef UINT UINT32;
typedef char CHAR;
Expand Down Expand Up @@ -63,9 +63,9 @@ typedef int NTSTATUS;
#define CHAR_BIT 8
#define UCHAR_MAX 255

void _swsmi(short smi_code_data,
__u64 rax_value, __u64 rbx_value, __u64 rcx_value, __u64 rdx_value,
__u64 rsi_value, __u64 rdi_value);
#define IO_SIZE_BYTE 0
#define IO_SIZE_WORD 1
#define IO_SIZE_DWORD 2

void _read_pci_compatible_configuration_space(UINT8 Bus,
UINT8 Device, UINT8 Function, PVOID pOut);
Expand All @@ -82,17 +82,27 @@ void _wrmsr(int MSR, UINT64 Value);


typedef struct _SW_SMI_CALL {
UINT8 SwSmiNumber; // 0xb2
UINT8 SwSmiData; // 0xb3
UINT64 SwSmiNumber; // 0xb2
UINT64 SwSmiData; // 0xb3
UINT64 TriggerPort;
UINT64 rax;
UINT64 rbx;
UINT64 rcx;
UINT64 rdx;
UINT64 rsi;
UINT64 rdi;
UINT64 r8;
UINT64 r9;
UINT64 r10;
UINT64 r11;
UINT64 r12;
UINT64 r13;
UINT64 r14;
UINT64 r15;
// append maybe?
} SW_SMI_CALL, *PSW_SMI_CALL;


void _swsmi(SW_SMI_CALL *smi_call);

typedef struct _READ_PCI_CONFIGURATION_SPACE_CALL {
UINT8 bus;
Expand Down Expand Up @@ -144,7 +154,11 @@ typedef struct _WRITE_MSR_CALL {
UINT64 value;
} WRITE_MSR_CALL, *PWRITE_MSR_CALL;


typedef struct _IO_PORT_CALL {
UINT8 size;
UINT16 port;
UINT32 data;
} IO_PORT_CALL, *PIO_PORT_CALL;

/* Use 'n' as magic number */
#define KERNETIX_IOC_MAGIC 'n'
Expand Down Expand Up @@ -176,3 +190,5 @@ typedef struct _WRITE_MSR_CALL {

#define IOCTL_GET_EFI_MEMMAP_ADDRESS _IOWR(KERNETIX_IOC_MAGIC, 20, void *)

#define IOCTL_READ_IO_PORT _IOR(KERNETIX_IOC_MAGIC, 21, void *)
#define IOCTL_WRITE_IO_PORT _IOR(KERNETIX_IOC_MAGIC, 22, void *)
Loading

0 comments on commit 7a7953b

Please sign in to comment.