将dll从进程模块列表中移除并保持正常运行

VS2022 C++ DLL开发:解决只生成DLL不生成LIB文件的完整指南 动态链接库(DLL)是Windows平台实现代码模块化与复用的核心技术,其原理在于将函数实现与调用分离。通过导出符号机制,DLL公开特定接口供外部程序调用,而导入库(LIB文件)则充当链接阶段的“地址簿”,记录这些接口的定位信息,实现隐式链接。这项技术的核心价值在于提升软件的可维护性、促进团队协作并优化内存使用。在Visual Studio 2022的C++开发环境中,开发者常遇到项目编译后仅生成DLL而缺失关键LIB文件的问题,这直接导致其他应用程序无法便捷地引用该动态库。本文将聚焦于**导出声明**与* 阅读详情

 


将dll从进程模块列表中移除并保持正常运行,这玩意想想是挺简单,n久前byshell就用了,

简单的思路就是给当前的dll内存映像做份拷贝,然后跳到那份拷贝的地址空间的代码,回头free掉原来的dll,

然后马上用VirtualAlloc在原基址上申请块同样大小的空间,并将那份拷贝还原回去,再跳回去执行。完。

代码写完后再实际程序中应用后发现问题,一旦调用到malloc或new的话就会崩溃,
于是去看了下byshell的代码,发现他申请内存是用VirtualAlloc,但是我大量的代码都是用new来分配,而且类对象不好用VirtualAlloc来分配吧~

经调式才清楚,原来每个dll,windows都会给其分配一个heap,
在freelibrary时系统会将其完全destroy掉,不怕你内存泄露。

调试时在FreeLibrary后HeapDestroy断点正好触发一次,就是这一次那个heap给销毁了。

解决办法就是在FreeLibrary前修改HeapDestroy的第一条指令为return,FreeLibrary后再修复。

实践证明,稳定......

*/


#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <psapi.h>

#pragma comment(lib, "Psapi.lib")

#define __printf printf

void HideLibrary(HMODULE hModule, LPVOID pCallBackAddr, LPVOID lParam);

typedef struct
{
      HMODULE lpDllBase;
      LPVOID lpNewDllBase;
      PTHREAD_START_ROUTINE pAddress;
      LPVOID lParam;
}UNLOADLIB_CALLBACK, *PUNLOADLIB_CALLBACK;

typedef
LPVOID WINAPI VIRTUALALLOC(
    LPVOID lpAddress,
    SIZE_T dwSize,
    DWORD flAllocationType,
    DWORD flProtect
);

typedef
BOOL WINAPI VIRTUALFREE(
    LPVOID lpAddress,
    SIZE_T dwSize,
    DWORD dwFreeType
);


typedef
BOOL WINAPI HEAPDESTROY(
    HANDLE hHeap
);

typedef
HMODULE WINAPI LOADLIBRARY(
    LPCTSTR lpFileName
);

typedef
HANDLE WINAPI CREATETHREAD(
    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    SIZE_T dwStackSize,
    LPTHREAD_START_ROUTINE lpStartAddress,
    LPVOID lpParameter,
    DWORD dwCreationFlags,
    LPDWORD lpThreadId
);

typedef void *    __cdecl MEMCPY(void *, const void *, size_t);

 

BOOL incLibraryCount(HMODULE hMe)
{
      //FreeLibrary后很多系统dll也会free掉,所以将所有已加载的再load一次以增加计数
    
      HANDLE hModsSnap =    CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);

      if(INVALID_HANDLE_VALUE == hModsSnap)
      {
          return FALSE;
      }

      MODULEENTRY32 meModuleEntry;
      meModuleEntry.dwSize = sizeof(MODULEENTRY32);

      if(!Module32First(hModsSnap, &meModuleEntry))
      {
          CloseHandle(hModsSnap);
          return FALSE;
      }
      do
      {
          if(LoadLibrary(meModuleEntry.szModule) == hMe)
              FreeLibrary(hMe);

      } while(Module32Next(hModsSnap, &meModuleEntry));

      CloseHandle(hModsSnap);

      return TRUE;
}

//枚举指定进程的所有线程
DWORD WINAPI EnumAndSetThreadState(LPVOID lParam)
{
      HANDLE hThreadSnap = NULL;
      THREADENTRY32 te32;
      memset(&te32,0,sizeof(te32));
      te32.dwSize = sizeof(THREADENTRY32);
      hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);

      DWORD myThreadId = GetCurrentThreadId();
      DWORD pid = GetCurrentProcessId();

      if (Thread32First(hThreadSnap, &te32))
      {
          do
          {
               if (pid == te32.th32OwnerProcessID)
               {
                   if(myThreadId != te32.th32ThreadID)
                   {
                       HANDLE hThread = OpenThread(
                           THREAD_SUSPEND_RESUME,
                           FALSE,
                           te32.th32ThreadID);

                       if(hThread != NULL)
                       {
                           if((int)lParam)
                               ResumeThread(hThread);
                           else
                               SuspendThread(hThread);

                           CloseHandle(hThread);
                       }
                   }
               }
          }
          while (Thread32Next(hThreadSnap,&te32));
      }
      CloseHandle( hThreadSnap );

      return 0;
}

DWORD WINAPI GotoCallBackAddr(LPVOID lParam)
{
      PUNLOADLIB_CALLBACK cbFunc = (PUNLOADLIB_CALLBACK)lParam;

      DWORD dwThreadId;
      HANDLE hThread;

      if(cbFunc->pAddress)
      {
          hThread = CreateThread(
              NULL,
              0,
              cbFunc->pAddress,
              cbFunc->lParam,
              0,
              &dwThreadId);

          if(hThread)
              CloseHandle(hThread);
      }

      //那份dll的拷贝不需要了,释放~
      VirtualFree(cbFunc->lpNewDllBase, 0, MEM_DECOMMIT);
      delete cbFunc;

      return 0;
}

DWORD WINAPI UnLoadLibrary(LPVOID lParam)
{
      //__asm INT 3
      __printf("UnLoadLibrary Entry./r/n");

      BYTE HeapDestroy_HookCode_bak[4];
      BYTE HeapDestroy_HookCode[4] = "/xC2/x04/x00";//RETN 0004
      MODULEINFO modinfo;
      DWORD oldProtect;

      PUNLOADLIB_CALLBACK cbFunc = (PUNLOADLIB_CALLBACK)lParam;

      HMODULE hDllInstance = cbFunc->lpDllBase;
      char dllpath_bak[MAX_PATH];

      GetModuleFileName(hDllInstance, dllpath_bak, sizeof(dllpath_bak));
      GetModuleInformation(GetCurrentProcess(), hDllInstance, &modinfo, sizeof(MODULEINFO));

      //给所有dll(除了自己)增加计数,防止FreeLibrary的时候那些dll给系统卸载掉
      incLibraryCount(hDllInstance);

      //保险起见,挂起其他线程,搞定后再恢复
      EnumAndSetThreadState((LPVOID)FALSE);

      //FreeLibrary之后原来存放api地址的内存也会被释放,
      //但是FreeLibrary之后还有些动作,趁现在还没free,关键API记下来
      VIRTUALALLOC *_VirtualAlloc = (VIRTUALALLOC*)
          GetProcAddress(GetModuleHandle("kernel32.dll"), "VirtualAlloc");
      LOADLIBRARY    *_LoadLibrary    = (LOADLIBRARY*)
          GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
      CREATETHREAD *_CreateThread = (CREATETHREAD*)
          GetProcAddress(GetModuleHandle("kernel32.dll"), "CreateThread");
      MEMCPY         *_memcpy         = (MEMCPY*)
          GetProcAddress(GetModuleHandle("ntdll.dll"), "memcpy");

      //这个很关键,并不是我要调用,是 FreeLibrary 时系统会调用,我要hook它,
      //不能给系统破坏这个heap,否则之后的dll貌似能工作,
      //但却不能用new或malloc申请内存, VirtualAlloc可以代替之,
      //但如果改写好多代码是划不来的,况且一些代码不好改,如list<T>的push内部的new

      HEAPDESTROY *_HeapDestroy    = (HEAPDESTROY*)
          GetProcAddress(GetModuleHandle("kernel32.dll"), "HeapDestroy");

      VirtualProtect(_HeapDestroy, 3, PAGE_EXECUTE_READWRITE, &oldProtect);

      //修改第一条指令为直接返回
      _memcpy(HeapDestroy_HookCode_bak, _HeapDestroy, 3);
      _memcpy(_HeapDestroy, HeapDestroy_HookCode, 3);


      //Sleep(100);
      //终于到这里了~~~^_^!
      FreeLibrary(hDllInstance);//释放

      //修复刚hook的函数
      _memcpy(_HeapDestroy, HeapDestroy_HookCode_bak, 3);
      //_memcpy(_RtlFreeHeap, RtlFreeHeap_HookCode_bak, 3);

      //在原来的dll基址申请同样大小的内存,并把之前的那份dll拷贝还原回去
      if(_VirtualAlloc(hDllInstance,
          modinfo.SizeOfImage,
          MEM_COMMIT|MEM_RESERVE,
          PAGE_EXECUTE_READWRITE) == NULL
          )
      {
          //失败,加载原来dll, 以正常方式工作
          //注意,不宜在dllmain中调用HideLibrary,LoadLibrary将导致dllmain再次被调用,导致死循环啦
          HMODULE hDll = _LoadLibrary(dllpath_bak);

          //重新计算回调函数在hDll地址空间的地址
          cbFunc->pAddress = (LPTHREAD_START_ROUTINE)
              ((DWORD)cbFunc->pAddress - (DWORD)hDllInstance + (DWORD)hDll);

          LPTHREAD_START_ROUTINE pFunc1 = (LPTHREAD_START_ROUTINE)
              ((DWORD)EnumAndSetThreadState - (DWORD)hDllInstance + (DWORD)hDll);

          //恢复被挂起的线程
          _CreateThread(0, 0, pFunc1, (LPVOID)TRUE, 0, 0);

          //调用回调函数
          if(cbFunc->pAddress)
              _CreateThread(0, 0, cbFunc->pAddress, cbFunc->lParam, 0, 0);

          return 0;
      }

      _memcpy(hDllInstance, cbFunc->lpNewDllBase, modinfo.SizeOfImage);

      //恢复被挂起的线程
      EnumAndSetThreadState((LPVOID)TRUE);

      //跳回原dll地址空间的GotoCallBackAddr,由它来释放这边VirtualAlloc申请的指针
      _CreateThread(0, 0, GotoCallBackAddr, cbFunc, 0, 0);

      return 0;
}

