scrollfix source code

Viewing 1 post (of 1 total)
  • Author
    Posts
  • #66036
    Chike
    Administrator

    The code demonstrate easy injection of code using system wide hook, and windows subclassing.
    All the main program has to do is load the DLL, the rest is done by the DLL itself.

    The part of  the actual fix is missing, they aint getting it free from me.

    #include "stdafx.h"
    
    #include <map>
    #include 
    #include 
    
    // NOTE: ALL members of the shared section must be initialized
    #pragma data_seg(".shareddata")
     DWORD dwAppProcessId = 0; // accessible across all processes
    #pragma data_seg()
    #pragma comment(linker, "/section:.shareddata,rws")
    
    HHOOK hook = 0; // used by application
    bool active = false; // true for paltal, false for any other process
    
    bool Hook(HINSTANCE hInstance);
    void Unhook();
    
    void subclass_all();
    void unsubclass_all();
    
    int WINAPI DllMain(HINSTANCE hInst, DWORD fwdreason, LPVOID /*lpvReserved*/)
    {
         switch(fwdreason)
         { /* reason */
         //**********************************************
         // PROCESS_ATTACH
         //**********************************************
         case DLL_PROCESS_ATTACH:
             // first module that loads (application)
             // enfotce dll in application directory
             TCHAR  mmpath[MAX_PATH];
             if (dwAppProcessId == 0) {
                 TCHAR mpath[MAX_PATH];
                 if (GetModuleFileName(hInst, mpath, sizeof(mpath)) && GetModuleFileName(NULL, mmpath, sizeof(mmpath))) {
                     *wcsrchr(mpath, '\\') = '';
                     *wcsrchr(mmpath, '\\') = '';
                     if (lstrcmpi(mpath, mmpath) == 0) {
                         if (!Hook(hInst))
                             return FALSE;
                         dwAppProcessId = GetCurrentProcessId();
                     }
                 } else
                     return FALSE;
                     // ignore any process other than paltak 
             } else if (GetModuleFileName(NULL, mmpath, sizeof(mmpath)) &&
                         lstrcmpi(wcsrchr(mmpath, '\\')+1, TEXT("paltalk.exe")) == 0) {
                 if (!active) { // should never be true
                     subclass_all();
                     active = true;
                 }
             }
             break;
    
        //**********************************************
         // PROCESS_DETACH
         //**********************************************
         case DLL_PROCESS_DETACH:
             if (hook != NULL) // application exists - unhook
                 Unhook();
             else if (active) { // only for paltalk  active = true
                 active = false;
                 unsubclass_all();
             }
         } /* reason */
         return TRUE;
    }
    
    static LRESULT CALLBACK ShellProc(int nCode, WPARAM wParam, LPARAM lParam);
    bool Hook(HINSTANCE hInstance)
    {
         if (hook == NULL)
             hook = SetWindowsHookEx(WH_SHELL, ShellProc, hInstance, 0);
         return (hook != NULL);
    }
    
    void Unhook()
    {
         if (hook != NULL)
             UnhookWindowsHookEx(hook);
         hook = NULL;
    }
    
    void subclass(HWND hwnd);
    void unsubclass(HWND hwnd);
    static
     LRESULT CALLBACK ShellProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
         if (nCode < 0) // required according to documentation
             return CallNextHookEx(hook, nCode,wParam, lParam);
    
        if (active) { // this is paltalk
             switch (nCode) {
             case HSHELL_WINDOWCREATED:  // subclass newly oppened chatrooms
                 subclass((HWND)wParam);
                 break;
             case HSHELL_WINDOWDESTROYED:// unsubclass closed rooms
                 unsubclass((HWND)wParam);
                 break;
             }
         }
         // Pass the message on to the next hook
         return CallNextHookEx(hook, nCode, wParam, lParam);
    }
    
    /*
         Internal lib stuff
     */
    typedef std::pair<hwnd,bool> enum_param;
    
        // finds room control for chatrooms windows only
         BOOL CALLBACK FindControlsRoomProc(HWND hwnd, LPARAM lParam) {
             int ctlID = GetDlgCtrlID(hwnd);
             enum_param *ctl = (enum_param*) lParam;
             switch (ctlID) {
             case 0x6FD:
                 if (IsWindowVisible(hwnd)) // user list is only visable in chatrooms
                     ctl->second = true;
                 break;
             case 0xCA:
                 ctl->first = hwnd; // room text control
                 break;
             case 0xCB:
                 break;
             }
             return TRUE;
         }
    
    // used by chatroom text WndProc for the fix
    struct POS {
    // code removed
    };
    
    // subclassed chatroom text control data
    struct subctl {
         subctl(WNDPROC prev)
         {
             this->prev = prev;
         }
         WNDPROC prev;
         POS pos;
    };
    
    typedef std::map<hwnd,hwnd> subwins; // chat windows with subclassed controls
    typedef std::map<hwnd,subctl> subctls; // subclassed controls
    
    subwins windows;
     subctls controls;
    
    LRESULT APIENTRY RoomTexcProc(HWND, UINT, WPARAM, LPARAM);
    void subclass(HWND hwnd)
    {
         TCHAR str[128];
         // subclass is called blindly, check it is a chatroom window
         if (GetClassName(hwnd, str, sizeof(str)) == 0)
             return;
         if (lstrcmp(str, L"DlgGroupChat Window Class"))
             return;
         enum_param ctl;
         EnumChildWindows(hwnd, FindControlsRoomProc, LPARAM(&ctl));
         if (ctl.second && ctl.first != NULL) {
             assert( windows.find(ctl.first) == windows.end() );
             // install subclass WndProc
             WNDPROC prev = (WNDPROC) SetWindowLongPtr(ctl.first, GWL_WNDPROC, LONG(RoomTexcProc));
             // save subclassed chatroom window
             windows.insert(subwins::value_type(hwnd, ctl.first));
             // save subclassed control
             controls.insert(subctls::value_type(ctl.first, subctl(prev)));
         }
    }
    
        BOOL CALLBACK SubclassProc(HWND hwnd, LPARAM lParam)
         {
             subclass(hwnd);
             return TRUE;
         }
    
    void subclass_all()
    {
         EnumThreadWindows(GetCurrentThreadId(), SubclassProc, 0);
    }
    
    void unsubclass(subwins::const_iterator it)
    {
         subctls::const_iterator cit = controls.find(it->second);
         assert (cit != controls.end() );
         // restore original WndProc
         SetWindowLongPtr(cit->first, GWL_WNDPROC, LONG(cit->second.prev));
         // remove window and controll from lists
         controls.erase(cit);
         windows.erase(it);
    }
    
    void unsubclass(HWND hwnd)
    {
         subwins::const_iterator it = windows.find(hwnd);
         // unsubclass is called blindly, check if this window in our list
         if (it != windows.end())
             unsubclass(it);
    }
    
    void unsubclass_all()
    {
         while (!windows.empty()) {
             unsubclass(windows.begin());
         }
    }
    
        LRESULT
         APIENTRY RoomTexcProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
         {
             subctls::iterator it = controls.find(hwnd); // find control data in subclassed controlls list
             WNDPROC wndprocPrev = it->second.prev;
             POS *pos;
    
            switch (uMsg) {
             // fix code gremoved
             }
             // call original WndProc
             return CallWindowProc(wndprocPrev, hwnd, uMsg, wParam, lParam);
         }
    
    
    
     
Viewing 1 post (of 1 total)
  • You must be logged in to reply to this topic.