Threads in fremdem Prozess killen

Hi,

Wie der Titel schon sagt, versuche ich Threads in einem fremden Prozess zu killen.
Alle Threads, die beendet werden sollen, sind im gleichen Modul (also einer geladen DLL).

Ein Bekannter hat mir vorgeschlagen, dass ich einfach diese DLL entladen soll, da deren Threads dann
abstürzten sollten. Da ich aber keine Funktion gefunden habe, um Module in einem fremden Prozess zu entladen,
werde ich nun versuchen die Threads einfach manuell zu beenden.
Eine DLL-Injection um FreeLibrary() aufzurufen, wäre mir dafür zu komplex.

Nun wollte ich folgendermaßen vorgehen:
Mittels Toolhelp die PID ermitteln, alle Threads auflisten und die betroffenen Threads
dann mittels OpenThread() und TerminateThread() beenden.

Meine frage ist nun: Wie kann ich ermitteln, von welchem Modul ein Thread ausgeht?
In den Structs, die ich von Toolhelp bekomme befindet sich lediglich die ThreadID.

Danke schonmal im Vorraus!
 
man ptrace

duerfte das sein was du suchst.
 
Danke erstmal für deine Antwort.

Aber leider nein. Es handelt sich um zum einen um Windows und zum anderen suche Ich eine Möglichkeit
den DLL-Namen des Threads per WinAPI zu ermitteln und kein eigenständiges Programm dazu.
 
Also vorher noch alle Module auflisten:
http://msdn.microsoft.com/en-us/library/ms682489(VS.85).aspx
MODULEENTRY liefert Größe in Bytes + Handle (was nichts anderes ist, als die Adresse des Moduls im Speicher der Anwendung)
http://msdn.microsoft.com/en-us/library/ms684225(VS.85).aspx
damit hast Du schon mal den nötigen "Wirkungsbereich" der DLL.

Nun die Threads durchgehen und für einen Thread
NtQueryInformationThread aufrufen:
http://undocumented.ntinternals.net... Objects/Thread/NtQueryInformationThread.html
mit der THREAD_INFORMATION_CLASS=ThreadQuerySetWin32StartAddress sollte man die Adresse herausbekommen.
also (in etwa):
Code:
hThread=OpenThread(...);
hDLL=LoadLibrary("ntdll.dll");
funcPointer=GetProcAddress(hDLL,"NtQueryInformationThread");

status=funcPointer(hThread,ThreadQuerySetWin32StartAddress,&resultBuffer,sizeof(resultBuffer),NULL)
if (status!=0)  ...  //nur Vermutung, da meistens die Rückgabe bei Erfolg ungleich 0 ist.
return resultBuffer  //muss 4 Bytes groß sein;
Jetzt muss man nur noch schauen, in welchem "Bereich" der vorher ermittelten DLLs die Startadresse liegt.
Was die vorgestellten Funktionsnamen und Flags angeht - da musst Du nach dem Header suchen, habe leider auf die schnelle bei mir keine Definition gefunden.
 
Wenn du eine DLL in einem Fremden Prozess entladen willst, musste ja nicht unbedingt eine injecten. Ein kleines bisschen Code reicht da vollkommen aus, dh prinzipiell so um die 40 Bytes, alles andere ist nur der Dllname. Hab mal dazu ein bisschen Code geschrieben:

Code:
#include <windows.h>

typedef HMODULE (WINAPI *GETMODULEHANDLE)(LPCTSTR);
typedef BOOL (WINAPI *FREELIBRARY)(HMODULE);

typedef struct _unloadi
{
   GETMODULEHANDLE   _GetModuleHandle;
   char              name[256];
   FREELIBRARY       _FreeLibrary;
}unloadi;

void unload(unloadi *k)
{
   k->_FreeLibrary(k->_GetModuleHandle(k->name));
}
void sizeofunload(void)
{ }

int SetDebugPrivileges(void)
{
    TOKEN_PRIVILEGES priv;
    HANDLE           hProc, hToken;
    
    hProc=OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());

    OpenProcessToken(hProc, TOKEN_ALL_ACCESS, &hToken);
    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid);

    priv.PrivilegeCount = 1;
    priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken, FALSE, &priv, 0, NULL, NULL);

    CloseHandle(hProc);
    CloseHandle(hToken);
    return(0);
}

int main(int argc, char *argv[])
{
   unloadi           k;
   HANDLE            hProc;
   LPVOID            r_addr, param;
   DWORD             szNeeded;
   
   if(argc!=3)
   {
      
      printf("usage: %s <pid> <modname>\nsizeof unload code %d Bytes", argv[0],\
            ((DWORD)sizeofunload-(DWORD)unload+sizeof(k)));
      return 0;
   }
   
   SetDebugPrivileges();
   k._GetModuleHandle=(GETMODULEHANDLE)GetProcAddress(GetModuleHandle(("KERNEL32.DLL")),\
                                                      "GetModuleHandleA");
   k._FreeLibrary=(FREELIBRARY)GetProcAddress(GetModuleHandle(("KERNEL32.DLL")),\
                                                "FreeLibrary");
   strncpy(k.name, argv[2], 256);
   szNeeded=((DWORD)sizeofunload-(DWORD)unload+sizeof(k));
   if(NULL==(hProc=OpenProcess(PROCESS_ALL_ACCESS, FALSE, atoi(argv[1]))))
   {
      printf("[-] error opening process\n");
      return 0;
   }
   if(NULL==(r_addr=VirtualAllocEx(hProc, NULL, (SIZE_T)szNeeded, MEM_RESERVE|MEM_COMMIT,\
                                    PAGE_EXECUTE_READWRITE)))
   {
      printf("[-] error allocating mem\n");
      return 0;
   }
   param=(LPVOID)((DWORD)r_addr+((DWORD)sizeofunload-(DWORD)unload));
   WriteProcessMemory(hProc, r_addr, unload, (DWORD)sizeofunload-(DWORD)unload, 0);
   WriteProcessMemory(hProc, param, &k, (DWORD)sizeof(k), 0);
   CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)r_addr, param, 0, NULL);
   
   return 0;
}

Theoretisch koennte man den Unloadcode noch viel kleiner machen indem man annimmt, dass die DLL immer an die Adr, wie sie im PE-Header (s. ImageBase) vorgegeben ist, geladen wird. Da dies aber nicht immer der Fall sein muss, habe ich mich fuer die Variante mit GetModuleHandle entschieden.

Ich hoffe das Prinzip des Codes ist klar, ansonsten einfach fragen.
 
Hi,

danke euch beiden für die Antworten!

Du hast Recht, dmesg, der eingeschleuste Code kann auch direkt die DLLs entladen,
da brauche ich gar keine extra nachzuladen, die das dann übernimmt.

Ich werde aber bei der Methode von CDW bleiben, da ich die Threads mittlerweile nur suspende,
damit spare ich mich dann einen Neustart der Anwendung wenn ich sie wieder brauche. ;)
 
Zurück
Oben