DWORD WINAPI HideLibrary02(LPVOID lParam)
{
      //__asm INT 3
      __printf("HideLibrary02 Entry./r/n");

      PUNLOADLIB_CALLBACK cbFunc = (PUNLOADLIB_CALLBACK)lParam;

      MODULEINFO modinfo;

      GetModuleInformation(GetCurrentProcess(), cbFunc->lpDllBase, &modinfo, sizeof(MODULEINFO));

      //申请一块和当前dll同样大小的内存
      cbFunc->lpNewDllBase = VirtualAlloc(NULL, modinfo.SizeOfImage, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);

      if(cbFunc->lpNewDllBase == NULL)
          return FALSE;

      //给当前dll做份拷贝,复制所有数据到刚申请的内存,
      memcpy(cbFunc->lpNewDllBase, modinfo.lpBaseOfDll, modinfo.SizeOfImage);

      //计算在copy中UnLoadLibrary的地址,并另起线程到该地址执行
      void *pNewUnLoadLibrary = LPVOID((DWORD)cbFunc->lpNewDllBase + (DWORD)UnLoadLibrary - (DWORD)modinfo.lpBaseOfDll);

      DWORD ThreadId;
      HANDLE hThread = CreateThread(0,0,
          (LPTHREAD_START_ROUTINE)pNewUnLoadLibrary, (LPVOID)cbFunc, CREATE_SUSPENDED, &ThreadId);

      if(hThread == NULL)
      {
          VirtualFree(cbFunc->lpNewDllBase, 0, MEM_DECOMMIT);
          delete cbFunc;

          return FALSE;
      }

      ResumeThread(hThread);
      CloseHandle(hThread);

      return TRUE;
}


void HideLibrary(HMODULE hModule, LPVOID pCallBackAddr, LPVOID lParam)
{
      __printf("HideLibrary Entry./r/n");

      PUNLOADLIB_CALLBACK lparam = new UNLOADLIB_CALLBACK;

      lparam->lpDllBase      = hModule;
      lparam->lpNewDllBase = NULL;
      lparam->pAddress       = (PTHREAD_START_ROUTINE)pCallBackAddr;
      lparam->lParam         = lParam;

      HANDLE hThread = CreateThread(0,0,
          HideLibrary02, (LPVOID)lparam, 0, NULL);

      if(hThread == NULL)
      {
          __printf("CreateThread HideLibrary02 Failed./r/n");

          delete lparam;
          return;
      }

      CloseHandle(hThread);

      return;
}

