Browse Source

feat: more paths for libc.so

master
Dnomd343 3 years ago
parent
commit
7d7ee4b89c
  1. 201
      ProxyBuilder/main.py

201
ProxyBuilder/main.py

@ -1,96 +1,105 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*-
import time import os
import ctypes import time
import random import ctypes
import socket import random
import subprocess import socket
from ProxyBuilder import Shadowsocks import subprocess
from ProxyBuilder import Shadowsocks
# TODO: find in multi path
libcPath = '/lib/libc.musl-x86_64.so.1' # for Alpine libcPaths = [
'/usr/lib64/libc.so.6', # CentOS
# TODO: TCP/UDP IPv4/IPv6 '/lib/i386-linux-gnu/libc.so.6', # Debian / Ubuntu
def __checkPortAvailable(port, host = '127.0.0.1'): # 检测端口可用性 '/lib/x86_64-linux-gnu/libc.so.6',
s = None '/lib/aarch64-linux-gnu/libc.so.6',
try: '/lib/libc.musl-x86_64.so.1', # Alpine
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ]
s.settimeout(1)
s.connect((host, int(port))) # TODO: TCP/UDP IPv4/IPv6
return False def __checkPortAvailable(port, host = '127.0.0.1'): # 检测端口可用性
except socket.error: s = None
return True try:
finally: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if s: s.settimeout(1)
s.close() s.connect((host, int(port)))
return False
def __genTaskFlag(length = 16): # 生成任务代号 except socket.error:
flag = "" return True
for i in range(0, length): finally:
tmp = random.randint(0, 15) if s:
if tmp >= 10: s.close()
flag += chr(tmp + 87) # a ~ f
else: def __genTaskFlag(length = 16): # 生成任务代号
flag += str(tmp) # 0 ~ 9 flag = ""
return flag for i in range(0, length):
tmp = random.randint(0, 15)
def __getAvailablePort(rangeStart, rangeEnd): # 获取一个空闲端口 if tmp >= 10:
if rangeStart > rangeEnd: flag += chr(tmp + 87) # a ~ f
return None else:
while True: flag += str(tmp) # 0 ~ 9
port = random.randint(rangeStart, rangeEnd) # 随机选取 return flag
if __checkPortAvailable(port):
return port def __getAvailablePort(rangeStart, rangeEnd): # 获取一个空闲端口
time.sleep(0.1) # 100ms if rangeStart > rangeEnd:
return None
def build(proxyInfo, configDir): # 构建代理节点连接 while True:
taskFlag = __genTaskFlag() port = random.randint(rangeStart, rangeEnd) # 随机选取
socksPort = __getAvailablePort(1024, 65535) # Socks5测试端口 if __checkPortAvailable(port):
if not 'type' in proxyInfo: return port
return None time.sleep(0.1) # 100ms
proxyType = proxyInfo['type'] # 节点类型
proxyInfo.pop('type') def build(proxyInfo, configDir): # 构建代理节点连接
taskFlag = __genTaskFlag()
configFile = configDir + '/' + taskFlag + '.json' # 配置文件路径 socksPort = __getAvailablePort(1024, 65535) # Socks5测试端口
if (proxyType == 'shadowsocks'): # Shadowsocks节点 if not 'type' in proxyInfo:
startCommand = Shadowsocks.load(proxyInfo, socksPort, configFile) return None
else: # 未知类型 proxyType = proxyInfo['type'] # 节点类型
return None proxyInfo.pop('type')
try: configFile = configDir + '/' + taskFlag + '.json' # 配置文件路径
exitWithMe = lambda: ctypes.CDLL(libcPath).prctl(1, 15) # SIGTERM if (proxyType == 'shadowsocks'): # Shadowsocks节点
process = subprocess.Popen(startCommand, \ startCommand = Shadowsocks.load(proxyInfo, socksPort, configFile)
stdout = subprocess.DEVNULL, \ else: # 未知类型
stderr = subprocess.DEVNULL, \ return None
preexec_fn = exitWithMe) # 子进程跟随退出
except: try:
process = subprocess.Popen(startCommand, \ for libcPath in libcPaths:
stdout = subprocess.DEVNULL, \ if os.path.exists(libcPath): # 定位libc.so文件
stderr = subprocess.DEVNULL) # prctl失败 回退正常启动 break
exitWithMe = lambda: ctypes.CDLL(libcPath).prctl(1, 15) # SIGTERM
return { # 返回连接参数 process = subprocess.Popen(startCommand, \
'flag': taskFlag, stdout = subprocess.DEVNULL, \
'port': socksPort, stderr = subprocess.DEVNULL, \
'file': configFile, preexec_fn = exitWithMe) # 子进程跟随退出
'process': process, except:
'pid': process.pid, process = subprocess.Popen(startCommand, \
} stdout = subprocess.DEVNULL, \
stderr = subprocess.DEVNULL) # prctl失败 回退正常启动
def check(taskInfo): # 检查客户端是否正常
process = taskInfo['process'] return { # 返回连接参数
if process.poll() != None: 'flag': taskFlag,
return False # 死亡 'port': socksPort,
else: 'file': configFile,
return True # 正常 'process': process,
'pid': process.pid,
def destroy(taskInfo): # 结束客户端并清理 }
process = taskInfo['process']
if process.poll() == None: # 未死亡 def check(taskInfo): # 检查客户端是否正常
process.terminate() # SIGTERM process = taskInfo['process']
while process.poll() == None: # 等待退出 if process.poll() != None:
time.sleep(1) return False # 死亡
process.terminate() else:
try: return True # 正常
os.remove(taskInfo.file) # 删除配置文件
except: pass def destroy(taskInfo): # 结束客户端并清理
process = taskInfo['process']
if process.poll() == None: # 未死亡
process.terminate() # SIGTERM
while process.poll() == None: # 等待退出
time.sleep(1)
process.terminate()
try:
os.remove(taskInfo.file) # 删除配置文件
except: pass

Loading…
Cancel
Save