wordpress建站前端,seo网站结构优化,wordpress新闻模版,赣南脐橙网络营销策划书一#xff1a;背景 前段时间在训练营上课的时候就有朋友提到一个问题#xff0c;为什么 Windbg 附加到 C# 程序后#xff0c;程序就处于中断状态了#xff1f;它到底是如何实现的#xff1f;其实简而言之就是线程的远程注入#xff0c;这一篇就展开说一下。二#xff1a…一背景 前段时间在训练营上课的时候就有朋友提到一个问题为什么 Windbg 附加到 C# 程序后程序就处于中断状态了它到底是如何实现的其实简而言之就是线程的远程注入这一篇就展开说一下。二实现原理1. 基本思路WinDbg 在附加进程的时候会注入一个线程到 C# 进程 中注入成功后会执行一个 DbgBreakPoint() 函数其实就是 int 3 这时候 CPU 就会执行 3 号中断函数将当前进程的所有线程进行暂停文字不好理解的话画一个图大概就是这样。口说无凭接下来用上一个简单案例演示一下。2. 案例演示首先写一个简单的 C# 程序不断的输出时间和标号代码如下internal class Program{static void Main(string[] args){for (int i 0; i 10000; i){Console.WriteLine(${DateTime.Now},i{i});Thread.Sleep(1000);}}}把程序跑起来后使用 WinDbg 附加你可以发现 Command 自动切换到了 8 号线程通过 k 命令可以看到最上面是一个 int 3 中断截图如下这里就有一个想法了既然 WinDbg 可以注入为何我的程序就注入不得呢既然我的程序可以注入那就可以做一些我想做的事情。3. 自定义注入有了自定义注入的想法接下来的实现步骤大概是这样的。注入一个线程到 C# 程序中。让程序加载一个 dll 文件。在 dll 中做一些我想做的业务逻辑。接下来新建一个 C 的动态链接库在 DLLMain 入口函数的 DLL_PROCESS_ATTACH 事件中写一个 printf 函数如果在 C# 程序中输出来了就算成功注入了参考代码如下#include Windows.h
#include stdio.hBOOL APIENTRY DllMain(HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved
)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:printf( 总部总部我已经成功打入内部ul_reason_for_call%d\n , ul_reason_for_call);break;}return TRUE;
}要被加载的 MyInject.dll 已经构建完毕接下来就用 Win32 API 的 CreateRemoteThread() 实现远程注入但注入之前需要做三件事情。获取 C# 程序的 进程句柄。在 C# 进程中申请一块内存空间存放加载的 path 路径。调用 LoadLibraryW 函数在 C# 进程中实现 dll 加载。过程有了新建一个 C 控制台程序 ConsoleApplication1.exe 整体的参考代码如下#include iostream
#include Windows.h
#include stdio.h
#include stdlib.h
#include Tlhelp32.hDWORD GetPid(const WCHAR* szName)
{HANDLE hprocessSnap NULL;PROCESSENTRY32 pe32 { 0 };hprocessSnap CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);pe32.dwSize sizeof(PROCESSENTRY32);if (Process32First(hprocessSnap, pe32)){do {if (!wcscmp(szName, pe32.szExeFile)) {return (int)pe32.th32ProcessID;}} while (Process32Next(hprocessSnap, pe32));}else{CloseHandle(hprocessSnap);}return 0;
}int main()
{const wchar_t* path LD:\\net6\\ConsoleApp1\\x64\\Debug\\MyInject.dll; //要注入的dll文件地址//1. 获取进程IDDWORD procID GetPid(LConsoleApp4.exe);//2. 获取进程句柄HANDLE hProcess OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);//3. 在目标进程中开辟一块空间LPVOID pRemoteAdress VirtualAllocEx(hProcess, NULL, wcslen(path) * 2, MEM_COMMIT, PAGE_READWRITE);//4. 将 path 写入到这块空间中BOOL bRet WriteProcessMemory(hProcess, pRemoteAdress, path, wcslen(path) * 2, NULL);//5. 让目标线程调用 LoadLibraryW 加载我们注入的 dllHMODULE hModule GetModuleHandle(Lkernel32.dll);LPTHREAD_START_ROUTINE dwLoadAddr (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, LoadLibraryW);HANDLE hThread CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)dwLoadAddr,pRemoteAdress,NULL,NULL);//6. 函数执行完后释放这块空间。WaitForSingleObject(hThread, -1);VirtualFreeEx(hProcess, pRemoteAdress, 1, MEM_DECOMMIT);system(pause);return 0;
}万事具备接下来我们将 ConsoleApplication1.exe 启动可以成功观察到 ConsoleApp4.exe 上已经注入成功的输出截图如下三总结 这就是对 WinDbg 实现注入拦截的一个衍生知识整体思路还是很明朗的当然有注入就有反注入比如下面两条策略。设置进程的保护属性。屏蔽 或者 混淆 Win32 的 LoadLibraryW 函数。等等各种反注入策略当然这不是我所关心的毕竟我只专注 .NET高级调试