Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 19

Discussione: [C/C++] DLL injection

  1. #1

    [C/C++] Dll injection

    Vorrei sapere bene come funziona questa tecnica e come applicarla.
    Allora, il programma inietta nello spazio di un'altro programma il codice della dll, giusto?
    ecco, tale codice quand'è che viene eseguito?

    cioè, questo è il codice che ho usato per fare un'esperimento:


    Dllinjector.c
    codice:
    #include <stdio.h>
    #include <windows.h>
    #include "functions.h"
    
    int main(){
    	char processName[] = "calc.exe"; /* Nome processo su cui effettuare injection */
    	char logFile[]= "log.log"; /* Nome del file di log per controllare successo o fallimento operazioni */
    	char dllName[]="dll.dll"; /* Nome dll da cui prelevare il codice da iniettare */
    
    	HANDLE proc, thread;
    	DWORD threadId, bWritten;
    	BOOL check;
    	VOID *remoteBuff;
    	DWORD pid;
    	FILE *fp;
    
    	fp = fopen(logFile, "w");
    	fprintf(fp, "Looking for: %s\n\n", processName);
    
    	pid = trovaPid(processName, fp);
    
    	if(pid == 0xFFFFFFFF){
    		fprintf(fp, "\nProcess not found\n");
    		return 0;
    	}
    
    	check = abilitaSeDebugName(fp);
    	if (check == 0){
    		fprintf(fp, "\nAbilitazione privilegio SE_DEBUG_NAME fallita\n");
    	}
    
    	proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    	if (proc == NULL){
    		fprintf(fp, "Errore OpenProcess() %d\n", GetLastError());
    		return -1;
    	}
    
    	remoteBuff = VirtualAllocEx(proc, NULL, strlen(dllName), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    	if (remoteBuff == NULL){
    		fprintf(fp, "Errore VirtualAllocEx() %d\n", GetLastError());
    		return -1;
    	}
    	else
    		fprintf(fp, "\nCreati %d bytes all' indirizzo 0x%x\n", strlen(dllName), (ULONG)remoteBuff);
    
    	check = WriteProcessMemory(proc, remoteBuff, dllName, strlen(dllName), &bWritten);
    	if (check == 0){
    		fprintf(fp, "Errore WriteProcessMemory() %d\n", GetLastError());
    		return -1;
    	}
    
    	thread = CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(LoadLibrary("kernel32.dll"), "LoadLibraryA"), remoteBuff, 0, &threadId);
    	if (thread == NULL)
    		fprintf(fp, "Errore CreateRemoteThread() %d\n", GetLastError());
    
    	fprintf(fp, "\nInjection eseguita\n");
    	fclose(fp);
    	return 0;
    }
    Functions.h
    codice:
    int trovaPid(char *procName, FILE *log)
    {
    	typedef struct _LSA_UNICODE_STRING { /* struttura dati di una stringa Unicode */
    		USHORT Length;
    		USHORT MaximumLength;
      		PWSTR Buffer;
    	} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;
    
    	typedef struct _STRING { /* struttura dati di una stringa Ansi */
      		USHORT  Length;
      		USHORT  MaximumLength;
      		PCHAR  Buffer;
    	} ANSI_STRING, *PANSI_STRING;
    
    	typedef enum _SYSTEM_INFORMATION_CLASS {
    	SystemBasicInformation,
    	SystemProcessorInformation,
    	SystemPerformanceInformation,
    	SystemTimeOfDayInformation,
    	SystemNotImplemented1,
    	SystemProcessesAndThreadsInformation,
    	SystemCallCounts,
    	SystemConfigurationInformation,
    	SystemProcessorTimes,
    	SystemGlobalFlag,
    	SystemNotImplemented2,
    	SystemModuleInformation,
    	}SYSTEM_INFORMATION_CLASS;
    
    	typedef struct _SYSTEM_PROCESSES { /* Informazioni sui processi di sistema (struttura non completa) */
    		ULONG NextEntryDelta;
    		ULONG ThreadCount;
    		ULONG Reserved1[6];
    		LARGE_INTEGER CreateTime;
    		LARGE_INTEGER UserTime;
    		LARGE_INTEGER KernelTime;
    		UNICODE_STRING ProcessName;
    		ULONG BasePriority;
    		ULONG ProcessId;
    	} SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
    
    	/* Definizione delle funzioni non presenti nei compilatori tradizionali */
    	typedef DWORD (WINAPI *PfZwQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PBYTE, ULONG, PULONG);
    	typedef DWORD (WINAPI *PfRtlAnsiStringToUnicodeString)(PUNICODE_STRING, PANSI_STRING, BOOL);
    	typedef DWORD (WINAPI *PfRtlUnicodeStringToAnsiString)(PANSI_STRING, PUNICODE_STRING, BOOL);
    	typedef DWORD (WINAPI *PfRtlCompareUnicodeString)(PUNICODE_STRING, PUNICODE_STRING, BOOL);
    
    	PfZwQuerySystemInformation MyZwQuerySystemInformation;
    	PfRtlAnsiStringToUnicodeString MyRtlAnsiStringToUnicodeString;
    	PfRtlUnicodeStringToAnsiString MyRtlUnicodeStringToAnsiString;
    	PfRtlCompareUnicodeString MyRtlCompareUnicodeString;
    
    
    	BOOL check;
    	DWORD pid = 0xFFFFFFFF;
    	void *pStruct; /* buffer per contenere la struttura delle informazioni sui processi */
    	ULONG dimBuffer = 0x8000; /* dimensione del buffer pStruct */
    	PSYSTEM_PROCESSES sp;
    	ANSI_STRING buffAnsi;
    	UNICODE_STRING buffUni;
    	ULONG dimRich;
    
    
    	buffAnsi.Buffer = (PCHAR)malloc(lstrlenA(procName) + 1);
    
    	lstrcpyA(buffAnsi.Buffer, procName);
    	buffAnsi.Length = lstrlenA(buffAnsi.Buffer);
    	buffAnsi.MaximumLength = lstrlenA(buffAnsi.Buffer);
    
    	MyRtlAnsiStringToUnicodeString = (PfRtlAnsiStringToUnicodeString)GetProcAddress(LoadLibrary("ntdll.dll"), "RtlAnsiStringToUnicodeString");
    	MyRtlAnsiStringToUnicodeString(&buffUni, &buffAnsi, TRUE);
    
    	pStruct = (void *)malloc(dimBuffer);
    
    	MyZwQuerySystemInformation = (PfZwQuerySystemInformation)GetProcAddress(LoadLibrary("ntdll.dll"), "ZwQuerySystemInformation");
    	check = MyZwQuerySystemInformation(SystemProcessesAndThreadsInformation, (PBYTE)pStruct, dimBuffer, &dimRich);
    	if (check != 0){
    		fprintf(log, "Errore ZwQuerySystemInformation() dimensione minima buffer: 0x%x\n", dimRich);
    		return -1;
    	}
    
    	/* ciclo di ricerca del processo da terminare */
    	do{
    		sp = (PSYSTEM_PROCESSES) pStruct;
    		MyRtlUnicodeStringToAnsiString = (PfRtlUnicodeStringToAnsiString)GetProcAddress(LoadLibrary("ntdll.dll"), "RtlUnicodeStringToAnsiString");
    		MyRtlUnicodeStringToAnsiString(&buffAnsi, &(sp->ProcessName), TRUE);
    
    		fprintf(log, "Process Name: %s\tProcess ID: %d\n", buffAnsi.Buffer, sp->ProcessId);
    
    		MyRtlCompareUnicodeString = (PfRtlCompareUnicodeString)GetProcAddress(LoadLibrary("ntdll.dll"), "RtlCompareUnicodeString");
    		check = MyRtlCompareUnicodeString(&buffUni, &(sp->ProcessName), TRUE);
    		if (check == 0){
    			fprintf(log, "FOUND!!\n");
    			pid = sp->ProcessId;
    		}
    		pStruct = (void*)((ULONG)pStruct + sp->NextEntryDelta);
    	}
    	while(sp->NextEntryDelta != 0);
    
    	return pid;
    }
    
    int abilitaSeDebugName(FILE *log){
    	BOOL check;
    	HANDLE currProc, tok;
    	LUID lu_sdn;
    	TOKEN_PRIVILEGES tp;
    	LUID_AND_ATTRIBUTES luaa;
    
    	currProc = GetCurrentProcess();
    	if (currProc == NULL){
    		fprintf(log, "\nErrore GetCurrentProcess() %d\n", GetLastError());
    		return 0;
    	}
    
    	check = OpenProcessToken(currProc, TOKEN_ALL_ACCESS, &tok);
    	if (check == 0){
    		fprintf(log, "\nErrore OpenProcessToken() %d\n", GetLastError());
    		return 0;
    	}
    
    	check = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &lu_sdn);
    	if (check == 0){
    		fprintf(log, "\nErrore LookupPrivilegeValue() %d\n", GetLastError());
    		return 0;
    	}
    
    	/* abilitazione del privilegio SE_DEBUG_NAME */
    	tp.PrivilegeCount = 1;
    	luaa.Luid = lu_sdn;
    	luaa.Attributes = SE_PRIVILEGE_ENABLED;
    	tp.Privileges[0] = luaa;
    
    	check = AdjustTokenPrivileges(tok, FALSE, &tp, sizeof(tp), NULL, NULL);
    	if (check == 0){
    		fprintf(log, "\nErrore AdjustTokenPrivileges() %d\n", GetLastError());
    		return 0;
    	}
    	return 1;
    }
    e la dll mostra una semplice messagebox:

    codice:
    #include <windows.h>
    
    BOOL APIENTRY DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
    {
        switch (fdwReason)
        {
        case DLL_PROCESS_ATTACH:
        {
            MessageBox(0, "Codice eseguito!!!!", "DLL Loaded", MB_OK);
            return TRUE;
            }
        case DLL_PROCESS_DETACH: /* operazioni di rilascio della dll */
            break;
            }
        return TRUE;
    }
    allora,io avvio calc.exe poi eseguo dllinjector.exe che nel log conferma che l'operazione è stata completata con successo, ora? dove e quando verrà eseguito il codice della dll?

    help me please! :master:

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,464
    La dll deve essere in un percorso conosciuto dato che viene fornita senza percorso assoluto.

    Copia la dll.dll in \windows\system32

    Dimenticavo ... il codice della dll viene eseguito quando viene caricata e questo avviene in

    thread = CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(LoadLibrary ("kernel32.dll"), "LoadLibraryA"), remoteBuff, 0, &threadId);


    P.S. La injection è una tecnica "delicata" e "scivolosa" ... a cosa ti serve ?

  3. #3
    l'ho spostata in %systemroot%\system32.
    ho avviato calc.exe.
    ho eseguito l'iniezione e ora? io non vedo nessun messaggio?
    dove lo dovrei visualizzare?

    ho capito che viene eseguita con la funzione

    codice:
    thread = CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(LoadLibrary("kernel32.dll"), "LoadLibraryA"), remoteBuff, 0, &threadId);
    però io la messagebox non la vedo!!

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,464
    1) Copia la dll.dll in \windows\system32

    2) Avvia Calc.exe

    3) Esegui il programma che effettua l'iniezione (l'eseguibile)

    Fai in modo di avere il desktop visibile perche' la Message Box eseguita nella DLL appare al centro dello schermo e potrebbe stare sotto ad altre finestre ...

    Puoi eseguire quel codice una sola volta. Se vuoi farlo nuovamente, devi chiudere il Calc e aprirne un altro.

  5. #5
    ca**o! non mi funzia! quando eseguo l'eseguibile mi compare x un secondo la finestra del dos e poi niente!

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,464
    Aggiungi la riga

    fprintf(fp, "CreateThread %d\n", GetLastError());

    dopo la

    thread = CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(LoadLibrary ("kernel32.dll"), "LoadLibraryA"), remoteBuff, 0, &threadId);

    Ricompila, chiudi e riapri calc ed esegui. Leggi cosa c'e' nel log ...

  7. #7
    ecco il log:

    codice:
    Looking for: calc.exe
    
    Process Name: 	Process ID: 0
    Process Name: System	Process ID: 4
    Process Name: smss.exe	Process ID: 488
    Process Name: csrss.exe	Process ID: 540
    Process Name: winlogon.exe	Process ID: 568
    Process Name: services.exe	Process ID: 612
    Process Name: lsass.exe	Process ID: 624
    Process Name: svchost.exe	Process ID: 776
    Process Name: svchost.exe	Process ID: 852
    Process Name: svchost.exe	Process ID: 920
    Process Name: svchost.exe	Process ID: 992
    Process Name: svchost.exe	Process ID: 1108
    Process Name: explorer.exe	Process ID: 1304
    Process Name: spoolsv.exe	Process ID: 1356
    Process Name: ashDisp.exe	Process ID: 1516
    Process Name: qttask.exe	Process ID: 1528
    Process Name: iTunesHelper.exe	Process ID: 1544
    Process Name: mixer.exe	Process ID: 1560
    Process Name: jusched.exe	Process ID: 1588
    Process Name: ctfmon.exe	Process ID: 1616
    Process Name: aswUpdSv.exe	Process ID: 1748
    Process Name: ashServ.exe	Process ID: 1780
    Process Name: sqlservr.exe	Process ID: 1880
    Process Name: iPodService.exe	Process ID: 1404
    Process Name: ashMaiSv.exe	Process ID: 972
    Process Name: ashWebSv.exe	Process ID: 2004
    Process Name: alg.exe	Process ID: 2164
    Process Name: calc.exe	Process ID: 3036
    FOUND!!
    Process Name: DllInjector.exe	Process ID: 3044
    
    Creati 7 bytes all' indirizzo 0x3a0000
    CreateThread 0
    
    Injection eseguita

  8. #8
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,464
    Beh ... mi pare tutto a posto ...

    A questo punto non rimane che provare l'eseguibile e la dll nel mio pc.

    Crea uno zip con i due file e fammelo scaricare.

  9. #9

  10. #10
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,464
    Ho visto e in effetti non funziona.

    Tu hai usato il DevCpp e quando l'ho fatto anch'io, non ha funzionato.

    Adesso non ho molto tempo per fare dei test (lo faro' questa sera) ma sospetto che il DevCpp ottimizzi il codice in maniera strana e non includa il codice che chiama la MessageBox.

    Io ho compilato con Visual C/C++ (2003 ma anche 2005, modalità Release) e tutto funziona.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.