从res资源中运行exe,不用释放出来

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情
unit MemoryRun;

interface

uses Windows;

type
TImportItem = record
Name: String;
PProcVar: ^Pointer;
end;

TwordArr = array [0..0] of Word;
PwordArr = ^TwordArr;
TdwordArr = array [0..0] of DWORD;
PdwordArr = ^TdwordArr;

TImageImportDescriptor = packed record
OriginalFirstThunk: DWORD;
TimeDateStamp: DWORD;
ForwarderChain: DWORD;
Name: DWORD;
FirstThunk: DWORD;
end;
PImageImportDescriptor = ^TImageImportDescriptor;

TImageBaseRelocation = packed record
VirtualAddress: Cardinal;
SizeOfBlock: Cardinal;
end;
PImageBaseRelocation = ^TImageBaseRelocation;

TEXEEntryProc = function(hinstDLL: HMODULE; hPrevInstance: HMODULE; lpCmdLine: PChar; nCmdShow: Integer): Boolean; stdcall;

TStringArray = array of String;

TLibInfo = record
ImageBase: Pointer;
EXEProc: TEXEEntryProc;
LibsUsed: TStringArray;
end;

PLibInfo = ^TLibInfo;
PPointer = ^Pointer;
TSections = packed array [0..100000] of TImageSectionHeader;

const
IMPORTED_NAME_OFFSET = $00000002;
IMAGE_ORDINAL_FLAG32 = $80000000;
IMAGE_ORDINAL_MASK32 = $0000FFFF;
PROCESS_ATTACH = 1;

procedure MemoryRunExe(pExe: Pointer);
procedure MemoryRunExeName(HIns: LongWord; Field: Pchar; ResName: Pchar);
function PeLoader(Src: Pointer): Pointer;
function PeFree(Src: Pointer): Boolean;

procedure Add(Strings: TStringArray; Text: string);
function StrToInt(S: string): integer;
function Find(Strings: array of string; Text: string; var Index: integer): boolean;
function GetSectionProtection(ImageScn: cardinal): cardinal;

implementation

procedure MemoryRunExe(pExe: Pointer);
var pSrc: Pointer;
begin
pSrc:=PeLoader(pExe);
PeFree(pSrc);
end;

procedure MemoryRunExeName(HIns: LongWord; Field: Pchar; ResName: Pchar);
var pExe,pSrc: Pointer;
begin
pExe:=LockResource(LoadResource(HIns,FindResource(HIns,Field,ResName)));
pSrc:=PeLoader(pExe);
PeFree(pSrc);
end;

function PeLoader(Src: Pointer): Pointer;
var
ImageBase: Pointer;
ImageBaseDelta: Integer;
ImageNtHeaders: PImageNtHeaders;
PSections: ^TSections;
SectionLoop: Integer;
SectionBase: Pointer;
VirtualSectionSize: Cardinal;
RawSectionSize: Cardinal;
OldProtect: Cardinal;
NewLibInfo: TLibInfo;

function IsImportByOrdinal(ImportDescriptor: dword; HLib: THandle): boolean;
begin
Result := (ImportDescriptor and IMAGE_ORDINAL_FLAG32) <> 0;
end;

procedure ProcessRelocs(PRelocs:PImageBaseRelocation);
var
PReloc: PImageBaseRelocation;
RelocsSize: cardinal;
Reloc: PWord;
ModCount: cardinal;
RelocLoop: cardinal;
begin
PReloc := PRelocs;
RelocsSize := ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
while cardinal(PReloc) - cardinal(PRelocs) < RelocsSize do
begin
ModCount := (PReloc.SizeOfBlock-Sizeof(PReloc^)) div 2;
Reloc := pointer(cardinal(PReloc)+sizeof(PReloc^));
for RelocLoop := 0 to ModCount - 1 do begin
if Reloc^ and $f000 <> 0 then Inc(pdword(cardinal(ImageBase) + PReloc.VirtualAddress + (Reloc^ and $0fff))^, ImageBaseDelta);
Inc(Reloc);
end;
PReloc := pointer(Reloc);
end;
end;

procedure ProcessImports(PImports: PImageImportDescriptor);
var
PImport: PImageImportDescriptor;
Import: LPDword;
PImportedName: pchar;
LibHandle: HModule;
ProcAddress: pointer;
PLibName: pchar;
ImportLoop: integer;
begin
PImport := PImports;
while PImport.Name<>0 do
begin
PLibName := pchar(cardinal(PImport.Name) + cardinal(ImageBase));
if not Find(NewLibInfo.LibsUsed, PLibName, ImportLoop) then
begin
LibHandle := LoadLibrary(PLibName);
Add(NewLibInfo.LibsUsed, PLibName);
end else begin
LibHandle := cardinal(NewLibInfo.LibsUsed[ImportLoop]);
end;

