11import sys
22import ctypes
3- from PyQt5 .QtWidgets import (QApplication , QMainWindow , QPushButton , QVBoxLayout , QWidget , QLineEdit , QLabel ,
4- QFileDialog , QDialog , QListWidget )
5-
3+ from PyQt5 .QtWidgets import (QApplication , QMainWindow , QPushButton , QVBoxLayout , QWidget , QLabel ,
4+ QFileDialog , QDialog , QListWidget , QCheckBox , QTextEdit )
65import psutil
76from pyinjector import inject
87
@@ -23,37 +22,45 @@ def populate_process_list(self):
2322
2423 def process_selected (self , item ):
2524 process_info = item .text ().split (" (PID: " )
26- process_name = process_info [0 ]
25+ process_name = process_info [0 ][: - 1 ] # Remove the trailing ")"
2726 self .parent ().process_name_input .setText (process_name )
2827 self .accept ()
2928
3029class DLLInjectorGUI (QMainWindow ):
3130 def __init__ (self ):
3231 super ().__init__ ()
32+ self .settings_file = "dll_paths.txt"
3333 if not self .is_admin ():
3434 self .request_admin ()
3535 sys .exit ()
3636
3737 self .setWindowTitle ('DLL Injector GUI' )
38- self .setGeometry (100 , 100 , 320 , 250 )
38+ self .setGeometry (100 , 100 , 320 , 300 ) # Adjusted for additional UI elements
3939 self .initUI ()
40+ self .load_dll_paths ()
4041
4142 def initUI (self ):
4243 layout = QVBoxLayout ()
4344
4445 self .process_name_label = QLabel ('Process Name:' )
45- self .process_name_input = QLineEdit ()
46+ self .process_name_input = QTextEdit ()
47+ self .process_name_input .setText ("metin2client.exe" )
48+ self .process_name_input .setPlaceholderText ("Enter process name here" )
49+ self .process_name_input .setMaximumHeight (30 )
4650
4751 self .select_process_button = QPushButton ('Select Process' )
4852 self .select_process_button .clicked .connect (self .openProcessListDialog )
4953
50- self .dll_path_label = QLabel ('DLL Path:' )
51- self .dll_path_input = QLineEdit ()
54+ self .dll_path_label = QLabel ('DLL Path(s):' )
55+ self .dll_path_input = QTextEdit ()
56+ self .dll_path_input .setPlaceholderText ("Enter DLL paths, one per line" )
5257
5358 self .browse_button = QPushButton ('Browse...' )
5459 self .browse_button .clicked .connect (self .openFileDialog )
5560
56- self .inject_button = QPushButton ('Inject DLL' )
61+ self .remember_dlls_checkbox = QCheckBox ("Remember DLLs" )
62+
63+ self .inject_button = QPushButton ('Inject DLL(s)' )
5764 self .inject_button .clicked .connect (self .onInjectButtonClicked )
5865
5966 self .status_label = QLabel ('Status: Awaiting input...' )
@@ -64,6 +71,7 @@ def initUI(self):
6471 layout .addWidget (self .dll_path_label )
6572 layout .addWidget (self .dll_path_input )
6673 layout .addWidget (self .browse_button )
74+ layout .addWidget (self .remember_dlls_checkbox )
6775 layout .addWidget (self .inject_button )
6876 layout .addWidget (self .status_label )
6977
@@ -77,30 +85,53 @@ def openProcessListDialog(self):
7785
7886 def openFileDialog (self ):
7987 options = QFileDialog .Options ()
80- dll_path , _ = QFileDialog .getOpenFileName (self , "Select DLL file" , "" , "DLL Files (*.dll);;All Files (*)" , options = options )
81- if dll_path :
82- self .dll_path_input .setText (dll_path )
88+ dll_paths , _ = QFileDialog .getOpenFileNames (self , "Select one or more DLL files" , "" , "DLL Files (*.dll);;All Files (*)" , options = options )
89+ if dll_paths :
90+ self .dll_path_input .setText ("\n " .join (dll_paths ))
91+
92+ def load_dll_paths (self ):
93+ try :
94+ with open (self .settings_file , "r" ) as file :
95+ dll_paths = file .read ().strip ()
96+ if dll_paths :
97+ self .dll_path_input .setText (dll_paths )
98+ self .remember_dlls_checkbox .setChecked (True )
99+ except FileNotFoundError :
100+ pass
101+
102+ def save_dll_paths (self ):
103+ if self .remember_dlls_checkbox .isChecked ():
104+ paths = self .dll_path_input .toPlainText ().strip ()
105+ with open (self .settings_file , "w" ) as file :
106+ file .write (paths )
107+ else :
108+ with open (self .settings_file , "w" ) as file :
109+ file .write ("" ) # Clear the stored paths if the checkbox is not checked
83110
84111 def find_process_id (self , process_name ):
85112 for proc in psutil .process_iter (['name' , 'pid' ]):
86- if proc .info ['name' ] == process_name :
113+ if proc .info ['name' ]. lower () == process_name . lower () :
87114 return proc .info ['pid' ]
88115 return None
89116
90- def inject_dll (self , pid , dll_path ):
91- try :
92- inject (pid , dll_path )
93- self .status_label .setText ('DLL injected successfully.' )
94- except Exception as e :
95- self .status_label .setText (f'Failed to inject DLL: { e } ' )
117+ def inject_dll (self , pid , dll_paths_str ):
118+ dll_paths = dll_paths_str .split ('\n ' )
119+ for dll_path in dll_paths :
120+ try :
121+ inject (pid , dll_path .strip ())
122+ self .status_label .setText (f'DLL injected successfully: { dll_path .strip ()} ' )
123+ except Exception as e :
124+ self .status_label .setText (f'Failed to inject DLL: { e } ' )
125+ break # Stop on the first error
96126
97127 def onInjectButtonClicked (self ):
98- process_name = self .process_name_input .text ()
99- dll_path = self .dll_path_input .text ()
128+ process_name = self .process_name_input .toPlainText (). strip ()
129+ dll_paths_str = self .dll_path_input .toPlainText ()
100130 pid = self .find_process_id (process_name )
101131 if pid :
102132 self .status_label .setText (f'Found { process_name } with PID: { pid } ' )
103- self .inject_dll (pid , dll_path )
133+ self .inject_dll (pid , dll_paths_str )
134+ self .save_dll_paths ()
104135 else :
105136 self .status_label .setText (f'Could not find process: { process_name } ' )
106137
@@ -117,4 +148,4 @@ def request_admin(self):
117148 app = QApplication (sys .argv )
118149 gui = DLLInjectorGUI ()
119150 gui .show ()
120- sys .exit (app .exec_ ())
151+ sys .exit (app .exec_ ())
0 commit comments