Kan ik de eigenschappen van een externe Window aanpassen?(die dus niet bij mijn proces hoort) Zodat ik bijvoorbeeld de caption-bar van een willekeurige window weg kan halen?
Verwijderd
Je kan met EnumDesktopWindows window handles opvragen van alle windows, dus niet alleen die van je eigen applicatie. Elke applicatie kan de eigenschappen van elk window veranderen, zolang het window van die gebruiker is (je kan dus niet op bijvoorbeeld een win2k met terminal services anderman's windows aan gaan passen).
Op http://unfix.org/projects/onatopp/ staat een tooltje wat van deze eigenschap van Windows gebruik maakt om alpha blending en 'on top' van windows in te stellen. Met spy++ (bijgeleverd met visual c++) kan je kijken wat voor eigenschappen een bepaald window heeft.
Op http://unfix.org/projects/onatopp/ staat een tooltje wat van deze eigenschap van Windows gebruik maakt om alpha blending en 'on top' van windows in te stellen. Met spy++ (bijgeleverd met visual c++) kan je kijken wat voor eigenschappen een bepaald window heeft.
Thanx!
Weet iemand misschien ook met welke WM_??? ik de caption bar van een Window kan verwijderen?
Weet iemand misschien ook met welke WM_??? ik de caption bar van een Window kan verwijderen?
Verwijderd
(zo even uit 't hoofd, dus kan 't helemaal fout hebben)
Niet met een window message, maar met de API functies GetWindowLong() en SetWindowLong(). De caption van een window is onderdeel van de dwStyle die je opgeeft bij CreateWindow().
De code er voor zal vast iets in deze richting zijn:
edit:
Even opgezocht... er zit een grote maar aan:
Remarks
The SetWindowLong function fails if the window specified by the hWnd parameter does not belong to the same process as the calling thread.
Nou is daar ook wel omheen te programmeren (door een thread aan te maken in het proces wat de eigenaar is van dat window) maar dat is niet zo triviaal meer...
Niet met een window message, maar met de API functies GetWindowLong() en SetWindowLong(). De caption van een window is onderdeel van de dwStyle die je opgeeft bij CreateWindow().
De code er voor zal vast iets in deze richting zijn:
code:
1
2
3
| DWORD dwStyle = GetWindowLong(hWnd, GWL_STYLE); dwStyle &= ~WS_CAPTION; SetWindowLong(hWnd, GWL_STYLE, dwStyle); |
edit:
Even opgezocht... er zit een grote maar aan:
Remarks
The SetWindowLong function fails if the window specified by the hWnd parameter does not belong to the same process as the calling thread.
Nou is daar ook wel omheen te programmeren (door een thread aan te maken in het proces wat de eigenaar is van dat window) maar dat is niet zo triviaal meer...
Da's nou jammer..Op donderdag 01 november 2001 12:37 schreef Qlone het volgende:
Even opgezocht... er zit een grote maar aan:
Remarks
The SetWindowLong function fails if the window specified by the hWnd parameter does not belong to the same process as the calling thread.
Ik hoef het alleen maar te doen bij één specifiek window die in fullscreen mode zijn caption bar laat zien (staat zo lelijk op een beamer bij een presentatie). Dus mag het best een hack zijn..Nou is daar ook wel omheen te programmeren (door een thread aan te maken in het proces wat de eigenaar is van dat window) maar dat is niet zo triviaal meer...
Maar hoe doe ik zoiets, heb ik dan de HINSTANCE nodig van het proces
Verwijderd
[een halfuurtje prutsen verder]
Okee. De manier om zoiets te doen is via de window handle die je opvraagt achter het process id te komen van het proces waarvan je een window wilt aanpassen. Vervolgens open je dat proces met OpenProcess, laat je er je eigen thread in draaien met CreateRemoteThread (die dus wel die SetWindowLong() enzo mag uitvoeren) en pas je op die manier dat window aan.
Het klinkt heel eenvoudig, maar er komt nog wel wat programmeerwerk bij kijken. Ik heb even snel een voorbeeldprogrammaatje in elkaar gedraaid wat bovenstaande dus doet op een window handle die er hardcoded in zit, en die ik via spy++ heb opgevraagd voor een notepad.exe. Als je dit zelf gaat gebruiken moet je wel op een wat slimmere manier aan zo'n handle komen; ze zijn telkens anders.
Let op: onderstaande code is niet voor mensen met zwakke zenuwen of maagklachten
edit:
nu zonder al die tikfouten.
Okee. De manier om zoiets te doen is via de window handle die je opvraagt achter het process id te komen van het proces waarvan je een window wilt aanpassen. Vervolgens open je dat proces met OpenProcess, laat je er je eigen thread in draaien met CreateRemoteThread (die dus wel die SetWindowLong() enzo mag uitvoeren) en pas je op die manier dat window aan.
Het klinkt heel eenvoudig, maar er komt nog wel wat programmeerwerk bij kijken. Ik heb even snel een voorbeeldprogrammaatje in elkaar gedraaid wat bovenstaande dus doet op een window handle die er hardcoded in zit, en die ik via spy++ heb opgevraagd voor een notepad.exe. Als je dit zelf gaat gebruiken moet je wel op een wat slimmere manier aan zo'n handle komen; ze zijn telkens anders.
Let op: onderstaande code is niet voor mensen met zwakke zenuwen of maagklachten
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
| // Enge code...
//
#include "stdafx.h"
#include <windows.h>
#pragma check_stack (off)
typedef LONG (WINAPI *MyGetWindowLong)(HWND, int);
typedef LONG (WINAPI *MySetWindowLong)(HWND, int, LONG);
typedef LONG (WINAPI *MySetWindowPos)(HWND, HWND, int, int, int, int, UINT);
struct Info
{
HWND hWnd;
MyGetWindowLong mgwl;
MySetWindowLong mswl;
MySetWindowPos mswp;
};
static DWORD WINAPI MyThread(LPVOID lpParameter)
{
Info *pInfo = (Info *)lpParameter;
DWORD dwStyle = pInfo->mgwl(pInfo->hWnd, GWL_STYLE);
dwStyle &= ~WS_CAPTION;
pInfo->mswl(pInfo->hWnd, GWL_STYLE, dwStyle);
pInfo->mswp(pInfo->hWnd, 0, 0, 0, 0, 0,
SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
return 0;
}
static void After() { }
int main(int argc, char* argv[])
{
DWORD dwId;
HWND hWnd = (HWND)0x00B9027E; // Obtained using spy++...
GetWindowThreadProcessId(hWnd, &dwId);
HANDLE hProcess = OpenProcess(
PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|
PROCESS_VM_READ, false, dwId);
int nCodeSize = ((BYTE *)(DWORD)After - (BYTE *)(DWORD)MyThread);
void *pRemoteCode = VirtualAllocEx(hProcess, 0, nCodeSize + 100,
MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (pRemoteCode) printf("Remote memory allocated OK\n");
DWORD dwWritten;
if (WriteProcessMemory(hProcess, pRemoteCode, MyThread, nCodeSize, &dwWritten))
printf("Written successfully! (%d bytes)\n", dwWritten);
HMODULE hUser32 = GetModuleHandle(__TEXT("User32"));
Info *pData = (Info *)((BYTE *)pRemoteCode + ((nCodeSize + 4) & ~ 3));
Info LocalData;
LocalData.hWnd = hWnd;
LocalData.mgwl = (MyGetWindowLong)GetProcAddress(hUser32, "GetWindowLongA");
if (LocalData.mgwl) printf("LocalData: mgwl\n");
LocalData.mswl = (MySetWindowLong)GetProcAddress(hUser32, "SetWindowLongA");
if (LocalData.mswl) printf("LocalData: mswl\n");
LocalData.mswp = (MySetWindowPos)GetProcAddress(hUser32, "SetWindowPos");
if (LocalData.mswp) printf("LocalData: mswp\n");
WriteProcessMemory(hProcess, pData, &LocalData, sizeof(Info), &dwWritten);
DWORD dwTId;
CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)(DWORD)pRemoteCode, (void *)pData, 0, &dwTId);
//CreateThread(NULL, 0, &MyThread, (void *)hWnd, 0, &dwTId);
Sleep(5000);
return 0;
} |
edit:
nu zonder al die tikfouten.
Thanx! (again)

* traviandus houdt wel van enge code
Nu kan ik de window handle wel resolven door zijn naam, want die staat (in mijn geval) vast.
Misschien ook wel leuk om er een interface omheen te bouwen waarmee Window properties van alle desktop window kunnen worden veranderd. Helemaal niet zo moeilijk op deze manier!
* traviandus houdt wel van enge code
Nu kan ik de window handle wel resolven door zijn naam, want die staat (in mijn geval) vast.
Misschien ook wel leuk om er een interface omheen te bouwen waarmee Window properties van alle desktop window kunnen worden veranderd. Helemaal niet zo moeilijk op deze manier!
Beetje door de code heen gelopen: Wel heeeeel eng!
Ooit eens een debugger geschreven ofzo!?
Maar ik heb nog een vraag:
De functie VirtualAllocEx() werkt alleen onder NT
en ik heb Win98. Alle andere functies werken wel onder 98, behalve dus dus dat remote alloceren. Het progje werkt zo dus niet...
Weet je daar iets op?
Ooit eens een debugger geschreven ofzo!?
Maar ik heb nog een vraag:
De functie VirtualAllocEx() werkt alleen onder NT
Weet je daar iets op?
Ah, kijk een topic waar ik mijn kennis in kwijt kan. 
Je kunt bij ieder window komen in je complete besturingssysteem. Je kunt dat doen door middel van system-hooks op de GetMessage of SendMessage functies. Op deze manier doet Spy++ dat bijvoorbeeld ook. Op die manier kun je dus dynamisch een window-handle opvragen, van het window dat je nodig hebt. Zoals eerder gezegd veranderen de window-handles continue, je kunt dus niet hardcoded een windowhandle in je source-code zetten, want dat gaat niet werken.
Je moet inderdaad wel gebruik maken van de SetWindowLong functie.
Ik heb bij een software bedrijf gewerkt die applicaties schreef ter beveiliging van het besturingssysteem, daar heb ik een module ontwikkeld welke diep in het besturingssysteem verankerd zat en o.a. de distributie van windows-messages kon analyseren/wijzigen/blokkeren etc.
Als ik tijd heb zal ik er vanavond nog eens uitgebreider naar kijken.
Ik weet niet of het op de manier kan zoals Qlone zegt, maar het ik denk dat hij er ook het nodige vanaf weet dat het ook werkt. Op de manier zoals ik het doe moet je een DLL schrijven die gemapped wordt in de process-adres space van het proces waarvan je het window wilt wijzigen. Dit werkt onder Windows 9x/Windows NT 3.5x en hoger/Windows 2000 en zelfs onder Win 3.1 (na enige aanpassingen)
.
Je kunt bij ieder window komen in je complete besturingssysteem. Je kunt dat doen door middel van system-hooks op de GetMessage of SendMessage functies. Op deze manier doet Spy++ dat bijvoorbeeld ook. Op die manier kun je dus dynamisch een window-handle opvragen, van het window dat je nodig hebt. Zoals eerder gezegd veranderen de window-handles continue, je kunt dus niet hardcoded een windowhandle in je source-code zetten, want dat gaat niet werken.
Je moet inderdaad wel gebruik maken van de SetWindowLong functie.
Ik heb bij een software bedrijf gewerkt die applicaties schreef ter beveiliging van het besturingssysteem, daar heb ik een module ontwikkeld welke diep in het besturingssysteem verankerd zat en o.a. de distributie van windows-messages kon analyseren/wijzigen/blokkeren etc.
Als ik tijd heb zal ik er vanavond nog eens uitgebreider naar kijken.
Ik weet niet of het op de manier kan zoals Qlone zegt, maar het ik denk dat hij er ook het nodige vanaf weet dat het ook werkt. Op de manier zoals ik het doe moet je een DLL schrijven die gemapped wordt in de process-adres space van het proces waarvan je het window wilt wijzigen. Dit werkt onder Windows 9x/Windows NT 3.5x en hoger/Windows 2000 en zelfs onder Win 3.1 (na enige aanpassingen)
"The fastest code, is the code that is never called."
D'r komen inderdaad maar weinig hardcore Win32 vraagjes voorbij.. gelukkig zitten er tussen al die script kiddies nog wat mensen die hier een beetje verstand van hebben.Op donderdag 01 november 2001 16:48 schreef Primal het volgende:
Ah, kijk een topic waar ik mijn kennis in kwijt kan.
Ik zie nog niet gelijk het verband tussen een hook op SendMessage() en het wijzigen van de window style..Je kunt bij ieder window komen in je complete besturingssysteem. Je kunt dat doen door middel van system-hooks op de GetMessage of SendMessage functies. Op deze manier doet Spy++ dat bijvoorbeeld ook. Op die manier kun je dus dynamisch een window-handle opvragen, van het window dat je nodig hebt. Zoals eerder gezegd veranderen de window-handles continue, je kunt dus niet hardcoded een windowhandle in je source-code zetten, want dat gaat niet werken.
Je moet inderdaad wel gebruik maken van de SetWindowLong functie.
Aha, nou begin ik het een beetje te snappen. Dan roep je SetWindowLong() aan vanuit je hook proc als bv. het window wordt aangemaakt. Maar hoe implementeer ik zoiets?Op de manier zoals ik het doe moet je een DLL schrijven die gemapped wordt in de process-adres space van het proces waarvan je het window wilt wijzigen. Dit werkt onder Windows 9x/Windows NT 3.5x en hoger/Windows 2000 en zelfs onder Win 3.1 (na enige aanpassingen).
Qlone: Jouw methode moet vast wel werken onder Win98, omdat bijna alles kan (WriteProcessMemory(), CreateRemoteThread()) behalve dan dat alloceren.. daar moet toch een workaround voor zijn?
Verwijderd
Ik weet niet of het op de manier kan zoals Qlone zegt, maar het ik denk dat hij er ook het nodige vanaf weet dat het ook werkt.
Het stukje code wat ik gepaste heb werkt uitstekend, maar natuurlijkOp de manier zoals ik het doe moet je een DLL schrijven die gemapped wordt in de process-adres space van het proces waarvan je het window wilt wijzigen.
Goeie reden om dat dan maar niet meer te gebruikenDe functie VirtualAllocEx() werkt alleen onder NT en ik heb Win98
Overigens, als je serieus bezig gaat met software ontwikkeling onder windows is het sowieso een goed idee om een NT-gebaseerde versie te nemen; dingen als debuggen en het opvangen van fouten in je code zijn een stuk robuuster daarop.
Nee... het was eigenlijk die vraag van jou en het niet werken van de oplossing die ik in eerste instantie in gedachten had waardoor ik eens verder ben gaan nadenken en hier op ben uitgekomen. Nou zijn dit soort functies wel voornamelijk bedoeld om dingen als debuggen makkelijker te maken, en ze laten zich goed misbruiken als je eens wat creatiefs wilOoit eens een debugger geschreven ofzo!?
Een woord: QueueUserAPC.Op donderdag 01 november 2001 12:37 schreef Qlone het volgende:
Nou is daar ook wel omheen te programmeren (door een thread aan te maken in het proces wat de eigenaar is van dat window) maar dat is niet zo triviaal meer...
En voor nog meer pret over hoe je dat proces nu eigenlijk gaat vinden: CreateToolhelp32Snapshot, Process32First en Process32Next. Daarmee kun je gewoon op exe-name het process met al z'n threads en handles opzoeken a la TaskManager.
Sorry Traviandus, ik had gisteravond geen tijd meer om even verder te kijken. Ik zal het proberen vanavond te doen.
Maar het kan natuurlijk ook op een heel andere manier. Je kunt ook de handle naar de parent-window (de root) opvragen, is geloof ik altijd het desktop window. Daaronder hangt een boom-structuur van child-windows (alle andere applicaties). Je kunt deze structuur dan doorlopen en dan testen of je het goede window te pakken hebt (door bijvoorbeeld te checken op de window-titel).
Er zijn veel oplossingen, maar nogmaals ik heb nog niet veel tijd gehad om hier serieus over na te denken (ik werk namelijk ook
).
Ik heb zoveel systeem-crashes gehad, dat wil je niet weten. Maar ja, ik was natuurlijk wel wat 'low-level' bezig. 
Kijk kijk, er begint hem al iets te dagen! Right on! Dat heb je goed gedacht ja.Aha, nou begin ik het een beetje te snappen. Dan roep je SetWindowLong() aan vanuit je hook proc als bv. het window wordt aangemaakt. Maar hoe implementeer ik zoiets?
Sorry, maar dat ben ik niet met je eens. Je schrijft een normale DLL, die automatisch in het process-address space van een ander proces wordt gemapped. Dit gebeurt als je de system-hooks gaat gebruiken. De DLL krijgt de window-messages die bestemd zijn voor het betreffende window, dan eerst te zien, voordat deze worden door gestuurd naar de thread (die iedere applicatie heeft) die de afhandeling van window-messages verzorgd.De oplossing met de DLL is haast net zo ranzig als even een thread starten in een ander proces, maar een stuk meer programmeerwerk...
Maar het kan natuurlijk ook op een heel andere manier. Je kunt ook de handle naar de parent-window (de root) opvragen, is geloof ik altijd het desktop window. Daaronder hangt een boom-structuur van child-windows (alle andere applicaties). Je kunt deze structuur dan doorlopen en dan testen of je het goede window te pakken hebt (door bijvoorbeeld te checken op de window-titel).
Er zijn veel oplossingen, maar nogmaals ik heb nog niet veel tijd gehad om hier serieus over na te denken (ik werk namelijk ook
Inderdaad ja. Helaas gold dat voor mij niet tijdens het ontwikkelen van de module.Overigens, als je serieus bezig gaat met software ontwikkeling onder windows is het sowieso een goed idee om een NT-gebaseerde versie te nemen; dingen als debuggen en het opvangen van fouten in je code zijn een stuk robuuster daarop.
Schot in de roos!En voor nog meer pret over hoe je dat proces nu eigenlijk gaat vinden: CreateToolhelp32Snapshot, Process32First en Process32Next. Daarmee kun je gewoon op exe-name het process met al z'n threads en handles opzoeken a la TaskManager.
"The fastest code, is the code that is never called."
Verwijderd
Als ie automatisch in de adres space van de ander gemapped wordt gebeurt dat neem ik aan voor *alle* processen. Dat is wat ik tegen zulke oplossingen heb. Een kleine fout in zo'n DLL leidt dan al snel tot allerhande vage en moelijk te troubleshooten problemen in programma's.Sorry, maar dat ben ik niet met je eens. Je schrijft een normale DLL, die automatisch in het process-address space van een ander proces wordt gemapped. Dit gebeurt als je de system-hooks gaat gebruiken. De DLL krijgt de window-messages die bestemd zijn voor het betreffende window, dan eerst te zien, voordat deze worden door gestuurd naar de thread (die iedere applicatie heeft) die de afhandeling van window-messages verzorgd.
Doet me denken aan een oude versie van zipmagic... Die kon zip files 'transparant' maken voor het systeem, dus zo dat alle programma's een zipfile kunnen zien als een gewone directory. Leuk... ware het niet dat er een bug in de driver die dat programma gebruikte zat waardoor *sommige* programma's ineens geen file meer geopend kregen.
Ander voorbeeldje... Nero. Nero installeert een filter driver waardoor op sommige systemen hibernate spontaan niet meer werkt.
Ik ben er dus gewoon uit principe tegen om dit soort hacks invloed te laten hebben op meer dan het te 'hacken' proces, zelfs als dat betekent dat de te gebruiken oplossing minder mooi is dan zou kunnen.
Het maken van filterende componenten (kernel of userspace) is vaak minder triviaal dan het lijkt; je dekt zelden alle situaties goed af. Ik heb zelf op dit gebied meer ervaring in kernel mode. Opgedaan bij het schrijven van een TDI filter driver om logging van tcp en udp verkeer mogelijk te maken, en ben lang bezig geweest voor dat ook de wat minder vaak voorkomende situaties goed afgehandeld werden.
(bovenstaande argumenten gelden dus in het algemeen tegen hooken en filteren, niet specifiek tegen de door Primal aangedragen mogelijkheid... dat 't niet verkeerd wordt opgevat
Nooit mee gewerkt... kan je net als ik deed een klein voorbeeldprogrammaatje posten wat de titelbalk van een window weg kan halen op die manier? Ben benieuwd...Een woord: QueueUserAPC
Gaan we nu niet meer de kant op 'hoe sporen we een window/proces op'. Dat is geen probleem hier... het aanroepen van die SetWindowLong() was het oorspronkelijke probleem... de rest lukt welEn voor nog meer pret over hoe je dat proces nu eigenlijk gaat vinden: CreateToolhelp32Snapshot, Process32First en Process32Next.
Kijk dit vind ik nu een gewone normale leuke discussie over het oplossen van problemen zonder elkaar de haren in te vliegen. 
Waar ik het helemaal met je mee eens ben is als je code buggie is, het tot zeer grote problemen binnen je complete besturingssysteem kan leiden. Een algemene systeem-crash tot gevolg. Daar heb je gedeeltelijk gelijk in. Ik raad ook nooit aan om system-wide hooks te plaatsen, alleen thread-specifik. Dat is toch minder ingrijpend.
Ok, beetje offtopic, maar leuk om toch op een normale manier van iemand anders te horen hoe hij over bepaalde zaken denkt.
Dit klopt niet helemaal. Je kunt namelijk ook 'thread-specifik' hooks zetten. Dat wil zeggen dat je DLL alleen daar in de process-address space wordt gemapped bij het proces waarbij je het wilt.Op vrijdag 02 november 2001 17:21 schreef Qlone het volgende:
[..]
Als ie automatisch in de adres space van de ander gemapped wordt gebeurt dat neem ik aan voor *alle* processen. Dat is wat ik tegen zulke oplossingen heb. Een kleine fout in zo'n DLL leidt dan al snel tot allerhande vage en moelijk te troubleshooten problemen in programma's.
Waar ik het helemaal met je mee eens ben is als je code buggie is, het tot zeer grote problemen binnen je complete besturingssysteem kan leiden. Een algemene systeem-crash tot gevolg. Daar heb je gedeeltelijk gelijk in. Ik raad ook nooit aan om system-wide hooks te plaatsen, alleen thread-specifik. Dat is toch minder ingrijpend.
Ok, beetje offtopic, maar leuk om toch op een normale manier van iemand anders te horen hoe hij over bepaalde zaken denkt.
"The fastest code, is the code that is never called."
Ik zal vandaag eens aan de slag gaan met de aangedragen oplossingen. De resultaten post ik dan wel hier.
En wat is die klungelige oplossing?Goeie reden om dat dan maar niet meer te gebruiken Ik weet wel een manier om om die remote alloc heen te werken overigens, maar dat is een wat klungelige oplossing (helemaal 9x stijl ).
Daar heb je zeker gelijk in, maar ik ben niet zo veel bezig met Win32 software ontwikkeling. Bovendien moet de hack die ik probeer te maken draaien op een Windows 98 machine (daar kan ik niks aan veranderen)Overigens, als je serieus bezig gaat met software ontwikkeling onder windows is het sowieso een goed idee om een NT-gebaseerde versie te nemen; dingen als debuggen en het opvangen van fouten in je code zijn een stuk robuuster daarop.
Dat zal ik dan maar proberen. Moet ik wel eerst een flink stuk lezen over Win32 hooks in MSDN, want daar weet ik nog (nauwelijks) iets van.Dit klopt niet helemaal. Je kunt namelijk ook 'thread-specifik' hooks zetten. Dat wil zeggen dat je DLL alleen daar in de process-address space wordt gemapped bij het proces waarbij je het wilt.
Niet gelukt
maar wel bijna 
Ik heb de hook methode geprobeerd. Alleen komen de messages die ik met SendMessage verstuur niet langs mijn hook proc. Messages van windows, zoals het bewegen van de muis over de window, gaan wél via mijn hook procedure.
Hier is mijn code:
De DLL
De Applicatie
De WM_HIDECAPTION message die wordt verzonden gaat dus niet via mijn hook procedure.
Ik heb de hook methode geprobeerd. Alleen komen de messages die ik met SendMessage verstuur niet langs mijn hook proc. Messages van windows, zoals het bewegen van de muis over de window, gaan wél via mijn hook procedure.
Hier is mijn code:
De DLL
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
| // The DLL containing the hook
#include <windows.h>
#include <fstream.h>
#include <stdio.h>
#defineWM_HIDECAPTIONWM_USER + 1000
typedef LONG (WINAPI *MyGetWindowLong)(HWND, int);
typedef LONG (WINAPI *MySetWindowLong)(HWND, int, LONG);
typedef LONG (WINAPI *MySetWindowPos)(HWND, HWND, int, int, int, int, UINT);
struct Info
{
MyGetWindowLong mgwl;
MySetWindowLong mswl;
MySetWindowPos mswp;
};
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern "C"
LRESULT CALLBACK HookRemoveCaption(int nCode,WPARAM wParam,LPARAM lParam)
{
CWPSTRUCT* cwp = (CWPSTRUCT*)lParam;
if (cwp->message == WM_HIDECAPTION) {
Info LocalData;
HMODULE hUser32 = GetModuleHandle(__TEXT("User32"));
LocalData.mgwl = (MyGetWindowLong)GetProcAddress(hUser32, "GetWindowLongA");
LocalData.mswl = (MySetWindowLong)GetProcAddress(hUser32, "SetWindowLongA");
LocalData.mswp = (MySetWindowPos)GetProcAddress(hUser32, "SetWindowPos");
DWORD dwStyle = LocalData.mgwl(cwp->hwnd, GWL_STYLE);
dwStyle &= ~WS_CAPTION;
LocalData.mswl(cwp->hwnd, GWL_STYLE, dwStyle);
LocalData.mswp(cwp->hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
}
return 0; // ..bypass other hooks..
} |
De Applicatie
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
| #include <windows.h>
#include <stdio.h>
#include <string>
using namespace std;
#pragma check_stack (off)
#defineWM_HIDECAPTIONWM_USER + 1000
#define NBUF 512
char buffer[NBUF];
HWND theVictimHwnd = NULL;
BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam)
{
GetWindowText(hwnd,buffer,NBUF);
string wndStr(buffer);
int loc = wndStr.find((char*)lParam);
if (loc != string::npos) {
// match found!
theVictimHwnd = hwnd;
GetWindowText(hwnd,buffer,NBUF);
printf("patching \"%s\"...\n",buffer);
return FALSE;
}
return TRUE;
}
int main(int argc, char* argv[])
{
HOOKPROC hkprc;
HHOOK hook;
HINSTANCE instDLL;
DWORD pID;
if (argc == 1) {
printf("usage: remcapt <window title>\n");
return 0;
}
// find the handle of the specified window
EnumWindows(EnumWindowsProc,(LPARAM)argv[1]);
if (theVictimHwnd == NULL) {
printf("error: window containing \"%s\" not found\n",argv[1]);
return 0;
}
// install a hook on the specified window
instDLL = LoadLibrary("..//Dll//Debug//Dll.dll");
if (instDLL == NULL) {
printf("error: remcapt.dll not found.");
return 0;
}
hkprc = (HOOKPROC)GetProcAddress(instDLL,"HookRemoveCaption");
hook = SetWindowsHookEx(WH_CALLWNDPROC,hkprc,instDLL,
GetWindowThreadProcessId(theVictimHwnd,&pID));
if (hook == NULL) {
DWORD Nbr=GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,Nbr,
MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),buffer,NBUF,
NULL);
printf("error: failed to place hook --%s",buffer);
}
// hide caption bar
SendMessage(theVictimHwnd,WM_HIDECAPTION,0,0);
Sleep(3000);
// exit
if (hook != NULL) UnhookWindowsHookEx(hook);
FreeLibrary(instDLL);
return 0;
} |
De WM_HIDECAPTION message die wordt verzonden gaat dus niet via mijn hook procedure.
Messages van bijv. de muis worden d.m.v. de PostMessage functie verstuurd. Deze functie wordt gebruikt in het geval dat er geen synchronisatie hoeft plaats te vinden. De functie wordt door het OS aangeroepen en meteen weer geretouneerd zonder te wachten op het resultaat. Dit in tegenstelling tot de SendMessage functie.
Je hebt dus op zijn minst 2 verschillende manieren van versturen/ontvangen van messages. Daarom heb je ook 2 type hooks nodig, nl.:
-WH_CALLWNDPROC
-WH_GETMESSAGE
Deze geef je dus op als parameter voor de SetWindowsHookEx functie (1 keer voor de CallWndHook en 1 keer voor de GetMessageHook).
De filter c.q. hook-functie voor bijvoorbeeld de messages die verstuurd zijn met PostMessage moet er qua opzet zo uitzien:
Het is belangrijk dat je in je 'hook' functies als laatste de message door-'passed' naar de volgende filter c.q. hook-functie in de hook-chain. Dat moet je doen middels de volgende functie aanroep:
Een voorbeeld van een filter c.q. hook-functie die message opvangt die met SendMessage verstuurd zijn is:
De filter c.q. hook-functies zitten dus in je DLL!
Vergeet niet de hooks te verwijderen als je applicatie stopt, als je ze niet meer nodig hebt of als het werk gedaan is (bijv. als je de eigenschappen van het window dat je zocht gewijzigd zijn). Doe je dit niet en laat je ze open staan als je applicatie beïndigd is, dan kan dit tot een systeem-crash leiden. Beware!
Verwijderen doe je met de functie UnhookWindowsHookEx.
Ik heb effe een klein stukje geschreven, de rest moet je zelf doen.
Maar ik heb het idee dat je dat wel lukt, aangezien je toch redelijkerwijs begrijpt waar ik c.q. Qlone het over hebben.
Oh ja, kijk voor jezelf welke oplossing jij het beste vind, misschien een middenweg. In ieder geval is dit weer een goede leerschool voor je.
Uiteraard zijn er vele wegen die leiden tot dezelfde oplossing. Sommige zijn korter, andere langer. 
Altijd vrij tot vragen.
Je hebt dus op zijn minst 2 verschillende manieren van versturen/ontvangen van messages. Daarom heb je ook 2 type hooks nodig, nl.:
-WH_CALLWNDPROC
-WH_GETMESSAGE
Deze geef je dus op als parameter voor de SetWindowsHookEx functie (1 keer voor de CallWndHook en 1 keer voor de GetMessageHook).
De filter c.q. hook-functie voor bijvoorbeeld de messages die verstuurd zijn met PostMessage moet er qua opzet zo uitzien:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| LRESULT CALLBACK SpyGetMsgProc(INT iHookCode,WPARAM wParam,LPARAM lParam)
{
PMSG pMessage;
pMessage = (PMSG)lParam;
// De variabele iHookCode geeft aan of de message
// zonder enige modificatie vertraging etc.
// doorverzonden moet worden aan de volgende filter-
// functie in de hook-chain.
if ((iHookCode >= 0) && (pMessage) && (pMessage->hwnd))
{
// Hier kun je dus je code, modificeren van de
// window-titel, window-eigenschappen wijzigen,
// messages verwijderen etc. In jou geval moet je
// dus weten (door te testen op bijv. window-titel)
// om welk window het gaat, anders ga je in ieder
// window rommelen. :) Ook leuk trouwens.
}
// Roep de volgende filter-functie in de 'hook-chain'
// aan.
return(CallNextHookEx(NULL, iHookCode, wParam, lParam));
} |
Het is belangrijk dat je in je 'hook' functies als laatste de message door-'passed' naar de volgende filter c.q. hook-functie in de hook-chain. Dat moet je doen middels de volgende functie aanroep:
code:
1
| return(CallNextHookEx(NULL, iHookCode, wParam, lParam)); |
Een voorbeeld van een filter c.q. hook-functie die message opvangt die met SendMessage verstuurd zijn is:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| LRESULT CALLBACK SpyCallMsgProc(INT iHookCode,WPARAM wParam,LPARAM lParam)
{
PCWPSTRUCT pCwps;
pCwps = (PCWPSTRUCT)lParam;
// De variabele iHookCode geeft aan of de message
// zonder enige modificatie vertraging etc.
// doorverzonden moet worden aan de volgende filter-
// functie in de hook-chain.
if ((iHookCode >= 0) && (pCwps) && (pCwps->hwnd))
{
// Hier kun je dus je code, modificeren van de
// window-titel, window-eigenschappen wijzigen,
// bla bla
}
// Roep de volgende filter-functie in de 'hook-chain'
// aan.
return(CallNextHookEx(NULL, iHookCode, wParam, lParam));
} |
De filter c.q. hook-functies zitten dus in je DLL!
Vergeet niet de hooks te verwijderen als je applicatie stopt, als je ze niet meer nodig hebt of als het werk gedaan is (bijv. als je de eigenschappen van het window dat je zocht gewijzigd zijn). Doe je dit niet en laat je ze open staan als je applicatie beïndigd is, dan kan dit tot een systeem-crash leiden. Beware!
Verwijderen doe je met de functie UnhookWindowsHookEx.
Ik heb effe een klein stukje geschreven, de rest moet je zelf doen.
Oh ja, kijk voor jezelf welke oplossing jij het beste vind, misschien een middenweg. In ieder geval is dit weer een goede leerschool voor je.
Altijd vrij tot vragen.
"The fastest code, is the code that is never called."
Verwijderd
Ehh om de verwarring dan maar wat groter te maken, je code werkt gewoon hier... heeft hier 1x gewerkt maar daarna niet meer!?Op zaterdag 03 november 2001 19:35 schreef traviandus het volgende:
De WM_HIDECAPTION message die wordt verzonden gaat dus niet via mijn hook procedure.
Gelukt! 
Ik heb de code maar even online gezet..
remcapt.cpp
remcapt_dll.cpp
remcapt.def
Ik heb dus de eerder geposte prog aangepast en de suggesties van Primal toegepast.
Qlone en Primal, bedankt voor jullie uitgebreide reacties!
Ik heb de code maar even online gezet..
remcapt.cpp
remcapt_dll.cpp
remcapt.def
Ik heb dus de eerder geposte prog aangepast en de suggesties van Primal toegepast.
Qlone en Primal, bedankt voor jullie uitgebreide reacties!
Het werkt dus? Ok, great job!
"The fastest code, is the code that is never called."
Verwijderd
Wat doen jullie moeilijk? Je hoeft niets met threads of hooks te doen. In een paar regels, alle windows in het systeem transparant maken:
roep ergens
EnumWindows(EnumWindowsProc, 0);
aan, en laat het feest beginnen:
roep ergens
EnumWindows(EnumWindowsProc, 0);
aan, en laat het feest beginnen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
LONG windowSettings = GetWindowLong(hwnd, GWL_EXSTYLE);
// --- Make window transparent
if (lParam == 0)
{
windowSettings |= 0x80000;
SetWindowLong(hwnd, GWL_EXSTYLE, windowSettings);
SetLayeredWindowAttributes(hwnd, 0, 150, 0x2);
}
else
{
windowSettings ^= 0x80000;
SetWindowLong(hwnd, GWL_EXSTYLE, windowSettings);
UpdateWindow(hwnd);
}
return TRUE;
} |
Tjonge jonge, dat is nou jammer dat het toch nog verpest wordt. Meneer (as I assume) heeft niet goed gelezen.Op zondag 04 november 2001 17:30 schreef Kurzweil het volgende:
Wat doen jullie moeilijk?
As I quote myself:
Oh ja, kijk voor jezelf welke oplossing jij het beste vind, misschien een middenweg. In ieder geval is dit weer een goede leerschool voor je. Uiteraard zijn er vele wegen die leiden tot dezelfde oplossing. Sommige zijn korter, andere langer.
"The fastest code, is the code that is never called."
Dat zou toch niet mogen werken...Wat doen jullie moeilijk? Je hoeft niets met threads of hooks te doen. In een paar regels, alle windows in het systeem transparant maken:
Toch?Op donderdag 01 november 2001 12:37 schreef Qlone het volgende:
Remarks
The SetWindowLong function fails if the window specified by the hWnd parameter does not belong to the same process as the calling thread.
Jawel, aangezien je callback functie vanuit het systeem wordt aangeroepen en dus niet vanuit je eigen Thread context. Op die manier kun je dus dingen met alle windows doen.Op maandag 05 november 2001 08:59 schreef traviandus het volgende:
Dat zou toch niet mogen werken...
Toch?
Of het altijd werkt en of het netjes is is een hele grote 2e
- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!
Verwijderd
En ik heb er zeer sterk mijn twijfels bij. Zelfs als enumwindowproc aangeroepen wordt vanuit het systeem, dan is dat nog steeds niet vanuit een thread die 'eigenaar' is van zo'n window.Of het altijd werkt en of het netjes is is een hele grote 2e
Verder weet ik niet of je dit getest hebt en op welke versie van windows, maar onder NT/2k/XP worden callbacks uitgevoerd in de context van je eigen proces, ivm beveiliging. (zou mooie boel zijn als je via een enum callback ineens system rechten zou hebben...)
Als het onder Win98 werkt vind ik het best...Op maandag 05 november 2001 11:21 schreef Qlone het volgende:
Verder weet ik niet of je dit getest hebt en op welke versie van windows, maar onder NT/2k/XP worden callbacks uitgevoerd in de context van je eigen proces, ivm beveiliging. (zou mooie boel zijn als je via een enum callback ineens system rechten zou hebben...)
Ik zal het straks ff proberen.
En dat is nu juist een voordeel van de oplossing/leermethode
die ik heb beschreven, want daar gebeurt het dus wel.
De DLL die je geschreven hebt wordt namelijk gemapped in het process-address space van het proces waarvan je het wilt (thread-specifik) of van alle draaiende processen (system-wide). Bij een thread-specifik wordt de filter-functie aangeroepen vanuit de context van de thread (eigenaar van het window dat je wilt hacken) en bij een system-wide hook kan de filter functie aangeroepen worden vanuit de context van iedere thread in het OS.
Ik zal dus nogmaals het grote nadeel van 'system-wide' hooks aanstippen. Aangezien ze in de process-address space' van alle draaiende processen worden gemapped, zal dit tenkoste gaan van de performance (op de huidige systemen in de zin van Gigahertzen valt het niet meer zo op, maar op een 166Mhz. Pentium wel
). Ander nadeel is dat als je code buggie is je een proces dus helemaal omlaag kunt trekken, omdat ze in zijn address-space zitten. Leuk voor als je wilt hacken
. Dit zijn eigenlijk de 2 grootste nadelen, ook al eerder aangestipt door Qlone.
De DLL die je geschreven hebt wordt namelijk gemapped in het process-address space van het proces waarvan je het wilt (thread-specifik) of van alle draaiende processen (system-wide). Bij een thread-specifik wordt de filter-functie aangeroepen vanuit de context van de thread (eigenaar van het window dat je wilt hacken) en bij een system-wide hook kan de filter functie aangeroepen worden vanuit de context van iedere thread in het OS.
Ik zal dus nogmaals het grote nadeel van 'system-wide' hooks aanstippen. Aangezien ze in de process-address space' van alle draaiende processen worden gemapped, zal dit tenkoste gaan van de performance (op de huidige systemen in de zin van Gigahertzen valt het niet meer zo op, maar op een 166Mhz. Pentium wel
"The fastest code, is the code that is never called."
code:
1 2 3 4 5 6 7 8 9static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { //..blabla.. SetWindowLong(hwnd, GWL_EXSTYLE, windowSettings); // .. return TRUE; }
Dit werkt dus inderdaad niet. SetWindowLong() geeft 0 terug (op win98), hij failed dus.En ik heb er zeer sterk mijn twijfels bij. Zelfs als enumwindowproc aangeroepen wordt vanuit het systeem, dan is dat nog steeds niet vanuit een thread die 'eigenaar' is van zo'n window.
Die CALLBACK functie gewoon een procedure net als iedere andere in je proces, maar met een andere calling convention (FAR) omdat hij van buiten je proces (het OS) moet kunnen worden aangeroepen.
Dus toch niet voor niks geweest om een DLL te schrijven.
Edit:
offtopic:
Kurzweil, lParam is toch altijd 0 hier?
[code]if (lParam == 0)
{
// ..
}
else
{
// hier komen we dus nooit?
}[/code]
Kurzweil, lParam is toch altijd 0 hier?
[code]if (lParam == 0)
{
// ..
}
else
{
// hier komen we dus nooit?
}[/code]
Pagina: 1