Cómo utilizar enlaces y mapeo de archivos de memoria para implementar la inserción remota de subprocesos *** Disfrute de la tecnología
-OpenProcess: se utiliza para abrir el proceso de destino que se va a parasitar.
-VirtualAllocEx/VirtualFreeEx: se utiliza para asignar/liberar espacio de memoria en el proceso de destino.
-WriteProcessMemory - Se utiliza para escribir el nombre de la DLL que se cargará en el proceso de destino.
-CreateRemoteThread: el núcleo de la DLL de carga remota, que se utiliza para controlar el proceso de destino para llamar a funciones API.
-LoadLibrary-El proceso de destino carga la DLL del virus llamando a esta función.
Pero -VirtualAllocEx/VirtualFreeEx, WriteProcessMemory es una API para operar memoria virtual.
En 98, no existe tal API.
En 98, no existe tal API, entonces, ¿qué debemos hacer?
El autor vio recientemente el código fuente de una inserción remota de subprocesos de Delphi en Internet. El gancho se utiliza para insertar subprocesos en el proceso del administrador de recursos. Solo requiere una DLL y es común a 98, 2k y XP. . (Adjunto a continuación)
El proceso general:
Start.exe instala el gancho WH_GETMESSAGE en Insert.dll. En la función de devolución de llamada del gancho
determina si el ID del proceso actual es el ID del proceso del administrador de recursos encontrado previamente por Start.exe; de ser así,
carga la biblioteca (Insert.dll) nuevamente y busque la función ThreadPro. En este momento, se creará un
nuevo hilo. La función del hilo es ThreadPro. El nuevo hilo primero coloca un
mensaje de salida del hilo WM_QUIT en la cola de mensajes de Start.exe. su bucle de mensajes para finalizar. En este punto, la inserción del hilo se completa... Puedes ver los números cambiantes en la esquina superior izquierda de la pantalla
... Esto significa que nuestro código se está ejecutando. Start.exe no está en la lista de procesos.
Al utilizar Process Manager para observar, puede ver que el proceso de Resource Manager tiene un subproceso adicional de Insert.dll.
Si quieres finalizar el hilo insertado en el explorador, pulsa Alt L...
****************** ************************************************** * ************************************************* ** ***** **********************==
***Archivo fuente Start.exe:
Inicio del programa;
{$R 'ICON32.RES' 'ICON32.TXT' }
usa
Windows, funit en 'funit. pas' ; //cargar módulo funit
// ¿Usar personalización del tipo de datos?
tipo
nodo = registro
MainThread: Longword; // ID del hilo Start.exe
ExplorerID: Longword; ID de proceso
MainPath. array[0..500] of char; // ruta
end;
Pnode = ^node;
//Declarar DLL
/------------ DLL ------------//
procedimiento GetMsgHookOn ; externo '...\HookDLL\Insert.dll';
procedimiento GetMsgHookOff; externo '...\HookDLL\Insert.dll'; -------- DLL ------------//
Declarar variables
var
ThreadMessage: TMsg ;
Explorador_PID.
Longword;
FileMapH: DWORD;
TheNodeP: Pnode;
MutexHandle:
//Se crea la ventana de inicio y se repiten prohibido por mutex (exclusión mutua)
comenzar
if OpenMutex(MUTEX_ALL_ACCESS, FALSE, 'MutexForExe8Mazi')lt;gt;0 luego Salir //abre el mutex;
MutexHandle:= CreateMutex(nil, TRUE, 'MutexForExe8Mazi'); //Crea un mutex para prohibir la ejecución repetida
//Encuentra el proceso del administrador de recursos, consulta el módulo funit. aquí subrutina FindProcess()
Explorer_PID:= FindProcess('Explorer.exe');
si (Explorer_PID=0) entonces
comenzar
MessageBox(0, 'Error al encontrar el proceso del Explorador', nil, 0 Salir;
end;
//Crear archivo asignado en memoria
FileMapH:= CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(node), 'HookExplorer8Mazi');
si (FileMapH=0) entonces
comenzar
MessageBox(0, 'Error al crear el archivo asignado en memoria', nil, 0 Salir;
end;
/Asignar a este espacio de proceso
< p); >TheNodeP:= MapViewOfFile(FileMapH, FILE_MAP_ WRITE, 0, 0, 0);si (TheNodeP=nil) entonces
comenzar
MessageBox( 0 , 'Error de asignación a este espacio de proceso ', nil, 0);
CloseHandle(FileMapH);
end
// Write * * ** disfrute de los datos, aquí se hace referencia a las subrutinas GetDLDirectory() y StrCopy() del módulo funit
TheNodeP^.MainThread:=GetCurrentThreadID;
TheNodeP^.ExplorerID:=Explorer_PID <; /p>
StrCopy(TheNodeP^.MainPath, pchar(GetDLDirectory(ParamStr(0))));
//Cerrar mapeo de memoria
UnmapViewOfFile(TheNodeP);
// Cuelgue el gancho de trampolín de DLL, consulte la función GetMsgHookOn en Insert.Dll. dll
GetMsgHookOn;
// Bucle de mensajes del hilo (1. El hilo no finalizará inmediatamente para mantener activo el gancho de trampolín; 2. Espere a que se inserte un nuevo hilo en el administrador de recursos a enviar WM_QUIT
Mientras GetMessage(ThreadMessage, 0, 0, 0) lo hace; //*****Recibir el mensaje WM_QUITc enviado por el nuevo hilo insertado en el administrador de recursos
Luego regrese)
//Cierre el gancho de trampolín de DLL, consulte la función GetMsgHookOff en Insert.dll
.
dll
GetMsgHookOff;
//Cerrar el archivo de mapeo
CloseHandle(FileMapH);
/Cerrar Mutex
ReleaseMutex(MutexHandle); //.......... .END.......//
end.
* *** ************************************************* ************************************************* ***** ****** ****************
fuente funit.pas:
unit funit; p>
interfaz
función FindProcess(ExeName: cadena): Longword; //buscar proceso
función StrCopy(Dest: PChar; const Fuente: PChar): //copiar cadena
función GetDLLDirectory(FullPath: string): string; //obtener ruta de la DLL
implementación
usa Windows;
tipo
TProcessEntry32 = registro empaquetado
dwSize: DWORD;
cntUsage: DWORD
th32ProcessID: DWORD; p>th32DefaultHeapID: DWORD ;
th32ModuleID: DWORD; // exe asociado
cntThreads: DWORD
cntThreads: DWORD; th32ParentProcessID: DWORD; // El proceso padre de este proceso
pcPriClassBase: Longint; // La prioridad base del hilo del proceso
dwFlags: DWORD;
szExeFile: matriz[0.. MAX_PATH - 1] de Char; // Ruta 260-1
end;
//---------API-- ------- -//
función CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): THandle stdcall; externo 'kernel32.dll';
función Process32First(hSnapshot: THandle ; var lppe: TProcessEntry32): BOOL stdcall; función externa 'kernel32.dll'; Process32Next( hSnapshot: THandle; var lppe: TProcessEntry32): BOOL s
tdcall; externo 'kernel32.dll';
//---------API----------//
//Encuentra el proceso especificado y devuelve su ID.
función FindProcess(ExeName: string): Longword;
//(Subfunción) Si la cadena final coincide, no distingue entre mayúsculas y minúsculas
p>función AnsiEndsText(const ASubText, AText: cadena): booleano
var
P: PChar
L, L2: entero;
comenzar
P := PChar(AText);
L := Longitud(ASubText); AText);
Inc(P, L2 - L);
si L gt; entonces
Resultado:= Falso
else
Resultado:= CompareString(LOCALE_USER_DEFAULT, NORM_ IGNORECASE, P, L, PChar(ASubText), L) =
end
<; p>varsphandle: DWORD; Encontrado: Bool;
PStruct: TProcessEntry32
comenzar
Resultado: = 0; /p>
sphandle:= CreateToolhelp32Snapshot($00000002, 0);
PStruct.dwSize:= Sizeof(PStruct);
Encontrado:= Process32First(sphandle, PStruct);
mientras se encuentra,
comience
si AnsiEndsText(ExeName, PStruct.szExefile) entonces
comience
Resultado:= PStruct.th32ProcessID; Break;
end;
Encontrado:= Process32Next(sphandle, PStruct);
end;
CloseHandle(shandle);
end;
//Copia de cadena PChar, (********** ¿Qué significa compilación aquí? ¡Realmente no puedo entenderlo! ¿Se puede usar en lugar de
WriteProcessMemory?)
función StrCopy(Dest: PChar; const Fuente: PChar):
asm
asm
PUSH EDI
PUSH ESI
MOV ESI, EAX
MOV EDI, EDX
MOV ECX,0FFFFFFFFH
XOR AL, AL<
/p>
REPNE SCASB
NO ECX
MOV EDI, ESI
MOV EDI,
MOV ESI, EDX
MOV EDX, ECX
MOV EAX, EDI
SHR ECX, 2
REP MOVSD
MOV ECX , EDX
Y ECX, 3
REP MOVSB
POP ESI
POP EDI
end;
//Obtener el directorio donde se encuentra la DLL
función GetDLLDirectory(FullPath: string): string;
var
i: entero;
p>
comenzar
i := longitud(FullPath)
mientras igt;=1 hacer
comenzar
si (FullPath='\') luego romper
dec(i
fin
Resultado:= copiar(FullPath, 1, i-9 ) 'HookDLL\';
end;
end.
********** ************ ********************************** ***** ********** **************************************** *********** ****************************
***Fuente código en Insert.dll:
Inserción de biblioteca
Propósito
Windows, mensajes,
públicos en 'publics.pas',
Subproceso 'Thread.pas' en,
'JumpHook.pas ';
procedimiento DLLProcess(dwReason: integer
); comenzar
si dwReason= DLL_PROCESS_DETACH entonces //entrada de DLL
comenzar
if (TheNodePlt;gt;nil) luego UnmapViewOfFile(TheNodeP);
if (FileMapHlt;gt;0) entonces CloseHandle(FileMapH);
fin
fin
exportaciones
GetMsgHookOn, GetMsgHookOff, ThreadPro;
comenzar
FileMapH := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 'HookExplorer8Mazi'); //
if FileMaphlt;gt;0 entonces
TheNodeP := MapViewOfFile(FileMapH, FILE_MAP_ALL_ACCESS, 0, 0, 0);
DllProc:= @DLLProcess;
end.
****************************** *******************==
//La función de devolución de llamada del gancho GetMessage se inyectará en el proceso del sistema
función GetMsgHookPro (nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
comenzar
If (TheNodePlt;gt;nil)and(TheNodeP^.ExplorerIDlt;gt; 0) y
(GetCurrentProcessId=TheNodeP^.ExplorerID) entonces // es el proceso Explorer
begin
LibraryH := LoadLibrary(Pchar(TheNodeP^. MainPath 'Insert. dll')); //cargar biblioteca de enlaces dinámicos
if (LibraryH lt; gt; 0) entonces
ThreadPt:= GetProcAddress(LibraryH, 'ThreadPro') ; //localiza la función del hilo
if (ThreadPt lt; gt; nil) the
CreateThread(nil, 0, ThreadPt, nil, 0, ThreadID); thread
end;
Resultado:= CallNextHookEx(GetMsgHook, nCode, wParam, lParam); //Engancha la devolución de llamada al siguiente proceso hasta que se encuentre
Proceso ResourceManager
p>Fin;
//Función GetMsgHookOn.
Suspender el gancho de trampolín de DLL
Procesar GetMsgHookOn;
comenzar
GetMsgHook:= SetWindowsHookEx(WH_GETMESSAGE, @GetMsgHookPro, HInstance, 0);
end;
//Función GetMsgHookOff, cierra el gancho de trampolín de DLL
procedimiento GetMsgHookOff;
comenzar
UnHookWindowsHookEx(GetMsgHook);
fin;
fin.
*************************** *** ************************************************* ************************************************* ****** *************************==
** Función ThreadPro en Insert.dll: p>
// Para insertar Código de hilo
procedimiento ThreadPro(); stdcall;
var
theMsg: TMsg;
Recuento: Entero;
HotKeyID: ATOM;
comenzar
PostThreadMessage(TheNodeP^.MainThread, WM_QUIT, 0, 0); ******** mensaje de salida del hilo WM_QUIT
HotKeyID:= GlobalAddAtom('HotKeyID8Mazi'); //...Request GlobalAtom
RegisterHotKey(0, HotKeyID, MOD_ALT , Ord('L')); / /...Registrar tecla de acceso directo Alt L
Contar:= 0;
mientras sea verdadero
comenzar {. ..Obtener información...}. {...Mensaje de tecla de acceso rápido...} {...
si PeekMessage(theMsg, 0, 0, 0, PM_REMOVE) y(theMsg.message=WM_HOTKEY) entonces interrumpe;
WriteScreen( ' ' Int2Hex(Count) ' (La demostración es de www com) '
Count := Count 1;
end;
UnregisterHotKey(0, HotKeyID); //...Anular el registro de la tecla de acceso rápido Alt L
DeleteAtom(HotKeyID); //.Liberar el átomo global
end ;
fin.
********************************************* *** ************************************************* ************************************************* **** *******=
API clave:
*SetWindowsHookEx(WH_GETMESSAGE, @GetMsgHookPro, HInstance, 0); //WH_GETMESSAGE gancho de mensaje global
p>*UnHookWindowsHookEx(GetMsgHook) // Cerrar el enlace
*CallNextHookEx(GetMsgHook, nCode, wParam, lParam); // Continuar con el enlace anterior
*PostThreadMessage( TheNodeP^.MainThread, WM_QUIT, 0, 0); // Enviar mensaje (salida del hilo) WM_QUIT
*GetMessage(ThreadMessage, 0, 0) // Extraer mensaje
*GetMessage (ThreadMessage, 0, 0, 0) // Extraer mensaje
*CreateFileMapping(-1, nil, PAGE_READWRITE, 0, SizeOf//Crear archivo mapeado en memoria (nodo), 'HookExplorer8Mazi'); p>
*MapViewOfFile(FileMapH, FILE_MAP_WRITE, 0, 0, 0); //asignar a este espacio de proceso
*OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 'HookExplorer8Mazi'); file
* CloseHandle(FileMapH); //Cerrar el archivo del kernel
*LoadLibrary(Pchar(TheNodeP^.MainPath 'Insert.dll') //Cargar el enlace dinámico biblioteca
*GetProcAddress(LibraryH, 'ThreadPro'); //Ubicar función de subproceso
*CreateThread(nil, 0, ThreadPt, nil, 0, ThreadID); nuevo hilo
Espérenlo….
************ Según tengo entendido, Start.exe primero obtiene el PID del proceso remoto, su propio PID y la ruta de la DLL, y luego los escribe. en el mapa de memoria creado por el archivo API y luego instale el enlace global WH_GETMESSAGE en Insert.dll
(en la DLL) para inyectar el enlace en cada código de función de devolución de llamada del sistema. El código de la función de devolución de llamada de enlace (en la DLL) se inyecta en cada espacio de proceso del sistema y Start.exe ejecuta un bucle de mensajes hasta que se recibe un mensaje de salida.
En el programa de código de la función de devolución de llamada de gancho, primero asigne el archivo asignado en memoria creado por Start.exe al espacio del proceso del host y luego recupere el PID del proceso remoto almacenado en el archivo asignado en memoria.
Compárelo con el PID del host y, si es así, inicie un nuevo hilo, cargando el número de ThreadPro en Insert.DLL.
Luego envíe el mensaje de salida del hilo
a Start.exe, de modo que el ciclo del mensaje finalice, Start.exe salga y se complete la inserción del hilo.