///////////////////////////////////////////////////////////
//example
//rundll32 UnloadLibrary.dll,Test

DWORD WINAPI testThread(LPVOID lParam)
{
      char *ptest = new char[512];

      sprintf(ptest, "My Pid: %d/r/n 用一些软件查看下,找不到这个dll吧?", GetCurrentProcessId());

      MessageBox(0, ptest, (char*)lParam, 0);

      delete ptest;

      return 0;
}


DWORD WINAPI testThread02(LPVOID lParam)
{

      HMODULE hModule = (HMODULE)lParam;


      char *ptest = new char[512];

      sprintf(ptest, "testThread02/r/n");

      Sleep(500);

      MessageBox(0, ptest, "start", 0);

      //不设置回调函数,成功还好,一旦失败则gameover
      HideLibrary(hModule, 0, 0);

      sprintf(ptest, "My Pid: %d/r/n 用一些软件查看下,找不到这个dll吧?", GetCurrentProcessId());
      MessageBox(0, ptest, "ok", 0);


      delete ptest;

      return 0;
}

HMODULE hDll;
extern "C"
{
__declspec(dllexport) int Test();
}

int Test()
{
      //1
      //主要线程开始工作后再HideLibrary不是很安全
      //CreateThread(0, 0, testThread02, hDll, 0, 0);
//
      //2
      //free掉dll后再开启主要工作线程妥当些
      char *p = strdup("hello");
      HideLibrary(hDll, testThread, p);

      Sleep(60000);

      return 0;
}


BOOL APIENTRY DllMain( HANDLE hModule,
                         DWORD    ul_reason_for_call,
                         LPVOID lpReserved
                       )
{
      switch (ul_reason_for_call)
      {
      case DLL_PROCESS_ATTACH:
          {
              hDll = (HMODULE)hModule;

          }
          break;

      }
    
      return TRUE;
}

 
ShellcodePack赋能DLL与COM劫持:高级隐蔽进程控制技术实践 在Windows系统安全与进程控制领域,DLL劫持和COM劫持是两种经典的代码注入技术。其核心原理在于利用系统模块加载机制中的信任关系,例如DLL搜索顺序或COM组件注册表查找,诱导目标进程主动加载并执行攻击者预设的代码。这类技术的核心价值在于其极高的隐蔽性,能够绕过传统基于文件特征的静态检测,实现权限维持和持久化访问。在实际应用场景中,红队渗透测试和高级威胁模拟常利用这些技术进行横向移动和防御规避。为了进一步提升对抗能力,现代载荷封装工具如ShellcodePack被广泛采用。它通过对原始Shellcod 阅读详情

相关推荐

gh0st1.0完整源码.rar

gh0st1.0完整源码。网络上很多1.0的源码都不能编译,现在发个完整版的上来,只要你的SDK和TX库都打上补丁了,编译不通过,生成不了,资源分就原数返还给你!

易语言对x64进程卸载DLL技术(可卸载64位进程里DLL)

易语言对x64进程卸载DLL技术(可卸载64位进程里DLL) 代码非常简单: 以上是注入和卸载的代码 下面示范64位游戏魔兽世界: 详细视频教程:链接: https://pan.baidu.com/s/1uZP3W3EYKLDSrPT_bPX8nA 提取码: 9kdi 本文章转载来自:http://bbs.dult.cn/forum.php?mod=viewthread&tid=24201 已取得该站文章版权 ...

hzw320的博客 1928

易语言结束进程中的DLL

易语言结束进程中的DLL源码,结束进程中的DLL,提升进程权限,列表,表项,取模块路径,列调用的模块,结束进程中DLL,Module32First,ExtractIconA,打开进程,获取线程,打开令牌,恢复权限,获取令牌特权,CreateToolhelp32Snapshot,Module32Next,关闭句柄,VirtualAllocEx

wince 流驱动

1、动态链接库的入口函数 DllEntry(HINSTANCE DllInstance, INT Reason, LPVOID Reserved); 说明: 每个动态链接库都需要输出这个函数,它只在动态库被加载和卸载时被调用,也就是设备管理器调用LoadLibrary而引起它被装入内存和调用UnloadLibrary将其从内存释放时被调用, 因而它是每个动态链接库最早被调用的函数,一般用它做一些全局变量的初始化。 参数: DllInstance:DLL的句柄,可以通过它在得到DLL中的一些资源,例如对话框,