if PImport.TimeDateStamp = 0 then
Import := LPDword(pImport.FirstThunk+cardinal(ImageBase))
else
Import := LPDword(pImport.OriginalFirstThunk + cardinal(ImageBase));

while Import^ <> 0 do
begin
if IsImportByOrdinal(Import^, LibHandle) then
ProcAddress := GetProcAddress(LibHandle, pchar(Import^ and $ffff))
else begin
PImportedName := pchar(Import^ + cardinal(ImageBase) + IMPORTED_NAME_OFFSET);
ProcAddress := GetProcAddress(LibHandle, PImportedName);
end;
PPointer(Import)^ := ProcAddress;
Inc(Import);
end;
Inc(PImport);
end;
end;

begin
ImageNtHeaders := pointer(int64(cardinal(Src)) + PImageDosHeader(Src)._lfanew);
ImageBase := VirtualAlloc(nil, ImageNtHeaders.OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_NOACCESS);
ImageBaseDelta := cardinal(ImageBase) - ImageNtHeaders.OptionalHeader.ImageBase;
SectionBase := VirtualAlloc(ImageBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_READWRITE);
Move(Src^, SectionBase^, ImageNtHeaders.OptionalHeader.SizeOfHeaders);
VirtualProtect(SectionBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders, PAGE_READONLY, OldProtect);
PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) + ImageNtHeaders.FileHeader.SizeOfOptionalHeader);

for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
begin
VirtualSectionSize := PSections[SectionLoop].Misc.VirtualSize;
RawSectionSize := PSections[SectionLoop].SizeOfRawData;

if VirtualSectionSize < RawSectionSize then
begin
VirtualSectionSize := VirtualSectionSize xor RawSectionSize;
RawSectionSize := VirtualSectionSize xor RawSectionSize;
VirtualSectionSize := VirtualSectionSize xor RawSectionSize;
end;

SectionBase := VirtualAlloc(PSections[SectionLoop].VirtualAddress + pchar(ImageBase), VirtualSectionSize, MEM_COMMIT, PAGE_READWRITE);
FillChar(SectionBase^, VirtualSectionSize, 0);
Move((pchar(src) + PSections[SectionLoop].PointerToRawData)^, SectionBase^, RawSectionSize);
end;

NewLibInfo.ExeProc := TEXEEntryProc(ImageNtHeaders.OptionalHeader.AddressOfEntryPoint + cardinal(ImageBase));
NewLibInfo.ImageBase := ImageBase;
SetLength(NewLibInfo.LibsUsed, 0);

if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress <> 0 then ProcessRelocs(pointer(ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + cardinal(ImageBase)));

if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress <> 0 then ProcessImports(pointer(ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + cardinal(ImageBase)));

for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
VirtualProtect(PSections[SectionLoop].VirtualAddress + pchar(ImageBase), PSections[SectionLoop].Misc.VirtualSize, GetSectionProtection(PSections[SectionLoop].Characteristics), OldProtect);

if @NewLibInfo.ExeProc <> nil then
begin
if not NewLibInfo.ExeProc(cardinal(ImageBase), DLL_PROCESS_ATTACH, nil,0) then
begin
NewLibInfo.ExeProc := nil;
PeFree(NewLibInfo.ImageBase);
end;
end;

Result:=NewLibInfo.ImageBase;
end;

function PeFree(Src: Pointer): Boolean;
begin
try
VirtualFree(Src, 0, MEM_RELEASE);
finally
Result:= True;
end;
end;

function StrToInt(S: string): integer;
begin
Val(S, Result, Result);
end;

procedure Add(Strings: TStringArray; Text: string);
begin
SetLength(Strings, Length(Strings) + 1);
Strings[Length(Strings)-1] := Text;
end;

function Find(Strings: array of string; Text: string; var Index: integer): boolean;
var StringLoop: integer;
begin
Result := False;
for StringLoop := 0 to Length(Strings) - 1 do
begin
if lstrcmpi(pchar(Strings[StringLoop]), pchar(Text)) = 0 then
begin
Index := StringLoop;
Result := True;
end;
end;
end;

function GetSectionProtection(ImageScn: cardinal): cardinal;
begin
Result := 0;
if (ImageScn and IMAGE_SCN_MEM_NOT_CACHED) <> 0 then Result := Result or PAGE_NOCACHE;

if (ImageScn and IMAGE_SCN_MEM_EXECUTE) <> 0 then begin

if (ImageScn and IMAGE_SCN_MEM_READ)<> 0 then  begin

