Red de conocimiento informático - Material del sitio web - Cómo utilizar enlaces y mapeo de archivos de memoria para implementar la inserción remota de subprocesos *** Disfrute de la tecnología

Cómo utilizar enlaces y mapeo de archivos de memoria para implementar la inserción remota de subprocesos *** Disfrute de la tecnología

Como todos sabemos, la inserción remota tradicional de subprocesos se realiza a través de la siguiente API:

-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;

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>var

sphandle: 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:

// 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');

*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.