qq_33782617的博客 1097

冒泡排序的并行计算

本人也是并行计算的小白,在这里记录下自己的学习笔记。 今天做了一下冒泡排序的并行计算比较: 串行冒泡排序如下: #include <stdio.h> #include <stdlib.h> #include <windows.h> void BubbleSort(int * pData, int nSize) { if (!pData) { ...

gaoyi的专栏 4491

deap数据集的情绪检测代码环境搭建与实现

deap数据数据集很大

f的博客 4157

解决办法一:GetProcAddress函数返回值总为NULL

  一直为NULL吾亦莫名其妙。网上说加入extern "C"的办法并没有解决。具体的解决办法是: 增加def EXPORTS getDefaultPrinter @1 调用 #define FUNCTION_INDEX 1 #define FUNCTION_NAME(i) (LPCSTR)MAKEINTRESOURCE(i) TestFunction function = (TestFunction)GetProcAddress(hDLL, FUNCTION_NAME(FUNCTION_IN

柳鲲鹏 1732

Palabos User Guide中文解读 | 第五章 | Palabos编程 (跳过了第四章Palabos-Java接口)

作者的话:本人在学习palabos时,发现国内中文资料甚少,恰好网上可以直接搜到palabos user guide这种英文资料,加之时间充裕,便打算开始翻译,翻了一节后发现这可能算侵权,就比较伤脑筋,突然想到自己写中文解读即可,便有了下面的博客。 Palabos User Guide Release 1.0 r1 Copyright © 2019 University of Geneva Jul...

Yulan Fang's notes. 2298

关于GetProcAddress返回错误代码为127的解决方案

关于GetProcAddress返回错误代码为127的解决方案 加载dll动态链接库时,一般都有两种加载方式。一种是装载期间通过#pragma命令指明要链接的动态库,还有一种是运行期间显示地去加载DLL库,从中到处需要的函数。 第一种加载方式只要动态链接库的目录地址写对,代码中包含相应的文件一般不会出错。当自己写第二种方式的时候,虽然新添了 我们对Markdown编辑器进行了一些功能拓展与语...

BUG搬运工的博客 4828

CESM2 实验笔记

文章目录1. 重新启动1.1 关于重启文件2. RUN_TYPE 初始化运行方式startupbranchhybrid3. branch 或者 hybrid运行的示例4. 其他声明5. 关于RESUBMIT 1. 重新启动 参考: https://bb.cgd.ucar.edu/cesm/threads/how-to-restart-cesm2-1-3-fhist-from-a-backup.5245/#post-36275 适用情况:模型运行因时间不足或其它原因中断,需要继续运行 方法1:将CONTIN

qq_38607066的博客 1万+

车辆横向控制MPC实战:从‘老王模型’到CasADi求解的保姆级避坑指南

本文详细解析了车辆横向控制MPC的实战应用,从经典动力学模型选择到CasADi求解器的优化配置,提供了一套完整的避坑指南。重点介绍了车辆动力学模型的验证要点、CasADi环境的高效配置技巧以及MPC问题建模的核心要素,帮助开发者快速实现稳健的横向控制方案。

weixin_42524499的博客 346

Qt文件操作(二)Qt删除文件、文件夹#慎用QDir::removeRecursively()remove()危险用法

又是一次踩坑,程序猿就是这样子成长的吧。 Qt文件操作 用到最多的还是QDir::mkdir 、 QDir::mkpath 不过偶尔也会需要删除QDir::remove , QDir::rmdir , QDir::rmpath 记一次踩坑 今天调试的时候发现了一段代码的写法 大致就是酱紫~~!(出于职业操守。改了一下内容再贴上来) 老样子,眼尖的先瞅瞅~ 然后跑完,喝口咖啡提提神。正当我准备再次...

weixin_39800118的博客 1万+

基于Java+SpringBoot+Vue的中小企业设备管理系统的设计与开发(源码+lw+部署文档+讲解等)

💗博主介绍:✌新人博主,工作经验两年+、专注于Java、小程序技术领域和毕业项目实战✌💗🌟文末获取源码+数据库🌟

2301_76502068的博客 1383

