GC stealing my delegate. menu

User Tag List

Results 1 to 3 of 3
  1. #1
    Cephalopod's Avatar Member
    Reputation
    5
    Join Date
    Sep 2008
    Posts
    85
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    GC stealing my delegate.

    The garbage collector keeps getting rid of my delegate and I can't figure out why.

    Class:
    Code:
    using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Text;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    namespace Cephalopod.Cephalopod_Management
    {
        class CephKeyHook
        {
            public delegate int keyboardHookProc(int code, int wParam, ref keyboardHookStruct lParam);
    
            public struct keyboardHookStruct
            {
                public int vkCode;
                public int scanCode;
                public int flags;
                public int time;
                public int dwExtraInfo;
            }
    
            Logger _logger = new Logger();
    
            const int WH_KEYBOARD_LL = 13;
            const int WM_KEYDOWN = 0x100;
            const int WM_KEYUP = 0x101;
            const int WM_SYSKEYDOWN = 0x104;
            const int WM_SYSKEYUP = 0x105;
    
            public static Hashtable Modifiers = new Hashtable();
            public static List<CephKeyHook> HookedKeys = new List<CephKeyHook>();
            int index;
            int ModifierPressed;
            int ModifierToSend;
            int KeyPressed;
            int KeySent;
            string SpecialCommands;
            string SendTo;
            int RoundRobin = 0;
    
            IntPtr hhook = IntPtr.Zero;
            static bool KeyHookEnabled = false;
    
            public void AddKey(int index, int mod_p, int key_p, int mod_s, int key_s, string Sendto, string Special)
            {
                CephKeyHook KeyToHook = new CephKeyHook();
                KeyToHook.index = index;
    
                KeyToHook.ModifierPressed = mod_p;
                KeyToHook.ModifierToSend = mod_s;
                KeyToHook.KeyPressed = key_p;
                KeyToHook.KeySent = key_s;
                KeyToHook.SpecialCommands = Special;
                KeyToHook.SendTo = Sendto;
    
                    if (mod_p > 0)
                    {
                        if (Modifiers.Contains(mod_p) == true)
                        {
                            HookedKeys.Add(KeyToHook);
                        }
                    }
                    
                    HookedKeys.Add(KeyToHook);
    
            }
    
            public void AddModifier(int key)
            {
                Modifiers.Add(key, "false");
    
                //hook();
            }
    
            internal void hook()
            {
                IntPtr hInstance = LoadLibrary("User32");
                hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);
                GC.KeepAlive(hhook);
            }
    
            private void unhook()
            {
                UnhookWindowsHookEx(hhook);
            }
    
            private int hookProc(int code, int wParam, ref keyboardHookStruct lParam)
            {
                if (code >= 0)
                {
                    Keys key = (Keys)lParam.vkCode;
                    KeyEventArgs kea = new KeyEventArgs(key);
                    int keycode = lParam.vkCode;
                    if (Modifiers.Contains(lParam.vkCode) == true)
                    {
                        if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)
                            Modifiers[lParam.vkCode] = "true";
                        if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)
                            Modifiers[lParam.vkCode] = "false";
                    }
                        var MatchingKeys = from k in HookedKeys where k.KeyPressed == keycode select new { k.index, k.ModifierPressed, k.KeyPressed, k.SendTo };
                        foreach (var _keys in MatchingKeys)
                        {
                            if (_keys.SendTo == "KEYHOOKS" && wParam == WM_KEYDOWN)
                            {
                                if (KeyHookEnabled)
                                {
                                    KeyHookEnabled = false;
                                }
                                else
                                {
                                    KeyHookEnabled = true;
                                }
                            }
    
                            if (KeyHookEnabled)
                            {
                                if (wParam == WM_KEYDOWN)
                                {
                                    if (_keys.ModifierPressed > 1)
                                    {
                                        if (Modifiers[_keys.ModifierPressed].ToString() == "true")
                                        {
                                            ProcessKeyHooked(_keys.index, wParam);
                                        }
                                    }
                                    else
                                    {
                                        ProcessKeyHooked(_keys.index, wParam);
                                    }
                                }
                                else if (wParam == WM_KEYUP)
                                {
                                    ProcessKeyHooked(_keys.index, wParam);
                                }
                            }
                        }
                }
    
                return CallNextHookEx(hhook, code, wParam, ref lParam);
            }
    
            private void ProcessKeyHooked(int index, int wParam)
            {
                int WM_CODE = Win32.WM_KEYDOWN;
    
                if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)
                {
                    WM_CODE = Win32.WM_KEYDOWN;
                    _logger.LogMessage(index.ToString() + " : KEYDOWN");
                }
                else if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)
                {
                    WM_CODE = Win32.WM_KEYUP;
                    _logger.LogMessage(index.ToString() + " : KEYUP");
                }
                if (HookedKeys[index].SpecialCommands == null)
                {
                    switch (HookedKeys[index].SendTo)
                    {
                        case "ALL":
                            for (int i = 0; i < CephWindowManipulation.WoWInstances.Count(); i++)
                            {
                                if (CephWindowManipulation.WoWInstances[i].Title == "World of Warcraft")
                                {
                                    if (HookedKeys[index].ModifierToSend != 0)
                                    {
                                        Win32.PostMessage(CephWindowManipulation.WoWInstances[i].Handle, WM_CODE, HookedKeys[index].ModifierToSend, 0);
                                    }
                                    Win32.PostMessage(CephWindowManipulation.WoWInstances[i].Handle, WM_CODE, HookedKeys[index].KeySent, 0);
                                }
                            }
                            break;
                        case "SLAVES":
                            for (int i = 0; i < CephWindowManipulation.WoWInstances.Count(); i++)
                            {
                                if (CephWindowManipulation.WoWInstances[i].Title == "World of Warcraft" && int.Parse(CephWindowManipulation.WoWInstances[i].Handle.ToString()) != CephWindowManipulation.position[0])
                                {
                                    if (HookedKeys[index].ModifierToSend != 0)
                                    {
                                        Win32.PostMessage(CephWindowManipulation.WoWInstances[i].Handle, WM_CODE, HookedKeys[index].ModifierToSend, 0);
                                    }
                                    Win32.PostMessage(CephWindowManipulation.WoWInstances[i].Handle, WM_CODE, HookedKeys[index].KeySent, 0);
                                }
                            }
                            break;
                        case "KEYHOOKS":
    
                            break;
                    }
                }
            }
    
            private void RoundRobinProcessing(int index)
            {
                string WhoTo;
                int CountTo;
    
            }
    
            #region DLL imports
    
            [DllImport("user32.dll")]
            static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId);
    
            [DllImport("user32.dll")]
            static extern bool UnhookWindowsHookEx(IntPtr hInstance);
    
            [DllImport("user32.dll")]
            static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref keyboardHookStruct lParam);
    
            [DllImport("kernel32.dll")]
            static extern IntPtr LoadLibrary(string lpFileName);
            #endregion
        }
    }
    It's messy, I know, but I am learning keyboard hooks at the same time as doing this and I'm not cleaning the code upm till it actually works.

    Posted on EE:
    Garbage Collector running early

    His suggestions have failed, I did implement his suggestions in the last post but removed them again here for this post.

    Error:
    A callback was made on a garbage collected delegate of type 'Cephalopod!Cephalopod.Cephalopod_Management.CephKeyHook+keyboardHookProc::Invok e'. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called.
    If I add a logger message to just before call keyboardhookex and remove the others (so I get an accurate count) I am finding the error occurs between 121 and 126 procs every time.

    GC stealing my delegate.
  2. #2
    Cephalopod's Avatar Member
    Reputation
    5
    Join Date
    Sep 2008
    Posts
    85
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If I remove my hashtable and list and then implement GC.KeepAlive on the call to the class it works. However, without my hashtable and list the keyhook is useless.

    Any ideas? All I can think of is storing the code related to the hashtable and list in a different class, seperate from the actual hook.

    EDIT: Above is wrong. Delegate was collected @ around 25,000 hits.

    EDIT2: Ignore this thread. Going to create a class library instead so I can reuse the keyhook code in other projects. It works standalone, so meh. Cheap fix.
    Last edited by Cephalopod; 02-15-2009 at 01:50 PM.

  3. #3
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Midol View Post
    If I remove my hashtable and list and then implement GC.KeepAlive on the call to the class it works. However, without my hashtable and list the keyhook is useless.

    Any ideas? All I can think of is storing the code related to the hashtable and list in a different class, seperate from the actual hook.

    EDIT: Above is wrong. Delegate was collected @ around 25,000 hits.

    EDIT2: Ignore this thread. Going to create a class library instead so I can reuse the keyhook code in other projects. It works standalone, so meh. Cheap fix.
    Lol. Sorry, just now read this. Your delegate is never instantiated at the class level. (You're simply just calling new MyDelegate() each time) Keep a delegate var somewhere in your class so it doesn't lose scope, and get collected via the GC.

Similar Threads

  1. Steal Leader in ANY Raid Group
    By agrestic in forum World of Warcraft Exploits
    Replies: 7
    Last Post: 01-02-2007, 11:02 PM
  2. OGH is stealing form this site
    By Scrubs in forum World of Warcraft General
    Replies: 4
    Last Post: 12-26-2006, 01:00 PM
  3. Steal alotta loot
    By Glikko92 in forum World of Warcraft Guides
    Replies: 11
    Last Post: 10-19-2006, 09:02 PM
  4. [Exploit] Steal MC/BWL Raids
    By oninuva in forum World of Warcraft Exploits
    Replies: 4
    Last Post: 05-17-2006, 11:15 PM
  5. [News] WoW Trojan Steals Passwords To Cash Out
    By Cypher in forum World of Warcraft General
    Replies: 9
    Last Post: 05-04-2006, 02:16 PM
All times are GMT -5. The time now is 02:38 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search