Selbstlöschende Dll möglich?

bigbang

Grünschnabel
Ich weiss das exe dateien sich selbst löschen können, nun muss ich das gleiche auch bei einer dll machen.

mit folgendem code war es mir möglich meine test.exe sich selbst löschen zu lassen.

Code:
   BOOL SelfDelete() 
   { 
      TCHAR szFile[MAX_PATH], szCmd[MAX_PATH]; 

      if ((GetModuleFileName(0, szFile, MAX_PATH) != 0) && (GetShortPathName(szFile, szFile, MAX_PATH) != 0)) 
      { 
         lstrcpy(szCmd, "/c del "); 
         lstrcat(szCmd, szFile); 
         lstrcat(szCmd, " >> NUL"); 

         if ((GetEnvironmentVariable("ComSpec", szFile, MAX_PATH) != 0) && ((INT)ShellExecute(0, 0, szFile, szCmd, 0, SW_HIDE) > 32)) 
         return TRUE; 
      } 
      return FALSE; 
   }

und dann der aufruf vom bool selfdelete:


Code:
      if (!bWasIchHierChecke(meinparam1, meinparam2, meinparam3, meinparam4, meinparam5)) 
      { 
         SelfDelete(); 
         ExitProcess(0); 
         //shutdownpc();//shutdowns pc if wrong serial 
      }


nun muss ich das gleiche auch bei meiner dll machen. meine dll wird in einen target process geladen. meine dll ist in unicode gecodet. meine dll checkt wie auch meine exe ihre datei integrität, dann ein paar hardware seriennummern und noch ein paar andere checks, falls irgendetwas nicht im rahmen des gültigen ist, soll sich die dll selbst löschen, den prozess in den sie geladen wurde beenden, den computer runterfahren. alles ausser dem selbst löschen klappt.

hier der code den ich benutze, damit die dll ihren pfad und aktuellen namen weiss, damit sie sich selbst checken kann.

Code:
BOOL APIENTRY DllMain(HMODULE hDll, DWORD Reason, PVOID lpReserved) 
{ 
   if (Reason == DLL_PROCESS_ATTACH) 
   { 
      GetModuleFileNameA((HMODULE)hDll, bfr, sizeof(bfr)); 

      DisableThreadLibraryCalls(hDll); ....u.s.w.


Code:
FILE *pDLLFile;//pointer to DLL 
... 

pDLLFile = fopen(bfr, "rb");//open .DLL for read in binary mode


meine frage ist, wie kann ich es schaffen das sich die dll selbst löschen kann?
ich hab die dll mit dem self delete code in den target prozess geladen, ich habs auch geschafft das der target prozess nach dem ExitProcess(0); befehl, gelöscht wurde, was nicht meine absicht war, es wäre nun schön wenn anstelle der target.exe die geladene Dll gelöscht wird.

jede hilfe und jeder anstoss zur lösung des problems und wenn er noch so klein ist sehr willkommen. und dank schon mal im voraus für jede hilfe.
 
Ich denke mal dein Problem liegt beim GetModuleFilename. Du übergibst da 0, deshalb wird der Pfad der exe zurück gegeben. Übergib hier das Modul der DLL Datei (hDLL in deiner DLLMain).
 
entschuldigung, ich hab vergessen zu erwähnen das ich das, wie du gesagt hast mit dem hDll anstatt 0 in GetModuleFileNameW schon so gemacht habe.
hier das kurze beispiel was ich gerade in meiner dll benutze:
Code:
	BOOL SelfDelete()
	{
		TCHAR szCmd[MAX_PATH];
		if ((GetModuleFileNameW((HMODULE)hDll, path, sizeof(path)) != 0) &&  (GetShortPathNameW(path, path, sizeof(path)) != 0))
		{
			lstrcpy(szCmd, L"/c del ");
			lstrcat(szCmd, path);
			lstrcat(szCmd, L" >> NUL");
			//MessageBox(NULL, path, TEXT("Info"), 0); 
			//MessageBox(NULL, szCmd, TEXT("Info"), 0); 
			if ((GetEnvironmentVariable(L"ComSpec", path, MAX_PATH) != 0) && ((INT)ShellExecute(0, 0, path, szCmd, 0, SW_HIDE) > 32))
			return TRUE;
		}
		return FALSE;
	}

wie man sehen kann, habe ich tests mit einer messagebox gemacht, ich wollte mir dabei einmal den pfad und dann noch die commandline anzeigen lassen. das merkwürdige dabei ist, obwohl ich hDll benutze zeigt mir die messagebox als pfad, den pfad zur .exe in der meine dll geladen ist. wenn ich aber die messagebox in die dllmain verlege, zeigt sie mir dann den korrekten pfad zur dll an. was mir auch noch in den sinn gekommen ist, warum sich die dll ausser vielleicht einer falschen pfadangabe nicht löschen lässt, ist eine möglichkeit das windows die dll nicht zum löschen freigeben will, weil ja der zielprozess, in den die dll geladen wurde sie noch benützt. ich kann es mir aber nicht denken, ich schliesse doch sofort nach dem lösch befehl den ziel prozess.

ich experimentiere gerade ob ich nicht was anderes zu testzwecken löschen könnte. z.b.
Code:
TCHAR tex[MAX_PATH] = L"C:\\Dokumente und Einstellungen\\a\\Desktop\\lol\\test.txt";
und dann halt
Code:
lstrcat(szCmd, tex);
damit könnte ich herausfinden ob der code löschen kann oder nicht, zumindest hat mir die messagebox den korrekten pfad zur test.txt anzeigen können. also die test.txt müsste sich auf alle fälle löschen lassen, da kein prozess ein handle auf sie hat.
 
Zuletzt bearbeitet:
mods ihr könnt den thread schliessen. hab's geschafft und es funtioniert super. meine dll kann sich nun selbst löschen. der code dazu ist in der dll, ein paar checks starten dann die selbst lösch funktion, egal ob ein schreibschutz auf der dll besteht oder nicht, sie wird sich löschen.
 
Ziemlich cool wäre es ja dann, wenn du deinen Mitmenschen erzähltest, wie du das hinbekommen hast, weil ja andere Leute ein ähnliches Problem haben können.

Und den Thread kannst du selbst schließen, indem du auf den schönen Button am Ende der Seite klickst.;-)
 
Martin Schroeder hat gesagt.:
Ziemlich cool wäre es ja dann, wenn du deinen Mitmenschen erzähltest, wie du das hinbekommen hast, weil ja andere Leute ein ähnliches Problem haben können.

Und den Thread kannst du selbst schließen, indem du auf den schönen Button am Ende der Seite klickst.;-)
stimmt.
der folgende code ist gekürzt worden von mir aufs wesentliche, ohne die specials.
//in Main.cpp
Code:
bool APIENTRY DllMain(HMODULE hDll, DWORD dwReason, PVOID lpReserved)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
		DisableThreadLibraryCalls(hDll);

		if (!bChecked)
		{
			ck.Check();
			bChecked = 1;
		}
		StartofregularDll();
	}
	else if (dwReason == DLL_PROCESS_DETACH)
	{
		SelfDelete(hDll);
	}
	return TRUE;
}
//in Main.h
Code:
bool bChecked = 0;
bool bDelete  = 0;
DWORD pid;

BOOL ExitProcess(DWORD pid)
{
	pid = GetCurrentProcessId();
	HANDLE hp = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);

    if (hp != NULL)
    {
        BOOL bRet = TerminateProcess(hp, 1);
        CloseHandle(hp);

        return(bRet);
    }

    return(FALSE);
}

void SelfDelete(HMODULE hDll)
{
	char deldll[MAX_PATH];
	char delCmd[MAX_PATH];

	GetModuleFileNameA(hDll, deldll, MAX_PATH);
	GetShortPathNameA(deldll, deldll, MAX_PATH);
	SetFileAttributesA(deldll, FILE_ATTRIBUTE_NORMAL);

	if (bDelete)
	{
		strcpy(delCmd, "/c del ");
		strcat(delCmd, " >> NUL");
		strcat(delCmd, "COMSPEC");

		GetEnvironmentVariableA("ComSpec", deldll, MAX_PATH);
		((INT)ShellExecuteA(0, 0, deldll, delCmd, 0, SW_HIDE) > 32);
	}

		if (!GetModuleFileNameA(0, deldll, MAX_PATH))
		{
			ExitProcess(pid);
		}

 		if (!GetShortPathNameA(deldll, deldll, MAX_PATH))
		{
			ExitProcess(pid);
		}

		if (!GetEnvironmentVariableA("ComSpec", deldll, MAX_PATH))
		{
			ExitProcess(pid);
		}

		if (!((INT)ShellExecuteA(0, 0, deldll, delCmd, 0, SW_HIDE) > 32))
		{
			ExitProcess(pid);
		}
}
//in class object ck in CK.h
Code:
bool CheckOk(char* Parameter1)
{
	if (strcmp((char*)Parameter1, storedParameter1) == 0)
	{
		return TRUE;
	}
	else
		return FALSE;
}

void Check()
{
	if (!CheckOk(Parameter1))
	{
		ExitProcess(pid);
		bDelete = 1;
	}
	bChecked = 1;
}

man kann auch das if (!CheckOk(Parameter1)) in void Check() weglassen, falls man nur die dll löschen möchte und sich ein eine funktion basteln die nur exitprocess und selfdelete aufruft. ferner kann man statt den process zu terminieren, ihn vielleicht einfach nur restarten lassen und während des restartens könnte man vielleicht die dll löschen. das problem ist das man unter windows dateien auf die ein process ein handle hat schwer löschen kann, in linux gehts. falls man es doch schafft eine dll zu löschen auf die ein process ein handle hat, dann wird meistens der process gecrasht. man könnte versuchen das handle von der dll zu entfernen indem man die dll auslädt aus dem process speicher und dann könnte man sie gefahrlos löschen. falls jemand eine idee wie man eine dll unlocken und löschen kann während ein process ein handle auf sie hat, kann er es gerne hier beitragen.
 
michaelsinterface hat gesagt.:
@bigbang: bitte achte zukünftig in Deinen Beiträgen auf die Groß- und Kleinschreibung, siehe Netiquette Nr.15.
Oh je, ich schreibe und rede soviel in Englisch ich habe es nicht mal bemerkt das ich alles klein geschrieben habe. @michaelsinterface, Du musst verstehen, es ist sehr schwierig sich umzustellen, hab ein bischen Verständniss, danke.
 
bigbang hat gesagt.:
Oh je, ich schreibe und rede soviel in Englisch ich habe es nicht mal bemerkt das ich alles klein geschrieben habe. @michaelsinterface, Du musst verstehen, es ist sehr schwierig sich umzustellen, hab ein bischen Verständniss, danke.
Ich hab damit keine Probleme, und ich sprech den ganzen Tag Englisch.
 
Zurück