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: