From 5c943b8f3836ed2cf7eaedf1e75009dc88d1cdc1 Mon Sep 17 00:00:00 2001 From: BrentHoltsclaw Date: Wed, 6 Mar 2019 10:44:18 -0800 Subject: [PATCH] Changes to windows helper and driver to support return values --- chipsec/helper/win/win32helper.py | 11 +++++-- drivers/win7/amd64/cpu.asm | 55 +++++++++++++++++-------------- drivers/win7/driver.c | 48 ++++++++++++++------------- drivers/win7/include/cpu.h | 10 ++++++ 4 files changed, 76 insertions(+), 48 deletions(-) diff --git a/chipsec/helper/win/win32helper.py b/chipsec/helper/win/win32helper.py index d6645698..333fb447 100644 --- a/chipsec/helper/win/win32helper.py +++ b/chipsec/helper/win/win32helper.py @@ -131,6 +131,12 @@ IOCTL_WRCR = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x818, METHOD_BUF IOCTL_RDCR = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x819, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS) IOCTL_MSGBUS_SEND_MESSAGE = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x820, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS) +# +# Format for IOCTL Structures +# +_pack = 'Q' if sys.maxsize > 2**32 else 'I' +_smi_msg_t_fmt = 7*_pack + # # NT Errors # @@ -810,9 +816,10 @@ class Win32Helper(Helper): out_length = 0 out_buf = (c_char * out_length)() out_size = c_ulong(out_length) - in_buf = struct.pack( '=H6Q', SMI_code_data, _rax, _rbx, _rcx, _rdx, _rsi, _rdi ) + in_buf = struct.pack( _smi_msg_t_fmt, SMI_code_data, _rax, _rbx, _rcx, _rdx, _rsi, _rdi ) out_buf = self._ioctl( IOCTL_SWSMI, in_buf, out_length ) - return + ret = struct.unpack( _smi_msg_t_fmt, out_buf) + return ret def _get_handle_for_pid( self, pid=0, ro=True ): if pid == 0: diff --git a/drivers/win7/amd64/cpu.asm b/drivers/win7/amd64/cpu.asm index c67bbd36..9637fd70 100644 --- a/drivers/win7/amd64/cpu.asm +++ b/drivers/win7/amd64/cpu.asm @@ -343,49 +343,56 @@ SendAPMSMI PROC ret SendAPMSMI ENDP +;------------------------------------------------------------------------------ +;This function has one argument: swsmi_msg_t structure which contain 7 regs: rcx, rdx, r8, r9, r10, r11, r12: +; IN UINT64 smi_code_data +; IN UINT64 rax_value +; IN UINT64 rbx_value +; IN UINT64 rcx_value +; IN UINT64 rdx_value +; IN UINT64 rsi_value +; IN UINT64 rdi_value ;------------------------------------------------------------------------------ ; void -; _swsmi ( -; unsigned int smi_code_data // rcx -; IN UINT64 rax_value // rdx -; IN UINT64 rbx_value // r8 -; IN UINT64 rcx_value // r9 -; IN UINT64 rdx_value // sp+0x28 -; IN UINT64 rsi_value // sp+0x30 -; IN UINT64 rdi_value // sp+0x38 +; __swsmi__ ( +; swsmi_msg_t* ; ) ;------------------------------------------------------------------------------ _swsmi PROC + push rbx push rsi push rdi - - ; sp - 0x18 - + ; setting up GPR (arguments) to SMI handler call ; notes: ; RAX will get partially overwritten (AX) by _smi_code_data (which is passed in RCX) - mov rax, rdx ; rax_value - mov ax, cx ; smi_code_data - mov rdx, [rsp+040h] ; rdx_value sp+0x28+0x18 - - mov rbx, r8 ; rbx_value - mov rcx, r9 ; rcx_value - mov rsi, [rsp+048h] ; rsi_value - mov rdi, [rsp+050h] ; rdi_value - + ; RDX will get partially overwritten (DX) by the value of APMC port (= 0x00B2) + mov r10, rcx ; //pointer for struct into r10 + xchg rax, [r10+08h] ; //rax_value overwritten by _smi_code_data + mov rax, [r10] ; //smi_code_data + xchg rbx, [r10+10h] ; //rbx value + xchg rcx, [r10+18h] ; //rcx value + xchg rdx, [r10+20h] ; //rdx value + xchg rsi, [r10+28h] ; //rsi value + xchg rdi, [r10+30h] ; //rdi value + ; this OUT instruction will write WORD value (smi_code_data) to ports 0xB2 and 0xB3 (SW SMI control and data ports) - out 0B2h, ax - - ; @TODO: some SM handlers return data/errorcode in GPRs, need to return this to the caller + out 0B2h, ax ; 0xB2 + ; some SM handlers return data/errorcode in GPRs, need to return this to the caller + xchg [r10+08h], rax ; //rax value + xchg [r10+10h], rbx ; //rbx value + xchg [r10+18h], rcx ; //rcx value + xchg [r10+20h], rdx ; //rdx value + xchg [r10+28h], rsi ; //rsi value + xchg [r10+30h], rdi ; //rdi value pop rdi pop rsi pop rbx ret _swsmi ENDP - ;------------------------------------------------------------------------------ ; void ; WritePCIByte ( diff --git a/drivers/win7/driver.c b/drivers/win7/driver.c index 6e2c651b..d20dbb24 100644 --- a/drivers/win7/driver.c +++ b/drivers/win7/driver.c @@ -945,51 +945,55 @@ DriverDeviceControl( } case IOCTL_SWSMI: { - CPU_REG_TYPE gprs[6] = {0}; - CPU_REG_TYPE _rax = 0, _rbx = 0, _rcx = 0, _rdx = 0, _rsi = 0, _rdi = 0; - unsigned int _smi_code_data = 0; + swsmi_msg_t smi_msg; DbgPrint("[chipsec] > IOCTL_SWSMI\n"); pInBuf = Irp->AssociatedIrp.SystemBuffer; if( !pInBuf ) { - DbgPrint( "[chipsec] ERROR: NO data provided\n" ); + DbgPrint( "[chipsec] ERROR: NO data provided\n" ); Status = STATUS_INVALID_PARAMETER; break; } - if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(UINT16) + sizeof(gprs) ) + if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(smi_msg) ) { - DbgPrint( "[chipsec] ERROR: STATUS_INVALID_PARAMETER (input buffer size < sizeof(UINT16) + sizeof(gprs))\n" ); + DbgPrint( "[chipsec] ERROR: STATUS_INVALID_PARAMETER (input buffer size < sizeof(smi_msg))\n" ); Status = STATUS_INVALID_PARAMETER; break; } - RtlCopyBytes( &_smi_code_data, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(UINT16) ); - RtlCopyBytes( gprs, (BYTE*)Irp->AssociatedIrp.SystemBuffer + sizeof(UINT16), sizeof(gprs) ); - _rax = gprs[ 0 ]; - _rbx = gprs[ 1 ]; - _rcx = gprs[ 2 ]; - _rdx = gprs[ 3 ]; - _rsi = gprs[ 4 ]; - _rdi = gprs[ 5 ]; - DbgPrint( "[chipsec][IOCTL_SWSMI] SW SMI to ports 0x%X-0x%X <- 0x%04X\n", 0xB2, 0xB3, _smi_code_data ); - DbgPrint( " RAX = 0x%I64x\n", _rax ); - DbgPrint( " RBX = 0x%I64x\n", _rbx ); - DbgPrint( " RCX = 0x%I64x\n", _rcx ); - DbgPrint( " RDX = 0x%I64x\n", _rdx ); - DbgPrint( " RSI = 0x%I64x\n", _rsi ); - DbgPrint( " RDI = 0x%I64x\n", _rdi ); + RtlCopyBytes( &gprs, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(smi_msg) ); + + DbgPrint( "[chipsec][IOCTL_SWSMI] SW SMI to ports 0x%X-0x%X <- 0x%04X\n", 0xB2, 0xB3, smi_msg.code_data ); + DbgPrint( " RAX = 0x%I64x\n", smi_msg.rax ); + DbgPrint( " RBX = 0x%I64x\n", smi_msg.rbx ); + DbgPrint( " RCX = 0x%I64x\n", smi_msg.rcx ); + DbgPrint( " RDX = 0x%I64x\n", smi_msg.rdx ); + DbgPrint( " RSI = 0x%I64x\n", smi_msg.rsi ); + DbgPrint( " RDI = 0x%I64x\n", smi_msg.rdi ); // -- // -- send SMI using port 0xB2 // -- __try { - _swsmi( _smi_code_data, _rax, _rbx, _rcx, _rdx, _rsi, _rdi ); + _swsmi( &smi_msg ); } __except( EXCEPTION_EXECUTE_HANDLER ) { Status = GetExceptionCode(); break; } + + RtlCopyBytes( (BYTE*)Irp->AssociatedIrp.SystemBuffer, &smi_msg, sizeof(smi_msg) ); + dwBytesWritten = sizeof(smi_msg); + + DbgPrint( "[chipsec][IOCTL_SWSMI] SW SMI return from ports 0x%X-0x%X <- 0x%04X\n", 0xB2, 0xB3, smi_msg.code_data ); + DbgPrint( " RAX = 0x%I64x\n", smi_msg.rax ); + DbgPrint( " RBX = 0x%I64x\n", smi_msg.rbx ); + DbgPrint( " RCX = 0x%I64x\n", smi_msg.rcx ); + DbgPrint( " RDX = 0x%I64x\n", smi_msg.rdx ); + DbgPrint( " RSI = 0x%I64x\n", smi_msg.rsi ); + DbgPrint( " RDI = 0x%I64x\n", smi_msg.rdi ); + Status = STATUS_SUCCESS; break; } diff --git a/drivers/win7/include/cpu.h b/drivers/win7/include/cpu.h index df887558..4908d7eb 100644 --- a/drivers/win7/include/cpu.h +++ b/drivers/win7/include/cpu.h @@ -125,4 +125,14 @@ typedef struct _DESCRIPTOR_TABLE_RECORD { } DESCRIPTOR_TABLE_RECORD, *PDESCRIPTOR_TABLE_RECORD; #pragma pack() +typedef struct _swsmi_msg_t { + UINTN code_data; + UINTN rax; + UINTN rbx; + UINTN rcx; + UINTN rdx; + UINTN rsi; + UINTN rdi; +} swsmi_msg_t; + #endif // CPU_H