3838
3939def tableExists (tableFile , regex = None ):
4040 tables = getFileItems (tableFile , lowercase = Backend .getIdentifiedDbms () in (DBMS .ACCESS ), unique = True )
41- retVal = []
4241
4342 infoMsg = "checking table existence using items from '%s'" % tableFile
4443 logger .info (infoMsg )
@@ -54,21 +53,25 @@ def tableExists(tableFile, regex=None):
5453 tables .append (word )
5554
5655 tables = filterListValue (tables , regex )
57- count = [0 ]
58- length = len (tables )
59- threads = []
60- items = set ()
61- tbllock = threading .Lock ()
62- iolock = threading .Lock ()
63- kb .threadContinue = True
64- kb .bruteMode = True
56+
57+ threadData = getCurrentThreadData ()
58+ threadData .shared .count = 0
59+ threadData .shared .limit = len (tables )
60+ threadData .shared .outputs = []
61+ threadData .shared .unique = set ()
6562
6663 def tableExistsThread ():
67- while count [0 ] < length and kb .threadContinue :
68- tbllock .acquire ()
69- table = safeSQLIdentificatorNaming (tables [count [0 ]])
70- count [0 ] += 1
71- tbllock .release ()
64+ threadData = getCurrentThreadData ()
65+
66+ while kb .threadContinue :
67+ kb .locks .countLock .acquire ()
68+ if threadData .shared .count < threadData .shared .limit :
69+ table = safeSQLIdentificatorNaming (tables [threadData .shared .count ])
70+ threadData .shared .count += 1
71+ kb .locks .countLock .release ()
72+ else :
73+ kb .locks .countLock .release ()
74+ break
7275
7376 if conf .db and METADB_SUFFIX not in conf .db :
7477 fullTableName = "%s%s%s" % (conf .db , '..' if Backend .getIdentifiedDbms () in (DBMS .MSSQL , DBMS .SYBASE ) else '.' , table )
@@ -77,12 +80,12 @@ def tableExistsThread():
7780
7881 result = inject .checkBooleanExpression ("%s" % safeStringFormat ("EXISTS(SELECT %d FROM %s)" , (randomInt (1 ), fullTableName )))
7982
80- iolock .acquire ()
83+ kb . locks . ioLock .acquire ()
8184
82- if result and table .lower () not in items :
83- retVal .append (table )
85+ if result and table .lower () not in threadData . shared . unique :
86+ threadData . shared . outputs .append (table )
8487
85- items .add (table .lower ())
88+ threadData . shared . unique .add (table .lower ())
8689
8790 dataToSessionFile ("[%s][%s][%s][TABLE_EXISTS][%s]\n " % (conf .url ,\
8891 kb .injection .place , safeFormatString (conf .parameters [kb .injection .place ]),\
@@ -94,77 +97,27 @@ def tableExistsThread():
9497 dataToStdout (infoMsg , True )
9598
9699 if conf .verbose in (1 , 2 ):
97- status = '%d/%d items (%d%s)' % (count [ 0 ], length , round (100.0 * count [ 0 ] / length ), '%' )
100+ status = '%d/%d items (%d%s)' % (threadData . shared . count , threadData . shared . limit , round (100.0 * threadData . shared . count / threadData . shared . limit ), '%' )
98101 dataToStdout ("\r [%s] [INFO] tried %s" % (time .strftime ("%X" ), status ), True )
99102
100- iolock .release ()
101-
102- if conf .threads > 1 :
103- infoMsg = "starting %d threads" % conf .threads
104- logger .info (infoMsg )
105- else :
106- while True :
107- message = "please enter number of threads? [Enter for %d (current)] " % conf .threads
108- choice = readInput (message , default = str (conf .threads ))
109- if choice and choice .isdigit ():
110- if int (choice ) > MAX_NUMBER_OF_THREADS :
111- errMsg = "maximum number of used threads is %d avoiding possible connection issues" % MAX_NUMBER_OF_THREADS
112- logger .critical (errMsg )
113- else :
114- conf .threads = int (choice )
115- break
116-
117- if conf .threads == 1 :
118- warnMsg = "running in a single-thread mode. This could take a while."
119- logger .warn (warnMsg )
120-
121- # Start the threads
122- for numThread in range (conf .threads ):
123- thread = threading .Thread (target = tableExistsThread , name = str (numThread ))
124- thread .start ()
125- threads .append (thread )
103+ kb .locks .ioLock .release ()
126104
127- # And wait for them to all finish
128105 try :
129- alive = True
106+ runThreads ( conf . threads , tableExistsThread , threadChoice = True )
130107
131- while alive :
132- alive = False
133-
134- for thread in threads :
135- if thread .isAlive ():
136- alive = True
137- thread .join (5 )
138108 except KeyboardInterrupt :
139- kb .threadContinue = False
140- kb .threadException = True
141-
142- print
143- logger .debug ("waiting for threads to finish" )
144-
145- warnMsg = "user aborted during common table existence check. "
146- warnMsg += "sqlmap will display some tables only"
109+ warnMsg = "user aborted during table existence "
110+ warnMsg += "check. sqlmap will display partial output"
147111 logger .warn (warnMsg )
148112
149- try :
150- while (threading .activeCount () > 1 ):
151- pass
152-
153- except KeyboardInterrupt :
154- raise sqlmapThreadException , "user aborted"
155- finally :
156- kb .bruteMode = False
157- kb .threadContinue = True
158- kb .threadException = False
159-
160113 clearConsoleLine (True )
161114 dataToStdout ("\n " )
162115
163- if not retVal :
116+ if not threadData . shared . outputs :
164117 warnMsg = "no table(s) found"
165118 logger .warn (warnMsg )
166119 else :
167- for item in retVal :
120+ for item in threadData . shared . outputs :
168121 if not kb .data .cachedTables .has_key (conf .db ):
169122 kb .data .cachedTables [conf .db ] = [item ]
170123 else :
0 commit comments