将dll从进程模块列表中移除并保持正常运行 可修改自动重启

将dll从进程模块列表中移除并保持正常运行,这玩意想想是挺简单,n久前byshell就用了, 简单的思路就是给当前的dll内存映像做份拷贝,然后跳到那份拷贝的地址空间的代码,回头free掉原来的dll, 然后马上用VirtualAlloc在原基址上申请块同样大小的空间,并将那

363

从菜鸟到大神:VSCode助力HTML开发全攻略

本文全面介绍 VSCode 在 HTML 开发中的高效应用。先引导读者完成 VSCode 的安装与个性化设置,助其快速适应开发环境;接着推荐 Live Server、Prettier 等实用插件,实现实时预览、代码格式化等功能,提升开发效率。通过详细的开发实战步骤,从新建文件到添加样式,带领读者掌握 HTML 基础结构与常用标签使用。还分享代码片段管理、多人协作等进阶技巧,解决常见开发问题。旨在帮助开发者利用 VSCode,轻松高效完成 HTML 开发,打造优质网页。

邓邓子的博客 3365

【赛题解析&命令脚本配置】2023年全国职业院校技能大赛GZ073网络系统管理赛项赛题第9套模块A:网络构建 & (三)无线网络配置+(四)出口网络配置-命令配置

【赛题解析&命令脚本配置】2023年全国职业院校技能大赛GZ073网络系统管理赛项赛题第9套模块A:网络构建 & (三)无线网络配置+(四)出口网络配置-命令配置

君逍遥o 1018

移除dll并保持正常运行

将dll从进程模块列表中移除并保持正常运行,这玩意想想是挺简单,n久前byshell就用了,简单的思路就是给当前的dll内存映像做份拷贝,然后跳到那份拷贝的地址空间的代码,回头free掉原来的dll,然后马上用VirtualAlloc在原基址上申请块同样大小的空间,并将那份拷贝还原回去,再跳回去执行。完。代码写完后再实际程序中应用后发现问题,一旦调用到malloc或new的话就会崩溃,

894

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

pla.dll文件丢失导致程序无法运行问题

其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个pla.dll文件(挑选合适的版本文件)把它放入到程序或系统目录中,当我们执行某一个.exe程序时,相应的DLL文件就会被调用,因此将缺失的文件放回到原目录之后就能打开你的软件或游戏了.那么出现pla.dll丢失要怎么解决?

2301_76755223的博客 938

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

找不到msvcr100.dll怎么办,轻松解决msvcr100.dll丢失的5种方法

msvcr100.dll 是一个由微软(Microsoft)开发的动态链接库(Dynamic Link Library, DLL)文件,它是 Microsoft Visual C++ Redistributable Package 的一部分,专门为基于 Visual Studio 2010 编译的应用程序提供运行时支持。检查并浏览回收站,看是否误删的msvcr100.dll文件还在其中。不当的系统清理:使用一些系统清理工具时,如果不小心删除了重要的系统文件,也可能会引起msvcr100.dll文件的丢失。

2301_77698200的博客 1298

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

告别DLL错误:Visual C++ Redistributable AIO如何3分钟解决Windows程序运行难题

你是否曾经兴奋地下载了一个新游戏或软件,却在启动时遭遇"找不到msvcp140.dll"、"应用程序无法启动"或"由于找不到VCRUNTIME140.dll"的冰冷提示?或者作为一名IT管理员,你是否厌倦了为每台电脑重复安装十几个不同版本的Visual C++运行库?这些问题背后,都指向Windows系统中一个常见但令人头疼的依赖问题——Visual C++运行库缺失或版本冲突。 Visual

gitblog_00906的博客 445

Windows DLL注入终极指南:用Xenos轻松掌控任何进程

想要在不修改源代码的情况下为Windows程序添加新功能吗?想要实时调试和监控应用程序的内部行为吗?Xenos这款强大的Windows DLL注入工具正是你需要的利器!无论你是软件开发者、安全研究人员,还是想要深入了解Windows系统机制的技术爱好者,Xenos都能让你在几分钟内掌握进程控制的魔法。 ## 为什么选择Xenos进行DLL注入? DLL注入是Windows开发和安全分析中的核心

gitblog_00970的博客 120
上一篇: Radmin和嘿洞的多SOCKET文件操作
下一篇: 简单过QQ的nProtect键盘加密保护
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值