Click here to Skip to main content
Click here to Skip to main content

Manipulating Windows using messages and simple CBT hooking

By , 7 Aug 2003
 

Introduction

Windows is essentially a message driven Operating System in the sense that, the majority of actions that take place are responses to messages sent to the main window procedure of an application. Whether you press a key, or move the mouse or drag a window the application receives messages through it's message queue and reacts accordingly. Now this results in a rather interesting corollary that can be taken advantage of by us, developers; by sending the correct messages to a window or it's child windows in the proper order, we can actually simulate human actions on an application. And this has it's uses in various scenarios. Obviously the first one that comes to mind is the ability to automate a task, like for example opening a document in word, left justifying the entire text and taking a print out.

But for me a more interesting usage of this technique is when it's applied to take advantage of the Windows user interface to quickly do tasks, which might otherwise require a lot of programming calls and access to undocumented information. This includes changing various system properties, making changes through the control panel applets or even changing display properties for the desktop. In this article I will randomly select one such scenario ( a test case scenario ) and see how to go about automating the task by using some simple windows techniques like posting messages to a window, enumerating child windows and elementary CBT hooking.

Test scenario

I am going to be using Windows XP Professional as my test platform and therefore my example scenario is only meaningful in an XP context. Users of other Operating Systems might have to make suitable changes to my example code snippets to get the same end result as in this article.

By default, the keyboard navigation short cuts for menus are not shown in the XP operating system ( something that both puzzled and annoyed a lot of users when they first encountered this in Windows 2000 ). Having long abandoned Windows 2000, I do not remember if there was a documented way of changing this setting in 2000, other than by editing the registry or using some tweaking application, but in XP this setting can be easily changed by using the Display Properties control panel applet. All you need to do is select the Appearances tab from the Display Properties dialog box, bring up the Effects sub-window and uncheck the check box that says "Hide underlined letters for keyboard navigation until I press the Alt key". Now I am wholly sure that this setting can probably be changed by modifying a trivial registry entry; but for the sake of this test case scenario and the article, let's assume that we do not know how to achieve the same programmatically.

The human approach

Let's see how we'd do this had we done this manually sitting in front of the machine. We'd probably have to follow these steps ( or something very similar ) :-

  1. Right click on the desktop and bring up the Display Properties control panel applet
  2. Chose the Appearances tab
  3. Bring up the Effects sub-window by clicking on the Effects button
  4. Check/Uncheck the corresponding check box depending on what we are trying to do
  5. Click OK to dismiss the Effects sub-window
  6. Click OK to dismiss the Display Properties and apply our changes globally

The solution in code

Now we need to decide what we need to do to achieve the same sequence of events through code.

  1. Bringing up the Display Properties window and choosing the Appearances tab can be done in just one step because we know that the Display Properties control panel applet is called desk.cpl and that it takes command line arguments that can be used to dictate which tab comes up by default. In fact we need to call it like this :-
    control.exe desk.cpl Display,@Appearance

    Control.exe is used to bring up the control panel applet passed to it as first argument, and the additional arguments are used to force it to start with the Appearance tab selected.

  2. Now we need to enumerate the child windows ( controls ) on the Appearance tab till we find the Effects button and this can be achieved using EnumChildWindows. Once we obtain the Effects button's handle we can send a button click message to it and bring up the Effects sub-window.
  3. To locate the required check box on the Effects sub-window we would need to first get the handle to the sub-window that just popped up. We achieve this by setting up a global CBT hook ( this means we'd need to put all put code into a DLL ), and watching for all newly activated windows. We know the title text for the Effect sub-window and thus we obtain the handle to the window the moment it gets activated. Now we do the same as previous, i.e. we use EnumChildWindows to retrieve the handle to the check box, and then send a button click message to it.
  4. We post a WM_COMMAND message to the Effects sub-window with a command ID of IDOK which is the equivalent of closing the window by clicking on the OK button.
  5. We do the same for the main Display Properties window.

Implementation details

Bringing up the Display Properties window

BOOL BringUpDisplayAppearance()
{
    return reinterpret_cast<int>(ShellExecute(GetDesktopWindow(),
        "open","control.exe","desk.cpl Display,@Appearance",
        "",SW_SHOW )) > 32 ? TRUE : FALSE; 
}

The code is quite simple and straightforward, we simply use ShellExecute to bring up the Display Properties applet window with the default tab set to the Appearances tab. I have used SW_SHOW here because using SW_HIDE will have no effect on the display properties window ( I believe the control.exe program or perhaps desk.cpl itself will later call ShowWindow(hWnd, SW_SHOW) somewhere in the code ). We do our window hiding in the hook procedure ( but even this is not fully effective and there is a short flash on screen, but then our aim is not really to hide what we are doing from our end user, but to try and make things as lucid as possible, which we achieve by reducing the time the window remains visible to a few milliseconds ).

Getting the handle to the Effects button

HWND GetEffectsButton(HWND hWndParent)
{
    HWND hWnd = NULL;

    EnumChildWindows(hWndParent, EnumAppearanceChildProc, 
        (LPARAM)&hWnd);
    return hWnd;
}

BOOL CALLBACK EnumAppearanceChildProc(HWND hwnd, LPARAM lParam)
{
    TCHAR buff[512];
    GetWindowText(hwnd,buff,512); 
    if(_tcscmp(buff,_T("&Effects...")) == 0)
    { 
        *reinterpret_cast<HWND*>(lParam) = hwnd;
        return FALSE;
    }
    return TRUE;
}

Using Spy++ we extract the exact text associated with the Effects button which happens to be "&Effects..." and we use this knowledge to compare the text of each child control with this text repeatedly till we get the button control we want.

Getting the check box handle

HWND GetMenuUnderlineCheck(HWND hWndParent)
{
    HWND hWnd = NULL; 
    EnumChildWindows(hWndParent, EnumEffectsChildProc, 
        (LPARAM)&hWnd);
    return hWnd;
}

BOOL CALLBACK EnumEffectsChildProc(HWND hwnd, LPARAM lParam)
{
    TCHAR buff[512];
    GetWindowText(hwnd,buff,512); 
    if(_tcsstr(buff,_T("&Hide underlined")))
    { 
        *reinterpret_cast<HWND*>(lParam) = hwnd;
        return FALSE;
    }
    return TRUE;
}

This is very similar to how we obtained the handle to the Effects button.

The CBT hook procedure

LRESULT CALLBACK CBTProc(int nCode, 
                         WPARAM wParam, LPARAM lParam)
{
    if(nCode == HCBT_ACTIVATE)
    {
        HWND hWnd = (HWND) wParam;
        TCHAR buff[512];
        GetWindowText(hWnd,buff,512);
        if(_tcscmp(buff,_T("Effects")) == 0)
        { 
            ShowWindow(hWnd,SW_HIDE);
            g_hWndEffects = hWnd; 
            UnhookWindowsHookEx(g_hook); 
        }
        if(_tcscmp(buff,_T("Display Properties")) == 0)
        { 
            ShowWindow(hWnd,SW_HIDE); 
        }
    }

    return 0;
}

The HCBT_ACTIVATE code indicates that a window is about to be activated. We compare the title text of this window with "Effects" and if they match, we know that this is the window we were searching for. If you are wondering why we had to install a CBT hook, instead of using FindWindow using the title text; this is to make sure that even if there was already an existing window with the same title text, it won't interfere with our search because we are only checking newly activated windows. We set the CBT hook quite late into the code and uninstall it the moment we get the window we want. The duration the hook is active is from the time we bring up the Display Properties window till the Effects sub-window is just about to be activated, and under most circumstances this shouldn't be more than a few milliseconds.

We also use the hook procedure to hide the windows that pop up, which include both the main Display Properties window as well as the Effects sub-window. The infinitesimal flash still exists and if anyone has any ideas on further reducing this, they are welcome to make suggestions.

The main function ( exported )

DEMODLL_API BOOL ToggleMenuUnderline(void)
{
    HWND hWndAppearance = NULL;
    BOOL ret = TRUE;

    g_hook = SetWindowsHookEx(WH_CBT, 
        CBTProc, g_hModule, 0); 

    ret = BringUpDisplayAppearance();
    Sleep(500);//Wait for the window to come up
    if(ret)
    {
        hWndAppearance = FindWindow(NULL,
            _T("Display Properties"));
        ret = hWndAppearance != NULL; 

        if(ret)
        {
            HWND hWndEffectsButton = GetEffectsButton(
                hWndAppearance);
            ret = hWndEffectsButton != NULL;

            if(ret)
            {
                PostMessage(hWndEffectsButton,BM_CLICK,0,0); 

                //Wait for the Effects window to come up 
                while(!IsWindow(g_hWndEffects))
                    Sleep(100); 

                HWND hWndCheck = GetMenuUnderlineCheck(
                    g_hWndEffects);

                ret = hWndCheck != NULL;

                if(ret)
                { 
                    PostMessage(hWndCheck,BM_CLICK,0,0); 
                    PostMessage(g_hWndEffects,WM_COMMAND,
                        IDOK,NULL);
                    PostMessage(hWndAppearance,WM_COMMAND,
                        IDOK,NULL);

                    //Wait for the window to be dismissed
                    while(IsWindow(hWndAppearance))
                        Sleep(100); 
                }
            }
        }
    }

    //Final checks in case of error conditions
    if(IsWindow(g_hWndEffects))
        PostMessage(g_hWndEffects,WM_CLOSE,0,0);
    if(IsWindow(hWndAppearance))
        PostMessage(hWndAppearance,WM_CLOSE,0,0);

    return ret;
}

We first set up our CBT hook and then call the BringUpDisplayAppearance function to bring up the Display Properties window with the Appearance tab selected. Once the window comes up we obtain the handle to the Effects button using the GetEffectsButton function, and then post a BM_CLICK message to the Effects button using the handle we just obtained. Almost instantly the Effect sub-window pops up and we retrieve it's handle through our CBT hook procedure which also uninstalls the hook since it's no longer of any use to us. We wait for the Effects window to come up, using the following while loop :-

while(!IsWindow(g_hWndEffects))
    Sleep(100);

This way we avoid sleeping for too long or for too less. Now we obtain the handle to the check box using the GetMenuUnderlineCheck function and post a BM_CLICK message to the check box which effectively toggles it's state which is just what we are trying to do. Now we simply post WM_COMMAND messages with wParam set to IDOK to the Effects sub-window as well as to the Display Properties main window. That's all; we have now successfully toggled the state of the "Underline keyboard navigation shortcuts for menus" system-wide property.

Conclusion

The test scenario we considered was perhaps too simplistic to reveal the actual power of this technique, but when you consider that you can now do anything from your program that a user can do manually using the Windows GUI, you'll be slowly impressed by the awesome possibilities of the technique.  You can use this technique to enumerate Windows themes, change the current theme, change display settings, change system settings, automate your own applications etc. The only tool you'd need in addition to Everett is Spy++ or some such similar application. Good luck with your own message based Windows automation attempts.

History

  • August 8th 2003 - First written

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

About the Author

Nish Sivakumar
United States United States
Member
Nish is a real nice guy who has been writing code since 1990 when he first got his hands on an 8088 with 640 KB RAM. Originally from sunny Trivandrum in India, he has been living in various places over the past few years and often thinks it’s time he settled down somewhere.
 
Nish has been a Microsoft Visual C++ MVP since October, 2002 - awfully nice of Microsoft, he thinks. He maintains an MVP tips and tricks web site - www.voidnish.com where you can find a consolidated list of his articles, writings and ideas on VC++, MFC, .NET and C++/CLI. Oh, and you might want to check out his blog on C++/CLI, MFC, .NET and a lot of other stuff - blog.voidnish.com.
 
Nish loves reading Science Fiction, P G Wodehouse and Agatha Christie, and also fancies himself to be a decent writer of sorts. He has authored a romantic comedy Summer Love and Some more Cricket as well as a programming book – Extending MFC applications with the .NET Framework.
 
Nish's latest book C++/CLI in Action published by Manning Publications is now available for purchase. You can read more about the book on his blog.
 
Despite his wife's attempts to get him into cooking, his best effort so far has been a badly done omelette. Some day, he hopes to be a good cook, and to cook a tasty dinner for his wife.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWhat about textboxes, listviews, etc...?memberpeepsicola18 Dec '07 - 5:08 
Hey,
 
Great article,
 
What about manipulating a textbox on a form...?
QuestionIs completely hidden possible?memberrobot_chou19 Dec '06 - 21:53 
Great article!
I'am a Chinese programmer. I just finish a program that has a module doing the similar task(just want to "Clear SSL State" like IE, use inetcpl.cpl). I used the LaunchInternetControlPanel() API and create another thread to get last active popup window and call ShowWindow() to hide it. When I launch it, it behaves better than the CBT hook one. But theoretically, the hook method is supposed to work better(cuz it hides the window earlier),right???
Then I added HCBT_CREATEWND on, subclass the window and intercept the WM_INITDIALOG message, but unfortunately, it didn't work the way I expected. For me, it's essential to hide the windows from users. So the question: Is it possible to completely (no infinitesimal flash) hide all the popup windows? Anyone can give me some hints? Thanx!!!!!
Here is my code:
LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode == HCBT_CREATEWND)
{
HWND hWnd = (HWND) wParam;
CBT_CREATEWND *pCreateWnd = (CBT_CREATEWND *)lParam;
LPCSTR lpWinText = pCreateWnd->lpcs->lpszName;
 
if (lpWinText != NULL)
{
if((_tcscmp(lpWinText,_T("SSL Cache Cleared Successfully")) == 0)
|| (_tcscmp(lpWinText,_T("Content")) == 0))
{
pOldProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG)InitDlgWndProc);
}
}
}


if(nCode == HCBT_ACTIVATE)
{
HWND hWnd = (HWND) wParam;
TCHAR buff[512];
GetWindowText(hWnd, buff, 512);

if(_tcscmp(buff,_T("SSL Cache Cleared Successfully")) == 0)
{
g_hWndSuccess = hWnd;
UnhookWindowsHookEx(g_hook);
}
 
if(_tcscmp(buff,_T("Internet Options")) == 0)
{
g_hWndInetProperty = hWnd;
}
}

return 0;
}
 
LRESULT CALLBACK InitDlgWndProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
LRESULT rc = CallWindowProc( pOldProc, hwnd, uMsg, wParam, lParam );
if (uMsg == WM_INITDIALOG)
{
WINDOWPLACEMENT wp;
 
wp.length=sizeof(WINDOWPLACEMENT);
 
wp.flags=WPF_RESTORETOMAXIMIZED;
 
wp.showCmd=SW_HIDE;
 
SetWindowPlacement(hwnd, &wp);


}
return rc;
}

QuestionWokring under Windows CEmemberFiras19 Nov '06 - 1:20 
Hi,
 
I am wondering if there is a way to do the same thing under windows ce? SetWindowsHookEx() is not supported under Windows CE and so, CBT hooking is not there too.
 
Any ideas?
 
Thanks! Smile | :)
 
To be, or not to be, those are the parameters.

GeneralQuestion on WindowsmemberGabriyel12 May '06 - 4:19 
hi,
 
i have an application which i hope i can use it without using my mouse to click on the options. is there a way to automate this by using some form of coding to achieve what i want?
 
e.g. i'd like to execute the following sequence: start the app -> goto file menu and open a file -> click on a specific button in the app
 
can the above be automated via programming?
 
thanks very much for your advice.
 
gab
 
The most beautiful thing in this world cannot be seen by the eye.
GeneralRemote Controlmemberkissmoses3 Jan '06 - 9:24 
Hello Nish,
Could you give me some guidelines as to what it would take to be able to control a desktop environment remotely.
I am working on a remote desktop control project with the client running on WinCE (pocketPC2003) and Server in Win32 (winXp). Am connecting the two over Bluetooth Virtual COMports.
 
So far, I can "monitor" the server by simply capturing its screen and sendin it to the client.
 
I now need to add control capability; i.e. make mouse(stylus)/keyboard inputs on the PPC and have them reflect on the desktop of the server.
 
Am a Hooks newbie, but sofar (with your article) I suppose this is the way. Any guidelines as to what is involved, or any references you may provide will be appreciated!
Thanks
Moses
PS: gave up the sunny india for snow!...must be crazy!Laugh | :laugh:
Generaldll compile errormemberpeter ho9 Mar '05 - 13:38 
When I compile the dll source code I get the following error:
"definition of dllimport function not allowed"
 
Any idea of how to fix this error
 
Thanks,
GeneralHooking to push buttonsmemberHarishB24 Nov '04 - 17:59 
How can we hook to a push button control in an windows application. Wht is the type of the hook (WH_ )that should be installed and wht is the message (WM_ command) that we get when we push the button.

GeneralReally a very nice article.memberDigvijay Singh Chauhan4 Jul '04 - 0:43 
Thanks for sharing a good example.
Not only gave a few good tips about the CBT hook but also made me learn when to use the reinterpret_cast<>.
 
thanks,
 
DS
GeneralMove the mousememberTimbit12 Nov '03 - 1:12 
Your article is great! But what if I wanted to move the mouse and click the "OK" button? How would I programatically move the mouse? Assume I know ahead of time where the button is going to be. How do programs like "Fakesurf" work?
 
Thanks.

GeneralRe: Move the mousemembergrv5754 Aug '04 - 4:59 
If you want to simulate mouse presses send the WM_LBUTTONDOWN message to the window. the wparam should be set to 1 I believe and the lparam parameter determines the x-y coordinates of the button click. To get this parameter use something like spy++ or winspector (maybe?) to get the right code when you click the button yourself (in other words use the message monitor mode).
GeneralGetting handle to window just created but not activememberSantosh M. P.16 Sep '03 - 19:10 
Hi,
I posting this question here just because this article contains something about CBT hooks. I need to get the handle of the message box of the messenger service in windows 2000/XP. MSDN says that CBT hooks can be used for this. So i installed a CBT hook, check for HCBT_CREATEWND in the nCode parameter so that I can get the handle to the window in wParam. But this does not happen. Also I cannot check for HCBT_ACTIVATE because in Win 2K/XP, the message box from the messenger service does not have focus when it is created. Anybody ?? WTF | :WTF:
 
« Superman »
GeneralSuggestion, alternativemembersaikatsen18 Aug '03 - 21:09 
One suggestion: to make your example complete, one would want to check the state of the checkbox before sending a click. Also, you'd want to check the state of different buttons (they may be disabled due to insufficient privileges or policy restrictions).
 
Alt suggestion: one could use Windows Accessible APIs to do this too.
 
Limitation: Your method is for Win32 controls only.
 
But yes, more than the message example, you have given a decent example of using CBT hooks.
 
- Saikat
GeneralRe: Suggestion, alternativeeditorNishant S25 Aug '03 - 18:16 
saikatsen wrote:
One suggestion: to make your example complete, one would want to check the state of the checkbox before sending a click. Also, you'd want to check the state of different buttons (they may be disabled due to insufficient privileges or policy restrictions).
 
Thanks for the suggestions. Will add them in the next update Smile | :)
 
Nish
 

Extending MFC Applications with the .NET Framework [NW] (coming soon...)
Summer Love and Some more Cricket [NW] (My first novel)
Shog's review of SLASMC [NW]
Come with me if you want to live

GeneralAlso relevant...memberShog910 Aug '03 - 13:43 
A while back, John Robbins did a series of articles in MSDN detailing how to play back a script written to do things such as you describe.
 
IMHO, it's kinda sad in these days of COM and .NET that such techniques are still so very useful in testing (commercial products such as Rational Robot that do pretty much the same thing will sell for fat wads of cash).
 
But that being as it is, it's pretty cool that we have this capability.
 
For reference:
BUGSLAYER - Tester Utility, Take 3: Adding Mouse Recording and Playback
 
Shog9
Let your mercy spill / On all these burning hearts in hell
If it be your will / To make us well...

GeneralRe: Also relevant...editorNishant S25 Aug '03 - 18:15 
Shog9 wrote:
IMHO, it's kinda sad in these days of COM and .NET that such techniques are still so very useful in testing
 
What's sad about it? The fact that we keep going back to older technology?
 
Nish
 

Extending MFC Applications with the .NET Framework [NW] (coming soon...)
Summer Love and Some more Cricket [NW] (My first novel)
Shog's review of SLASMC [NW]
Come with me if you want to live

GeneralRe: Also relevant...memberShog926 Aug '03 - 4:51 
Not so much that. Rather, that this sort of testing is kindof a hack, easily broken by small UI changes, while a script based on, say, an automation interface would be unaffected.
 
We've three people in our QA group writing such scripts, and even small changes such as a spelling correction on a button, or customization of a listbox can break many, many of their scripts.
 
This isn't to take anything away from your article - as i said, the technique is useful. I just wish it was less used (at least around me Wink | ;) ).
 
Shog9
I returned and saw under the sun,
that the race is not to the swift,
nor the battle to the strong...

GeneralLocalized Windows versionsmemberbarto9 Aug '03 - 3:15 
I'd be very careful with this kind of code. It'll probably fail on all versions of Windows except english-language versions. Have you thought of just checking the control IDs instead of the window texts? Either way is OS dependand, but I guess that's inevitable with this technique.
GeneralRe: Localized Windows versionseditorNishant S9 Aug '03 - 3:32 
The language issue can be taken care of, if the control order number is known in advance, because then we do not need to depend on the text of the control.
 
Nish
 

Extending MFC Applications with the .NET Framework [NW] (My book with Tom)
Summer Love and Some more Cricket [NW] (My first novel)
Shog's review of SLASMC [NW]
Come with me if you want to live

GeneralWindows Scripting Might Be More Flexible/RobustmemberMike O'Neill8 Aug '03 - 15:42 
Windows Script Host (see article at http://msdn.microsoft.com/msdnmag/issues/02/05/wsh/default.aspx[^], "Windows Script Host 5.6 Boasts Windows XP Integration, Security, New Object Model") might provide more flexibility. It might also be more robust since it would not rely on inherently undependable things, like the text of a button (here, "Effects..." or "Hide underlined") remaining unchanged from release-to-release.
 
But I still like your article Wink | ;)
 
Regards,
Mike
GeneralRe: Windows Scripting Might Be More Flexible/RobusteditorNishant S25 Aug '03 - 18:14 
Thanks for the feedback, Mike
 
Nish
 

Extending MFC Applications with the .NET Framework [NW] (coming soon...)
Summer Love and Some more Cricket [NW] (My first novel)
Shog's review of SLASMC [NW]
Come with me if you want to live

GeneralThere's a catch here...memberAndy Marks8 Aug '03 - 4:58 
This technique only works for messages where all the data can
be stored in the WPARAM and LPARAM. Any message where you pass
a memory address in WPARAM or LPARAM isn't going to work
(like trying to locate a string in a ListView).
 
To send these types of messages, you would need to use one of the
methods for injecting code into a process and then running it.
GeneralRe: There's a catch here...editorNishant S8 Aug '03 - 5:01 
Yup, it does have it's limitations, but the benefits far out weigh the limitations in my opinion. And it does work for most purposes I guess.
 
Nish
 

Extending MFC Applications with the .NET Framework [NW] (My book with Tom)
Summer Love and Some more Cricket [NW] (My first novel)
Shog's review of SLASMC [NW]
Come with me if you want to live

GeneralRe: There's a catch here...member.:fl0yd:.22 Aug '03 - 15:21 
While injecting code is one solution this type of thing can be accomplished in an easier fashion: allocate memory in the target process using VirtualAllocEx() and copy the desired data into that location using WriteProcessMemory() before sending the appropriate message. Likewise, locating a string in a ListView can be achieved by taking the returned pointer and apply ReadProcessMemory() to copy data from the target process.
 
.f
GeneralRe: There's a catch here...sussAnonymous23 Aug '03 - 1:06 
VirtualAllocEx() is not available on Win9x. I think that at this point in time supporting those OS's is still a requirement, those it is getting to be less of one.
 
Is there any way to determine the base address (needed for Read/WriteProcessMemory) of a process? Is VirtualAllocEx() the only way?

GeneralRe: There's a catch here...member.:fl0yd:.23 Aug '03 - 5:21 
Anonymous wrote:
VirtualAllocEx() is not available on Win9x.
 
True, and honestly I haven't thought about that. So this does reduce the usability of WriteProcessMemory() on those systems. Since Win9x system do not seperate processes' address spaces as much as WinNT does, there are regions of memory that are shared between all running processes, so using VirtualAlloc() within this region might be a -- admittedly hackish -- solution.
 

Anonymous wrote:
Is there any way to determine the base address (needed for Read/WriteProcessMemory) of a process?
 
The base address is just the address where you want to start reading from/writing to. Let's assume you intercepted a WM_SETTEXT message then the lParam (a pointer to a null-terminated string) would be the base address for ReadProcessMemory().
 
.f

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 8 Aug 2003
Article Copyright 2003 by Nish Sivakumar
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid