forked from longld/peda
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnasm.py
103 lines (87 loc) · 3.19 KB
/
nasm.py
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
#
# PEDA - Python Exploit Development Assistance for GDB
#
# Copyright (C) 2012 Long Le Dinh <longld at vnsecurity.net>
#
# License: see LICENSE file for details
#
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
from utils import *
import config
class Nasm(object):
"""
Wrapper class for assemble/disassemble using nasm/ndisassm
"""
def __init__(self):
pass
@staticmethod
def assemble(asmcode, mode=32):
"""
Assemble ASM instructions using NASM
- asmcode: input ASM instructions, multiple instructions are separated by ";" (String)
- mode: 16/32/64 bits assembly
Returns:
- bin code (raw bytes)
"""
if not os.path.exists(config.NASM):
error_msg("%s binary not found, please install NASM for asm/rop functions" % config.NASM)
raise UserWarning("missing requirement")
asmcode = asmcode.strip('"').strip("'")
asmcode = asmcode.replace(";", "\n")
asmcode = ("BITS %d\n" % mode) + asmcode
asmcode = decode_string_escape(asmcode)
asmcode = re.sub("PTR|ptr|ds:|DS:", "", asmcode)
infd = tmpfile()
outfd = tmpfile(is_binary_file=True)
infd.write(asmcode)
infd.flush()
execute_external_command("%s -f bin -o %s %s" % (config.NASM, outfd.name, infd.name))
infd.close()
if os.path.exists(outfd.name):
bincode = outfd.read()
outfd.close()
return bincode
# reopen it so tempfile will not complain
open(outfd.name,'w').write('B00B')
return None
@staticmethod
def disassemble(buf, mode=32):
"""
Disassemble binary to ASM instructions using NASM
- buf: input binary (raw bytes)
- mode: 16/32/64 bits assembly
Returns:
- ASM code (String)
"""
out = execute_external_command("%s -b %d -" % (config.NDISASM, mode), buf)
return out
@staticmethod
def format_shellcode(buf, mode=32):
"""
Format raw shellcode to ndisasm output display
"\x6a\x01" # 0x00000000: push byte +0x1
"\x5b" # 0x00000002: pop ebx
TODO: understand syscall numbers, socket call
"""
def nasm2shellcode(asmcode):
if not asmcode:
return ""
shellcode = []
pattern = re.compile("([0-9A-F]{8})\s*([^\s]*)\s*(.*)")
matches = pattern.findall(asmcode)
for line in asmcode.splitlines():
m = pattern.match(line)
if m:
(addr, bytes, code) = m.groups()
sc = '"%s"' % to_hexstr(codecs.decode(bytes, 'hex'))
shellcode += [(sc, "0x"+addr, code)]
maxlen = max([len(x[0]) for x in shellcode])
text = ""
for (sc, addr, code) in shellcode:
text += "%s # %s: %s\n" % (sc.ljust(maxlen+1), addr, code)
return text
out = execute_external_command("%s -b %d -" % (config.NDISASM, mode), buf)
return nasm2shellcode(out)