Ok, veamos en lo que te puedo ayudar y a ver si e entendido bien que es lo que quieres hacer.
Quieres un programa que cuando encuentre X título en una ventana inyecte una dll en su proceso que hooke el api DrawText, es así?
Bien, para eso vas a necesitar dos cosas, la primera un código en delphi para poder inyectar tu dll (que irá en tu proyecto y se ejecutará cuando encuentre dicho título), este es un código que encontré googleando:
program Project1;
uses
Windows;
var
PID, BytesWritten, Process, Thread, ThreadId: dword;
Paramaters: pointer;
DLL: pchar;
function xCreateRemoteThread(hProcess: dword; lpThreadAttributes: Pointer; dwStackSize: dword; lpStartAddress: Pointer; lpParameter: Pointer; dwCreationFlags: dword; lpThreadId: dword): dword; stdcall; external 'RT.dll';
function xVirtualAllocEx(hProcess: dword; lpAddress: Pointer; dwSize: dword; flAllocationType: dword; flProtect: dword): Pointer; stdcall; external 'RT.dll';
function xVirtualFreeEx(hProcess: dword; lpAddress: Pointer; dwSize: dword; dwFreeType: dword): boolean; stdcall; external 'RT.dll';
begin
DLL := 'c:\Inject\Library.dll'; //full path!
PID := 1784; //process id!
Process := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
Paramaters := xVirtualAllocEx(Process, nil, 4096, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(Process, Paramaters, Pointer(DLL), 4096, BytesWritten);
Thread := xCreateRemoteThread(Process, nil, 0, GetProcAddress(GetModuleHandle('KERNEL32.DLL'), 'LoadLibraryA'), Paramaters, 0, ThreadId);
WaitForSingleObject(Thread, INFINITE);
xVirtualFreeEx(Process, Paramaters, 0, MEM_RELEASE);
CloseHandle(Thread);
CloseHandle(Process);
end.
Metes lo que en ese código es el programa principal en una función y listo, no me preguntes por que designan el api CreateRemoteThread como xCreateRemoteThread (no se si para intentar dejarlo indetectable) por que yo de delphi ni idea, pme sacas de pascal y me pierdo xDD
Bien, ahora ya tienes la función para inyectar tu dll, pero claro, te falta una dll para poder hacer el gancho, que de eso en delphi si que no e encontrado ningún ejemplo, pero es muy simple, te dejo un tuto que escribí (el del rootkit, en C):
http://foro.elhacker.net/analisis_y_diseno_de_malware/querias_tutos_de_programacion_de_malware_pues_toma-t196251.0.htmlIntenta adaptarlo a Delphi, la idea es simple, lo primero que tienes que hacer es ver cuantos bytes tienes que cojer del api a hookear (viene bien explicad) sustituir estos por un jump (0xE9) que salte a tu función hookeadora, si te lias calculando la distancia del salto puedes poner al inicio del api a hookear:
push DireccionRealDeTuFuncionHookeadora
ret
Y arreglado, pero ten en cuenta que eso no son 6 bytes a la hora de sobrescribir el api

Finalmente en tu función hookeadora cambias lo que quieres y llamas a un buffer que te tienes que crear con los bytes del api a hookear que te hayas cargado y un salto a la dirección del api a partir de los bytes que te has cargado.
Puede parecer confuso, pero viene mejor explicado en el tuto xDDDD
Los códigos en ASM que tengo hechos son un poco más abanzados de los que buscas, el único que te podría ser útil es este, que hookea una función sin usar ninguna dll, en el ejemplo que hice es una especie de rootkit que oculta los archivos que empiezan por ~, aquí te lo dejo, aunque creo que muy útil no te va a ser:
include 'H:\archivos de programa\fasm\include\win32ax.inc'
.data
HookApi db 'FindNextFileW' , 0 ; Nombre del api a hookear
HookDll db 'Kernel32.dll' , 0 ; Nombre de la dll que contiene el api a hookear
DirApi dd ? ; Dirección del api a hookear
process dd ? ; El handle del proceso donde inyectaremos
pid dd 2160 ; El pid del proceso donde inyectaremos
x dd 7 ; El número de bytes que tiene al principio el api a hookear (suelen ser 5 ó 7)
BufferCall dd ? ; Puntero al buffer para llamar al api (en nuestro propio proceso)
inyBufferCall dd ? ; Puntero al buffer para llamar al api una vez INYECTADO
tamFun dd ? ; Tamaño de la función que suplantará al api
inyFun dd ? ; Puntero a la función que reemplazará al api una vez INYECTADA
BufferApi dd ? ; Buffer de 5 bytes que pondremos en el inicio del api FindNextFileW para que salte
; a nuestra función
struct Datos
sBufferCall dd ? ; Puntero a inyBufferCall para poder llamar al api original
ends
dat Datos ?
SizeofDatos dd 4 ; El tamaño de la estructura, hay que ir contando los bytes
dirStruct dd ? ; La dirección donde esta escribe la estructura una vez INYECTADA
Prote dd ? ; Necesario para VirtualProtect
.code
start:
; Obtenemos el handle del proceso donde inyectaremos
mov eax, PROCESS_VM_OPERATION
or eax, PROCESS_VM_WRITE
invoke OpenProcess, eax, FALSE, [pid]
mov [process], eax
; Obtenemos la dirección del api a Hookear
invoke GetModuleHandle, HookDll
invoke GetProcAddress, eax, HookApi
mov [DirApi], eax
; Creamos un buffer con los x primeros bytes del api a hookear
; y un salto al api + x para poder llamar con normalidad al api
; Estructura del buffer:
; x bytes | 1 byte | 4 byte | 1 byte
; x primeros bytes del api | push [0x68] | DirApi + x | ret [0xC3]
mov eax, dword [x]
add eax, 6
invoke LocalAlloc, LPTR, eax ; eax = x + 6
mov [BufferCall], eax
invoke RtlMoveMemory, [BufferCall], [DirApi], [x] ; Copiamos los x primeros bytes del api
mov eax, [BufferCall]
add eax, [x]
mov byte [eax], 0x68
inc eax
mov ebx, [DirApi]
add ebx, [x]
mov dword [eax], ebx
add eax, 4
mov byte [eax], 0xC3
; Inyectamos el buffer que acabamos de crear y guardamos
; su dirección en inyBufferCall
mov eax, MEM_RESERVE ; eax = MEM_RESERVE | MEM_COMMIT
or eax, MEM_COMMIT
mov ecx, [x] ; ecx = x + 6
add ecx, 6
invoke VirtualAllocEx, [process], 0, ecx, eax, PAGE_READWRITE
mov [inyBufferCall], eax
mov ebx, [x] ; ebx = x + 6
add ebx, 6
invoke WriteProcessMemory, [process], [inyBufferCall], [BufferCall], ebx, NULL
; Inicializamos la estructura con todos los datos necesarios para poder interceptar el api
mov eax, [inyBufferCall] ; Metemos el puntero al buffer para llamar
mov [dat.sBufferCall], eax ; con normalidad al api
; [...]
; Reservemos espacio para la estructura en el proceso a inyectar y la escribimos
mov eax, MEM_RESERVE
or eax, MEM_COMMIT
invoke VirtualAllocEx, [process], 0, [SizeofDatos], eax, PAGE_READWRITE
mov [dirStruct], eax
invoke WriteProcessMemory, [process], [dirStruct], dat, [SizeofDatos], NULL
; Cambiamos el 0x0000 de la función a inyectar por un puntero a la estructura
; antes de inyectarla.
mov ebx, CAMBIO ; ebx = El 0x0000 que hay que cambiar (4 bytes)
sub ebx, 4
invoke VirtualProtect, ebx, 6, PAGE_EXECUTE_READWRITE, Prote
invoke RtlMoveMemory, ebx, dirStruct, 4
; Calculamos el tamaño de la función a inyectar
mov eax, FIN_MyFindNextFileW
sub eax, MyFindNextFileW
mov [tamFun], eax
; Reservamos espacio para la función en el proceso a inyectar y la escribimos.
mov eax, MEM_RESERVE ; eax = MEM_RESERVE | MEM_COMMIT
or eax, MEM_COMMIT
invoke VirtualAllocEx, [process], 0, [tamFun], eax, PAGE_EXECUTE_READWRITE
mov [inyFun], eax
invoke WriteProcessMemory, [process], [inyFun], MyFindNextFileW, [tamFun], NULL
; Creamos un buffer de 5 bytes que pondremos en el principio de la llamada a
; FindNextFileW en el proceso remoto para que salte a nuestra función.
; Estructura del buffer:
; 1 bytes | 4 bytes
; jmp [0xE9] | Tamaño del salto
invoke LocalAlloc, LPTR, 5
mov [BufferApi], eax
mov byte [eax], 0xE9
inc eax
mov ebx, [inyFun]
sub ebx, [DirApi]
sub ebx, 5 ; 5 = -1 por el 0xE9 y -4 por la dirección
mov dword [eax], ebx
; Modificamos el inicio del api FindNextFileW del proceso "víctima" para que
; salte a nuestra función que la suplantará.
mov eax, MEM_RESERVE ; eax = MEM_RESERVE | MEM_COMMIT
or eax, MEM_COMMIT
invoke VirtualAllocEx, [process], [DirApi], 5, eax, PAGE_EXECUTE_READWRITE
invoke WriteProcessMemory, [process], [DirApi], [BufferApi], 5, NULL
; Salimos
invoke ExitProcess, 0
; La función que suplantará al api
proc MyFindNextFileW hFindFile, lpFindFileData
OK:
mov ebx, 0x0000 ; Este 0x0000 es remplazado anteriormente por el
CAMBIO: ; programa por un puntero a la estructura inyectada.
push [lpFindFileData]
push [hFindFile]
call dword [ebx]
mov ebx, eax
cmp ebx, 0 ; Si hemos terminado de listar todos los
je RETORNAR_FIN ; archivos devolvemos 0
mov eax, [lpFindFileData] ; Nos situamos en
add eax, 44 ; cFileName
cmp byte [eax], '~' ; y ocultamos los que
je OK ; empiecen por '~'
mov eax, 1 ; Si aun quedan archivos por listar
ret ; devolvemos 1
RETORNAR_FIN:
mov eax, 0
ret
endp
FIN_MyFindNextFileW:
.end start
Salu2 y en el manual que te e puesto puedes encontrar un ejemplo de dll de como hookear un api, solo es cambiar los valores necesarios y puedes hacer la dll en C, que no pasa nada
