예제 #1
0
        public string print_args(ParsedFunc func, bool with_type)
        {
            if (func.args_list.Count == 1 &&
                func.args_list[0].arg_name == "void")
            {
                return("");
            }

            string res    = "";
            bool   bFirst = true;

            foreach (ParsedArgument arg in func.args_list)
            {
                if (!bFirst)
                {
                    res += ", ";
                }

                if (with_type == true)
                {
                    res += arg.arg_type;
                }
                res += arg.arg_name;

                if (bFirst)
                {
                    bFirst = false;
                }
            }

            return(res);
        }
예제 #2
0
        public string build_global_functions_hook()
        {
            string res = "";

            //res += "Functions!!!!\r\n";

            m_MainTokenizer.reset();

            ParsedFunc func = null;

            while (true)
            {
                func = parse_func();
                if (null == func)
                {
                    break;
                }

                res += generate_function_code_GlobalFunction(func);
                res += "\r\n";
            }


            //res += generate_function_code_MemberFunction(func) + "\r\n";


            return(res);
        }
예제 #3
0
        public string generate_function_code_MemberFunction_VTABLE_HOOK_mhook_call(ParsedFunc func, string class_name, int index)
        {
            //string result = "\t\t{\r\n";
            string result = "";

            result += "\tvoid hook_func_" + class_name + "_" + func.func_name + "(PVOID* orig_vtable, PVOID* my_vtable)\r\n";
            result += "\t{\r\n";

            /*
             * //extract virtual function address from the real object
             * //PVOID* p_IDirect3D9_VMT = *reinterpret_cast<PVOID**>(pOrig);
             * PVOID p_IDirect3D9_QueryInterface = p_IDirect3D9_VMT[1];
             * memcpy(&g_pMy_IDirect3D9->Real_Target, &p_IDirect3D9_QueryInterface, sizeof(&g_pMy_IDirect3D9->Real_Target));
             *
             * //extract virtual function address from our object
             * //PVOID* p_IDirect3D9_MY_VTABLE = *reinterpret_cast<PVOID**>(g_pMy_IDirect3D9);
             * PVOID p_My_IDirect3D9_QueryInterface = p_IDirect3D9_MY_VTABLE[1];
             *
             * BOOL result = Mhook_SetHook((PVOID*) &g_pMy_IDirect3D9->Real_Target ,
             *  p_My_IDirect3D9_QueryInterface
             *  );
             */

            int iMyWrapperFuncIndex   = index;
            int iOrigWrapperFuncIndex = index;

            result += "\t\t\t//extract virtual function address from the real object\r\n";
            //result += "\t\t\tPVOID p_" + class_name + "_" + func.func_name + " = p_" + class_name + "_VTABLE[" + iOrigWrapperFuncIndex.ToString() + "];\r\n";
            result += "\t\t\tPVOID p_" + class_name + "_" + func.func_name + " = orig_vtable[" + iOrigWrapperFuncIndex.ToString() + "];\r\n";
            result += "\t\t\tmemcpy(&g_p" + class_name + "_MY->" + func.func_name + "_ORIG, &p_" + class_name + "_" + func.func_name + ", sizeof(&g_p" + class_name + "_MY->" + func.func_name + "_ORIG));\r\n";

            result += "\t\t\t//extract virtual function address from our object\r\n";
            //result += "\t\t\tPVOID p_My_" + class_name + "_" + func.func_name + " = p_" + class_name + "_MY_VTABLE[" + iMyWrapperFuncIndex.ToString() + "];\r\n";
            result += "\t\t\tPVOID p_My_" + class_name + "_" + func.func_name + " = my_vtable[" + iMyWrapperFuncIndex.ToString() + "];\r\n";

            result += "\t\t\t//do the hook\r\n";
            result += "\t\t\tBOOL res = Mhook_SetHook((PVOID*) &g_p" + class_name + "_MY->" + func.func_name + "_ORIG ,\r\n";
            result += "\t\t\t\tp_My_" + class_name + "_" + func.func_name + ");\r\n";
            result += "\t\t\tassert(TRUE==res);\r\n";

            result += "\t}\r\n";

            return(result);
        }
예제 #4
0
        public string generate_function_code_DEBUG(ParsedFunc func)
        {
            string result = "";

            result += "Return type:[" + func.return_type + "] ";
            result += "Func Name:[" + func.func_name + "] ";
            result += "(";

            foreach (ParsedArgument arg in func.args_list)
            {
                result += "Type:[" + arg.arg_type + "] ";
                result += "Name:[" + arg.arg_name + "] ";
            }

            result += ")\r\n";
            result += "{ ... };";

            return(result);
        }
