Skip to content

Instantly share code, notes, and snippets.

@miyamuko
Created December 22, 2011 04:14
Show Gist options
  • Save miyamuko/1508896 to your computer and use it in GitHub Desktop.
Save miyamuko/1508896 to your computer and use it in GitHub Desktop.
#xyzzy の network stream からソケットハンドルを無理やり取り出してみる PoC
;;
;; xyzzy の network stream からソケットハンドルを無理やり取り出してみる PoC
;; メモリレイアウトに依存する危険な処理なので良い子は真似しないように
;;
;; Windows SDK/.../WinSock2.h
(c:define SOL_SOCKET #xffff)
(c:define SO_SNDTIMEO #x1005)
(c:define SO_RCVTIMEO #x1006)
(c:define TCP_NODELAY #x0001)
(c:define IPPROTO_TCP 6)
(c:define-c-type (c:void *) SOCKET)
(c:define-dll-entry
c:int
getsockopt (SOCKET ; s,
c:int ; level,
c:int ; optname,
(c:char *) ; optval,
(c:int *) ; optlen
)
"ws2_32.dll")
(c:define-dll-entry
c:int
setsockopt (SOCKET ; s,
c:int ; level,
c:int ; optname,
(c:char *) ; optval,
c:int ; optlen
)
"ws2_32.dll")
(c:define-dll-entry
c:int
WSAGetLastError ()
"ws2_32.dll")
;; xyzzy/src/stream.h
(c:define-c-type c:int stream_type)
(c:define-c-struct lstream
; ストリームのサブタイプ
; st_socket = (sti_socket_stream | sti_input_stream | sti_output_stream) = 0x8030
(stream_type type)
(c:int column) ; カラム位置
(c:long linenum) ; 行番号
((c:void *) input) ; sockinet
((c:void *) output)) ; -
;; xyzzy/src/sock.h
(c:define-c-struct sock
; sock は仮想関数を含むのでまず vtable へのポインタがある
; g++ でのメモリレイアウトの例は以下にのっている (VC++ もだいたい同じかな)
; http://en.wikipedia.org/wiki/Virtual_method_table
((c:void *) vtable) ; vtable
(SOCKET socket) ; ソケット
;; 省略
)
(defun get-socket-handle (stream)
(let* ((lstream (make-lstream nil (si:address-of stream)))
(sock (make-sock nil (lstream-input lstream))))
(sock-socket sock)))
(defun make-int32-chunk (&optional (value 0))
(let ((r (si:make-chunk nil 4)))
(si:pack-int32 r 0 (or value 0))
r))
(defun set-sockopt-int32 (handle level optname optval)
(check-type optval integer)
(zerop (setsockopt handle level optname (make-int32-chunk optval) 4)))
(defun get-sockopt-int32 (handle level optname)
(let ((optval-chunk (make-int32-chunk))
(optlen-chunk (make-int32-chunk 4)))
(unless (zerop (getsockopt handle level optname optval-chunk optlen-chunk))
(error "Socket error: 0x~X" (WSAGetLastError)))
(si:unpack-int32 optval-chunk 0)))
;; test
(setf stream (connect "localhost" 8080))
#<socket-stream 79566692>
(setf handle (get-socket-handle stream))
1560
(get-sockopt-int32 handle IPPROTO_TCP TCP_NODELAY)
0
(set-sockopt-int32 handle IPPROTO_TCP TCP_NODELAY 1)
t
(get-sockopt-int32 handle IPPROTO_TCP TCP_NODELAY)
1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment