How to Locate Code Execution at the Push of a Button

By the meaning of the above title is to determine the precise location of code of execution, when user perform some mouse click on any of UI objects in windows environment. The UI object usually in the form of menu item, or button.

The method described in this article is not relevant to the condition when we have the complete source code, or full debug symbol for the code in question.

It is useful only in the source-less application, and we want to know the precise location of code that gets executed when certain UI command is activated by the user.

OK, let’s take some sample real-world source-less application that maybe of interest to some of the readers here, which is Omega’s TradeStation :).

Suppose I want to export my EL strategy to some file, I will choose Import/Export EasyLanguage from File Menu. Then the application will bring me the wizard dialog box to choose the EL strategy from available list, after that I will arrive at the final stage of wizard dialog box :

When I click the Finish button, the application will perform some action, and I will have the exported ELD file as the result.

In this article, I want to pinpoint the precise location of the code that is executed when the Finish button is pushed.

For the starting point, I need to know the hWnd (window handle) and its associated window procedure for this button. Using the Accessibility Framework, and GetWindowLong function, in this current state, the window handle is 0x70d5a and its associated windows procedure is 0x773E208B which is COMCTL32’s (COMCTL32.DLL) MasterSubclassProc.

After analyzing this procedure when user pressed the button by capturing the WM_LBUTTONUP (0x202) notification, what’s this button procedure’s doing is call the next windows procedure (CallNextSubclassProc) after obtaining the button’s property information.

Based on obtained property, the CallNextSubclassProc will determine which procedure that the notification should be passed, and in this case it is Prsht_ButtonSubclassProc.

This procedure in turn will call DefSubclassProc.

DefSubclassProc will again call CallNextSubclassProc. Because each call to CallNextSubclassProc will decrease the depth level of the control, this time, the windows procedure that gets called is now CallOriginalWndProc.

The CallOriginalWndProc will pass the address of Button_WndProc to be used next window procedure call chain. This routine (Button_WndProc) then will notify its parent (i.e. Dialog Box) by passing WM_COMMAND (0x111), Control’s ID and Control’s hWnd (Window Handle) and send the message to the parent object, which is dialog box.

Because the Dialog Box window handle is created with the MFC framework, which is proved with Windows Accessibility Framework, this message is finally captured by AfxWndProcBase. This is part of MFC42.DLL routine.

Because AfxWndProcBase is part of documented procedure in Microsoft Foundation Class Framework, we can obtain the actual source code for this procedure to be :

AfxWndProcBase(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
return AfxWndProc(hWnd, nMsg, wParam, lParam);

From the above source code, we can see that it just passed the obtained parameter to AfxWndProc. It is the same manner with AfxWndProc which passed the parameter to AfxCallWndProc, and also add the CWnd class to be used in subsequent window call chain, which is CWnd::WindowProc.

Inside CWnd::WindowProc there is a call to CWnd::OnWndMsg which in turn call the CPropertySheet::OnCommand. This is because the incoming message is WM_COMMAND (0x111).

Inside CPropertySheet::OnCommand there is assigment of control’s id to m_nModalResult, but returned FALSE at the end of this routine, meaning that this message (WM_COMMAND) is still not get handled.

Because it is still not get handled, the MFC framework inside CWnd::WindowProc called default window procedure as evidenced from this source code :

LRESULT CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
// OnWndMsg does most of the work, except for DefWindowProc call
LRESULT lResult = 0;
if (!OnWndMsg(message, wParam, lParam, &lResult))
lResult = DefWindowProc(message, wParam, lParam);
return lResult;

DefWindowProc then calls DefDlgProcA (a USER32.DLL exported routine). This routine is obtained using CWnd::FromHandlePermanent at AfxWndProc at the start of MFC windows message handling.

Because there is a child object within the dialog window object, this dialog window procedure will pass the message to COMCTL32’s PropSheetDlgProc.

Windows OS retrieve this routine via some address offset within the TEB (Thread Environment Block) that’s in the fs register (fs:[00000018]).

Inside this function (PropSheetDlgProc) the control id, control’s window handle and parent window handle is passed to Prsht_OnCommand.

Within this function, the control id is scanned against available id, and when it is found for 0x3025 it called _Ppd_SendNotify by passing the 0xFFFFFF30 as its notification code.

_Ppd_SendNotify then transformed the existing windows message to WM_NOTIFY (0x004E) along with 0xFFFFFF30 notification code. This code is actually PSN_WIZFINISH.

By tracing through this notification call stack, we arrive again at AfxWndProcBase, but this time with the WM_NOTIFY message, PSN_WIZFINISH notification code and appropriate property sheet window handle.

So, the usual MFC Framework handling stack begins again, this time with WM_NOTIFY and PSN_WIZFINISH notification code. So, now, CWnd::OnWndMsg will call CPropertyPage::OnNotify instead of CPropertyPage::OnCommand.

Because we now have the complete source code of this routine, we can verified that this routine will compare the notification with existing notification and execute the proper method which is :

*pResult = reinterpret_cast(OnWizardFinishEx());

At last, by performing breaking into this address, we eventually arrived at TradeStation’s implementation of ELD export routine :

73e3d9b9 ff90f4000000 call dword ptr [eax+0F4h] ds:0023:00fecb8c={ORELUI20!CTransferExportToPage::OnWizardFinish (00f8cd20)}.


2 Responses to “How to Locate Code Execution at the Push of a Button”

  1. Anonymous Says:

    this is the work of an engines talented person

  2. ekasiswanto Says:

    you’re welcome 🙂

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: