Local System 权限读取用户IE 代理设置的研究及简单HTTP代理验证

来源:互联网 发布:客户达软件怎么样 编辑:程序博客网 时间:2024/05/17 01:12
#include "windows.h"
#include "stdio.h"
#include "string.h"
//#include "winsock2.h"
//#include "wininet.h"

#pragma comment (lib,"ws2_32")

void LogToFile(char *LogText);

//有ProxyServer键值就取回来返回true,否则返回false;
bool CheckProxySetting(char * subkey,struct ProxyData * pCurrent);

//check proxyserver connection status
bool CheckProxyConnection(struct ProxyData * head);

//test http conn to either the proxy server or ditect the web server.
bool CheckHTTPconnction(char *hostname,int port,char * req,char * key);

//check intranet connection status
bool CheckIntranetConn();

struct ProxyData
{
 char pServer[128];
 int  pPort;
 ProxyData * pdNext;
};


void main()
{
 /*
 //使用wininet函数在system权限下是没有办法获得正确的结果的,另外,还存在另外一种情况,
 //就是没有勾选"使用代理服务器访问网络"的时候Internet Setting子键里面一样有Proxy Server的值,
 //这种情况存在的概率是相当大的,因为很多用户并不会用bypass设置来同时访问内外网,要访问内网就
 //关掉上面的勾选。读取注册表键理论上可以有效减少漏报。

//同样要解决system权限下current_user键没有办法使用的问题,测试的时候使用psu在system权限下看到
 //current_user里面的确没有信息,但是在HEKY_USERS/S-1-5-21-1935655697-725345543-839522115-500/
 //下面却有相应的信息。回到administrators权限下还是/S-1-5-21-1935655697-725345543-839522115-500/
 //有了下面枚举子键的想法。尝试中。

 INTERNET_PROXY_INFO *pIEinfo = NULL;
 DWORD dwSize = 0;
 BOOL bRet = InternetQueryOption(NULL, INTERNET_OPTION_PROXY, pIEinfo, &dwSize);
 pIEinfo = (INTERNET_PROXY_INFO*)new char[dwSize];
 bRet = InternetQueryOption(NULL, INTERNET_OPTION_PROXY, pIEinfo, &dwSize);
 LogToFile((char *)(pIEinfo+1));
 printf("/nResult:%s",pIEinfo+1);
 */

 int  index=0;
 char keyBuff[256]={0};
 DWORD dwSize=sizeof(keyBuff);
 struct ProxyData *p,*q,*head;
 char *got=NULL;
 bool succ=false;

 head=NULL;
 p=NULL;
 q=NULL;

 while(RegEnumKeyEx(HKEY_USERS,index,keyBuff,&dwSize,NULL,NULL,NULL,NULL)!=ERROR_NO_MORE_ITEMS)
 {
  printf("/nSubkey: %s",keyBuff);
  //LogToFile(keyBuff);

  //handle the result we have got
  if((strstr(keyBuff,"DEFAULT")==NULL)&&(strstr(keyBuff,"Classes")==NULL)) //we can only find right result in de key like xxxxx-xxx,experience from my test.
  {
   q=(struct ProxyData *)GlobalAlloc(GMEM_ZEROINIT,sizeof(struct ProxyData));   
   if(q == NULL)
   {
    printf("/nAllocate memory error!");
    return;
   }
   q->pdNext=NULL;

   if(CheckProxySetting(keyBuff,q))//once we got a result,the answer is success.
   {
    if(head!=NULL)
    {
     p->pdNext=q;
    }
    else
    {
     head=q;
    }
    p=q;
    succ=true;
   }
  }
  
  index++;
  memset(keyBuff,0,sizeof(keyBuff));
  dwSize=sizeof(keyBuff);
 }

 //test
 //CheckProxyConnection(head);
 CheckIntranetConn();

 //=================================
 //释放掉
 
 if(head != NULL)
 {
  q=p=head;  
  while(1)
  {
   printf("/nGlobalFree happen once!");
   q=p->pdNext;
   GlobalFree(p);
   if(q==NULL)
   {
    break;
   }
   p=q;
  }
 }
 //=================================
 /*if(succ)
 {
  printf("/nit seems that we have got the result.");
  return;
 }
 else
 {
  printf("/n!:( Bad luck!");
  return;
 }*/

}

//有ProxyServer键值就取回来返回true,否则返回false;
bool CheckProxySetting(char * subkey,ProxyData * pCurrent)
{
 char *path = "Software//Microsoft//Windows//CurrentVersion//Internet Settings";
 char *key = "ProxyServer";
 char *token;
 char *head = "http=";
 char *seps = ":";
 char *segs = ";";
 char buff[512] = {0};
 //struct hostent * hp=NULL;
 HKEY hResult;
 DWORD lpcbData;

 lpcbData=sizeof(buff);
 lstrcat(subkey,"//");
 lstrcat(subkey,path);//coherent
 //printf("/nsubkey formed:%s",subkey);

 LONG lFlag = RegOpenKeyEx( HKEY_USERS,subkey, NULL,KEY_ALL_ACCESS, &hResult);
 if(lFlag == ERROR_SUCCESS)
 {   
  lFlag = RegQueryValueEx(hResult, key, NULL, NULL, (LPBYTE)buff, &lpcbData);
  if(lFlag == ERROR_SUCCESS)
  {
   printf("/nbuffer:%s",buff);
   lFlag = RegCloseKey(hResult);
   if(lFlag != ERROR_SUCCESS)
   {
    printf("Close Registry Key: %s Failed!/n", subkey);
   }

   //*(buff+lpcbData+1)=0;//end the string with 0.may be no need.
   token = NULL;
   token = strstr(buff,head);
   if(token == NULL)//the address is like "10.10.10.10:8080" or "server:888" form.
   {
    token=strstr(buff,seps);
    if(token != NULL)
    {
     *token = 0; //break up the string.
     strcpy(pCurrent->pServer,buff);
     printf("/nTry:%s",pCurrent->pServer);
     pCurrent->pPort=atoi(token+1);
     printf("/npPort:%d",pCurrent->pPort);
    }
    else
    {
     GlobalFree(pCurrent);
     return false;
    }
   }
   else //address like "ftp=20.128.25.215:555;gopher=20.128.25.215:444;http=20.128.25.215:808;https=20.128.25.215:666;socks=20.128.25.215:333"
   {
    char *p = token+lstrlen(head); //at first, p point to 2 in upon example;
    token = strstr(p,segs);
    if(token != NULL)
    {
     *token = 0; //break up
    }
    token=strstr(p,seps);
    if(token != NULL)
    {
     *token = 0; //break up the string.
     strcpy(pCurrent->pServer,p);
     printf("/nTry:%s",pCurrent->pServer);
     pCurrent->pPort=atoi(token+1);
     printf("/npPort:%d",pCurrent->pPort);
    }
    else
    {
     GlobalFree(pCurrent);
     return false;
    }
   }
   // allright,if it does not return , we have got the addr,now we should resolve the addr to IP Address
   /*it seems we can't initiate the hostent derectly,so we return the string.  
   __try
   {    
    *pCurrent->server.sin_family = AF_INET;
    *pCurrent->server.sin_port = htons(atoi(port));
    *pCurrent->server.sin_addr.s_addr = inet_addr(addr);
    if(*pCurrent->server.sin_addr.s_addr == INADDR_NONE)//like www.sina.com form
    {
     hp = gethostbyname(addr);
     if (hp == NULL)
     {
      GlobalFree(pCurrent);
      pCurrent=NULL;
      printf("Can't resolve target address:[%s]./n",addr);
      return false;
     }
     memcpy(&(*pCurrent->server.sin_addr), hp->h_addr_list[0],hp->h_length);
    }
    //*pCurrent->pdNext=NULL;
    printf("/naddress we got:%s,port:%s.",addr,port);
    return true; //it's time to return,we have got the right result.
   }
   __finally
   {
    GlobalFree(pCurrent);
    pCurrent=NULL;
    return false;
   }*/
  }
  else
  {
   printf("/nQuery Registry Value: %s Failed!", key);
   lFlag = RegCloseKey(hResult);
   if(lFlag != ERROR_SUCCESS)
   {
    printf("/nClose Registry Key: %s Failed!", subkey);
    return false;
   }
   GlobalFree(pCurrent);
   return false;
  }
 }
 else
 {
  printf("Open Registry Key: %s Failed!/n",subkey);
  GlobalFree(pCurrent);
  return false;
 }
 return true;
}

void LogToFile(char *LogText)
{
 FILE *fp;
 SYSTEMTIME lpTime;
 char * LogFileName="c://log.txt";
 fp = fopen(LogFileName, "a+");
 if(fp)
 {
  GetSystemTime(&lpTime);
  fprintf(fp,"Performing Time: %d/%d/%d %d:%d:%d --> %s", lpTime.wMonth,lpTime.wDay,lpTime.wYear,lpTime.wHour,lpTime.wMinute,lpTime.wSecond,LogText);
  fclose(fp);
 }
}

//this function is used to check the proxy connection status.
//As the HKEY_USERS reg branch may have more users' information , that we may got more proxy information.
//We should test all the proxy we have got.
bool CheckProxyConnection(struct ProxyData * p)
{
 struct ProxyData * head=p;
 char* req = "GET http://www.baidu.com/ HTTP/1.0/r/n"
    "Accept: */*/r/n"
    "Accept-Language: zh-cn/r/n"
    "Pragma: no-cache/r/n"
    "If-Modified-Since: Wed, 05 Apr 2006 10:25:00 GMT/r/n"
    "If-None-Match: /"28986d-b53-44339afc/"/r/n"
    "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)/r/n"
    "Host: www.baidu.com/r/n"
    "Proxy-Connection: Keep-Alive/r/n"
    "Cookie: BAIDUID=F4138A121665C89084A8E99FD286D7B4/r/n/r/n";

 char *key = "百度——全球最大中文搜索引擎";

 
 while(head!=NULL)
 {
  if(CheckHTTPconnction(head->pServer,head->pPort,req,key))
  {
   return true;
  }
  head=head->pdNext;
 }
 printf("/nWe failed!");
 return false;
 
}

bool CheckHTTPconnction(char *hostname,int port,char * req,char * key)
{
 SOCKADDR_IN  saServer;
LPHOSTENT  lphostent;
WSADATA   wsadata;
unsigned short winsock_version;
SOCKET   hsocket;
int    nRet;

winsock_version = MAKEWORD( 2,0 );
if(WSAStartup(winsock_version,&wsadata))
{
printf("/ncan't initial socket");
return false;
}
lphostent=gethostbyname(hostname);

if(lphostent==NULL)
{
printf("/nlphostent is null");
  WSACleanup();
return false;
}

hsocket = socket(AF_INET, SOCK_STREAM, 0);
saServer.sin_family = AF_INET;
// Use def. now, need to handle general case
saServer.sin_port = htons(port);
saServer.sin_addr = *((LPIN_ADDR)*lphostent->h_addr_list);
nRet = connect(hsocket, (LPSOCKADDR)&saServer, sizeof(SOCKADDR_IN));
if (nRet == SOCKET_ERROR)
{
printf("/ncan't connect");
closesocket(hsocket);
  WSACleanup();
return false;
}
else
 {
printf("/nconnected with %s",hostname);
 }

nRet = send(hsocket, req, strlen(req), 0);
if (nRet == SOCKET_ERROR)
{
printf("/nsend() failed");
closesocket(hsocket);
  WSACleanup();
return false;
}
else
 {
printf("/nsend() OK");
 }

char dest[2048];
 int index=0;
nRet=1;
while(index<3&&nRet>0) //normally we use "<title>" section to check connection status, so it's not necessary to recive all size of the destination document.
{
  index++;
nRet=recv(hsocket,(LPSTR)dest,sizeof(dest),0);
if(nRet>0)
dest[nRet]=0;
else
dest[0]=0;
printf("/nReceived bytes:%d",nRet);
printf("/nResult:/n%s",dest);
  if(strstr(dest,key))
  {
   printf("/nWe got it!");
   closesocket(hsocket);
   WSACleanup();
   return true;
   
  }
}
 printf("/nBad luck :~( !");
 closesocket(hsocket);
 WSACleanup();
return false;
}


bool CheckIntranetConn()
{
 char* req = "GET / HTTP/1.1/r/n"
    "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*/r/n"
    "Accept-Language: zh-cn/r/n"
    "Accept-Encoding: gzip, deflate/r/n"
    "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)/r/n"
    "Host: 10.128.4.34/r/n"
    "Connection: Keep-Alive/r/n/r/n";

 char *key = "铁叉部";
 char *des = "10.128.4.34";
 int  dPort= 80;

 return CheckHTTPconnction(des,dPort,req,key);