예제 #5
0
        public string generate_function_code_MemberFunction_VTABLE_HOOK(ParsedFunc func, string class_name, bool with_definition)
        {
            // function definition
            string result = "\t";

            if (!with_definition)
            {
                result += "virtual ";
            }

            result += func.return_type + " ";
            result += func.call_type + " ";

            if (with_definition)
            {
                result += class_name + "_MY::";
            }

            result += func.func_name + " ";
            result += "(";

            result += print_args(func, true);

            if (!with_definition)
            {
                result += ");\r\n";
            }

            if (with_definition)
            {
                result += ")\r\n";

                result += "\t{ \r\n";

                result += "\t\t";
                result += "OutputDebugStringA(\"" + class_name + "_MY::" + func.func_name + " Hook!\\n\");\r\n";
                result += "\t\t";

                if (!func.return_type.Contains("void"))
                {
                    //result += "return ";
                    result += "" + func.return_type + " res;\r\n";
                    result += "\t\tres = ";
                }
                else
                {
                    result += "\t\t";
                }

                //ULONG hr = (this->*Real_Target)();
                result += "(this->*" + func.func_name + "_ORIG)(\r\n\t\t\t";

                result += print_args(func, false);

                result += ");\r\n";

                if (!func.return_type.Contains("void"))
                {
                    result += "\t\treturn res;\r\n";
                }

                result += "\t}\r\n";
            }

            if (!with_definition)
            {
                // static member function pointing to the original member function
                //
                //static ULONG  (WINAPI My_IDirect3D9::* Real_Target)(void);

                result += "\tstatic " + func.return_type + "(";
                result += func.call_type + " ";
                result += class_name + "_MY::* ";
                result += func.func_name + "_ORIG)(";
                result += print_args(func, true);
                result += ");\r\n";
            }

            return(result);
        }
예제 #6
0
        public string generate_function_code_MemberFunction_WRAPPER(ParsedFunc func)
        {
            string result = "\t";

            result += func.return_type + " ";
            result += func.func_name + " ";
            result += "(";

            bool bFirst = true;

            foreach (ParsedArgument arg in func.args_list)
            {
                if (!bFirst)
                {
                    result += ", ";
                }

                result += arg.arg_type;
                result += arg.arg_name;

                if (bFirst)
                {
                    bFirst = false;
                }
            }

            result += ")\r\n";
            result += "\t{ \r\n";
            result += "\t\t";

            if (!func.return_type.Contains("void"))
            {
                result += "return ";
            }

            result += "m_pOrig->" + func.func_name + "(\r\n";

            bFirst = true;
            foreach (ParsedArgument arg in func.args_list)
            {
                if (!bFirst)
                {
                    result += ",\r\n\t\t\t";
                }
                else
                {
                    result += "\t\t\t";
                }

                result += arg.arg_name;

                if (bFirst)
                {
                    bFirst = false;
                }
            }

            result += "\r\n\t\t);\r\n";
            result += "\t}\r\n";

            return(result);
        }
예제 #7
0
        public string generate_function_code_GlobalFunction(ParsedFunc func)
        {
            string result = "";

            result += "\r\n";
            result += "//////////////////////////////////////////////////////////////////\r\n";
            result += "// " + func.func_name + " Hooking\r\n";
            result += "//////////////////////////////////////////////////////////////////\r\n";
            result += "\r\n";

            //split return type from function description

            Tokenizer t = new Tokenizer(func.return_type);

            string return_type = "";
            string call_type = "";

            string tok = null;
            while (true)
            {
                tok = t.NextToken();

                if (null == tok)
                    break;

                if (tok.Contains("__declspec") || tok.Contains("__stdcall"))
                {
                    if (!tok.Contains("__declspec(dllimport)"))
                    {
                        call_type += tok + " ";
                    }
                }
                else
                {
                    return_type += tok + " ";
                }

            }

            ////////////
            // typedef
            ////////////

            result += "typedef " + return_type;
            result += " (" + call_type + "*" + func.func_name + "_FPTR)(\r\n";

            bool bFirst = true;

            foreach (ParsedArgument arg in func.args_list)
            {
                result += "\t";
                if (!bFirst)
                {
                    result += ",";
                }

                result += arg.arg_type + " ";
                result += arg.arg_name + "\r\n";

                bFirst = false;
            }

            result += "\t);\r\n";

            //////////////////////////
            // orig func pointer
            //////////////////////////

            result += func.func_name + "_FPTR g_" + func.func_name + "_ORIG = NULL;\r\n";

            /////////////////////////////
            // detour function
            /////////////////////////////

            result += return_type + " " + call_type + " " + func.func_name + "_DETOUR (\r\n";

            bFirst = true;

            foreach (ParsedArgument arg in func.args_list)
            {
                result += "\t";
                if (!bFirst)
                {
                    result += ",";
                }

                result += arg.arg_type + " ";
                result += arg.arg_name + "\r\n";

                bFirst = false;
            }

            result += "\t)\r\n";
            result += "{\r\n";

            //assert to test the orig func pointer is valid
            result += "\tassert(g_" + func.func_name + "_ORIG);\r\n";

            //call the orig function

            result += "\t";

            if ("void " != return_type)
            {
                result += "return ";
            }

            result += "\tg_" + func.func_name + "_ORIG(\r\n";

            bFirst = true;
            foreach (ParsedArgument arg in func.args_list)
            {
                result += "\t\t";
                if (!bFirst)
                {
                    result += ",";
                }

                result += arg.arg_name + "\r\n";

                bFirst = false;
            }

            result += "\t\t);\r\n";

            result += "}\r\n";

            // show to hook code itself

            result += "\r\n...\r\n";

            result += "void Init_" + func.func_name + "_Hook()\r\n";
            result += "{\r\n";

            //HMODULE hUser32 = LoadLibrary("user32.dll");

            //TODO: identify module for system functions

            result += "\tHMODULE hmod = LoadLibraryA(\"??????.dll\")\r\n";
            result += "\tassert(hmod);\r\n";
            result += "\tif (hmod)\r\n";
            result += "\t{\r\n";

            result += "\t\tg_" + func.func_name + "_ORIG = (" + func.func_name + "_FPTR) GetProcAddress(hmod,\"" + func.func_name + "\");\r\n";
            result += "\t\tassert(g_" + func.func_name + "_ORIG);\r\n";

            result += "\t\tif (g_" + func.func_name + "_ORIG)\r\n";

            result += "\t\t{\r\n";
            //BOOL hook_res = Mhook_SetHook((PVOID*) &g_MessageBoxA_Orig, MessageBoxA_Detour);
            result += "\t\t\t BOOL hook_res = Mhook_SetHook((PVOID*) &g_" + func.func_name + "_ORIG, " + func.func_name + "_DETOUR);\r\n";
            result += "\t\t\t assert(hook_res);\r\n";

            result += "\t\t}\r\n";

            result += "\t}\r\n";

            result += "}\r\n";

            result += "\r\n...\r\n";

            return result;
        }
