Created
December 22, 2011 04:14
-
-
Save miyamuko/1508896 to your computer and use it in GitHub Desktop.
#xyzzy の network stream からソケットハンドルを無理やり取り出してみる PoC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; | |
;; 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