用Python构建一个PE文件

本文介绍了如何使用Python生成PE文件,包括PE+ShellCode、x86 PE+导入表和x64 PE+导入表的实现过程。通过学习PE格式,作者详细讲解了PE文件的组装流程,涉及到字段大小、对齐方式、Shellcode插入以及导入表的处理。在实践中,作者发现并解决了SectionAlignment设置不当导致的文件过大问题,并探讨了x86与x64调用约定的区别。
摘要由CSDN通过智能技术生成

用Python生成一个PE文件,主要是为了学习PE格式,因为看很多红队工具的原理都要掌握这个,这篇文章主要是记录调试代码的过程。

 

主要使用的是Python3。

 

有关PE的文件结构描述,之前写过一个简短的对每个字段的描述

描述pe格式的主要地方是winnt.h,其中有一节叫做Image Format,该节给出了DOS MZ格式和Windows 3.1 NE格式的文件头,之后就是PE文件的内容。在这个文件中几乎能找到所有关于PE文件的数据结构定义、枚举类型、常量定义。

  1. EXE文件和Dll文件是语义上的,它们使用完全的相同的PE格式,唯一的区别就是用一个字段标识这个是EXE还是DLL。

第一版 PE+ShellCode

照着PE结构的描述,用Python实现了,PE格式每个字段都有对应的大小,用到了struct库。

 

一个简要的例子,因为Windows一般字符存储都是小端模式,所以用<标明,后面的字母代表将数值转换的大小

  • H unsigned short 占2byte
  • L unsigned long 占 4byte
  • Q unsigned long long 占8byte

image-20210508194328681

 

然后用msf生成一个shellcode,到时候直接填入代码段

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

$ msfvenom -a x86 -p windows/exec CMD="calc" -f python

[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload

No encoder specified, outputting raw payload

Payload size: 189 bytes

Final size of python file932 bytes

buf =  b""

buf += b"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b"

buf += b"\x50\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7"

buf += b"\x4a\x26\x31\xff\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf"

buf += b"\x0d\x01\xc7\xe2\xf2\x52\x57\x8b\x52\x10\x8b\x4a\x3c"

buf += b"\x8b\x4c\x11\x78\xe3\x48\x01\xd1\x51\x8b\x59\x20\x01"

buf += b"\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b\x01\xd6\x31"

buf += b"\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03\x7d"

buf += b"\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66"

buf += b"\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0"

buf += b"\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f"

buf += b"\x5f\x5a\x8b\x12\xeb\x8d\x5d\x6a\x01\x8d\x85\xb2\x00"

buf += b"\x00\x00\x50\x68\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5"

buf += b"\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a"

buf += b"\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53"

buf += b"\xff\xd5\x63\x61\x6c\x63\x00"

完整代码

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的最好方法,就是自己写一个PE文件。这个例子展示了用python生成一个pe文件

import struct

import time

 

MZ_MAGIC = 0x5A4D

PE_MAGIC = 0x4550

IMAGE_FILE_MACHINE_I386 = 0x014c

 

IMAGE_SCN_MEM_EXECUTE = 0x20000000  # Section is executable.

IMAGE_SCN_MEM_READ = 0x40000000  # Section is readable.

IMAGE_SCN_MEM_WRITE = 0x80000000  # Section is writeable.

IMAGE_SCN_CNT_CODE = 0x00000020

IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040

 

 

class DOS_HEADER_32(object):

    '''

    DOS头只关心 magic 和 e_lfanew 位置就行

    '''

    e_magic = MZ_MAGIC

    e_cblp, e_cp, e_crlc, e_cparhdr, e_minalloc, e_maxalloc, e_ss, e_sp, \

    e_csum, e_ip, e_cs, e_lfarlc, e_ovno, e_res, e_oemid, \

    e_oeminfo, e_res2, e_lfanew = [0* 18

 

    def __init__(self):

        self.fmt = "<30HL"

        # 小端模式 30个H(unsigned short 占2byte) 后一个是L(unsigned long 占 4byte)

 

        self.e_res = [0000]

        self.e_res2 = [0000000000]

 

    de

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

平静愉悦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值