一直都对EXE捆绑机很感兴趣,想知道那种运行一个EXE文件就相当于运行多个EXE文件的软件是什么原理.之前学习了PE文件知识,再加上一段研究时间,终于写出了一个EXE捆绑机(轩辕EXE捆绑机http://bbs.pediy.com/showthread.php?s=&postid=191958#post191958).其实捆绑机在不懂之前感觉很神秘,弄懂它的原理后就很简单了,下面就开始解说捆绑机的制作原理.
  想实现运行一个EXE文件同时运行其它多个EXE文件,必须要把多个EXE文件"组合"成一个EXE文件,而这一个EXE文件还必须有"分解"的能力,这样才能把捆绑起来的EXE分离出来,使之正常运行.而"组合"也可以有多种形式,比如把EXE文件一个一个的加到文件末尾,或者以资源形式组合到一个EXE文件中,还有复杂一点的利用专用的安装打包工具组合(例如安装时捆绑的流氓软件).下面主要介绍最简单的第一种组合方式,也称为传统式捆绑机,其他方式可以触类旁通,举一反三.
  我把捆绑之前的文件叫宿主文件,其他EXE文件依次捆绑在宿主文件尾部.宿主文件运行的时候检查自身文件大小,如果发现比"纯洁"的宿主文件大就说明有别的EXE文件捆绑在宿主文件后,那么就把那个文件从自身读出来创建成一个新文件,否则就什么都不做退出(具体请参加源码).
  捆绑就更简单了,一般需要另写一个专门用来捆绑的程序,我管它叫主程序.主程序要和宿主文件协调工作,以规范的方式捆绑文件这样宿主文件才能读出捆绑的文件.比如在轩辕EXE捆绑机中就是简单的在宿主文件后先写入捆绑文件的大小,然后就是整个EXE文件.这样宿主文件先读出一个大小,再按大小读取相应个字节就能分解出EXE文件.
  运行方式:一般都是创建成一个新的EXE文件,并运行.不知道能不能直接读入内存运行,我功力太差就只能写文件了.功能强大一些的捆绑机还可以加入对运行程序的控制,比如隐藏运行,定时运行,关闭后自动删除等.
  轩辕EXE捆绑机制作初衷就是为了技术研究,根本没打算做成一个黑客工具,对捆绑的文件没有进行特殊处理(比如对文件每一个字节和文件大小进行异或运算,这里仅提供个思路),捆绑的文件运行后会在c:\windows\temp下创建捆绑的EXE文件,并运行.
  好了捆绑机的原理就介绍到这,是不是非常简单?
  附宿主文件汇编源码:

.386
.model flat, stdcall
option casemap:noneinclude        windows.inc
include        user32.inc
includelib    user32.lib
include        kernel32.inc
includelib    kernel32.lib
include     shell32.inc
includelib    shell32.lib.constszFormat        db    "%d", 0szErr1            db    "打开文件出错!", 0szErr2            db    "读取文件出错!", 0szErr3            db    "分配内存出错!", 0szDontRunMe        db    "此文件是EXE捆绑机的宿主文件,请不要单独运行!", 0szNameFormat    db    "c:\windows\temp\temp%d.exe", 0
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_RunProcess procLOCAL    @szFileName[MAX_PATH]:byte        ;存放文件名LOCAL    @hFileHandle                    ;文件句柄LOCAL    @dwFileSize                        ;文件大小LOCAL    @dwNumOfBytes                    ;实际影响的字节数LOCAL    @lpMemAddress                    ;分配内在基址LOCAL    @hFileWriteTo                    ;要写入文件句柄LOCAL    @si:SYSTEM_INFO                    ;系统信息结构LOCAL    @i                                ;处理第几个文件LOCAL    @szTempFileName[128]:byte        ;生成的临时文件名invoke    GetSystemInfo, addr @si            ;获取系统信息mov    @i, 1;获得自身文件大小,并判断是否已经捆绑了其他文件invoke    GetModuleFileName, NULL, addr @szFileName, MAX_PATHinvoke    CreateFile, addr @szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULLmov    @hFileHandle, eax.if    eax == INVALID_HANDLE_VALUEinvoke    MessageBox, NULL, offset szErr1, 0, MB_ICONERRORjmp    exit.endifinvoke    GetFileSize, @hFileHandle, NULL.if    eax == 3584        ;如果没捆绑其他文件则退出invoke    MessageBox, NULL, offset szDontRunMe, 0, MB_ICONERRORjmp    exit.endifinvoke    SetFilePointer, @hFileHandle, 8888, 0, FILE_BEGIN        ;文件指针移到捆绑文件开始处(具体位置需要在文件捆绑后重新设置);从文件尾部依次获取文件数据,写入临时文件并运行
@@:    invoke    ReadFile, @hFileHandle, addr @dwFileSize, 4, addr @dwNumOfBytes, NULL.if    @dwNumOfBytes == 0jmp    exit            ;没有更多的捆绑文件了.endif;invoke    wsprintf, addr @szFileName, offset szFormat, @dwFileSize    ;invoke    MessageBox, 0, addr @szFileName, 0, MB_OK            ;显示文件大小invoke    VirtualAlloc, NULL, @dwFileSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE                ;分配内存以存放文件数据mov    @lpMemAddress, eax.if    eax == NULLinvoke    MessageBox, NULL, offset szErr3, 0, MB_ICONERRORjmp exit.endifinvoke    ReadFile, @hFileHandle, @lpMemAddress, @dwFileSize, addr @dwNumOfBytes, NULL    ;读入EXE文件数据invoke    wsprintf, addr @szTempFileName, offset szNameFormat, @i;                        ;临时文件名,格式为temp1.exe, temp2.exe ...invoke    CreateFile, addr @szTempFileName, GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULLmov    @hFileWriteTo, eax.if    eax == INVALID_HANDLE_VALUEinvoke    MessageBox, NULL, offset szErr1, 0, MB_ICONERRORjmp    exit.endifinvoke    WriteFile, @hFileWriteTo, @lpMemAddress, @dwFileSize, addr @dwNumOfBytes, NULL    ;写入文件数据invoke    CloseHandle, @hFileWriteToinvoke    VirtualFree, @lpMemAddress, 0, MEM_RELEASE    ;释放内存invoke    ShellExecute, 0, 0, addr @szTempFileName, 0, 0, SW_SHOWinc    @ijmp    @b
exit:invoke    CloseHandle, @hFileHandle    ret_RunProcess endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>start:call    _RunProcessinvoke  ExitProcess, NULL
end    start要注意其中的一句invoke    SetFilePointer, @hFileHandle, 8888, 0, FILE_BEGIN 这里8888是随意写的数,当宿主文件被更改图标后可能造成原始文件大小变化,所以这个位置的具体数值需要在主程序对宿主文件进行图标更改操作后进行设置.这个数在编译好的宿文件中可以用W32DASM查到,在49EH处.

EXE捆绑机制作原理相关推荐

  1. php底层运行机制与原理

    php底层运行机制与原理 1 PHP的设计理念及特点 多进程模型:由于PHP是多进程模型,不同请求间互不干涉,这样保证了一个请求挂掉不会对全盘服务造成影响,当然,时代发展,PHP也早已支持多线程模型. ...

  2. PHP的运行机制与原理(底层)

    php看着很简单,但是要深入php的运行机制与原理也不是件容易的事,我们除了会使用之外还要知道它底层的工作原理,这样才能灵活的运用,对php运行机制感兴趣的朋友一起学习吧 说到php的运行机制还要先给 ...

  3. 天天用着Redis集群,主从同步该知道吧?集群工作原理是否需要了解下?

    作者:z小赵 ★ 一枚用心坚持写原创的"无趣"程序猿,在自身受益的同时也让朋友们在技术上有所提升. 前言 插播一个小插曲,本来文章已经写好准备发布了,手贱清理了缓存导致文本内容全部 ...

  4. syslog 向内存中缓存_动画:深入浅出从根上理解 HTTP 缓存机制及原理!

    HTTP 缓存,对于前端的性能优化方面来讲,是非常关键的,从缓存中读取数据和直接向服务器请求数据,完全就是一个在天上,一个在地下. 我们最熟悉的是 HTTP 服务器响应返回状态码 304,304 代表 ...

  5. 升腾威讯怎么恢复集群_Redis系列(四):天天用着Redis集群,主从同步该知道吧?集群工作原理是否需要了解下?...

    作者:z小赵 ★ 一枚用心坚持写原创的"无趣"程序猿,在自身受益的同时也让朋友们在技术上有所提升. 前言 插播一个小插曲,本来文章已经写好准备发布了,手贱清理了缓存导致文本内容全部 ...

  6. HTTP缓存机制和原理

    转自:微点阅读  https://www.weidianyuedu.com/content/2217415861309.html HTTP 缓存,对于前端的性能优化方面来讲,是非常关键的,从缓存中读取 ...

  7. 文件捆绑器的原理(转)

    一.传统的捆绑器 这种原理很简单,也是目前用的最多的一种.就是将B.exe附加到A.exe的末尾.这样当 A.exe被执行的时候,B.exe也跟着执行了.这种捆绑器的代码是满网都是.我最早是从jing ...

  8. 第12 课:HA下的Spark集群工作原理解密

    第12 课:HA下的Spark集群工作原理解密 本期内容: 1.Spark高可用HA实战 2. Spark集群工作原理详解 1,Spark高可用HA实战 Spark本身是Master/Slaves结构 ...

  9. Mysql事务回滚机制与原理

    Mysql事务回滚机制与原理 文章目录 Mysql事务回滚机制与原理 一.事务回滚机制 二.使用到的技术讨论 三.redo log和undo log介绍 3.1 redo log 3.2 undo l ...

  10. Java序列化的机制和原理

    有关Java对象的序列化和反序列化也算是Java基础的一部分,下面对Java序列化的机制和原理进行一些介绍. Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述 ...

最新文章

  1. 冷热分离和直接使用大数据库_中台有“数”:大数据技术为苏宁818保驾护航
  2. Oracle数据库备份报错12514,Oracle数据库备份导出时,报错:ORA-12514
  3. (chap9 基于HTTP的功能追加协议) HTTP瓶颈
  4. java类二次加载_深入理解java之类加载器
  5. 这年头,好文案都被它承包了!
  6. redis 使用管道pipeline和不使用管道的性能对比
  7. 通过阅读 Douglas Crockford 的源码学习如何写 JSON parser(一)
  8. 湖南计算机股份有限公司hcc-pr2e,PC台式机电脑如何连接使用HCC PR2E/K10打印机
  9. 字符串处理 —— 最大最小表示法
  10. java能做三国杀的特效吗_能不能在游戏中关闭将灵攻击特效,太恶心了
  11. android fragment学习4-底部布局扩展TabLayout
  12. yii mysql 查询 类型转换_Yii2.0 API改造(返回数据库对应字段数据类型)
  13. 互联网运营数据分析(3): 留存分析
  14. 30天试用期到了_如何战胜被天气支配的恐惧?洗衣干衣不用看“天”,国美干衣机免费等你试!...
  15. 超赞!UX写手必备技能
  16. 二叉树遍历算法C++实现
  17. 基于单片机程控滤波放大器增益设计-protues仿真
  18. word编辑公式并编号
  19. Git的安装步骤、配置(解决Git官网下载速度慢、无法下载,需要授权)
  20. RDDs, Spark Memory, and Execution

热门文章

  1. 高红梅 第一章 海明威自我身份意识的形成 第一节 文化氛围与自我身份意识的生成
  2. 谷歌gmail注册入口_Google向GMail添加免费电话语音通话
  3. 【学术报告】几经沉浮,人工智能(AI)前路何方?
  4. 市场调研-全球与中国汽车零部件涂层市场现状及未来发展趋势
  5. 使用Python,SMTP发邮件到qq邮箱(文本/超链接/图片/表格/附件表格)
  6. Dapper使用技巧和基础CRUD
  7. 2.4G RFID动物耳标解决方案 SI24R2F+
  8. kettle工具实现数据的颗粒度转换以及珊瑚橘商务规划计算
  9. ►崔凯在转基因食品360度论坛上演讲
  10. 计算机中丢失glut.dll,OpenGl的源程序,运行就提示,计算机丢失 glut32.dll文件