/
itoa.asm
59 lines (56 loc) · 1.4 KB
/
itoa.asm
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
<%
from pwnlib.shellcraft import pretty, common, registers
from pwnlib.shellcraft.amd64 import mov, pushstr
from pwnlib import constants
%>
<%docstring>
Converts an integer into its string representation, and pushes it
onto the stack.
Arguments:
v(str, int):
Integer constant or register that contains the value to convert.
alloca
Example:
>>> sc = shellcraft.amd64.mov('rax', 0xdeadbeef)
>>> sc += shellcraft.amd64.itoa('rax')
>>> sc += shellcraft.amd64.linux.write(1, 'rsp', 32)
>>> run_assembly(sc).recvuntil(b'\x00')
b'3735928559\x00'
</%docstring>
<%page args="v, buffer='rsp', allocate_stack=True"/>
<%
itoa_loop = common.label('itoa_loop')
size_loop = common.label('size_loop')
assert v in registers.amd64
%>\
/* atoi(${pretty(v,0)}) */
%if allocate_stack and buffer=='rsp':
sub rsp, 0x10
%endif
## We need to know how long the string is, in order for
## the beginning of the string to be *exactly* at rsp.
${mov('rdi', buffer)}
${mov('rax', v)}
push rax /* save for later */
${mov('rcx', 10)}
${size_loop}:
${mov('rdx', 0)}
div rcx
stosb
test rax, rax
jnz ${size_loop}
## null terminate
std
stosb
## Now we begin the actual division process
pop rax
${itoa_loop}:
${mov('rdx', 0)}
## rcx is already 10
div rcx
add dl, ${ord('0')}
mov BYTE PTR [rdi], dl
dec rdi
test rax, rax
jnz ${itoa_loop}
cld