diff --git a/include/ntapi/nt_ipc.h b/include/ntapi/nt_ipc.h index 7238146..80760c1 100644 --- a/include/ntapi/nt_ipc.h +++ b/include/ntapi/nt_ipc.h @@ -85,6 +85,19 @@ typedef int32_t __stdcall ntapi_ipc_connect_section_by_port( __out size_t * section_size); +typedef int32_t __stdcall ntapi_ipc_get_port_by_attr( + __out void ** hport, + __in nt_port_attr * attr); + + +typedef int32_t __stdcall ntapi_ipc_get_port_section_by_attr( + __out void ** hport, + __in nt_port_attr * attr, + __out void ** hsection, + __out void ** section_addr, + __out size_t * section_size); + + typedef int32_t __stdcall ntapi_ipc_init_section_by_port( __in void * hconn, __out void ** hsection, diff --git a/include/ntapi/nt_process.h b/include/ntapi/nt_process.h index 96bc727..c284185 100644 --- a/include/ntapi/nt_process.h +++ b/include/ntapi/nt_process.h @@ -60,6 +60,8 @@ typedef enum _nt_process_opcode_idx { NT_PROCESS_OPCODE_IDX_EXECVE, NT_PROCESS_OPCODE_IDX_STOPPED, NT_PROCESS_OPCODE_IDX_CONTINUED, + NT_PROCESS_OPCODE_IDX_CLIENT, + NT_PROCESS_OPCODE_IDX_SERVER, } nt_process_opcode_idx; @@ -505,6 +507,10 @@ typedef struct _nt_runtime_data { int32_t ppid_type; int32_t ppid_subtype; uint32_t ppid_keys[6]; + nt_guid ipc_guid; + int32_t ipc_type; + int32_t ipc_subtype; + uint32_t ipc_keys[6]; nt_guid semctl_guid; int32_t semctl_type; int32_t semctl_subtype; diff --git a/include/ntapi/nt_tty.h b/include/ntapi/nt_tty.h index 387c8b6..5555d85 100644 --- a/include/ntapi/nt_tty.h +++ b/include/ntapi/nt_tty.h @@ -50,6 +50,9 @@ typedef enum _nt_tty_opcode { NT_TTY_CLIENT_SESSION_DISCONNECT, NT_TTY_CLIENT_SESSION_QUERY, NT_TTY_CLIENT_SESSION_SET, + /* server-to-server coordination */ + NT_TTY_CLIENT_SESSION_SYNCHRONIZE, + NT_TTY_CLIENT_SESSION_TRANSFER, /* process registration */ NT_TTY_CLIENT_PROCESS_REGISTER, NT_TTY_CLIENT_PROCESS_UNREGISTER, @@ -87,6 +90,8 @@ typedef enum _nt_tty_opcode { NT_TTY_SEM_IOCTL, NT_TTY_SEM_CANCEL, NT_TTY_SEM_TRACE, + NT_TTY_SEM_TRANSFER, + NT_TTY_SEM_WAIT, /* virtual mount system */ NT_TTY_VMS_QUERY, NT_TTY_VMS_REQUEST, @@ -271,6 +276,40 @@ typedef struct __attr_ptr_size_aligned__ _nt_tty_session_info { int32_t syspid; } nt_tty_session_info; + +typedef struct __attr_ptr_size_aligned__ _nt_tty_ipc_info { + nt_port_attr ctrlsvc; + uint32_t ipckeys[6]; + void * hevent; + void * apc_routine; + void * apc_context; + nt_iosb * riosb; +} nt_tty_ipc_info; + + +typedef struct __attr_ptr_size_aligned__ _nt_tty_sync_info { + nt_client_id cid; + nt_port_attr ipcsvc; + uint32_t ipckeys[6]; + void * hevent; + void * apc_routine; + void * apc_context; + nt_iosb * riosb; +} nt_tty_sync_info; + + + +typedef struct __attr_ptr_size_aligned__ _nt_tty_transfer_info { + nt_client_id ccid; + nt_client_id tcid; + uint32_t ipckeys[6]; + void * hevent; + void * apc_routine; + void * apc_context; + nt_iosb * riosb; +} nt_tty_transfer_info; + + typedef struct __attr_ptr_size_aligned__ _nt_tty_register_msg { nt_port_message header; struct { @@ -334,6 +373,33 @@ typedef struct __attr_ptr_size_aligned__ _nt_tty_pid_msg { } nt_tty_pid_msg; +typedef struct __attr_ptr_size_aligned__ _nt_tty_ipc_msg { + nt_port_message header; + struct { + nt_tty_msg_info ttyinfo; + nt_tty_ipc_info ipcinfo; + } data; +} nt_tty_ipc_msg; + + +typedef struct __attr_ptr_size_aligned__ _nt_tty_sync_msg { + nt_port_message header; + struct { + nt_tty_msg_info ttyinfo; + nt_tty_sync_info syncinfo; + } data; +} nt_tty_sync_msg; + + +typedef struct __attr_ptr_size_aligned__ _nt_tty_transfer_msg { + nt_port_message header; + struct { + nt_tty_msg_info ttyinfo; + nt_tty_transfer_info transferinfo; + } data; +} nt_tty_transfer_msg; + + typedef struct __attr_ptr_size_aligned__ _nt_pty_fd_msg { nt_port_message header; struct { @@ -387,6 +453,10 @@ typedef struct __attr_ptr_size_aligned__ _nt_tty_port_msg { nt_tty_vms_info vmsinfo; nt_tty_peer_info peerinfo; nt_tty_sigctl_info ctlinfo; + nt_tty_ipc_info ipcinfo; + nt_tty_sync_info syncinfo; + nt_user_process_info pidinfo; + nt_tty_transfer_info transferinfo; nt_pty_fd_info fdinfo; nt_pty_io_info ioinfo; nt_pty_client_info clientinfo; @@ -412,6 +482,9 @@ __assert_aligned_size(nt_pty_sigctl_msg, __SIZEOF_POINTER__); __assert_aligned_size(nt_pty_fd_msg, __SIZEOF_POINTER__); __assert_aligned_size(nt_pty_io_msg, __SIZEOF_POINTER__); __assert_aligned_size(nt_tty_port_msg, __SIZEOF_POINTER__); +__assert_aligned_size(nt_tty_ipc_msg, __SIZEOF_POINTER__); +__assert_aligned_size(nt_tty_sync_msg, __SIZEOF_POINTER__); +__assert_aligned_size(nt_tty_transfer_msg, __SIZEOF_POINTER__); /* tty session */ diff --git a/include/ntapi/ntapi.h b/include/ntapi/ntapi.h index 23a99aa..71416d8 100644 --- a/include/ntapi/ntapi.h +++ b/include/ntapi/ntapi.h @@ -397,6 +397,8 @@ typedef struct _ntapi_vtbl { ntapi_ipc_connect_section_by_name * ipc_connect_section_by_name; ntapi_ipc_connect_section_by_symlink * ipc_connect_section_by_symlink; ntapi_ipc_connect_section_by_port * ipc_connect_section_by_port; + ntapi_ipc_get_port_by_attr * ipc_get_port_by_attr; + ntapi_ipc_get_port_section_by_attr * ipc_get_port_section_by_attr; ntapi_ipc_init_section_by_port * ipc_init_section_by_port; ntapi_ipc_disconnect_unmap_section_by_port * ipc_disconnect_unmap_section_by_port; ntapi_ipc_create_pipe * ipc_create_pipe; diff --git a/src/internal/ntapi.c b/src/internal/ntapi.c index 2459534..0940ebd 100644 --- a/src/internal/ntapi.c +++ b/src/internal/ntapi.c @@ -188,6 +188,8 @@ static int32_t __fastcall __ntapi_init_once(ntapi_vtbl ** pvtbl) __ntapi->ipc_connect_section_by_name = __ntapi_ipc_connect_section_by_name; __ntapi->ipc_connect_section_by_symlink = __ntapi_ipc_connect_section_by_symlink; __ntapi->ipc_connect_section_by_port = __ntapi_ipc_connect_section_by_port; + __ntapi->ipc_get_port_by_attr = __ntapi_ipc_get_port_by_attr; + __ntapi->ipc_get_port_section_by_attr = __ntapi_ipc_get_port_section_by_attr; __ntapi->ipc_init_section_by_port = __ntapi_ipc_init_section_by_port; __ntapi->ipc_disconnect_unmap_section_by_port = __ntapi_ipc_disconnect_unmap_section_by_port; diff --git a/src/internal/ntapi_fnapi.h b/src/internal/ntapi_fnapi.h index e7cb5ae..1e770ce 100644 --- a/src/internal/ntapi_fnapi.h +++ b/src/internal/ntapi_fnapi.h @@ -54,6 +54,8 @@ ntapi_ipc_connect_section_by_attr __ntapi_ipc_connect_section_by_attr; ntapi_ipc_connect_section_by_name __ntapi_ipc_connect_section_by_name; ntapi_ipc_connect_section_by_symlink __ntapi_ipc_connect_section_by_symlink; ntapi_ipc_connect_section_by_port __ntapi_ipc_connect_section_by_port; +ntapi_ipc_get_port_by_attr __ntapi_ipc_get_port_by_attr; +ntapi_ipc_get_port_section_by_attr __ntapi_ipc_get_port_section_by_attr; ntapi_ipc_init_section_by_port __ntapi_ipc_init_section_by_port; ntapi_ipc_disconnect_unmap_section_by_port __ntapi_ipc_disconnect_unmap_section_by_port; ntapi_ipc_create_pipe __ntapi_ipc_create_pipe_v1; diff --git a/src/ipc/ntapi_ipc_connect.c b/src/ipc/ntapi_ipc_connect.c index fceb527..6584f49 100644 --- a/src/ipc/ntapi_ipc_connect.c +++ b/src/ipc/ntapi_ipc_connect.c @@ -20,14 +20,142 @@ static int32_t __ipc_connect_return( } +static void __ipc_init_ctrl_msg_semctl( + const nt_port_attr * attr, + nt_tty_ipc_msg * msg) +{ + __ntapi->tt_aligned_block_memset( + (uintptr_t *)msg, + 0,sizeof(*msg)); + + msg->data.ipcinfo.ctrlsvc.type = attr->type; + msg->data.ipcinfo.ctrlsvc.subtype = attr->subtype; + + msg->data.ipcinfo.ctrlsvc.keys.key[0] = attr->keys.key[0]; + msg->data.ipcinfo.ctrlsvc.keys.key[1] = attr->keys.key[1]; + msg->data.ipcinfo.ctrlsvc.keys.key[2] = attr->keys.key[2]; + msg->data.ipcinfo.ctrlsvc.keys.key[3] = attr->keys.key[3]; + msg->data.ipcinfo.ctrlsvc.keys.key[4] = attr->keys.key[4]; + msg->data.ipcinfo.ctrlsvc.keys.key[5] = attr->keys.key[5]; + + __ntapi->tt_guid_copy( + &msg->data.ipcinfo.ctrlsvc.guid, + &attr->guid); +} + + +static void __ipc_init_ctrl_msg_semsvc( + nt_rtdata * rtdata, + nt_tty_ipc_msg * msg) +{ + __ntapi->tt_aligned_block_memset( + (uintptr_t *)msg, + 0,sizeof(*msg)); + + msg->data.ipcinfo.ctrlsvc.type = rtdata->semctl_type; + msg->data.ipcinfo.ctrlsvc.subtype = rtdata->semctl_subtype; + + msg->data.ipcinfo.ctrlsvc.keys.key[0] = rtdata->semctl_keys[0]; + msg->data.ipcinfo.ctrlsvc.keys.key[1] = rtdata->semctl_keys[1]; + msg->data.ipcinfo.ctrlsvc.keys.key[2] = rtdata->semctl_keys[2]; + msg->data.ipcinfo.ctrlsvc.keys.key[3] = rtdata->semctl_keys[3]; + msg->data.ipcinfo.ctrlsvc.keys.key[4] = rtdata->semctl_keys[4]; + msg->data.ipcinfo.ctrlsvc.keys.key[5] = rtdata->semctl_keys[5]; + + __ntapi->tt_guid_copy( + &msg->data.ipcinfo.ctrlsvc.guid, + &rtdata->semctl_guid); +} + + +static void __ipc_init_ctrl_msg_ipcpeer( + nt_rtdata * rtdata, + nt_tty_ipc_msg * msg) +{ + __ntapi->tt_aligned_block_memset( + (uintptr_t *)msg, + 0,sizeof(*msg)); + + msg->data.ipcinfo.ctrlsvc.type = rtdata->srv_type; + msg->data.ipcinfo.ctrlsvc.subtype = rtdata->srv_subtype; + + msg->data.ipcinfo.ctrlsvc.keys.key[0] = rtdata->srv_keys[0]; + msg->data.ipcinfo.ctrlsvc.keys.key[1] = rtdata->srv_keys[1]; + msg->data.ipcinfo.ctrlsvc.keys.key[2] = rtdata->srv_keys[2]; + msg->data.ipcinfo.ctrlsvc.keys.key[3] = rtdata->srv_keys[3]; + msg->data.ipcinfo.ctrlsvc.keys.key[4] = rtdata->srv_keys[4]; + msg->data.ipcinfo.ctrlsvc.keys.key[5] = rtdata->srv_keys[5]; + + __ntapi->tt_guid_copy( + &msg->data.ipcinfo.ctrlsvc.guid, + &rtdata->srv_guid); +} + + +static int32_t __ipc_set_client_keys( + void * hport, + const nt_port_attr * attr, + nt_rtdata * rtdata) +{ + int32_t status; + nt_tty_ipc_msg msg; + uint32_t opcode; + + switch (attr->type) { + case NT_PORT_TYPE_SEMCTL: + if (rtdata->srv_type == NT_PORT_TYPE_SEMSVC) + __ipc_init_ctrl_msg_ipcpeer( + rtdata,&msg); + else + __ipc_init_ctrl_msg_semctl( + attr,&msg); + + opcode = NT_TTY_SEM_FCNTL; + break; + + case NT_PORT_TYPE_SEMSVC: + if (rtdata->srv_type == NT_PORT_TYPE_SEMCTL) + return NT_STATUS_SUCCESS; + + __ipc_init_ctrl_msg_semsvc( + rtdata,&msg); + + opcode = NT_TTY_SEM_FCNTL; + break; + + default: + return NT_STATUS_SUCCESS; + } + + msg.header.msg_type = NT_LPC_NEW_MESSAGE; + msg.header.data_size = sizeof(msg.data); + msg.header.msg_size = sizeof(msg); + msg.data.ttyinfo.opcode = opcode; + + msg.data.ipcinfo.ipckeys[0] = rtdata->ipc_keys[0]; + msg.data.ipcinfo.ipckeys[1] = rtdata->ipc_keys[1]; + msg.data.ipcinfo.ipckeys[2] = rtdata->ipc_keys[2]; + msg.data.ipcinfo.ipckeys[3] = rtdata->ipc_keys[3]; + msg.data.ipcinfo.ipckeys[4] = rtdata->ipc_keys[4]; + msg.data.ipcinfo.ipckeys[5] = rtdata->ipc_keys[5]; + + if ((status = __ntapi->zw_request_wait_reply_port(hport,&msg,&msg))) + return status; + else if (msg.data.ttyinfo.status) + return msg.data.ttyinfo.status; + + return NT_STATUS_SUCCESS; +} + static int32_t __ipc_connect_by_attr( void ** hport, const nt_port_attr * attr, nt_unicode_string * str, void * hconn, - __out void ** hsection, - __out void ** secaddr, - __out size_t * secsize) + void ** hsection, + void ** secaddr, + size_t * secsize, + int fexisting) { int32_t status; struct dalist_node_ex * node; @@ -35,10 +163,12 @@ static int32_t __ipc_connect_by_attr( nt_port_attr * nconn; nt_ipc_conn * ipc; intptr_t * hlock; + nt_rtdata * rtdata; ntapi_internals * __internals; /* init */ __internals = __ntapi_internals(); + rtdata = __internals->rtdata; /* lock */ hlock = &(__internals->hlock); @@ -76,6 +206,10 @@ static int32_t __ipc_connect_by_attr( } } + /* __ipc_get_port? */ + if (fexisting) + return __ipc_connect_return(hlock,NT_STATUS_NOT_FOUND); + /* allocate list node */ if ((status = dalist_get_free_node( &__internals->ipc_conns, @@ -96,6 +230,41 @@ static int32_t __ipc_connect_by_attr( } } + /* server-to-server synchronization */ + if (!rtdata->ipc_keys[0]) { + rtdata->ipc_keys[0] = __ntapi->tt_buffer_crc32( + (uint32_t)(uintptr_t)&hport, + (char *)__internals,sizeof(*__internals)); + + rtdata->ipc_keys[1] = __ntapi->tt_buffer_crc32( + (uint32_t)(uintptr_t)&hconn, + (char *)rtdata,sizeof(*rtdata)); + + rtdata->ipc_keys[2] = __ntapi->tt_buffer_crc32( + (uint32_t)(uintptr_t)&attr, + (char *)attr,sizeof(*attr)); + + rtdata->ipc_keys[3] = __ntapi->tt_buffer_crc32( + (uint32_t)(uintptr_t)&node, + (char *)node,sizeof(*node)); + + rtdata->ipc_keys[4] = __ntapi->tt_buffer_crc32( + (uint32_t)(uintptr_t)&str, + (char *)pe_get_peb_address(), + sizeof(nt_peb)); + + rtdata->ipc_keys[5] = __ntapi->tt_buffer_crc32( + (uint32_t)(uintptr_t)&conn, + (char *)pe_get_teb_address(), + sizeof(nt_tib)); + } + + if ((status = __ipc_set_client_keys(hconn,attr,rtdata))) { + __ntapi->zw_close(hconn); + dalist_deposit_free_node(&__internals->ipc_conns,node); + return __ipc_connect_return(hlock,status); + } + /* add connection */ node->key = (uintptr_t)hconn; ipc = (nt_ipc_conn *)&node->dblock; @@ -143,7 +312,7 @@ int32_t __stdcall __ntapi_ipc_connect_section_by_attr( return __ipc_connect_by_attr( hport,attr,&str,0, - hsection,secaddr,secsize); + hsection,secaddr,secsize,0); } @@ -167,7 +336,7 @@ int32_t __stdcall __ntapi_ipc_connect_section_by_name( return __ipc_connect_by_attr( hport,&attr,&str,0, - hsection,secaddr,secsize); + hsection,secaddr,secsize,0); } @@ -204,7 +373,7 @@ int32_t __stdcall __ntapi_ipc_connect_section_by_symlink( return __ipc_connect_by_attr( hport,&attr,str,0, - hsection,secaddr,secsize); + hsection,secaddr,secsize,0); } @@ -217,7 +386,7 @@ int32_t __stdcall __ntapi_ipc_connect_section_by_port( { return __ipc_connect_by_attr( &(void *){0},attr,0,hconn, - hsection,secaddr,secsize); + hsection,secaddr,secsize,0); } @@ -298,6 +467,35 @@ int __ntapi_ipc_page_alloc( } +int32_t __stdcall __ntapi_ipc_get_port_by_attr( + __out void ** hport, + __in nt_port_attr * attr) +{ + return __ipc_connect_by_attr( + hport,attr,0,0, + &(void *){0}, + &(void *){0}, + &(size_t){0}, + 1); +} + + +int32_t __stdcall __ntapi_ipc_get_port_section_by_attr( + __out void ** hport, + __in nt_port_attr * attr, + __out void ** hsection, + __out void ** section_addr, + __out size_t * section_size) +{ + return __ipc_connect_by_attr( + hport,attr,0,0, + hsection, + section_addr, + section_size, + 1); +} + + int32_t __stdcall __ntapi_ipc_init_section_by_port( __in void * hconn, __out void ** hsection, diff --git a/src/process/ntapi_tt_fork.c b/src/process/ntapi_tt_fork.c index d76a994..68ae84b 100644 --- a/src/process/ntapi_tt_fork.c +++ b/src/process/ntapi_tt_fork.c @@ -25,9 +25,11 @@ static intptr_t __fastcall __ntapi_tt_fork_finalize( nt_oa oa; nt_cid cid; int page; + nt_rtdata * rtdata; ntapi_internals * __internals; __internals = __ntapi_internals(); + rtdata = __internals->rtdata; *hprocess = 0; *hthread = 0; @@ -73,6 +75,16 @@ static intptr_t __fastcall __ntapi_tt_fork_finalize( __internals->ipc_pages[page], NT_ALLOCATION_GRANULARITY); + rtdata->hsemctl = 0; + rtdata->hsempid = 0; + + rtdata->ipc_keys[0] = 0; + rtdata->ipc_keys[1] = 0; + rtdata->ipc_keys[2] = 0; + rtdata->ipc_keys[3] = 0; + rtdata->ipc_keys[4] = 0; + rtdata->ipc_keys[5] = 0; + return 0; } diff --git a/src/sem/ntapi_sem_connect.c b/src/sem/ntapi_sem_connect.c index 32c3610..2dc9a94 100644 --- a/src/sem/ntapi_sem_connect.c +++ b/src/sem/ntapi_sem_connect.c @@ -259,12 +259,17 @@ int32_t __stdcall __ntapi_sem_open( __in uint32_t share, __in uint32_t nslots) { - int32_t status; - uint32_t key; - uint32_t id; - void * hsymlink; - nt_oa ipcoa; - void * hipc; + int32_t status; + uint32_t key; + uint32_t id; + void * hsymlink; + nt_oa ipcoa; + void * hipc; + nt_rtdata * rtdata; + nt_tty_service_info semctl; + + /* init */ + rtdata = (__ntapi_internals())->rtdata; /* validate */ if (!oa->root_dir) @@ -310,6 +315,19 @@ int32_t __stdcall __ntapi_sem_open( return status; } + /* semctl service attributes */ + if (!rtdata->hsempid) + if ((status = __semctl_get_service_attr(rtdata,&semctl))) + return status; + + /* semctl server */ + if ((status = __semctl_server_connect(rtdata,&semctl))) + return status; + + /* sempid symlink */ + if ((status = __sempid_symlink_set(rtdata,&semctl))) + return status; + /* ipc connect */ status = __ntapi->ipc_connect_by_symlink( &hipc,hsymlink); diff --git a/src/sem/ntapi_sem_fcntl.c b/src/sem/ntapi_sem_fcntl.c index d48557f..d160e66 100644 --- a/src/sem/ntapi_sem_fcntl.c +++ b/src/sem/ntapi_sem_fcntl.c @@ -37,5 +37,6 @@ int32_t __stdcall __ntapi_sem_fcntl( (void)output_buffer; (void)output_buffer_length; - return 0; + /* internal only */ + return NT_STATUS_NOT_IMPLEMENTED; }