if (ImageScn and IMAGE_SCN_MEM_WRITE)<> 0 then Result := Result or PAGE_EXECUTE_READWRITE  else Result := Result or PAGE_EXECUTE_READ;

end else if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then
Result := Result or PAGE_EXECUTE_WRITECOPY else Result := Result or PAGE_EXECUTE;

end else if (ImageScn and IMAGE_SCN_MEM_READ)<> 0 then  begin

if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then
Result := Result or PAGE_READWRITE else Result := Result or PAGE_READONLY;

end else if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then
Result := Result or PAGE_WRITECOPY else Result := Result or PAGE_NOACCESS;

end;

end.


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

相关推荐

EXE ResPacker 7.0

【打包步骤】 1、指定EXE主程序; 2、添加软件使用到的附属文件,比如DLL动态库、数据文件、音视频等,确保相对路径要正确。 3、设置加密密钥; 4、开始打包; 打包生成一个可以独立运行exe文件,您可以将此打包后的文件分发给用户。 用户打开您打包的文件时会弹出一个认证框,要求用户输入开启密码才可以打开,此认证框中显示有 用户的机器码,用户将他的机器码发给你,你根据用户机器码为他创建开启密码: 【创建开启密码】 1、指定加密时使用的加密密钥; 2、指定用户的机器码; 3、创建开启密码; 开启密码发给用户,用户只能在自己的电脑上运行你的软件。

