内存加载并运行EXE程序

Unit MemoryRunUnitTwo; 
 
interface 
 
{$IMAGEBASE $10000000} 
 
uses 
  Windows; 
 
type 
  TSections = array [0..0] of TImageSectionHeader; 
 
procedure MemoryRunExe(FileMemory: Pointer); 
 
implementation 
 
function GetAlignedSize(Size: dword; Alignment: dword): dword; 
begin 
  if ((Size mod Alignment) = 0) then 
  begin 
    Result := Size; 
  end 
  else 
  begin 
    Result := ((Size div Alignment) + 1) * Alignment; 
  end; 
end; 
 
function ImageSize(Image: pointer): dword; 
var 
  Alignment: dword; 
  ImageNtHeaders: PImageNtHeaders; 
  PSections: ^TSections; 
  SectionLoop: dword; 
begin 
  ImageNtHeaders := pointer(dword(dword(Image)) + dword(PImageDosHeader(Image)._lfanew)); 
  Alignment := ImageNtHeaders.OptionalHeader.SectionAlignment; 
  if ((ImageNtHeaders.OptionalHeader.SizeOfHeaders mod Alignment) = 0) then 
  begin 
    Result := ImageNtHeaders.OptionalHeader.SizeOfHeaders; 
  end 
  else 
  begin 
    Result := ((ImageNtHeaders.OptionalHeader.SizeOfHeaders div Alignment) + 1) * Alignment; 
  end; 
  PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) + ImageNtHeaders.FileHeader.SizeOfOptionalHeader); 
  for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do 
  begin 
    if PSections[SectionLoop].Misc.VirtualSize <> 0 then 
    begin 
      if ((PSections[SectionLoop].Misc.VirtualSize mod Alignment) = 0) then 
      begin 
        Result := Result + PSections[SectionLoop].Misc.VirtualSize; 
      end 
      else 
      begin 
        Result := Result + (((PSections[SectionLoop].Misc.VirtualSize div Alignment) + 1) * Alignment); 
      end; 
    end; 
  end; 
end; 
 
procedure MemoryRunExe(FileMemory: Pointer); 
var 
  BaseAddress, Bytes, HeaderSize, InjectSize,  SectionLoop, SectionSize: dword; 
  Context: TContext; 
  FileData: pointer; 
  ImageNtHeaders: PImageNtHeaders; 
  InjectMemory: pointer; 
  ProcInfo: TProcessInformation; 
  PSections: ^TSections; 
  StartInfo: TStartupInfo; 
begin 
  ImageNtHeaders := pointer(dword(dword(FileMemory)) + dword(PImageDosHeader(FileMemory)._lfanew)); 
  InjectSize := ImageSize(FileMemory); 
  GetMem(InjectMemory, InjectSize); 
  try 
    FileData := InjectMemory; 
    HeaderSize := ImageNtHeaders.OptionalHeader.SizeOfHeaders; 
    PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) + ImageNtHeaders.FileHeader.SizeOfOptionalHeader); 
    for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do 
    begin 
      if PSections[SectionLoop].PointerToRawData < HeaderSize then HeaderSize := PSections[SectionLoop].PointerToRawData; 
    end; 
    CopyMemory(FileData, FileMemory, HeaderSize); 
    FileData := pointer(dword(FileData) + GetAlignedSize(ImageNtHeaders.OptionalHeader.SizeOfHeaders, ImageNtHeaders.OptionalHeader.SectionAlignment)); 
    for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do 
    begin 
      if PSections[SectionLoop].SizeOfRawData > 0 then 
      begin 
        SectionSize := PSections[SectionLoop].SizeOfRawData; 
        if SectionSize > PSections[SectionLoop].Misc.VirtualSize then SectionSize := PSections[SectionLoop].Misc.VirtualSize; 
        CopyMemory(FileData, pointer(dword(FileMemory) + PSections[SectionLoop].PointerToRawData), SectionSize); 
        FileData := pointer(dword(FileData) + GetAlignedSize(PSections[SectionLoop].Misc.VirtualSize, ImageNtHeaders.OptionalHeader.SectionAlignment)); 
      end 
      else 
      begin 
        if PSections[SectionLoop].Misc.VirtualSize <> 0 then FileData := pointer(dword(FileData) + GetAlignedSize(PSections[SectionLoop].Misc.VirtualSize, ImageNtHeaders.OptionalHeader.SectionAlignment)); 
      end; 
    end; 
    ZeroMemory(@StartInfo, SizeOf(StartupInfo)); 
    ZeroMemory(@Context, SizeOf(TContext)); 
    CreateProcess(nil, pchar(ParamStr(0)), nil, nil, False, CREATE_SUSPENDED, nil, nil, StartInfo, ProcInfo); 
    Context.ContextFlags := CONTEXT_FULL; 
    GetThreadContext(ProcInfo.hThread, Context); 
    ReadProcessMemory(ProcInfo.hProcess, pointer(Context.Ebx + 8), @BaseAddress, 4, Bytes); 
    VirtualAllocEx(ProcInfo.hProcess, pointer(ImageNtHeaders.OptionalHeader.ImageBase), InjectSize, MEM_RESERVE or MEM_COMMIT, PAGE_EXECUTE_READWRITE); 
    WriteProcessMemory(ProcInfo.hProcess, pointer(ImageNtHeaders.OptionalHeader.ImageBase), InjectMemory, InjectSize, Bytes); 
    WriteProcessMemory(ProcInfo.hProcess, pointer(Context.Ebx + 8), @ImageNtHeaders.OptionalHeader.ImageBase, 4, Bytes); 
    Context.Eax := ImageNtHeaders.OptionalHeader.ImageBase + ImageNtHeaders.OptionalHeader.AddressOfEntryPoint; 
    SetThreadContext(ProcInfo.hThread, Context); 
    ResumeThread(ProcInfo.hThread); 
  finally 
    FreeMemory(InjectMemory); 
  end; 
end; 
 
end. 
 

写了一个简单程序测试通过:) 

program Test1; 
 
//{$APPTYPE CONSOLE} 
 
uses 
  SysUtils, 
  Classes, 
  MemoryRunUnitTwo in ‘MemoryRunUnitTwo.pas‘; 
 
var 
    ABuffer: array of byte; 
    Stream: TFileStream; 
    ProcessId: Cardinal; 
begin 
    Stream := TFileStream.Create(‘HT.exe‘, fmOpenRead); 
    try 
        SetLength(ABuffer, Stream.Size); 
        Stream.ReadBuffer(ABuffer[0], Stream.Size); 
        MemoryRunExe(@ABuffer[0]); 
    finally 
        Stream.Free; 
    end; 
end.

原文地址:https://www.cnblogs.com/plug/p/8665542.html

时间: 2024-10-09 18:41:29

内存加载并运行EXE程序的相关文章

C++手动加载CLR运行托管程序(CLR Hosting)

转载自:http://www.linuxidc.com/Linux/2012-10/72293.htm 机制介绍 有些时候主程序是通过C/C++实现的,但是我们希望通过托管代码来扩展非托管程序,从而也获得托管代码带来的一系列优点.比如开发效率高,自动垃圾回收等. 运行托管与非托管代码根本区别在于托管代码是进程首先加载CLR然后通过CLR运行托管程序,而非托管代码则是操作系统直接根据其PE Header加载程序分配内存从而运行.因此如果需要通过托管代码来扩展非托管程序,首先要加载CLR来使非托管程

内存加载DLL

1.前言 目前很多敏感和重要的DLL(Dynamic-link library) 都没有提供静态版本供编译器进行静态连接(.lib文件),即使提供了静态版本也因为兼容性问题导致无法使用,而只提供DLL版本,并且很多专业软件的授权部分的API,都是单独提供一个DLL来完成,而主模块通过调用DLL中的接口来完成授权功能.虽然这些软件一般都采用了加壳和反调试等保护,但是一旦这些功能失去作用,比如脱壳,反反调试,HOOK API或者干脆写一个仿真的授权DLL(模拟授权DLL的所有导出函数接口),然后仿真

[javase学习笔记]-7.4 构造函数的内存加载

