用Python构建一个PE文件
用Python生成一个PE文件,主要是为了学习PE格式,因为看很多红队工具的原理都要掌握这个,这篇文章主要是记录调试代码的过程。
主要使用的是Python3。
有关PE的文件结构描述,之前写过一个简短的对每个字段的描述
描述pe格式的主要地方是winnt.h
,其中有一节叫做Image Format
,该节给出了DOS MZ格式和Windows 3.1 NE格式的文件头,之后就是PE文件的内容。在这个文件中几乎能找到所有关于PE文件的数据结构定义、枚举类型、常量定义。
- EXE文件和Dll文件是语义上的,它们使用完全的相同的PE格式,唯一的区别就是用一个字段标识这个是EXE还是DLL。
第一版 PE+ShellCode
照着PE结构的描述,用Python实现了,PE格式每个字段都有对应的大小,用到了struct
库。
一个简要的例子,因为Windows一般字符存储都是小端模式,所以用<
标明,后面的字母代表将数值转换的大小
H
unsigned short 占2byteL
unsigned long 占 4byteQ
unsigned long long 占8byte
然后用msf生成一个shellcode,到时候直接填入代码段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 |
|
这个是第一版本的代码,详细描述了PE文件的组装流程
- 先初始化
DOS_HEADER_32()
- 再
IMAGE_NT_HEADER_32()
- 再定义
section字段
- 再根据
文件对齐
字段补充0对齐 - 再填写section字段的具体代码
我是直接对text字段填入了shellcode(32位),这样一个PE文件就组装好了。
但是生成出来的文件有几kb太大了。原因是文件的section需要字节对齐
1 |
|
SizeOfRawData 要和SectionAlignment对齐才行,就导致了体积膨胀,修改SectionAlignment的大小竟然就无法运行了。但是看到有其他的程序SectionAlignment是可以设置得很小的
后面无意间用lordPE进行修复PE,发现它自动PE大小缩小并且能够运行了。于是我对比了两个文件找到了原因。
text.SizeOfRawData
是根据文件对齐
的字段来对齐的,我用节对齐
的字段对齐了。第一个
sizeofimage
字段我设置的太小了(代码问题,我是根据文件的长度对齐section的)- 导入表段不用对齐文件长度,这个很神奇,text段对齐就好了,导入表字段看lordPE是直接将后面填充
\x00
的去掉了 (这个后面有加导入表的PE格式)
修改SectionAlignment的大小竟然就无法运行了
这个的主要原因是sizeofimage设置得太小了
最后sizeOfImage修改为
1 |
|
第二版 x86 PE + 导入表
上一个版本使用了shellcode执行命令,这个版本直接通过导入表来调用API
有一个坑,MessageBoxA
需要ansi
编码的字符串,MessageBoxW
需要utf-16
编码的字符串,而python3是utf-8编码,所以对字符串变量处理的时候要转换一下
""..encode("mbcs")
ansi编码.encode("UTF-16")
utf16编码
x86 生成的文件1kb左右 (文件对齐默认是512,我尝试将它改小一些,但是会报错)
因为是根据汇编生成的机器码来的,所以需要去寻找字符串和一些dll的内存地址。我将这部分自动化了。
1 2 3 4 5 6 7 8 |
|
importer代表要导入的dll和函数,ConstString 代表输入的字符串。这是text字段的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
最后生成代码会自动对这些地址进行替换。
第三部 x64 + 导入表
32位的搞定了,再看看64位的,PE结构上的差异就几个地方。主要是header头和导入表,写一个新的结构进去就行。
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
然后x64 的调用约定和call的方式也不一样
x64调用约定
在32位汇编中,我们调用一个API时,采用的是stdcall,它有两个特点:一是所有参数入栈,通过椎栈传递;二是被调用的API负责栈指针(ESP)的恢复,我们在调用MessageBox后不用add esp,14h,因为MessageBox已经恢复过了。
而在x64汇编中,两方面都发生了变化。一是前四个参数分析通过四个寄存器传递:RCX、RDX、R8、R9,如果还有更多的参数,才通过椎栈传递。二是调用者负责椎栈空间的分配与回收。
x64 call偏移地址计算
内存地址-RIP-7=偏移地址
代码地址(x64) https://gist.github.com/boy-hack/dbfef2a3eff6b7b00791f6a9714b8aea
将win64改成True就会生成64位的程序了
代码完成了
- 代码完成了call偏移地址自动计算
- 自动置入字符串,自动计算字符串位置
- 代码基本上只需自定义'文本','导入函数',和调用代码,其他的绝对地址转换会自动实现
End
- 因为用了一些代码自动寻找地址,一度以为可以用python写exe了(定义好导入的函数和常量,text代码段可以自定义之类的)
- 对一些PE字段的定义,区块对齐,地址的转换,程序如何调用dll有了更深的了解
文章到这里就结束了,感谢你的观看
说实在的,每次在后台看到一些读者的回应都觉得很欣慰,我想把我收藏的一些编程干货贡献给大家,回馈每一个读者,希望能帮到你们。
干货主要有:
① 2000多本Python电子书(主流和经典的书籍应该都有了)
② Python标准库资料(最全中文版)
③ 项目源码(四五十个有趣且经典的练手项目及源码)
④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)
⑤ Python所有知识点汇总(可以弄清楚Python的所有方向和技术)
*如果你用得到的话可以直接拿走,在我的QQ技术交流群里,可以自助拿走,群号是857113825。*
用Python构建一个PE文件相关推荐
- [译] 用 Redis 和 Python 构建一个共享单车的 app
原文地址:Build a bikesharing app with Redis and Python 原文作者:Tague Griffith 译文出自:掘金翻译计划 本文永久链接:github.com ...
- 通过python构建一个区块链来学习区块链
了解区块链Blockchains如何工作的最快方法就是构建一个区块链.你来到这里是因为,和我一样,你对加密钱币的崛起感到很兴奋.而且你想知道区块链是如何工作的,想了解它们背后的基本技术. 但理解区块链 ...
- python推荐系统-利用python构建一个简单的推荐系统
摘要: 快利用python构建一个属于你自己的推荐系统吧,手把手教学,够简单够酷炫. 本文将利用python构建一个简单的推荐系统,在此之前读者需要对pandas和numpy等数据分析包有所了解. 什 ...
- 基于python的系统构建_利用python构建一个简单的推荐系统
摘要: 快利用python构建一个属于你自己的推荐系统吧,手把手教学,够简单够酷炫. 本文将利用python构建一个简单的推荐系统,在此之前读者需要对pandas和numpy等数据分析包有所了解. 什 ...
- python推荐_利用Python构建一个简单的推荐系统
原标题:利用Python构建一个简单的推荐系统 摘要:快利用python构建一个属于你自己的推荐系统吧,手把手教学,够简单够酷炫.在此之前读者需要对pandas和numpy等数据分析包有所了解. 什么 ...
- 如何使用Python打开一个TXT文件
如何使用Python打开一个TXT文件 1 相对路径 首先需要找到当前工作路径,使用以下代码: import os f=os.getcwd() print(f) 将需要打开的TXT文件放入刚才找到的同 ...
- 用python 打开一个excel文件
题目:用python 打开一个xls文件 import xlrd #打开xls文件 data1 = xlrd.open_workbook(r'C:\\Users\\Administrator\\Des ...
- PE文件格式分析系列(文章3)----一个PE文件rdata段的分析(Win32工程Release版)(二)
PE文件格式分析系列(文章3) 一个PE文件rdata段的分析(Win32工程Release版)(二) 下面分析这个PE文件rdata段的常量数据(000050A4---0000543D) 00005 ...
- 用python创建一个新文件_Python创建文件和追加文件内容实例
一.用Python创建一个新文件,内容是从0到9的整数, 每个数字占一行: 代码如下: #python >>>f=open('f.txt','w') # r只读,w可写,a追加 &g ...
- 一文告诉你,如何使用Python构建一个“谷歌搜索”系统 | 内附代码
来源 | hackernoon 编译 | 武明利 责编 | Carol 出品 | AI科技大本营(ID:rgznai100) 在这篇文章中,我将向您展示如何使用Python构建自己的答案查找系统.基本 ...
最新文章
- Windows Performance Toolkit
- python画圣诞树代码-python圣诞树代码
- Memcached缓存实例
- python中延时函数_python中实现延时回调普通函数示例代码
- linux mail命令查看邮件/mail控制台
- JS事件、对象基础篇
- C# DateTime 日期加1天 减一天 加一月 减一月 等方法
- TensorFlow基础篇(一)——tf.train.exponential_decay()
- C++11 std::function类模板
- PLC编程语言都在这里了!
- python处理rtf文档_python读取word文档的方法
- 怎样固定计算机桌面背景,Win7桌面背景老是被修改如何将其锁定不让他人随意修改...
- 【Qt象棋游戏】05_象棋走棋规则——象、马、将、兵
- [附源码]计算机毕业设计springboot公益组织登记与查询系统论文
- 揭开虚拟主机供应商的面纱
- python matplotlib 基础练习:画一元二次函数
- 压缩包解压后的文件名是乱码怎么解决
- JVM内存区域(Java内存区域)、JVM垃圾回收机制(GC)初探
- 如果你在犹豫要不要去外包公司,不妨看看这篇文章
- 【乱入】Uva11021麻球繁衍