Delphi中加载并运行内存中的EXE

 { ******************************************************* }{ * 从内存中加载并运行exe * }{ ******************************************************* }{ * 参数:

编程资料收集与共享交流 2047

ResScope(EXE文件修改器)

ResScope是一款专业的EXE文件修改器!!

MFC加载exe资源,程序调用exe功能

1、工程B为基于MFC对话框程序,先插入已经存EXE(或DLL)文件到VC资源文件中,如下图:       A、切换到资源视图,在上面单机右键:         B、单击"Import...",找到刚刚工程A编译生成的MsgBox.exe文件:         C、设置导入的资源类型名,这个名称将是该函数的第三个参数,我们取资源类型名为EXE:         D

zdhlwt2008的博客 4135

PE头的应用---插入代码到EXE或DLL文件中(DELPHI版本)

一、PE头原理请看我的另一篇笔记:http://blog.csdn.net/A00553344/archive/2007/12/13/1933320.aspx二、插入代码到EXE文件或DLL文件的原理请看我的另一篇笔记:http://blog.csdn.net/A00553344/archive/2007/12/17/1944491.aspx三、代码实现(DELPHI版本),采用第

A00553344的专栏 3960

PE头的应用---插入代码到EXE或DLL文件中

 三、代码实现(DELPHI版本),采用第三种方式实现代码插入。 1. 定义两个类,一个用来实现在内存中建立输入表;一个用来实现对PE头的代码插入。<!--.textBackGround {background-color: #F0F5FD;}-->DelphiCode: const MAX_SECTION_NUM = 20;const DYN_

不得闲.闲忆居 5138

不用懂抓包也能下载全网资源res-downloader 视频号抖音小红书下载从零上手

res-downloader 是一款基于 Go + Wails 开发的跨平台网络资源下载工具,通过本地代理自动嗅探视频、音频、图片、m3u8、直播流等资源,覆盖微信视频号、小程序、抖音、快手、小红书、QQ音乐、酷狗等主流平台。如果你只想把屏幕上看到的内容存到本地,又不想研究协议、证书、抓包原理,这篇文章就是为你准备的。 上个月帮一位做自媒体培训的朋友整理素材,他指着一堆录屏文件叹气:视频号里一个

gitblog_00248的博客 874

C++ Windows将文件资源打包到exe中并读取出来

你是否像我一样,喜欢构建出来的exe的总文件数(加上资源文件)尽量少一点,最好只有一个文件,或者有些东西不希望把一些重要的东西放到exe外面,即使加密后也不放心,那么rc与windows api就可以满足你的需求。如果你想像adobe那样,一个程序100多个dll与100以上的资源文件,让你眼花缭乱的话,也没有关系,就当看个乐吧! 基础知识 RC资源文件: RC,全称(Resource),它可以被windres.exe编译并将里面的资源打包到exe中,其基本语法...

m0_46393425的博客 8825

delphi制作资源文件(二)一个A.exe释放出B.exe 并且修改b.exe变量的值

首先,创建一个工程   edit1.txt:=XXXXX xxxxx  就是我们A.exe程序需要修改的值,写成XXXXX  是便于我们好查找它的位置。 打卡,winhex.exe  查找资源文件 的XXXX 位置 地址在   0004DD8C  转换成10 进制就是318844  (这个很关键,记下来) 在工程目录下创建两个文件,

qq_14876677的专栏 1508

delphiexe文件中嵌入另外一个exe文件

原理: 把需要包含的exe放入到进资源文件中,和原来的程序一起编译成一个exe文件,在程序第一次运行时释放出这个exe,然后调用这个exe文件。 步骤: 1、创建rc文件。可以用任意文本编辑器来写。文件格式为:"资源资源类型 文件名"。对于资源类型,如果是exe文件,应该是EXEFILE,如果是二进制文件,则是RCDATA。 这里创建一个文件float.rc: AEXE EXEFILE "...

weixin_34250709的博客 921

Delphi 资源文件( .res

一. 现在的Windows应用程序几乎都使用图标、图片、光标、声音等,我们称它们为资源Resource)。最简单的使用资源的办法是把这些资源的源文件打入软件包,以方便程序需要的时候调用。资源是程序的一部分,程序要正常运行就离不了资源文件。但是它是不可执行代码。 为了更好地管理资源Delphi中提供了一种.RES类型的资源文件。它可以把我们程序中所需要的资源整合到一个资源文件(.RES)下来。在编译应用程序时直接编译进了可执行程序里,成为应用程序的整合体。 这样做的好处是: 1。...

fangyuan621的专栏 1339

将多个exe作为资源融入到exe中并释放执行

将多个exe作为资源融入到exe中并释放执行,有别于rar方式压缩为1个文件,而是采用vc资源方式载入

exe放入另一个exe资源中,并在指定情况下提取并运行

VC6.0写的一个小程序,可以将一个exe文件编译到自己的资源中,并在指定的时候提取并保存到磁盘文件中,在调用该程序。非常简单的一个小东西,就不要资源分了,不好意思要…… 1. 单击程序的button1按钮会执行资源中的exe程序 2. 资源中的exe文件在try目录中,不放心的可以杀一下毒

资源(*.res) 文件使用及定义

资源(*.res) 文件使用及定义 资源(*.res) 文件使用及定义 作者: 评价: 上站日期: 2002-05-19 内容说明: 来源: -------------------------------------------------------------------------------- 资源标识符 + 关键字 + 资源文件名 ① 资源标识符:程序中调用资源时的特殊标号; ② 关键字:标识资源文件类型; Wave : 资源文件是声音文件; RCDATA : JPEG 文件; AVI : AVI

期待下集是个可爱梦儿 1745

释放资源文件中的exe文件并运行

delphi 释放资源文件中的exe文件并运行制作资源文件我就不用说了吧,下面是怎样释放并运行文件Res := TResourceStream.Create(Hinstance, 'aaa.exe', 'aaa');Res.SavetoFile('aaa.exe');winexec('aaa.exe',sw_Normal);

清风古韵 1786

RES资源运行文件

  bool Run(){ CFile f; char* pFileName = "Execution.exe"; if( !f.Open( pFileName, CFile::modeCreate | CFile::modeWrite, NULL ) ) { AfxMessageBox("Can no

kenxinyo的专栏 525

Res-Downloader终极指南:跨平台智能资源嗅探神器

在数字内容爆炸的时代,你是否曾为无法下载心仪的视频、音频资源而烦恼?Res-Downloader应运而生,这款跨平台智能资源嗅探工具彻底改变了传统下载方式,让你轻松捕获网络中的各种宝藏资源! ## 🎯 核心优势解密:与传统工具的天壤之别 | 功能维度 | 传统下载工具 | Res-Downloader | 优势对比 | |---------|-------------|-----------

gitblog_00597的博客 619

如何使用RC.exe生成VB中的RES文件

This article provides a short look at how to use the Resource Compiler (RC.EXE) to create resource files (.RES) for Visual Basic applications. Using RC.EXE directly is often better than using the wiza

盛政(kisssy)的专栏 4559

Windows编程日志——Windows 资源(RC)机制深度解析 — 从 rc.exe 到 .rsrc 到运行时加载

本文深入解析了Windows资源机制,从资源编译到运行时加载的全过程。主要内容包括: 资源编译器rc.exe将.rc文件编译为.res文件,再通过链接器嵌入PE文件的.rsrc节 Visual Studio中可视化创建资源的方法及底层实现 字符串、菜单、图标三种资源的存储格式和加载逻辑: 字符串以16个为一组存储,通过LoadString加载 菜单以模板形式存储,运行时解析为HMENU对象 图标分解为多个RT_ICON资源和组描述结构 文章详细介绍了资源从定义、编译到运行时加载的完整流程,以及相关API的底

charlie114514191的博客 1685
上一篇: VclSkin 简要说明和使用教程
下一篇: U盘格式为RAW格式,空间为0字节的解决办法
zuike
博客等级 码龄20年 23粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值