Test Foro de elhacker.net SMF 2.1

Programación => Programación C/C++ => Mensaje iniciado por: patilanz en 8 Julio 2015, 01:18 AM

Título: WH_CALLWNDPROC llamada de forma rara
Publicado por: patilanz en 8 Julio 2015, 01:18 AM
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
Título: Re: WH_CALLWNDPROC llamada de forma rara
Publicado por: 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.
Título: Re: WH_CALLWNDPROC llamada de forma rara
Publicado por: patilanz en 8 Julio 2015, 01:39 AM
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).
Título: Re: WH_CALLWNDPROC llamada de forma rara
Publicado por: ivancea96 en 8 Julio 2015, 01:41 AM
Sin palabras. Si encuentras la solución, coméntala :p
Título: Re: WH_CALLWNDPROC llamada de forma rara
Publicado por: ivancea96 en 8 Julio 2015, 01:56 AM
¿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 (https://msdn.microsoft.com/en-us/library/windows/desktop/ms644936%28v=vs.85%29.aspx) retorna 0 cuando obtiene el mensaje WM_QUIT.
Título: Re: WH_CALLWNDPROC llamada de forma rara
Publicado por: patilanz en 8 Julio 2015, 11:33 AM
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
Título: Re: WH_CALLWNDPROC llamada de forma rara
Publicado por: ivancea96 en 8 Julio 2015, 14:11 PM
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.
Título: Re: WH_CALLWNDPROC llamada de forma rara
Publicado por: x64core en 9 Julio 2015, 05:57 AM
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.