@@ -61,17 +61,26 @@ Example:
6161 mov rax , 0x1010110dfac01fe
6262 xor [ rsp ], rax
6363 pop rax
64- >>> with context.local(os = 'linux' ):
65- ... print shellcraft.amd64. mov ( 'eax' , 'SYS_read' ).rstrip()
66- xor eax , eax / * (SYS_read) * /
67- >>> with context.local(os = 'freebsd' ):
68- ... print shellcraft.amd64. mov ( 'eax' , 'SYS_read' ).rstrip()
69- push (SYS_read) / * 3 * /
70- pop rax
71- >>> with context.local(os = 'linux' ):
72- ... print shellcraft.amd64. mov ( 'eax' , 'PROT_READ | PROT_WRITE | PROT_EXEC' ).rstrip()
73- push (PROT_READ | PROT_WRITE | PROT_EXEC) / * 7 * /
74- pop rax
64+ >>> print shellcraft.amd64. mov ( 'rax' , 0xffffffff ).rstrip()
65+ mov eax , 0xffffffff
66+ >>> print shellcraft.amd64. mov ( 'rax' , 0x7fffffff ).rstrip()
67+ mov eax , 0x7fffffff
68+ >>> print shellcraft.amd64. mov ( 'rax' , 0x80010101 ).rstrip()
69+ mov eax , 0x80010101
70+ >>> print shellcraft.amd64. mov ( 'rax' , 0x80000000 ).rstrip()
71+ mov eax , 0x1010101 / * 2147483648 == 0x80000000 * /
72+ xor eax , 0x81010101
73+ >>> with context.local(os = 'linux' ):
74+ ... print shellcraft.amd64. mov ( 'eax' , 'SYS_read' ).rstrip()
75+ xor eax , eax / * (SYS_read) * /
76+ >>> with context.local(os = 'freebsd' ):
77+ ... print shellcraft.amd64. mov ( 'eax' , 'SYS_read' ).rstrip()
78+ push (SYS_read) / * 3 * /
79+ pop rax
80+ >>> with context.local(os = 'linux' ):
81+ ... print shellcraft.amd64. mov ( 'eax' , 'PROT_READ | PROT_WRITE | PROT_EXEC' ).rstrip()
82+ push (PROT_READ | PROT_WRITE | PROT_EXEC) / * 7 * /
83+ pop rax
7584
7685Args:
7786 dest ( str ): The destination register.
@@ -99,25 +108,32 @@ if get_register(src):
99108 if dest.size == 64 and src.size <= 32 :
100109 dest = get_register(dest.native32)
101110
102- src_size = src.size
103111else:
104112 with ctx.local(arch = 'amd64' ):
105113 src = eval(src)
106114
107115 if not dest.fits(src):
108116 log.error( "cannot mov %s, %r: dest is smaller than src" % (dest , src))
109117
110- src_size = bits_required(src)
118+ orig_dest = dest
111119
112- if dest.size == 64 and src_size <= 32 :
120+ if dest.size == 64 and bits_required(src) <= 32 :
113121 dest = get_register(dest.native32)
114122
115123 # Calculate the packed version
116124 srcp = packing.pack(src & (( 1 <<dest.size) - 1 ) , dest.size)
117125
118126 # Calculate the unsigned and signed versions
119127 srcu = packing.unpack(srcp , dest.size , sign=False)
120- srcs = packing.unpack(srcp , dest.size , sign=True)
128+
129+ # N.B.: We may have downsized the register for e.g. mov ( 'rax' , 0xffffffff )
130+ # In this case , srcp is now a 4 - byte packed value , which will expand
131+ # to "-1" , which isn't correct.
132+ if orig_dest.size != dest.size:
133+ srcs = src
134+ else:
135+ srcs = packing.unpack(srcp , dest.size , sign=True)
136+
121137%>\
122138% if is_register(src):
123139 % if src == dest:
0 commit comments