예제 #8
0
        public string generate_function_code_MemberFunction_VTABLE_HOOK_static_orig_assignment(ParsedFunc func, string class_name)
        {
            string result = "\t";

            //ULONG (WINAPI My_IDirect3D9::* My_IDirect3D9::Real_Target)(void) = (ULONG (WINAPI My_IDirect3D9::*)(void))&IDirect3D9::AddRef;

            result += func.return_type + " (";
            result += func.call_type + " ";
            result += class_name + "_MY::* ";
            result += class_name + "_MY::";
            result += func.func_name + "_ORIG)(";
            result += print_args(func, true);
            result += ") = (";
            result += func.return_type + " (";
            result += func.call_type + " ";
            result += class_name + "_MY::*)(";
            result += print_args(func, true);
            result += "))&";
            result += class_name + "::";
            result += func.func_name;
            result += ";\r\n";

            return(result);
        }
예제 #9
0
        private ParsedFunc parse_func()
        {
            ParsedFunc func = new ParsedFunc();

            string tok;
            string prev = "";

            bool arg_list_started = false;
            bool arg_list_ended   = false;

            func.return_type = ""; //might not have return value - constructor/destructor

            int scope_depth = 0;

            int template_scope_depth = 0;

            func.args_list = new List <ParsedArgument>();

            ParsedArgument arg = new ParsedArgument();

            //bool first_arg = true;

            tok  = m_MainTokenizer.NextToken();
            prev = tok;

            //using one lookahead.

            while (tok != null)
            {
                tok = m_MainTokenizer.NextToken();

                //note: i do not support const functions.

                if (";" == tok)
                {
                    if (prev == "}")
                    {
                        return(null);
                    }

                    if (func.func_name == func.return_type)
                    {
                        //constructor/destructor
                        func.return_type = "";
                    }

                    return(func);
                }

                if ("<" == prev)
                {
                    template_scope_depth++;
                }
                else if (">" == prev)
                {
                    template_scope_depth--;
                }

                if ("{" == prev)
                {
                    scope_depth++;
                }
                else if ("}" == prev)
                {
                    scope_depth--;

                    if (scope_depth < 0)
                    {
                        return(null);
                    }
                }
                else
                {
                    //if we're in deeper scope, then it's function definition which we don't care about.
                    if (0 == scope_depth)
                    {
                        if ("(" == tok)
                        {
                            arg_list_started = true;
                            func.func_name   = prev;
                        }
                        else if (")" == prev)
                        {
                            arg_list_ended = true;
                        }
                        else /*if (";" == prev)
                              * {
                              * if (func.func_name == func.return_type)
                              * {
                              * //constructor/destructor
                              * func.return_type = "";
                              * }
                              *
                              *
                              * return func;
                              * }
                              * else*/
                        {
                            if (!arg_list_started && !arg_list_ended)
                            {
                                if (prev.Contains("__declspec") ||
                                    prev.Contains("__stdcall") ||
                                    prev.Contains("virtual"))
                                {
                                    if (!prev.Contains("__declspec(dllimport)") && !prev.Contains("__declspec(nothrow)") && !prev.Contains("virtual"))
                                    {
                                        if (func.call_type != "")
                                        {
                                            func.call_type += " ";
                                        }

                                        func.call_type += prev;
                                    }
                                }
                                else
                                {
                                    if (func.return_type != "")
                                    {
                                        func.return_type += " ";
                                    }

                                    func.return_type += prev;
                                }
                            }
                            else if (arg_list_started == true && !arg_list_ended)
                            {
                                if (("(" != prev && "," != prev) || 0 != template_scope_depth)
                                {
                                    if (("," == tok || ")" == tok) && 0 == template_scope_depth) // if next is "," or ")" and we're not inside a template definition
                                    {
                                        arg.arg_name = prev;

                                        func.args_list.Add(arg);
                                        arg = new ParsedArgument();
                                    }
                                    else
                                    {
                                        arg.arg_type += prev + " ";
                                    }
                                }
                            }
                        }
                    }
                }



                prev = tok;
            }

            Debug.Print("Error! text ended before func declaration ended.\n");
            return(null);
        }
예제 #10
0
        public string generate_function_code_MemberFunction_VTABLE_HOOK(ParsedFunc func, string class_name,bool with_definition)
        {
            // function definition
            string result = "\t";

            if (!with_definition)
            {
                result += "virtual ";
            }

            result += func.return_type + " ";
            result += func.call_type + " ";

            if (with_definition)
            {
                result += class_name + "_MY::";
            }

            result += func.func_name + " ";
            result += "(";

            result += print_args(func,true);

            if (!with_definition)
            {
                result += ");\r\n";
            }

            if (with_definition)
            {

                result += ")\r\n";

                result += "\t{ \r\n";

                result += "\t\t";
                result += "OutputDebugStringA(\"" + class_name + "_MY::" + func.func_name + " Hook!\\n\");\r\n";
                result += "\t\t";

                if (!func.return_type.Contains("void"))
                {
                    //result += "return ";
                    result += "" + func.return_type + " res;\r\n";
                    result += "\t\tres = ";
                }
                else
                {
                    result += "\t\t";
                }

                //ULONG hr = (this->*Real_Target)();
                result += "(this->*" + func.func_name + "_ORIG)(\r\n\t\t\t";

                result += print_args(func, false);

                result += ");\r\n";

                if (!func.return_type.Contains("void"))
                {
                    result += "\t\treturn res;\r\n";
                }

                result += "\t}\r\n";

            }

            if (!with_definition)
            {
                // static member function pointing to the original member function
                //
                //static ULONG  (WINAPI My_IDirect3D9::* Real_Target)(void);

                result += "\tstatic " + func.return_type + "(";
                result += func.call_type + " ";
                result += class_name + "_MY::* ";
                result += func.func_name + "_ORIG)(";
                result += print_args(func, true);
                result += ");\r\n";
            }

            return result;
        }
예제 #11
0
        public string generate_function_code_DEBUG(ParsedFunc func)
        {
            string result = "";

            result += "Return type:[" + func.return_type + "] ";
            result += "Func Name:[" + func.func_name + "] ";
            result += "(";

            foreach( ParsedArgument arg in func.args_list)
            {
                result += "Type:["+arg.arg_type + "] ";
                result += "Name:[" + arg.arg_name + "] ";
            }

            result += ")\r\n";
            result += "{ ... };";

            return result;
        }
예제 #12
0
        public string generate_function_code_GlobalFunction(ParsedFunc func)
        {
            string result = "";

            result += "\r\n";
            result += "//////////////////////////////////////////////////////////////////\r\n";
            result += "// " + func.func_name + " Hooking\r\n";
            result += "//////////////////////////////////////////////////////////////////\r\n";
            result += "\r\n";

            //split return type from function description

            Tokenizer t = new Tokenizer(func.return_type);

            string return_type = "";
            string call_type   = "";

            string tok = null;

            while (true)
            {
                tok = t.NextToken();

                if (null == tok)
                {
                    break;
                }

                if (tok.Contains("__declspec") || tok.Contains("__stdcall"))
                {
                    if (!tok.Contains("__declspec(dllimport)"))
                    {
                        call_type += tok + " ";
                    }
                }
                else
                {
                    return_type += tok + " ";
                }
            }


            ////////////
            // typedef
            ////////////

            result += "typedef " + return_type;
            result += " (" + call_type + "*" + func.func_name + "_FPTR)(\r\n";

            bool bFirst = true;

            foreach (ParsedArgument arg in func.args_list)
            {
                result += "\t";
                if (!bFirst)
                {
                    result += ",";
                }

                result += arg.arg_type + " ";
                result += arg.arg_name + "\r\n";

                bFirst = false;
            }

            result += "\t);\r\n";

            //////////////////////////
            // orig func pointer
            //////////////////////////

            result += func.func_name + "_FPTR g_" + func.func_name + "_ORIG = NULL;\r\n";

            /////////////////////////////
            // detour function
            /////////////////////////////

            result += return_type + " " + call_type + " " + func.func_name + "_DETOUR (\r\n";

            bFirst = true;

            foreach (ParsedArgument arg in func.args_list)
            {
                result += "\t";
                if (!bFirst)
                {
                    result += ",";
                }

                result += arg.arg_type + " ";
                result += arg.arg_name + "\r\n";

                bFirst = false;
            }

            result += "\t)\r\n";
            result += "{\r\n";

            //assert to test the orig func pointer is valid
            result += "\tassert(g_" + func.func_name + "_ORIG);\r\n";

            //call the orig function

            result += "\t";

            if ("void " != return_type)
            {
                result += "return ";
            }

            result += "\tg_" + func.func_name + "_ORIG(\r\n";

            bFirst = true;
            foreach (ParsedArgument arg in func.args_list)
            {
                result += "\t\t";
                if (!bFirst)
                {
                    result += ",";
                }

                result += arg.arg_name + "\r\n";

                bFirst = false;
            }

            result += "\t\t);\r\n";

            result += "}\r\n";


            // show to hook code itself

            result += "\r\n...\r\n";

            result += "void Init_" + func.func_name + "_Hook()\r\n";
            result += "{\r\n";

            //HMODULE hUser32 = LoadLibrary("user32.dll");

            //TODO: identify module for system functions

            result += "\tHMODULE hmod = LoadLibraryA(\"??????.dll\")\r\n";
            result += "\tassert(hmod);\r\n";
            result += "\tif (hmod)\r\n";
            result += "\t{\r\n";

            result += "\t\tg_" + func.func_name + "_ORIG = (" + func.func_name + "_FPTR) GetProcAddress(hmod,\"" + func.func_name + "\");\r\n";
            result += "\t\tassert(g_" + func.func_name + "_ORIG);\r\n";

            result += "\t\tif (g_" + func.func_name + "_ORIG)\r\n";

            result += "\t\t{\r\n";
            //BOOL hook_res = Mhook_SetHook((PVOID*) &g_MessageBoxA_Orig, MessageBoxA_Detour);
            result += "\t\t\t BOOL hook_res = Mhook_SetHook((PVOID*) &g_" + func.func_name + "_ORIG, " + func.func_name + "_DETOUR);\r\n";
            result += "\t\t\t assert(hook_res);\r\n";



            result += "\t\t}\r\n";

            result += "\t}\r\n";

            result += "}\r\n";


            result += "\r\n...\r\n";


            return(result);
        }
예제 #13
0
        private string build_class_code_helper_VTABLE_HOOK(string class_name, int depth)
        {
            string result = "";

            //first step - output the entire class declaration

            if (0 == depth)
            {
                result += "/////////////// Hookit - Copyright (C) Yoel Shoshan - yoelshoshan at gmail.com\r\n";
                result += "// HEADER\r\n";

                result += "class " + class_name + "_MY : public " + class_name + "\r\n";
                result += "{\r\n";
                //constructor
                result += "\tpublic:\r\n";
                result += "\t" + class_name + "_MY()\r\n";
                result += "\t{\r\n";
                result += "\t}\r\n";

                //destructor
                result += "\tvirtual ~" + class_name + "_MY()\r\n";
                result += "\t{\r\n";
                result += "\t}\r\n";
            }

            //foreach (KeyValuePair<String, int> entry in classes)
            if (!m_ClassDeclarationLocations.ContainsKey(class_name))
            {
                return("Error! class [" + class_name + "] Not found in class defenitions map!\r\n");
            }

            int class_def_start_pos = m_ClassDeclarationLocations[class_name];

            m_MainTokenizer.m_pos = class_def_start_pos;

            int scope_depth = 0;

            string tok;

            bool reached_end = false;

            bool first = true;
            bool first_after_main_scope_start = true;

            string parent = "";

            bool func_decls_start = false;

            List <ParsedFunc> parsed_functions = new List <ParsedFunc>();

            while (true)
            {
                if (func_decls_start)
                {
                    ParsedFunc func = parse_func();
                    if (null == func)
                    {
                        break;
                    }

                    parsed_functions.Add(func);

                    //result += generate_function_code_MemberFunction_VTABLE_HOOK(func, class_name) + "\r\n";
                    continue;
                }

                tok = m_MainTokenizer.NextToken();

                if ("{" == tok)
                {
                    scope_depth++;
                }
                else if ("}" == tok)
                {
                    scope_depth--;
                    if (0 == scope_depth)
                    {
                        reached_end = true;
                        break;
                    }
                }
                else
                {
                    if (first)
                    {
                        if ("public" == tok || "private" == tok)
                        {
                            parent = m_MainTokenizer.NextToken();
                            if (":" == parent) // no inheritence case
                            {
                                parent = "";
                            }
                        }

                        first = false;
                        continue;
                    }

                    if (first_after_main_scope_start && scope_depth > 0)
                    {
                        if ("public" == tok || "private" == tok)
                        {
                            tok = m_MainTokenizer.NextToken();
                            if (":" != tok)
                            {
                                Debug.Print("Error! expected :\n");
                            }
                        }

                        first_after_main_scope_start = false;
                        func_decls_start             = true;
                        continue;
                    }

                    // member function declarations

                    func_decls_start = true;
                }
            }

            foreach (ParsedFunc f in parsed_functions) // Loop through List with foreach
            {
                result += generate_function_code_MemberFunction_VTABLE_HOOK(f, class_name, false) + "\r\n";
            }

            /*if (!reached_end)
             * {
             *  Debug.Print("Error! build_class_code::reached end without main function scope closing - } \n");
             * }*/

            //string dbg = "";
            //dbg += m_text.Substring(class_def_start_pos,m_pos - class_def_start_pos);

            if (parent != "")
            {
                result += build_class_code_helper_VTABLE_HOOK(parent, depth + 1);
            }


            if (0 == depth)
            {
                result += "};\r\n";
            }


            result += "\tvoid hook_" + class_name + "(" + class_name + "* pOrig);\r\n";

            result += "//CPP\r\n";

            foreach (ParsedFunc f in parsed_functions) // Loop through List with foreach
            {
                result += generate_function_code_MemberFunction_VTABLE_HOOK(f, class_name, true) + "\r\n";
            }

            //now, assign the orig static member functions

            foreach (ParsedFunc f in parsed_functions) // Loop through List with foreach
            {
                result += generate_function_code_MemberFunction_VTABLE_HOOK_static_orig_assignment(f, class_name) + "\r\n";
            }

            //our global class instance holder
            result += "\t" + class_name + "_MY* g_p" + class_name + "_MY = NULL;\r\n";


            // now, the actual mhook call

            int count = 0;

            foreach (ParsedFunc f in parsed_functions) // Loop through List with foreach
            {
                result += generate_function_code_MemberFunction_VTABLE_HOOK_mhook_call(f, class_name, count) + "\r\n";
                count++;
            }


            //My_IDirect3D9* g_pMy_IDirect3D9 = NULL;


            result += "\tvoid hook_" + class_name + "(" + class_name + "* pOrig)\r\n";
            result += "\t{\r\n";
            result += "\t\tif (g_p" + class_name + "_MY)\r\n";
            result += "\t\t{\r\n";
            result += "\t\t\treturn;\r\n";
            result += "\t\t}\r\n";

            result += "\t\tg_p" + class_name + "_MY = new " + class_name + "_MY();\r\n";
            result += "\t\t\r\n";

            //PVOID* p_IDirect3D9_VMT = *reinterpret_cast<PVOID**>(pOrig);
            //PVOID* p_IDirect3D9_MY_VTABLE = *reinterpret_cast<PVOID**>(g_pMy_IDirect3D9);
            result += "\t\tPVOID* p_" + class_name + "_VTABLE = *reinterpret_cast<PVOID**>(pOrig);\r\n";
            result += "\t\tPVOID* p_" + class_name + "_MY_VTABLE = *reinterpret_cast<PVOID**>(g_p" + class_name + "_MY);\r\n";

            result += "\t\t\r\n";
            result += "\t\t\r\n";

            // call all the hook functions

            count = 0;
            foreach (ParsedFunc f in parsed_functions) // Loop through List with foreach
            {
                result += "\t\thook_func_" + class_name + "_" + f.func_name + "(" + "p_" + class_name + "_VTABLE," + "p_" + class_name + "_MY_VTABLE);\r\n";
                count++;
            }

            result += "\t\t\r\n";
            result += "\t\t\r\n";


            result += "\t}\r\n";

            return(result);
        }
