WH_CALLWNDPROC llamada de forma rara

Iniciado por patilanz, 8 Julio 2015, 01:18 AM

0 Miembros y 1 Visitante están viendo este tema.

patilanz

Hola estuve probando cositas y en este codigo:

Código (cpp) [Seleccionar]

//Main.cpp
typedef void(_MakeHook)(DWORD threadID, int dlgID);

int _tmain(int argc, _TCHAR* argv[])
{
HWND hwnd = FindWindow("wxWindowNR", "FileZilla");
if (hwnd == 0){
printf("FileZilla not found\n");
getchar();
return 0;
}

HMODULE library = LoadLibrary("C:\\Users\\User\\Documents\\Visual Studio 2013\\Projects\\stealPwDll_real\\x64\\Debug\\stealPwDll_dll.dll");
if (library == NULL){
printf("error library %d\n",GetLastError());
}
_MakeHook * MakeHook = (_MakeHook *)GetProcAddress(library, "MakeHook");
if (MakeHook == 0){
printf("getpw error\n");
}
MakeHook(GetWindowThreadProcessId(hwnd, 0), 0xFFFF83C4);

MSG msg;
while (!GetMessage(&msg, 0, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}

getchar();
return 0;
}



Código (cpp) [Seleccionar]

//Código del main_dll.cpp
#include <Windows.h>
#include "main.h"
#include <stdio.h>

#pragma warning(disable:4996)

HMODULE hmodule;
HHOOK hook;
bool msgSend = false;
int g = 0;

BOOL WINAPI DllMain(HMODULE hmodule,DWORD reason,LPVOID){
if (reason == DLL_PROCESS_ATTACH){
::hmodule = hmodule;
}
return 1;
}




void MakeHook(DWORD id, int dlgID){
hook = SetWindowsHookEx(WH_CALLWNDPROC, getPw, hmodule, id);
if (hook == NULL){
char msg[100];
sprintf(msg, "Hook error -> %d", GetLastError());
MessageBox(0, msg, "Hook error", MB_ICONERROR);
}
}


LRESULT CALLBACK getPw(int code,WPARAM wparam,LPARAM lparam){
if (code != HC_ACTION){
return (CallNextHookEx(hook, code, wparam, lparam));
}
else if(!wparam){
if (!msgSend){
g++;
char msg[100];
sprintf(msg, "%d", g);
MessageBox(0, "Not current thread call", msg, MB_ICONINFORMATION); //  ----------- Parte rara --------
msgSend = true;
}
}
return 1;
}


Si utilizo el código del main_dll.cpp me muestra 30 MessageBox empezando desde g = 30
Si cambio el código:
Código (cpp) [Seleccionar]
LRESULT CALLBACK getPw(int code,WPARAM wparam,LPARAM lparam){
if (code != HC_ACTION){
return (CallNextHookEx(hook, code, wparam, lparam));
}
else if(!wparam){
if (!msgSend){
msgSend = true; // ----- Parte cambiada -> msgSend = true; sube primero
g++;
char msg[100];
sprintf(msg, "%d", g);
MessageBox(0, "Not current thread call", msg, MB_ICONINFORMATION);

}
}
return 1;
}


Me muestra solo un MessageBox como debe ser.

Porque???

Un saludo

ivancea96

Solo por si acaso, ¿despues del MessageBox se sigue ejecutando código? Pon otro MessageBox a ver.

patilanz

Cita de: ivancea96 en  8 Julio 2015, 01:35 AM
Solo por si acaso, ¿despues del MessageBox se sigue ejecutando código? Pon otro MessageBox a ver.

Si, en ambos casos (msgSend primero y ultimo).

ivancea96

#3
Sin palabras. Si encuentras la solución, coméntala :p

ivancea96

#4
¿Es posible que MessageBox() acabe provocando un timeout en el hook? Tengo entendido de que Windows 7 y en adelante eliminan hooks si se pasan del timeout. Puedes comprobarlo. Aunque no seguro que tenga que ver con eso.

Edito: A todo esto:

Código (cpp) [Seleccionar]
while (!GetMessage(&msg, 0, 0, 0))

GetMessage retorna 0 cuando obtiene el mensaje WM_QUIT.

patilanz

#5
Ahora compruebo el timeout que me dijiste pero mientras pongo lo que estuve comprobando:

Código (cpp) [Seleccionar]
MessageBox(0, "data", "g++", 0);
msgSend = true;
g++;
MessageBox(0, "data", "char msg[100]", 0);
char msg[100];
MessageBox(0, "data", "CWPSTRUCT *data = (CWPSTRUCT *)lparam;", 0);
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
MessageBox(0, "data", "sprintf", 0);

sprintf(msg, "%d -> %x", g, data->message);
MessageBox(0, msg, "Window title", 0);


Lo mismo que antes pero esta empieza desde 1 hasta 30 y el primer conjunto de  dialogboxes siempre se buquea y se queda sin texto como si msg estuviera vació. (Esto también pasaba antes)

Si pongo el msgSend antes de un messagebox todo perfecto.
Luego hice un log en un txt:

Código (cpp) [Seleccionar]
LRESULT CALLBACK getPw(int code,WPARAM wparam,LPARAM lparam){
if (code != HC_ACTION){
return (CallNextHookEx(hook, code, wparam, lparam));
}
else if(!wparam){
if (!msgSend){
if (file == NULL){
file = fopen("holaholahola", "w");
}
w("\n\n ---- New call ----");
w("g++");
MessageBox(0, "data", "g++", 0);
g++;
w("char msg[100]");
MessageBox(0, "data", "char msg[100]", 0);
char msg[100];
w("CWPSTRUCT *data = (CWPSTRUCT *)lparam;");
MessageBox(0, "data", "CWPSTRUCT *data = (CWPSTRUCT *)lparam;", 0);
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
w("sprintf");
MessageBox(0, "data", "sprintf", 0);

sprintf(msg, "%d -> %x", g, data->message);
w("msgSend = true;");
MessageBox(0, msg, "MsgSend", 0);
msgSend = true;

}
}
return 1;
}

void w(char *str){
fwrite(str, 1, strlen(str), file);
fwrite("\n", 1, 2, file);
fflush(file);
}


Resultado:

Citar

---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++


---- New call ----
g++
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;
char msg[100]
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
sprintf
msgSend = true;

@Edit: Usando el debugger while (!GetMessage(&msg, 0, 0, 0)) nunca entra en el bucle ni al pulsar al botón X de cerrar la consola.

@Editx2: Cambie el código para comprobar si el hook sigue activo y parece que no:

Código (cpp) [Seleccionar]
LRESULT CALLBACK getPw(int code,WPARAM wparam,LPARAM lparam){
if (code != HC_ACTION){
return (CallNextHookEx(hook, code, wparam, lparam));
}
else if(!wparam){
if (!msgSend){
if (file == NULL){
file = fopen("holaholahola", "w");
}
w("\n\n ---- New call ----");
...
msgSend = true;
}
else{
CWPSTRUCT *data = (CWPSTRUCT *)lparam;
if (data->message == WM_LBUTTONDOWN){
MessageBox(0, "El hook sigue activo", "Buenos dias senior X!!", 0);
}
}
}
return 1;
}


Después de los dialogbox del principio espero unos segundos y pulso con el ratón pero el evento parce que no se recibe porque no se muestra el dialogbox

ivancea96

Lo único que se me ocurre es que se llame 30 veces 30 hilos diferentes, y todos invoquen el MessageBox. Luego, cuando empiezas a cerrarlos, finalmente siguen y terminen los threads.

Haz una prueba: en vez de "g++" y " char msg[100]", saca al archivo "1 -> " + threadID y "2 -> " + threadID.

Si la teoría es cierta, el primer mensaje tendrá el mismo ID que el primer mensaje del segundo conjunto, y etc.

x64core

Eso es un efecto de un mal diseño. patilanz, No sé que exactamente queres hacer pero llamando a alguna funcion sincronica del SO en un callback de mensajes es mala idea. Mejor deberias de decir qué es lo que quieres hacer.