从内存中加载并运行exe (c)

深入解析如何在内存中运行EXE程序 在Windows系统环境中,将可执行文件(EXE)直接运行于内存中,而非传统地从磁盘加载,是一项极具挑战性的技术任务。该技术不仅涉及操作系统底层机制的理解,还要求开发者具备深厚的逆向工程、内存管理及程序加载流程的知识。内存中EXE执行常用于高级渗透测试、无文件攻击、安全研究以及软件保护等领域,具有极高的实战价值和研究意义。本章将介绍该技术的背景、应用场景及其核心实现难点,为后续章节的深入分析奠定基础。 阅读详情

  原理很简单:就是“借尸还魂”,启动一个僵尸进程(NT下可以是自身程序启动的另一个进程),然后在它运行前将其整个替换成内存中的exe内容,待正式运行后执行的就是你的目标代码了。  
   
  不过代码中还有一些不尽人意的地方,比如在98下运行会留一个僵尸程序的壳在硬盘上(其实那个僵尸程序本身就是一个完整的可执行程序,直接运行的话只显示一条错误信息然后就退出了)。另外由于客观条件限制,代码没有经过充分测试,只在XP下进行了一些初步测试:普通exe都能正常运行,upx压缩过的exe绝大多数情况下都能运行,只有在不能卸载僵尸外壳时才有问题(upx压缩过的exe没有重定向表,无法加载到其它地址运行)。    
   
  如果有bug望告之,如果有更好的方法特别是能解决98下的遗留尾巴的话希望不吝赐教。  
  ---------------------------------------------------------------------------------------  
   
  小弟没有翻译Win98下处理的方法,请大家参考原文:)  
   
  //   MemPE.cpp   :   Defines   the   entry   point   for   the   DLL   application.  
  //  
   
  #include   "stdafx.h"  
   
  typedef   IMAGE_SECTION_HEADER   (*PIMAGE_SECTION_HEADERS)[1];  
   
  //   计算对齐后的大小  
  unsigned   long   GetAlignedSize(unsigned   long   Origin,   unsigned   long   Alignment)  
  {  
  return   (Origin   +   Alignment   -   1)   /   Alignment   *   Alignment;  
  }  
   
  //   计算加载pe并对齐需要占用多少内存  
  //   未直接使用OptionalHeader.SizeOfImage作为结果是因为据说有的编译器生成的exe这个值会填0  
  unsigned   long   CalcTotalImageSize(PIMAGE_DOS_HEADER   MzH,   unsigned   long   FileLen,    
    PIMAGE_NT_HEADERS   peH,   PIMAGE_SECTION_HEADERS   peSecH)  
  {  
  unsigned   long   res;  
  //   计算pe头的大小  
  res   =   GetAlignedSize(peH->OptionalHeader.SizeOfHeaders,   peH->OptionalHeader.SectionAlignment);  
  //   计算所有节的大小  
  for(int   i=0;   i   <   peH->FileHeader.NumberOfSections;   ++i)  
  {  
  if(peSecH[i]->PointerToRawData   +   peSecH[i]->SizeOfRawData>FileLen){//   超出文件范围  
  return   0;  
  }  
  else   if(peSecH[i]->VirtualAddress){//计算对齐后某节的大小  
  if(peSecH[i]->Misc.VirtualSize){  
  res   =   GetAlignedSize(peSecH[i]->VirtualAddress   +   peSecH[i]->Misc.VirtualSize,    
  peH->OptionalHeader.SectionAlignment);  
  }  
  else{  
  res   =   GetAlignedSize(peSecH[i]->VirtualAddress   +   peSecH[i]->SizeOfRawData,    
  peH->OptionalHeader.SectionAlignment);  
  }  
  }  
  else   if(peSecH[i]->Misc.VirtualSize   <   peSecH[i]->SizeOfRawData){  
  res   +=   GetAlignedSize(peSecH[i]->SizeOfRawData,   peH->OptionalHeader.SectionAlignment);  
  }  
  else{  
  res   +=   GetAlignedSize(peSecH[i]->Misc.VirtualSize,   peH->OptionalHeader.SectionAlignment);  
  }  
  }  
  return   res;  
  }  
//   加载pe到内存并对齐所有节  
  BOOL   AlignPEToMem(void   *Buf,   long   Len,   PIMAGE_NT_HEADERS   &peH,   PIMAGE_SECTION_HEADERS   &peSecH,    
      void   *&Mem,   unsigned   long   &ImageSize)  
  {  
  PIMAGE_DOS_HEADER   SrcMz; //   DOS头  
  PIMAGE_NT_HEADERS   SrcPeH; //   PE头  
  PIMAGE_SECTION_HEADERS   SrcPeSecH; //   节表  
   
  SrcMz   =   (PIMAGE_DOS_HEADER)Buf;  
  if(Len   <   sizeof(IMAGE_DOS_HEADER))   return   FALSE;  
  if(SrcMz->e_magic   !=   IMAGE_DOS_SIGNATURE)   return   FALSE;  
  if(Len   <   SrcMz->e_lfanew   +   (long)sizeof(IMAGE_NT_HEADERS))   return   FALSE;  
  SrcPeH   =   (PIMAGE_NT_HEADERS)((int)SrcMz   +   SrcMz->e_lfanew);  
  if(SrcPeH->Signature   !=   IMAGE_NT_SIGNATURE)   return   FALSE;  
  if((SrcPeH->FileHeader.Characteristics   &   IMAGE_FILE_DLL)  
  ||   (SrcPeH->FileHeader.Characteristics   &   IMAGE_FILE_EXECUTABLE_IMAGE   ==   0)  
  ||   (SrcPeH->FileHeader.SizeOfOptionalHeader   !=   sizeof(IMAGE_OPTIONAL_HEADER)))   return   FALSE;  
  SrcPeSecH   =   (PIMAGE_SECTION_HEADERS)((int)SrcPeH   +   sizeof(IMAGE_NT_HEADERS));  
  ImageSize   =   CalcTotalImageSize(SrcMz,   Len,   SrcPeH,   SrcPeSecH);  
  if(ImageSize   ==   0)   return   FALSE;  
  Mem   =   VirtualAlloc(NULL,   ImageSize,   MEM_COMMIT,   PAGE_EXECUTE_READWRITE);   //   分配内存  
  if(Mem){  
  //   计算需要复制的PE头字节数  
  unsigned   long   l   =   SrcPeH->OptionalHeader.SizeOfHeaders;  
  for(int   i=0;   i   <   SrcPeH->FileHeader.NumberOfSections;   ++i)  
  if((SrcPeSecH[i]->PointerToRawData)   &&   (SrcPeSecH[i]->PointerToRawData   <   l))  
  l   =   SrcPeSecH[i]->PointerToRawData;  
  memmove(Mem,   SrcMz,   l);  
  peH   =   (PIMAGE_NT_HEADERS)((int)Mem   +   ((PIMAGE_DOS_HEADER)Mem)->e_lfanew);  
  peSecH   =   (PIMAGE_SECTION_HEADERS)((int)peH   +   sizeof(IMAGE_NT_HEADERS));  
  void   *Pt   =   (void   *)((unsigned   long)Mem   +   GetAlignedSize(peH->OptionalHeader.SizeOfHeaders,   peH->OptionalHeader.SectionAlignment));  
  for(i=0;   i   <   peH->FileHeader.NumberOfSections;   ++i)  
  {  
  //   定位该节在内存中的位置  
  if(peSecH[i]->VirtualAddress)  
  Pt   =   (void   *)((unsigned   long)Mem   +   peSecH[i]->VirtualAddress);  
  if(peSecH[i]->SizeOfRawData){  
  //   复制数据到内存  
  memmove(Pt,   (const   void   *)((unsigned   long)(SrcMz)   +   peSecH[i]->PointerToRawData),   peSecH[i]->SizeOfRawData);  
  if(peSecH[i]->Misc.VirtualSize   <   peSecH[i]->SizeOfRawData)  
  Pt   =   (void   *)((unsigned   long)Pt   +   GetAlignedSize(peSecH[i]->SizeOfRawData,   peH->OptionalHeader.SectionAlignment));  
  else   //   pt   定位到下一节开始位置  
  Pt   =   (void   *)((unsigned   long)Pt   +   GetAlignedSize(peSecH[i]->Misc.VirtualSize,   peH->OptionalHeader.SectionAlignment));  
  }  
  else{  
  Pt   =   (void   *)((unsigned   long)Pt   +   GetAlignedSize(peSecH[i]->Misc.VirtualSize,   peH->OptionalHeader.SectionAlignment));  
  }  
  }  
  }  
  return   TRUE;  
  }  
   
  typedef   void   *(__stdcall   *pfVirtualAllocEx)(unsigned   long,   void   *,   unsigned   long,   unsigned   long,   unsigned   long);  
  pfVirtualAllocEx   MyVirtualAllocEx   =   NULL;  
   
  BOOL   IsNT()  
  {  
  return   MyVirtualAllocEx!=NULL;  
  }  
   
  //   生成外壳程序命令行  
  char   *PrepareShellExe(char   *CmdParam,   unsigned   long   BaseAddr,   unsigned   long   ImageSize)  
  {  
  if(IsNT()){  
  char   *Buf   =   new   char[256];  
  memset(Buf,   0,   256);  
  GetModuleFileName(0,   Buf,   256);  
  strcat(Buf,   CmdParam);  
  return   Buf;   //   请记得释放内存;-)  
  }  
  else{  
  //   Win98下的处理请参考原文;-)  
  //   http://community.youkuaiyun.com/Expert/topic/4416/4416252.xml?temp=8.709133E-03  
  return   NULL;  
  }  
  }  
   
  //   是否包含可重定向列表  
  BOOL   HasRelocationTable(PIMAGE_NT_HEADERS   peH)  
  {  
  return   (peH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress)  
  &&   (peH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);  
  }   
 

#pragma   pack(push,   1)  
  typedef   struct{  
  unsigned   long   VirtualAddress;  
  unsigned   long   SizeOfBlock;  
  }   *PImageBaseRelocation;  
  #pragma   pack(pop)  
   
  //   重定向PE用到的地址  
  void   DoRelocation(PIMAGE_NT_HEADERS   peH,   void   *OldBase,   void   *NewBase)  
  {  
  unsigned   long   Delta   =   (unsigned   long)NewBase   -   peH->OptionalHeader.ImageBase;  
  PImageBaseRelocation   p   =   (PImageBaseRelocation)((unsigned   long)OldBase    
  +   peH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);  
  while(p->VirtualAddress   +   p->SizeOfBlock)  
  {  
  unsigned   short   *pw   =   (unsigned   short   *)((int)p   +   sizeof(*p));  
  for(unsigned   int   i=1;   i   <=   (p->SizeOfBlock   -   sizeof(*p))   /   2;   ++i)  
  {  
  if((*pw)   &   0xF000   ==   0x3000){  
  unsigned   long   *t   =   (unsigned   long   *)((unsigned   long)(OldBase)   +   p->VirtualAddress   +   ((*pw)   &   0x0FFF));  
  *t   +=   Delta;  
  }  
  ++pw;  
  }  
  p   =   (PImageBaseRelocation)pw;  
  }  
  }  
   
  //   卸载原外壳占用内存  
  BOOL   UnloadShell(HANDLE   ProcHnd,   unsigned   long   BaseAddr)  
  {  
  typedef   unsigned   long   (__stdcall   *pfZwUnmapViewOfSection)(unsigned   long,   unsigned   long);  
  pfZwUnmapViewOfSection   ZwUnmapViewOfSection   =   NULL;  
  BOOL   res   =   FALSE;  
  HMODULE   m   =   LoadLibrary("ntdll.dll");  
  if(m){  
  ZwUnmapViewOfSection   =   (pfZwUnmapViewOfSection)GetProcAddress(m,   "ZwUnmapViewOfSection");  
  if(ZwUnmapViewOfSection)  
  res   =   (ZwUnmapViewOfSection((unsigned   long)ProcHnd,   BaseAddr)   ==   0);  
  FreeLibrary(m);  
  }  
  return   res;  
  }  
   
  //   创建外壳进程并获取其基址、大小和当前运行状态  
  BOOL   CreateChild(char   *Cmd,   CONTEXT   &Ctx,   HANDLE   &ProcHnd,   HANDLE   &ThrdHnd,    
    unsigned   long   &ProcId,   unsigned   long   &BaseAddr,   unsigned   long   &ImageSize)  
  {  
  STARTUPINFOA   si;  
  PROCESS_INFORMATION   pi;  
  unsigned   long   old;  
  MEMORY_BASIC_INFORMATION   MemInfo;  
  memset(&si,   0,   sizeof(si));  
  memset(&pi,   0,   sizeof(pi));  
  si.cb   =   sizeof(si);  
   
  BOOL   res   =   CreateProcess(NULL,   Cmd,   NULL,   NULL,   FALSE,   CREATE_SUSPENDED,   NULL,   NULL,   &si,   &pi);   //   以挂起方式运行进程;  
  if(res){  
  ProcHnd   =   pi.hProcess;  
  ThrdHnd   =   pi.hThread;  
  ProcId   =   pi.dwProcessId;  
  //   获取外壳进程运行状态,[ctx.Ebx+8]内存处存的是外壳进程的加载基址,ctx.Eax存放有外壳进程的入口地址  
  Ctx.ContextFlags   =   CONTEXT_FULL;  
  GetThreadContext(ThrdHnd,   &Ctx);  
  ReadProcessMemory(ProcHnd,   (void   *)(Ctx.Ebx+8),   &BaseAddr,   sizeof(unsigned   long),   &old);   //   读取加载基址  
  void   *p   =   (void   *)BaseAddr;  
  //   计算外壳进程占有的内存  
  while(VirtualQueryEx(ProcHnd,   p,   &MemInfo,   sizeof(MemInfo)))  
  {  
  if(MemInfo.State   =   MEM_FREE)   break;  
  p   =   (void   *)((unsigned   long)p   +   MemInfo.RegionSize);  
  }  
  ImageSize   =   (unsigned   long)p   -   (unsigned   long)BaseAddr;  
  }  
  return   res;  
  }  
   
  //   创建外壳进程并用目标进程替换它然后执行  
  HANDLE   AttachPE(char   *CmdParam,   PIMAGE_NT_HEADERS   peH,   PIMAGE_SECTION_HEADERS   peSecH,    
        void   *Ptr,   unsigned   long   ImageSize,   unsigned   long   &ProcId)  
  {  
  HANDLE   res   =   INVALID_HANDLE_VALUE;  
  CONTEXT   Ctx;  
  HANDLE   Thrd;  
  unsigned   long   Addr,   Size;  
  char   *s   =   PrepareShellExe(CmdParam,   peH->OptionalHeader.ImageBase,   ImageSize);  
  if(s==NULL)   return   res;  
  if(CreateChild(s,   Ctx,   res,   Thrd,   ProcId,   Addr,   Size)){  
  void   *p   =   NULL;  
  unsigned   long   old;  
  if((peH->OptionalHeader.ImageBase   ==   Addr)   &&   (Size   >=   ImageSize)){//   外壳进程可以容纳目标进程并且加载地址一致  
  p   =   (void   *)Addr;  
  VirtualProtectEx(res,   p,   Size,   PAGE_EXECUTE_READWRITE,   &old);  
  }  
  else   if(IsNT()){  
  if(UnloadShell(res,   Addr)){//   卸载外壳进程占有内存  
  p   =   MyVirtualAllocEx((unsigned   long)res,   (void   *)peH->OptionalHeader.ImageBase,   ImageSize,   MEM_RESERVE   |   MEM_COMMIT,   PAGE_EXECUTE_READWRITE);  
  }  
  if((p   ==   NULL)   &&   HasRelocationTable(peH)){//   分配内存失败并且目标进程支持重定向  
  p   =   MyVirtualAllocEx((unsigned   long)res,   NULL,   ImageSize,   MEM_RESERVE   |   MEM_COMMIT,   PAGE_EXECUTE_READWRITE);  
  if(p)   DoRelocation(peH,   Ptr,   p);   //   重定向  
  }  
  }  
  if(p){  
  WriteProcessMemory(res,   (void   *)(Ctx.Ebx+8),   &p,   sizeof(DWORD),   &old);   //   重置目标进程运行环境中的基址  
  peH->OptionalHeader.ImageBase   =   (unsigned   long)p;  
  if(WriteProcessMemory(res,   p,   Ptr,   ImageSize,   &old)){//   复制PE数据到目标进程  
  Ctx.ContextFlags   =   CONTEXT_FULL;  
  if((unsigned   long)p   ==   Addr)  
  Ctx.Eax   =   peH->OptionalHeader.ImageBase   +   peH->OptionalHeader.AddressOfEntryPoint;   //   重置运行环境中的入口地址  
  else  
  Ctx.Eax   =   (unsigned   long)p   +   peH->OptionalHeader.AddressOfEntryPoint;  
  SetThreadContext(Thrd,   &Ctx); //   更新运行环境  
  ResumeThread(Thrd); //   执行  
  CloseHandle(Thrd);  
  }  
  else{//   加载失败,杀掉外壳进程  
  TerminateProcess(res,   0);  
  CloseHandle(Thrd);  
  CloseHandle(res);  
  res   =   INVALID_HANDLE_VALUE;  
  }  
  }  
  else{//   加载失败,杀掉外壳进程  
  TerminateProcess(res,   0);  
  CloseHandle(Thrd);  
  CloseHandle(res);  
  res   =   INVALID_HANDLE_VALUE;  
  }  
  }  
  delete[]   s;  
  return   res;  
  }  
   
    /*******************************************************/  
  {   *******************************************************   }  
  {   *                                   从内存中加载并运行exe                               *   }  
  {   *******************************************************   }  
  {   *   参数:                                                                                                 }  
  {   *   Buffer:   内存中的exe地址                                                               }  
  {   *   Len:   内存中exe占用长度                                                                 }  
  {   *   CmdParam:   命令行参数(不包含exe文件名的剩余命令行参数)}  
  {   *   ProcessId:   返回的进程Id                                                               }  
  {   *   返回值:   如果成功则返回进程的Handle(ProcessHandle),       }  
  {                         如果失败则返回INVALID_HANDLE_VALUE                       }  
  {   *******************************************************   }  
    /*******************************************************/  
  HANDLE   MemExecute(void   *ABuffer,   long   Len,   char   *CmdParam,   unsigned   long   *ProcessId)  
  {  
  HANDLE   res   =   INVALID_HANDLE_VALUE;  
  PIMAGE_NT_HEADERS   peH;  
  PIMAGE_SECTION_HEADERS   peSecH;  
  void   *Ptr;  
  unsigned   long   peSz;  
  if(AlignPEToMem(ABuffer,   Len,   peH,   peSecH,   Ptr,   peSz)){  
  res   =   AttachPE(CmdParam,   peH,   peSecH,   Ptr,   peSz,   *ProcessId);  
  VirtualFree(Ptr,   peSz,   MEM_DECOMMIT);  
  }  
  return   res;  
  }  
   
  //   初始化  
  class   CInit  
  {  
  public:  
  CInit(){  
  MyVirtualAllocEx   =   (pfVirtualAllocEx)GetProcAddress(GetModuleHandle("Kernel32.dll"),   "VirtualAllocEx");  
  }  
  }Init;   
 

下面是一段简单的测试程序:)  
   
  CFile   f;  
  if(f.Open("target.exe",   CFile::modeRead)){  
  void   *lpBuf   =   new   char[f.GetLength()];  
  f.Read(lpBuf,   f.GetLength());  
  unsigned   long   ProcessId;  
  HANDLE   MemExecute(void   *,   long,   char   *,   unsigned   long   *);  
  MemExecute(lpBuf,   f.GetLength(),   "",   &ProcessId);  
  f.Close();  
  delete[]   lpBuf;  
  }

将exe从资源加载到内存中运行:PE加载器原理与实战 Windows可执行文件在磁盘上遵循PE格式,这不仅是静态的二进制布局,更是程序加载进内存后的运行蓝图。理解DOS头、NT头、节表、导入表与重定位表,就可以绕过“先落盘再执行”的传统流程,直接在进程内构建可执行镜像并运行。这项技术是单文件绿色工具、主程序内嵌组件以及安全研究中行为分析的重要手段,能够减少临时文件残留并规避部分文件策略限制,同时提升轻度逆向门槛。实现路径主要有进程镂空(RunPE)与自写PE加载器两种,前者实现简单但会留下进程创建痕迹,后者完全掌控内存映射和IAT修复,适应面更广。围绕“从资源 阅读详情

相关推荐

易语言 - 内存中加载运行EXE源码

在程序中运行程序。易语言实现的两种方法源码,仅供学习参考。

易语言运行执行exe文件的三种方法

易语言一个很初级的问题,如何运行exe文件,可以进行游戏的一键启动,软件的一键启动,方便控制操作。 1、和程序同目录 如果你要运行和你程序同目录下的 “****.exe”,就用下面的例子: 运行(取运行目录()+"\****.exe") 如果你要把你想运行的这个1.exe加到你的程序里,可以先把这个1.exe放到图片资源里,比如在图片资源里的名字是 图片1,你可以先把他创建,在运行。例子: 写到文件(取运行目录()+"\****.exe",#图片1) 运行(取运行目录()+"\****.ex.

511遇见 4万+

实现exe从资源中加载到内存中运行

这是网上的一段代码稍微修改了下,实现在windows下将程序加载到资源,运行时从资源加载到内存,并运行

如何在易语言里运行c,【易语言】在内存中运行EXE

该楼层疑似违规已被系统折叠隐藏此楼查看此楼.版本 2.支持库 spec.程序集 程序集1.子程序 _启动子程序, 整数型_临时子程序 () ' 在初始化代码执行完毕后调用测试代码返回 (0) ' 可以根据您的需要返回任意数值.子程序 _临时子程序.局部变量 信息, 运行信息在内存中运行EXE (读入文件 (“C:\Windows\system32\winlogon.exe”), , 信息...

weixin_30684945的博客 3365

易语言-内存运行模块开源

支持内存运行EXE、DLL,原先发过,但当时写得太过复杂,太过杂乱,并且HOOK了系统的API,并不完美,也就没有开源。 现在重新整理了一下代码,并且开源。如果有不足之处,请大家参与修改。 1.2版本更新: 内存卸载的问题。

易语言在内存运行EXE何DLL

在内存中运行exe文件 不写出 不释放 支持dll 对于加壳的软件可能不是很理想 自己测试下吧 易语言在内存运行EXE何DLL

C/C++学习笔记1

c程序运行原理 1、c语言属于高级语言,在代码写好后,c编译器会把编译成二进制exe文件 2、在程序运行时,操作系统会把exe的源码转成机器指令存入内存中 3、程序会从main入口函数执行,然后顺序一条一条指令执行

不负韶华梦为马 411

易语言内存运行exe模块及例程.rar

易语言内存运行exe模块及例程。易语言有时候会存在误报或者不想让别人知道你运行的进程,可以使用此模块把程序加载到内存运行。

一个microsoft的.exe程序文件的启动过程

学习windows 编程从mfc角度来说可分为两部分那就是WinMain函数以前的,和WinMain函数以后的。前者涉及很多windows操作系统内部的知识,后者需要看mfc源码。虽然大多数程序不需要了解太多关于os加载应用程序这方面的知识,但能较深入了解windows os的运

w419675647的专栏 519

易语言内存中运行程序源码

易语言内存中运行程序源码

玩转易语言:内存加载exe实现高级功能

易语言内存加载exe,通过掌握易语言内存加载exe技术,您将能够提升软件开发的灵活性和安全性,并且可以实现一些高级功能。本文介绍了其基本原理、实现步骤和应用场景。此外,内存加载exe还可用于动态修改和更新程序逻辑、进行自我解压和加密操作以及实现虚拟化等高级功能。

初识c语言(预处理)

预处理

weixin_66196728的博客 234

沐数科技数据开发岗笔试题2025

与数据库中的主键(Primary Key)​有所不同,业务主键(Business Key)​是业务层面的唯一标识,通常由业务规则决定,例如,订单号、订单明细号,身份证号等。用户授信表(table_credit):包含用户ID(uid)、授信申请时间(credit_submit_time_local)、授信状态(credit_status)。:在正态分布中,大约68%的数据值落在距离均值一个标准差的范围内,约95%的数据值落在两个标准差的范围内,而约99.7%的数据值落在三个标准差的范围内。

weixin_40121264的博客 3526

从内存中加载并启动一个exe

 windows似乎只提供了一种启动进程的方法:即必须从一个可执行文件中加载并启动。而下面这段代码就是提供一种可以直接从内存中启动一个exe的变通办法。用途嘛, 也许可以用来保护你的exe,你可以对要保护的 exe 进行任意切分、加密、存储,只要运行时能将exe的内容正确拼接到一块内存中,就可以直接从内存中启动,而不必不安全地去生成一个临时文件再从临时文件启动进程。另外这段代码也提供了一种自己

白水绕东城 2056

SAP Script表单开发中ABAP preform方法的实战应用与调试技巧

本文深入探讨了在SAP Script表单开发中调用ABAP程序(preform方法)的实战应用与调试技巧。通过一个获取供应商版本名称的实例,详细讲解了如何在SE71中嵌入PERFORM指令、编写ABAP子程序进行数据查询与处理,并重点介绍了使用SAP Script Debugger进行高效调试的方法,帮助开发者灵活扩展表单功能,实现复杂业务逻辑。

o0p1q2r3的博客 554

闲鱼x-sign、x-mini-wua、x-umt三字段协同验证机制解析

在移动客户端风控体系中,设备标识与行为签名是保障接口安全的核心技术。x-sign并非传统时间戳+密钥的静态签名,而是融合设备特征、运行时状态与服务端动态因子的多阶段位运算结果;x-mini-wua作为小程序轻量水印,依赖主App注入的短时效sessionKey与截断时间戳;x-umt则通过设备硬件与网络环境联合编码实现强绑定。三者构成‘设备—环境—行为’三位一体的交叉验证链路,广泛应用于电商API防护、二手平台数据采集及自动化运营等场景。本文基于Android/iOS真机逆向与Frida动态分析,揭示其生成

weixin_30457551的博客 426

从内存中加载并运行exe

{配合anskya的AnyWhereFileToPas效果不错} {*******************************************************} {*从内存中加载并运行exe*} {*******************************...

a572893208的博客 409

基于 国产USRP B210 的通信+侦测+干扰三合一实验平台,解锁无线攻防全场景!

在当代复杂电磁环境与多样化通信需求并存的背景下,软件定义无线电(SDR)技术正展现出前所未有的系统灵活性与功能可重构性。由两台USRP-LW B210软件无线电设备模拟无线链路通信过程,能够模拟多种无线通信信号传输及图像传输场景,适用于通信协议验证、抗干扰测试及教学实验。,支持"通信-侦测-干扰-优化"的闭环实验流程,为无线通信领域的教学科研与工程应用提供了一套经济高效、功能完备的解决方案。系统可对通信链路信号进行快速、自动化侦测、识别、告警,并支持多种干扰信号生成、模式切换及效果评估功能。

luowave2012的博客 834

powershell加载EXE进内存运行

当实战中我们想在目标上运行一些相当复杂的功能,这些功能常是 EXE 文件的一部分。我不想直接在目标上放置一个二进制文件,因为这样可能会触发反病毒机制。一个很好的思路就是将二进制文件嵌入到 Powershell 脚本中,并直接通过脚本运行而不用将其写入到磁盘里。 大致思路流程:将我们需要执行的exe文件二进制进过编码转换成字符串,使其成为powershell脚本的一部分,再直接加载进内存运行...

weixin_30438813的博客 961

RK3588+TRL8367s 四网口千兆交换机配置与优化实战

本文详细介绍了基于RK3588高性能SoC与TRL8367s千兆交换芯片构建四网口交换机的完整实战流程。内容涵盖硬件连接、设备树配置、内核驱动加载、性能优化及常见问题排查,重点解析了RGMII时序调试、DSA架构配置等关键步骤,为嵌入式网络设备开发提供实用指南。

weixin_29266647的博客 676

详解RT-DETR网络结构/数据集获取/环境搭建/训练/推理/验证/导出/部署

本文给大家带来是利用RT-DETR模训练自己的数据集,RT-DETR是一种新提出的目标检测模型,它利用的自注意力机制来处理图像数据。不同于YOLO通过连续的卷积层直接对图像区域进行分析,RT-DETR采用Transformer架构中的自注意力机制,这允许模型更有效地理解图像中不同部分之间的关系。这种方法使得RT-DETR在处理图像中的复杂场景和多对象环境时,能够展现出更高的准确性和效率。此外,RT-DETR在保持高精度的同时,也针对实时处理进行了优化,使其适合需要快速响应的应用场景。

Snu77的博客 6万+

exe和dll的内存加载

这两天学习了PE结构后,做了一个简单的内存加载demo。在完成这个demo期间也是遇到了很多问题,大部分的问题最后都得到了解决,但还是有一些问题依然困扰着我,我在最后将会提到。不过总的来说也算是顺利完成了这个demo。对于一个java程序员来说,理解内存和指针确实有些困难 。因此这次用C语言编写demo对我来说是个不小的挑战。不过同样也让我对底层有了更深入的了解。因此在这里做一个工作总结,加深一下印象,同时也希望有朋友能解答我的一些疑惑。 内存加载win7内存加载节的映射修改重定位装载动态库修改入口点并跳转

qq_39415224的博客 935

Mybatis面试题(基础篇)

(1)mybatis是支持定制化SQL、存储过程以及高级映射的优秀的持久层框架。(2)mybatis避免了几乎所有的JDBC代码(说明了mybatis底层用的就是JDBC,只不过是封装了)和手动设置参数以及获取结果集。(3)mybatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的pojo映射成数据库中的记录。

qq_38196449的博客 1690

C#内存加载dll和EXE是不是差不多,主要是EXE有入口点

/ 被加载的 DLL 代码// 自定义有返回值方法内存加载并调用:csharp运行try// 1. 读取 DLL 字节(内存加载核心)// 2. 找 DLL 中的类型和方法(重点:自定义业务方法)if (calcType == null) throw new Exception("未找到 Calculator 类型");null,null);// 3. 调用方法并获取返回值Console.WriteLine($"DLL 方法返回值:{result}");// 输出 300。

903

YOLO26优化:注意力魔改 | 用于微小目标检测的上下文增强和特征细化网络ContextAggregation,助力小目标检测,暴力涨点

用于微小目标检测的上下文增强和特征细化网络ContextAggregation,助力小目标检测

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 492

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

上一篇: 另一个从内存中加载并运行EXE
下一篇: loadexe (delphi)
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值