예제 #14
0
        public string print_args(ParsedFunc func, bool with_type)
        {
            if (func.args_list.Count == 1 &&
                func.args_list[0].arg_name == "void")
            {
                return "";
            }

            string res = "";
            bool bFirst = true;

            foreach (ParsedArgument arg in func.args_list)
            {
                if (!bFirst)
                {
                    res += ", ";
                }

                if (with_type == true)
                {
                    res += arg.arg_type;
                }
                res += arg.arg_name;

                if (bFirst)
                {
                    bFirst = false;
                }
            }

            return res;
        }
예제 #15
0
        public string generate_function_code_MemberFunction_WRAPPER(ParsedFunc func)
        {
            string result = "\t";

            result += func.return_type + " ";
            result += func.func_name + " ";
            result += "(";

            bool bFirst = true;

            foreach (ParsedArgument arg in func.args_list)
            {
                if (!bFirst)
                {
                    result += ", ";
                }

                result += arg.arg_type;
                result += arg.arg_name;

                if (bFirst)
                {
                    bFirst = false;
                }
            }

            result += ")\r\n";
            result += "\t{ \r\n";
            result += "\t\t";

            if (!func.return_type.Contains("void"))
            {
                result += "return ";
            }

            result += "m_pOrig->" + func.func_name + "(\r\n";

            bFirst = true;
            foreach (ParsedArgument arg in func.args_list)
            {
                if (!bFirst)
                {
                    result += ",\r\n\t\t\t";
                } else
                {
                    result += "\t\t\t";
                }

                result += arg.arg_name;

                if (bFirst)
                {
                    bFirst = false;
                }
            }

            result += "\r\n\t\t);\r\n";
            result += "\t}\r\n";

            return result;
        }
예제 #16
0
        public string generate_function_code_MemberFunction_VTABLE_HOOK_static_orig_assignment(ParsedFunc func, string class_name)
        {
            string result = "\t";
            //ULONG (WINAPI My_IDirect3D9::* My_IDirect3D9::Real_Target)(void) = (ULONG (WINAPI My_IDirect3D9::*)(void))&IDirect3D9::AddRef;

            result += func.return_type + " (";
            result += func.call_type + " ";
            result += class_name + "_MY::* ";
            result += class_name + "_MY::";
            result += func.func_name + "_ORIG)(";
            result += print_args(func, true);
            result += ") = (";
            result += func.return_type + " (";
            result += func.call_type + " ";
            result += class_name + "_MY::*)(";
            result += print_args(func, true);
            result += "))&";
            result += class_name + "::";
            result += func.func_name;
            result += ";\r\n";

            return result;
        }
예제 #17
0
        public string generate_function_code_MemberFunction_VTABLE_HOOK_mhook_call(ParsedFunc func, string class_name, int index)
        {
            //string result = "\t\t{\r\n";
            string result = "";

            result += "\tvoid hook_func_"  +class_name+  "_"+func.func_name+"(PVOID* orig_vtable, PVOID* my_vtable)\r\n";
            result += "\t{\r\n";

            /*
            //extract virtual function address from the real object
            //PVOID* p_IDirect3D9_VMT = *reinterpret_cast<PVOID**>(pOrig);
            PVOID p_IDirect3D9_QueryInterface = p_IDirect3D9_VMT[1];
            memcpy(&g_pMy_IDirect3D9->Real_Target, &p_IDirect3D9_QueryInterface, sizeof(&g_pMy_IDirect3D9->Real_Target));

            //extract virtual function address from our object
            //PVOID* p_IDirect3D9_MY_VTABLE = *reinterpret_cast<PVOID**>(g_pMy_IDirect3D9);
            PVOID p_My_IDirect3D9_QueryInterface = p_IDirect3D9_MY_VTABLE[1];

            BOOL result = Mhook_SetHook((PVOID*) &g_pMy_IDirect3D9->Real_Target ,
                p_My_IDirect3D9_QueryInterface
                );
            */

            int iMyWrapperFuncIndex = index;
            int iOrigWrapperFuncIndex = index;

            result += "\t\t\t//extract virtual function address from the real object\r\n";
            //result += "\t\t\tPVOID p_" + class_name + "_" + func.func_name + " = p_" + class_name + "_VTABLE[" + iOrigWrapperFuncIndex.ToString() + "];\r\n";
            result += "\t\t\tPVOID p_" + class_name + "_" + func.func_name + " = orig_vtable[" + iOrigWrapperFuncIndex.ToString() + "];\r\n";
            result += "\t\t\tmemcpy(&g_p" + class_name + "_MY->" + func.func_name + "_ORIG, &p_" + class_name + "_" + func.func_name + ", sizeof(&g_p" + class_name + "_MY->" + func.func_name + "_ORIG));\r\n";

            result += "\t\t\t//extract virtual function address from our object\r\n";
            //result += "\t\t\tPVOID p_My_" + class_name + "_" + func.func_name + " = p_" + class_name + "_MY_VTABLE[" + iMyWrapperFuncIndex.ToString() + "];\r\n";
            result += "\t\t\tPVOID p_My_" + class_name + "_" + func.func_name + " = my_vtable[" + iMyWrapperFuncIndex.ToString() + "];\r\n";

            result += "\t\t\t//do the hook\r\n";
            result += "\t\t\tBOOL res = Mhook_SetHook((PVOID*) &g_p" + class_name + "_MY->" + func.func_name + "_ORIG ,\r\n";
            result += "\t\t\t\tp_My_" + class_name + "_" + func.func_name + ");\r\n";
            result += "\t\t\tassert(TRUE==res);\r\n";

            result += "\t}\r\n";

            return result;
        }
예제 #18
0
        private string build_class_code_helper_WRAPPER(string class_name, int depth)
        {
            string result = "";

            //first step - output the entire class declaration

            if (0 == depth)
            {
                result += "/////////////// Hookit - Copyright (C) Yoel Shoshan - yoelshoshan at gmail.com\r\n";
                result += "class " + class_name + "_Wrapper : public " + class_name + "\r\n";
                result += "{\r\n";
                result += "\t" + class_name + " *m_pOrig;\r\n";

                //constructor
                result += "\t" + class_name + "_Wrapper(" + class_name + " *pOrig )\r\n";
                result += "\t{\r\n";
                result += "\t\tm_pOrig = pOrig;\r\n";
                result += "\t}\r\n";

                //destructor
                result += "\tvirtual ~" + class_name + "_Wrapper()\r\n";
                result += "\t{\r\n";
                result += "\t\tm_pOrig = NULL;\r\n";
                result += "\t}\r\n";
            }

            //foreach (KeyValuePair<String, int> entry in classes)
            if (!m_ClassDeclarationLocations.ContainsKey(class_name))
            {
                return("Error! class [" + class_name + "] Not found in class defenitions map!\r\n");
            }

            int class_def_start_pos = m_ClassDeclarationLocations[class_name];

            m_MainTokenizer.m_pos = class_def_start_pos;

            int scope_depth = 0;

            string tok;

            bool reached_end = false;

            bool first = true;
            bool first_after_main_scope_start = true;

            string parent = "";

            bool func_decls_start = false;

            while (true)
            {
                if (func_decls_start)
                {
                    ParsedFunc func = parse_func();
                    if (null == func)
                    {
                        break;
                    }
                    result += generate_function_code_MemberFunction_WRAPPER(func) + "\r\n";
                    continue;
                }

                tok = m_MainTokenizer.NextToken();

                if ("{" == tok)
                {
                    scope_depth++;
                }
                else if ("}" == tok)
                {
                    scope_depth--;
                    if (0 == scope_depth)
                    {
                        reached_end = true;
                        break;
                    }
                }
                else
                {
                    if (first)
                    {
                        if ("public" == tok || "private" == tok)
                        {
                            parent = m_MainTokenizer.NextToken();
                            if (":" == parent) // no inheritence case
                            {
                                parent = "";
                            }
                        }

                        first = false;
                        continue;
                    }

                    if (first_after_main_scope_start && scope_depth > 0)
                    {
                        if ("public" == tok || "private" == tok)
                        {
                            tok = m_MainTokenizer.NextToken();
                            if (":" != tok)
                            {
                                Debug.Print("Error! expected :\n");
                            }
                        }

                        first_after_main_scope_start = false;
                        func_decls_start             = true;
                        continue;
                    }

                    // member function declarations

                    func_decls_start = true;
                }
            }

            /*if (!reached_end)
             * {
             *  Debug.Print("Error! build_class_code::reached end without main function scope closing - } \n");
             * }*/

            //string dbg = "";
            //dbg += m_text.Substring(class_def_start_pos,m_pos - class_def_start_pos);

            if (parent != "")
            {
                result += build_class_code_helper_WRAPPER(parent, depth + 1);
            }


            if (0 == depth)
            {
                result += "};\r\n";
            }

            return(result);
        }
예제 #19
0
        private ParsedFunc parse_func()
        {
            ParsedFunc func = new ParsedFunc();

            string tok;
            string prev = "";

            bool arg_list_started = false;
            bool arg_list_ended = false;

            func.return_type = ""; //might not have return value - constructor/destructor

            int scope_depth = 0;

            int template_scope_depth = 0;

            func.args_list = new List<ParsedArgument>();

            ParsedArgument arg = new ParsedArgument();

            //bool first_arg = true;

            tok = m_MainTokenizer.NextToken();
            prev = tok;

            //using one lookahead.

            while (tok!=null)
            {
                tok = m_MainTokenizer.NextToken();

                //note: i do not support const functions.

                if (";" == tok)
                {
                    if (prev == "}")
                    {
                        return null;
                    }

                    if (func.func_name == func.return_type)
                    {
                        //constructor/destructor
                        func.return_type = "";
                    }

                    return func;
                }

                if ("<" == prev)
                {
                    template_scope_depth++;
                }
                else if (">" == prev)
                {
                    template_scope_depth--;
                }

                if ("{" == prev)
                {
                    scope_depth++;
                }
                else if ("}" == prev)
                {
                    scope_depth--;

                    if (scope_depth < 0)
                        return null;
                }
                else
                {

                    //if we're in deeper scope, then it's function definition which we don't care about.
                    if (0 == scope_depth)
                    {
                        if ("(" == tok)
                        {
                            arg_list_started = true;
                            func.func_name = prev;
                        }
                        else if (")" == prev)
                        {

                            arg_list_ended = true;
                        }
                        else /*if (";" == prev)
                        {
                            if (func.func_name == func.return_type)
                            {
                                //constructor/destructor
                                func.return_type = "";
                            }

                            return func;
                        }
                        else*/
                        {
                            if (!arg_list_started && !arg_list_ended)
                            {

                                if (prev.Contains("__declspec")
                                    || prev.Contains("__stdcall")
                                    || prev.Contains("virtual") )
                                {
                                    if (!prev.Contains("__declspec(dllimport)") && !prev.Contains("__declspec(nothrow)") && !prev.Contains("virtual"))
                                    {
                                        if (func.call_type != "")
                                        {
                                            func.call_type += " ";
                                        }

                                        func.call_type += prev;
                                    }
                                }
                                else
                                {
                                    if (func.return_type != "")
                                    {
                                        func.return_type += " ";
                                    }

                                    func.return_type += prev;
                                }

                            }
                            else if (arg_list_started == true && !arg_list_ended)
                            {
                                if ( ("(" != prev && "," != prev) || 0!=template_scope_depth)
                                {
                                    if (("," == tok || ")" == tok) && 0 == template_scope_depth) // if next is "," or ")" and we're not inside a template definition
                                    {
                                        arg.arg_name = prev;

                                        func.args_list.Add(arg);
                                        arg = new ParsedArgument();
                                    }
                                    else
                                    {
                                        arg.arg_type += prev + " ";
                                    }
                                }

                            }

                        }
                    }
                }

                prev = tok;
            }

            Debug.Print("Error! text ended before func declaration ended.\n");
            return null;
        }