这一节我们来说说构造函数在内存中是如何被加载的. 我们之前说过,构造函数只有创建对象时才会被调用并且只调用一次.那么在创建对象的过程中内存中的变化是什么样的呢? 我们接着上一节的Person类,我们分析 class Person { private String name; private int age; Person()//构造函数,分别为成员变量name和age赋固定的值 { name = "baby"; age = 1; System.out.println("per

Android中apk加固完善篇之内存加载dex方案实现原理(不落地方式加载)

一.前言 时隔半年,困扰的问题始终是需要解决的,之前也算是没时间弄,今天因为有人在此提起这个问题,那么就不能不解决了,这里写一篇文章记录一下吧.那么是什么问题呢? 就是关于之前的一个话题:Android中apk加固技术实现 关于这个问题,之前的一篇文章已经说过了,没有了解的同学可以点击这里:Android中apk加固技术实现 请务必仔细的看完这篇文章,不然今天说的内容会感觉很蛋疼的,因为今天的文章就是为了解决当初的加固技术遗留的问题,这里先大致来说一下加固apk的原理吧,先来看一张图: 看到这张

Linux进程启动过程分析do_execve(可执行程序的加载和运行)

日期 内核版本 架构 作者 GitHub CSDN 2016-06-06 Linux-4.5 X86 & arm gatieme LinuxDeviceDrivers Linux进程管理与调度-之-进程的描述 execve系统调用 execve系统调用 我们前面提到了, fork, vfork等复制出来的进程是父进程的一个副本, 那么如何我们想加载新的程序, 可以通过execve来加载和启动新的程序. x86架构下, 其实还实现了一个新的exec的系统调用叫做execveat(自linux-3.

Linux进程启动过程分析do_execve(可执行程序的加载和运行)---Linux进程的管理与调度(十一)

execve系统调用 execve系统调用 我们前面提到了, fork, vfork等复制出来的进程是父进程的一个副本, 那么如何我们想加载新的程序, 可以通过execve来加载和启动新的程序. x86架构下, 其实还实现了一个新的exec的系统调用叫做execveat(自linux-3.19后进入内核) syscalls,x86: Add execveat() system call exec()函数族 exec函数一共有六个,其中execve为内核级系统调用,其他(execl,execle,

打造DLL内存加载引擎学习笔记

原文:http://www.pediy.com/kssd/index.html -- 病毒技术 -- 病毒知识 -- Anti Virus专题 首先看下我们内存加载引擎的流程. 1. 申请一段大小为dll映射内存后的映像大小的内存空间. 2. 移动各个区段的数据到申请的内存. 2. 修复引入表结构的地址表. 4. 通过重定位结构修复需要重定位的地址. 5. 调用DllMain入口点 流程解析: pe结构中nt header结构当中的ImageSize存放的是我们整个文件映射到内存后的映像大小,这

【Hight Performance Javascript】——脚本加载和运行

脚本加载和运行 当浏览器遇到一个<script>标签时,无法预知javascript是否在<p>标签中添加内容.因此,浏览器停下来,运行javascript代码,然后继续解析.翻译页面. 浏览器必须首先下载外部文件的代码,这要占用一些时间,然后解析并运行代码,这又要占用一些时间.此过程中,页面解析和用户交互是被完全阻塞的. 将脚本放在底部 合并脚本减少个数 延迟脚本(defer) <script src="file1.js" defer></s

未能加载文件或程序集“BLL”或它的某一个依赖项。生成此程序集的运行时比当前加载的运行时新,无法加载此程序集。

今天使用VS2012创建项目的时候,考虑到项目中代码的重用性以及清晰简洁性,搭建了一个三层架构,但是在项目运行的时候,总是报错: “未能加载文件或程序集“BLL”或它的某一个依赖项.生成此程序集的运行时比当前加载的运行时新,无法加载此程序集.” 在网上查找了半天也没有更好的办法,突然,灵感一现,修改.net版本,果断解决这个问题, 一开始是使用的版本是3.5:修改后的版本是:4.5 修改方法: 项目=>右键=>属性=>目标 framework=>选择版本