コード例 #1
0
        public async void CodeGen()
        {
            bool   IsCodeGenSuccess = false;
            string errorstring      = string.Empty;
            await Task.Run(() =>
            {
                try
                {
                    //codegen cpp
                    FileInfo dllfi = new FileInfo(DllTarget.ModuleName);
                    string dllfn   = dllfi.Name.Split('.')[0];

                    StreamWriter dllcppsw = new StreamWriter(CodeGenPath + "/" + dllfn + ".hook.c", false, new UTF8Encoding(false));

                    StreamWriter dllhsw = new StreamWriter(CodeGenPath + "/" + dllfn + ".hook.h", false, new UTF8Encoding(false));
                    dllhsw.WriteLine($"#ifndef {dllfn}_hook_H");
                    dllhsw.WriteLine($"#define {dllfn}_hook_H");
                    dllhsw.WriteLine($"//aheadlib plugin for csharp.by snikeguo,email:[email protected]");
                    dllhsw.WriteLine($"//codegen time:{DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss:fff")}");
                    //#ifndef __cplusplus
                    dllhsw.WriteLine("#ifdef __cplusplus");
                    dllhsw.WriteLine("extern \"C\" {");
                    dllhsw.WriteLine("#endif");
                    dllhsw.WriteLine("#include<Windows.h>");
                    if (DllMode == CodeGenDllMode.MemMode)
                    {
                        dllhsw.WriteLine("#include\"MemoryModulePP.h\"");
                        dllhsw.WriteLine("#include<Shlwapi.h>");
                    }

                    foreach (var func in Functions)
                    {
                        dllhsw.WriteLine($"#define FUNCTION_{ReplaceRuleLoader.Get_NameInSourceCode_From_Name(func.Name)} pfnAL_{func.NameInSourceCode} //{func.UndecorateName}");
                        dllhsw.WriteLine($"extern PVOID pfnAL_{func.NameInSourceCode};//{func.UndecorateName} {ReplaceRuleLoader.Get_NameInSourceCode_From_Name(func.Name)}");
                    }

                    foreach (var func in Functions)
                    {
                        dllhsw.WriteLine($"#define OLD_FUNCTION_{ReplaceRuleLoader.Get_NameInSourceCode_From_Name(func.Name)} Old_pfnAL_{func.NameInSourceCode} //{func.UndecorateName}");
                        dllhsw.WriteLine($"extern PVOID Old_pfnAL_{func.NameInSourceCode};//{func.UndecorateName} {ReplaceRuleLoader.Get_NameInSourceCode_From_Name(func.Name)}");
                    }
                    if (DllMode == CodeGenDllMode.FileMode)
                    {
                        dllhsw.WriteLine($"extern BOOL WINAPI {dllfn}_Init();");
                    }
                    else
                    {
                        dllhsw.WriteLine($"extern BOOL WINAPI {dllfn}_Init(void *fileData,int fileLength);");
                    }

                    dllhsw.WriteLine("#ifdef __cplusplus");
                    dllhsw.WriteLine("}");
                    dllhsw.WriteLine("#endif");

                    dllhsw.WriteLine("#endif");
                    dllhsw.Flush();
                    dllhsw.Close();

                    dllcppsw.WriteLine($"#include\"{dllfn}.hook.h\"");
                    dllcppsw.WriteLine("#pragma comment( lib, \"Shlwapi.lib\")");

                    if (DllTarget.Cpu.ToLower() == "i386")
                    {
                        foreach (var func in Functions)
                        {
                            dllcppsw.WriteLine($"#pragma comment(linker,\"/EXPORT:{func.Name}=_AL_{func.NameInSourceCode},@{func.Ordinal}\")");//有个下划线
                        }
                    }
                    else if (DllTarget.Cpu.ToLower() == "amd64")
                    {
                        foreach (var func in Functions)
                        {
                            dllcppsw.WriteLine($"#pragma comment(linker,\"/EXPORT:{func.Name}=AL_{func.NameInSourceCode},@{func.Ordinal}\")");//没有下划线
                        }
                    }


                    foreach (var func in Functions)
                    {
                        dllcppsw.WriteLine($"PVOID pfnAL_{func.NameInSourceCode};");
                    }
                    foreach (var func in Functions)
                    {
                        dllcppsw.WriteLine($"PVOID Old_pfnAL_{func.NameInSourceCode};");//define old dll function point
                    }
                    //load function
                    if (DllMode == CodeGenDllMode.FileMode)
                    {
                        FileDllLoad(dllcppsw, dllfn);
                    }
                    else
                    {
                        MemDllLoad(dllcppsw, dllfn);
                    }

                    dllcppsw.WriteLine("void GetAddresses()\r\n{");

                    foreach (var func in Functions)
                    {
                        if (DllMode == CodeGenDllMode.FileMode)
                        {
                            dllcppsw.WriteLine($"   pfnAL_{func.NameInSourceCode}=(PVOID)GetProcAddress({dllfn}_Old_Module,\"{func.Name}\");");
                        }
                        else
                        {
                            dllcppsw.WriteLine($"   pfnAL_{func.NameInSourceCode}=(PVOID)MemoryGetProcAddress({dllfn}_MemoryModule,\"{func.Name}\");");
                        }
                    }

                    foreach (var func in Functions)
                    {
                        dllcppsw.WriteLine($"   Old_pfnAL_{func.NameInSourceCode}=pfnAL_{func.NameInSourceCode};");
                    }

                    dllcppsw.WriteLine("}");

                    if (DllTarget.Cpu.ToLower() == "i386")
                    {
                        StreamWriter x32asmjmpcodesw = new StreamWriter(CodeGenPath + "/" + dllfn + "_jump.asm", false, new UTF8Encoding(false));

                        x32asmjmpcodesw.WriteLine("; 把 .asm 文件添加到工程一次");
                        x32asmjmpcodesw.WriteLine("; 右键单击文件-属性-常规-");
                        x32asmjmpcodesw.WriteLine("; 项类型:自定义生成工具");
                        x32asmjmpcodesw.WriteLine("; 从生成中排除:否");
                        x32asmjmpcodesw.WriteLine("; 然后复制下面命令填入");
                        x32asmjmpcodesw.WriteLine("; 命令行: ml /Fo $(IntDir)%(fileName).obj /c /Cp %(fileName).asm");
                        x32asmjmpcodesw.WriteLine("; 输出: $(IntDir)%(fileName).obj;%(Outputs)");
                        x32asmjmpcodesw.WriteLine("; 链接对象: 是");


                        x32asmjmpcodesw.WriteLine(".686P");
                        x32asmjmpcodesw.WriteLine(".MODEL FLAT,C");
                        x32asmjmpcodesw.WriteLine(".DATA");

                        foreach (var func in Functions)
                        {
                            x32asmjmpcodesw.WriteLine($"EXTERN pfnAL_{func.NameInSourceCode}:DWORD");
                        }
                        x32asmjmpcodesw.WriteLine("\r\n\r\n;jmp code");
                        x32asmjmpcodesw.WriteLine(".CODE");
                        foreach (var func in Functions)
                        {
                            string s = $"AL_{func.NameInSourceCode} PROC\r\n";
                            s       += $"jmp pfnAL_{func.NameInSourceCode}\r\n";
                            s       += $"AL_{func.NameInSourceCode} ENDP\r\n";
                            x32asmjmpcodesw.WriteLine(s);
                        }
                        x32asmjmpcodesw.WriteLine("END");
                        x32asmjmpcodesw.Flush();
                        x32asmjmpcodesw.Close();
                    }
                    else if (DllTarget.Cpu.ToLower() == "amd64")
                    {
                        StreamWriter x64asmjmpcodesw = new StreamWriter(CodeGenPath + "/" + dllfn + "_jump.asm", false, new UTF8Encoding(false));

                        x64asmjmpcodesw.WriteLine("; 把 .asm 文件添加到工程一次");
                        x64asmjmpcodesw.WriteLine("; 右键单击文件-属性-常规-");
                        x64asmjmpcodesw.WriteLine("; 项类型:自定义生成工具");
                        x64asmjmpcodesw.WriteLine("; 从生成中排除:否");
                        x64asmjmpcodesw.WriteLine("; 然后复制下面命令填入");
                        x64asmjmpcodesw.WriteLine("; 命令行: ml64 /Fo $(IntDir)%(fileName).obj /c /Cp %(fileName).asm");
                        x64asmjmpcodesw.WriteLine("; 输出: $(IntDir)%(fileName).obj;%(Outputs)");
                        x64asmjmpcodesw.WriteLine("; 链接对象: 是");


                        x64asmjmpcodesw.WriteLine(".DATA");
                        foreach (var func in Functions)
                        {
                            x64asmjmpcodesw.WriteLine($"EXTERN pfnAL_{func.NameInSourceCode}:QWORD");
                        }
                        x64asmjmpcodesw.WriteLine("\r\n\r\n;jmp code");
                        foreach (var func in Functions)
                        {
                            string s = $"AL_{func.NameInSourceCode} PROC\r\n";
                            s       += $"jmp pfnAL_{func.NameInSourceCode}\r\n";
                            s       += $"AL_{func.NameInSourceCode} ENDP\r\n";
                            x64asmjmpcodesw.WriteLine(s);
                        }
                        x64asmjmpcodesw.WriteLine("END");
                        x64asmjmpcodesw.Flush();
                        x64asmjmpcodesw.Close();
                    }

                    if (DllMode == CodeGenDllMode.FileMode)
                    {
                        dllcppsw.WriteLine($"BOOL WINAPI {dllfn}_Init(){{");
                        dllcppsw.WriteLine("BOOL loadresult=Load();");
                    }
                    else
                    {
                        dllcppsw.WriteLine($"BOOL WINAPI {dllfn}_Init(void *fileData,int fileLength){{");
                        dllcppsw.WriteLine("BOOL loadresult=Load(fileData,fileLength);");
                    }

                    dllcppsw.WriteLine("if(!loadresult){return FALSE;}");
                    dllcppsw.WriteLine("GetAddresses();");
                    dllcppsw.WriteLine("DWORD old = 0;");
                    dllcppsw.WriteLine($"UINT64 LowAddr = (UINT64)&Old_pfnAL_{Functions[Functions.Count - 1].NameInSourceCode};");
                    dllcppsw.WriteLine($"UINT64 HighAddr = (UINT64)&pfnAL_{Functions[0].NameInSourceCode};");
                    dllcppsw.WriteLine($"int VirtualProtectResult=VirtualProtect((LPVOID)LowAddr," +
                                       $"(HighAddr-LowAddr+(UINT64)(sizeof(PVOID)))," +
                                       $"PAGE_EXECUTE_READWRITE," +
                                       $"&old);");
                    dllcppsw.WriteLine("return TRUE;\r\n}");

                    dllcppsw.Flush();
                    dllcppsw.Close();

                    if (IsCodegenFunctionTrace == true)
                    {
                        StreamWriter tracehsw = new StreamWriter(CodeGenPath + "/" + dllfn + ".trace.h", false, new UTF8Encoding(false));
                        tracehsw.WriteLine($"#ifndef {dllfn}_TRACE_H");
                        tracehsw.WriteLine($"#define {dllfn}_TRACE_H");

                        tracehsw.WriteLine("#ifdef __cplusplus");
                        tracehsw.WriteLine("extern \"C\" {");
                        tracehsw.WriteLine("#endif");

                        tracehsw.WriteLine($"void {dllfn}_TraceInit();");
                        tracehsw.WriteLine($"#endif");

                        tracehsw.WriteLine("#ifdef __cplusplus");
                        tracehsw.WriteLine("}");
                        tracehsw.WriteLine("#endif");

                        tracehsw.Close();

                        StreamWriter tracecsw = new StreamWriter(CodeGenPath + "/" + dllfn + ".trace.c", false, new UTF8Encoding(false));
                        tracecsw.WriteLine($"#include\"{dllfn}.hook.h\"");
                        tracecsw.WriteLine("#include<stdio.h>");
                        tracecsw.WriteLine("static char LogFileName[256];");

                        tracecsw.WriteLine("static char *GetDateTimeString(void)");
                        tracecsw.WriteLine("{");
                        tracecsw.WriteLine("    static char s[128];");
                        tracecsw.WriteLine("    SYSTEMTIME sys;");
                        tracecsw.WriteLine("    GetLocalTime(&sys);");
                        tracecsw.WriteLine("    sprintf_s(s,128, \" %4d-%2d-%2d %2d:%2d:%2d:%4d\", sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds);");
                        tracecsw.WriteLine("    return s;");
                        tracecsw.WriteLine("}");

                        tracecsw.WriteLine("static void TraceImpl(char *tracefuntion,char *NameInSourceCode,char *dllUndecorateName,char *dllfunction)");
                        tracecsw.WriteLine("{");
                        tracecsw.WriteLine("    FILE* f;");
                        tracecsw.WriteLine("    f = fopen(LogFileName, \"at\");");
                        tracecsw.WriteLine("    fprintf(f, \"%-64s%-100s%-100s%-100s%-100s\\n\", GetDateTimeString(),tracefuntion,NameInSourceCode,dllUndecorateName,dllfunction);");
                        tracecsw.WriteLine("    fclose(f);");
                        tracecsw.WriteLine("}");

                        foreach (var func in Functions)
                        {
                            tracecsw.WriteLine($"__declspec(naked) void Trace_{func.NameInSourceCode}(void)");
                            tracecsw.WriteLine("{");
                            tracecsw.WriteLine($"   TraceImpl(__FUNCTION__,\"{func.NameInSourceCode}\",\"{func.UndecorateName}\",\"{func.Name}\");");
                            string jmptemp = "{" + $"jmp Old_pfnAL_{func.NameInSourceCode}" + "}";
                            tracecsw.WriteLine($"    __asm {jmptemp}");
                            tracecsw.WriteLine("}");
                        }

                        tracecsw.WriteLine($"void {dllfn}_TraceInit()");
                        tracecsw.WriteLine("{");
                        tracecsw.WriteLine("   SYSTEMTIME sys;");
                        tracecsw.WriteLine("   GetLocalTime(&sys);");
                        tracecsw.WriteLine($"   sprintf_s(LogFileName,256, \"{LogPath}{dllfn}_%4d-%2d-%2d__%2d_%2d_%2d_%4d.txt\",sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds);");

                        tracecsw.WriteLine("    FILE* f;");
                        tracecsw.WriteLine("    f = fopen(LogFileName, \"at\");");
                        tracecsw.WriteLine("    fprintf(f, \"%-64s%-100s%-100s%-100s%-100s\\n\",\"time\",\"trace function name\",\"NameInSourceCode\",\"UndecorateName\",\"Dll Name\");");
                        tracecsw.WriteLine("    fclose(f);");

                        foreach (var func in Functions)
                        {
                            tracecsw.WriteLine($"   pfnAL_{func.NameInSourceCode}=Trace_{func.NameInSourceCode};");
                        }
                        tracecsw.WriteLine("}");
                        tracecsw.Close();
                    }

                    IsCodeGenSuccess = true;
                }
                catch (Exception ex)
                {
                    errorstring = ex.Message;
                }
            });

            if (IsCodeGenSuccess == true)
            {
                MessageBox.Show("success!");
            }
            else
            {
                MessageBox.Show(errorstring, "error!", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }