├── .gitignore ├── LICENSE ├── README.md ├── myscan.c └── myscan.exe /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # myscan 2 | 多线程扫描ip段端口程序 3 | 4 | 命令行下: 5 | ``` 6 | myscan -p Port1[,Port2,Port3...] [-t Thread](default 10) [-d] (DEBUG) StartIp EndIp 7 | ``` 8 | Example: 9 | ``` 10 | myscan -p 80 192.168.1.1 192.168.1.254 11 | 12 | myscan -p 21,22,23,80,443,8080 -t 256 192.168.1.1 192.168.1.254 13 | ``` 14 | 请确保 StartIp 和 EndIp 为最后两项 15 | 16 | Please make sure that StartIp&EndIp are the last options. 17 | -------------------------------------------------------------------------------- /myscan.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #define DEFAULT_THREADS 10 //默认线程数 11 | unsigned int portlist[65536]; //端口池,portlist[0]为需要测试的端口数 12 | unsigned int Threads = DEFAULT_THREADS; //线程数 13 | int debug = 0; 14 | struct ScanData //分配给线程的数据 15 | { 16 | unsigned int ip; 17 | int port; 18 | }; 19 | const struct ScanData NILDATA; //初始化用的空数据 20 | pthread_attr_t t_c; //线程属性 21 | void usage(); 22 | void Init(); 23 | unsigned int getip(char *); 24 | char *ipback(unsigned int); 25 | void scan(unsigned int, unsigned int, unsigned int); 26 | void *threadscan(void *); 27 | void usage() 28 | { 29 | printf("Usage:\n" 30 | "program -p Port1[,Port2,Port3...] [-t Thread](default 10) [-d](DEBUG) StartIp EndIp\n" 31 | "Example:myscan -p 80 192.168.1.1 192.168.1.254\n" 32 | " myscan -p 21,22,23,80,443,8080 -t 256 192.168.1.1 192.168.1.254\n"); 33 | } 34 | void Init() 35 | { 36 | WSADATA wd; 37 | int ret = 0; 38 | ret = WSAStartup(MAKEWORD(2, 2), &wd); /*1.初始化操作*/ 39 | if (ret != 0) 40 | { 41 | printf("Init Fail"); 42 | exit(1); 43 | } 44 | if (HIBYTE(wd.wVersion) != 2 || LOBYTE(wd.wVersion) != 2) 45 | { 46 | printf("Init Fail"); 47 | WSACleanup(); 48 | exit(1); 49 | } 50 | 51 | pthread_attr_init(&t_c); //初始化线程属性 52 | pthread_attr_setdetachstate(&t_c, PTHREAD_CREATE_DETACHED); //设置线程属性 53 | } 54 | char *ipback(unsigned int ip) //把10进制无符号整形ip转换为点IP 55 | { 56 | char *ipstr = (char *)malloc(17 * sizeof(char)); 57 | unsigned int ip_temp_numbr = 24, ip_int_index[4]; 58 | 59 | for (int j = 0; j < 4; j++) 60 | { 61 | ip_int_index[j] = (ip >> ip_temp_numbr) & 0xFF; 62 | ip_temp_numbr -= 8; 63 | } 64 | sprintf(ipstr, "%d.%d.%d.%d", ip_int_index[0], ip_int_index[1], ip_int_index[2], ip_int_index[3]); 65 | return ipstr; 66 | } 67 | unsigned int getip(char *ip) //把IP地址转换为10进制无符号整形 68 | { 69 | char myip[20] = ""; 70 | strcpy(myip, ip); 71 | char str_ip_index[4] = ""; 72 | int k = 3, j = 0; 73 | unsigned int ip_add = 0; 74 | for (int i = 0; i <= strlen(myip); i++) 75 | { 76 | if (myip[i] == '.' || myip[i] == '\0') 77 | { 78 | unsigned int ip_int = atoi(str_ip_index); 79 | if (ip_int < 0 || ip_int > 255) 80 | { 81 | 82 | printf("!!!IP ERROR!!! Not regular IP\n"); 83 | exit(1); 84 | } 85 | ip_add += (ip_int * (unsigned int)(pow(256.0, k))); 86 | k--; 87 | for (int x = 0; x < 4; x++) 88 | str_ip_index[x] = '\0'; 89 | j = 0; 90 | continue; 91 | } 92 | str_ip_index[j] = myip[i]; 93 | j++; 94 | } 95 | return ip_add; 96 | } 97 | void scan(unsigned int StartIp, unsigned int EndIp, unsigned int Thread) 98 | { 99 | if (StartIp > EndIp) 100 | { 101 | usage(); 102 | printf("!!!ERROR!!! Your StartIp is bigger than your EndIp.\n"); 103 | exit(1); 104 | } 105 | int port_p = 1; //用于循环端口 106 | for (int i = StartIp; i <= EndIp;) //i为当前的ip(无符号整型式) 107 | { 108 | int last = EndIp - i; //last为每组的数量 109 | if (last >= Thread) 110 | { 111 | last = Thread; 112 | } 113 | else if (last == 0) 114 | last = 1; 115 | struct ScanData pData[last]; 116 | for (int k = 0; k < last; k++) 117 | pData[k] = NILDATA; //初始化扫描数据为空 118 | pthread_t t[last]; 119 | for (int j = 0; j < last; j++) 120 | { 121 | pData[j].ip = i; 122 | pData[j].port = portlist[port_p]; 123 | port_p++; 124 | if (port_p > portlist[0]) 125 | { 126 | port_p = 1; 127 | i++; 128 | } 129 | if (pthread_create(&t[j], &t_c, threadscan, (void *)&pData[j]) != 0)//创建线程 130 | printf("\nCREATE THREAD ERROR\n"); 131 | else 132 | pthread_join(t[j], NULL); 133 | Sleep(10); 134 | } 135 | Sleep(1000); 136 | } 137 | Sleep(3000); 138 | } 139 | void *threadscan(void *sd) 140 | { 141 | struct ScanData *pa = (struct ScanData *)sd; 142 | char ip[20] = ""; 143 | sprintf(ip, "%u", pa->ip); 144 | if (debug) 145 | printf("Testing %-16s %d ...\n", ipback(pa->ip), pa->port); 146 | SOCKET c; 147 | SOCKADDR_IN saddr; 148 | 149 | /*2.创建客户端socket*/ 150 | c = socket(AF_INET, SOCK_STREAM, 0); 151 | /*3.定义要连接的服务端信息*/ 152 | saddr.sin_addr.S_un.S_addr = inet_addr(ip); 153 | saddr.sin_family = AF_INET; 154 | saddr.sin_port = htons(pa->port); 155 | /*4.连接服务端*/ 156 | if (connect(c, (SOCKADDR *)&saddr, sizeof(SOCKADDR)) != -1) 157 | { 158 | printf("%-16s %d Open\n", ipback(pa->ip), pa->port); 159 | } 160 | closesocket(c); 161 | pthread_exit(NULL); 162 | return NULL; 163 | } 164 | int main(int argc, char **argv) 165 | { 166 | 167 | Init(); 168 | char opt; 169 | if (argc < 4) //ProgramName -pPort StartIp EndIp 170 | { 171 | usage(); 172 | WSACleanup(); 173 | return 1; 174 | } 175 | while ((opt = getopt(argc, argv, "p:t:d")) != -1) 176 | { 177 | switch (opt) 178 | { 179 | case 'p': //port 180 | { 181 | portlist[0] = 1; 182 | char *p = NULL; 183 | char *optarg_copy = strdup(optarg); //copy 184 | for (p = optarg_copy; *p != '\0'; p++) 185 | { 186 | if (*p == ',' && *(p + 1) != ',' && *(p + 1) != '\0') //计算输入的端口数 187 | portlist[0]++; 188 | else if (*p < '0' || *p > '9') //检查合法 189 | { 190 | printf("!!!PORT ERROR!!! Check your port set.\n"); 191 | free(optarg_copy); 192 | exit(1); 193 | } 194 | } 195 | 196 | int i = 1; 197 | if (portlist[0] != 1) //输入的端口不唯一 198 | { 199 | if ((p = strtok(optarg_copy, ",")) != NULL) //分割字符串,分离端口 200 | { 201 | int temp = atoi(p); 202 | if (temp <= 0 || temp > 65535) 203 | { 204 | printf("!!!PORT ERROR!!! Check your port set.\n"); 205 | free(optarg_copy); 206 | exit(1); 207 | } 208 | portlist[i++] = temp; 209 | while ((p = strtok(NULL, ",")) != NULL) //strtok用法:第一次为字符串,后面用NULL 210 | { 211 | int temp = atoi(p); 212 | if (temp <= 0 || temp > 65535) 213 | { 214 | printf("!!!PORT ERROR!!! Check your port set.\n"); 215 | free(optarg_copy); 216 | exit(1); 217 | } 218 | portlist[i++] = temp; 219 | } 220 | } 221 | } 222 | else 223 | { 224 | int temp = atoi(optarg_copy); 225 | if (temp <= 0 || temp > 65535) 226 | { 227 | printf("!!!PORT ERROR!!! Check your port set.\n"); 228 | free(optarg_copy); 229 | exit(1); 230 | } 231 | portlist[i++] = temp; 232 | } 233 | free(optarg_copy); 234 | break; 235 | } 236 | case 't': //thread 237 | { 238 | int temp = atoi(optarg); 239 | if (temp <= 0) 240 | { 241 | printf("!!!THREAD ERROR!!! Check your thread set."); 242 | exit(1); 243 | } 244 | else 245 | Threads = temp; 246 | break; 247 | } 248 | case 'd': //debug 249 | debug = 1; 250 | break; 251 | default: 252 | usage(); 253 | exit(1); 254 | break; 255 | } 256 | } 257 | scan(getip(argv[argc - 2]), getip(argv[argc - 1]), Threads); 258 | WSACleanup(); 259 | return 0; 260 | } -------------------------------------------------------------------------------- /myscan.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobackdoor/myscan/4fb476c03fa09fd5f714d689754f6d09b681f10c/myscan.exe --------------------------------------------------------------------------------