Skip to content

Commit 1d5e1fd

Browse files
authored
Merge branch 'dev' into newline_for_windows
2 parents 714e56f + 9e4b11a commit 1d5e1fd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+15502
-214
lines changed

.github/workflows/android.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
- uses: actions/checkout@v4
1515

1616
- name: Cache for pip
17-
uses: actions/cache@v3
17+
uses: actions/cache@v4
1818
id: cache-pip
1919
with:
2020
path: ~/.cache/pip

.github/workflows/ci.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
git log --oneline --graph -10
2121
2222
- name: Cache for pip
23-
uses: actions/cache@v3
23+
uses: actions/cache@v4
2424
id: cache-pip
2525
with:
2626
path: ~/.cache/pip
@@ -164,6 +164,7 @@ jobs:
164164
pwn phd -l 0x3d --color=always /etc/os-release
165165
166166
pwn checksec /bin/bash
167+
(ulimit -v 500000 && pwn checksec /bin/bash)
167168
168169
pwn errno 2
169170
pwn errno -1
@@ -172,6 +173,7 @@ jobs:
172173
pwn constgrep -c freebsd -m ^PROT_ '3 + 4'
173174
pwn constgrep ^MAP_ 0
174175
pwn constgrep -e O_RDWR
176+
pwn constgrep C
175177
176178
pwn libcdb file /lib/x86_64-linux-gnu/libc.so.6
177179
pwn libcdb lookup puts 5f0 __libc_start_main_ret d0a

.github/workflows/lint.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
steps:
1313
- uses: actions/checkout@v4
1414
- name: Cache for pip
15-
uses: actions/cache@v3
15+
uses: actions/cache@v4
1616
id: cache-pip
1717
with:
1818
path: ~/.cache/pip

.github/workflows/pylint.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
steps:
1313
- uses: actions/checkout@v4
1414
- name: Cache for pip
15-
uses: actions/cache@v3
15+
uses: actions/cache@v4
1616
id: cache-pip
1717
with:
1818
path: ~/.cache/pip

CHANGELOG.md

+32-1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,23 @@ The table below shows which release corresponds to each branch, and what date th
8080
- [#2308][2308] Fix WinExec shellcraft to make sure it's 16 byte aligned
8181
- [#2279][2279] Make `pwn template` always set context.binary
8282
- [#2310][2310] Add support to start a process on Windows
83+
- [#2335][2335] Add lookup optimizations in DynELF
84+
- [#2334][2334] Speed up disasm commandline tool with colored output
85+
- [#2328][2328] Lookup using $PATHEXT file extensions in `which` on Windows
86+
- [#2189][2189] Explicitly define p64/u64 functions for IDE support
87+
- [#2339][2339] Fix: Allow setting attributes on gdb Breakpoints
88+
- [#2323][2323] Retry failed lookups after one week in libcdb
89+
- [#2325][2325] Match against local system libc first in libcdb
90+
- [#2336][2336] Add `ELF.stripped` and `ELF.debuginfo` properties
91+
- [#2161][2161] Add basic support for darwin shellcraft/asm/disasm/run_shellcode/run_assembly
92+
- [#2161][2161] Fix freebsd amd64 SyscallABI
93+
- [#2160][2161] Fix invalid shellcraft.mov on arm64
94+
- [#2284][2161] Fix invalid shellcraft.pushstr_array on arm64
95+
- [#2345][2345] Fix pwn constgrep when it matches a non-constant type
96+
- [#2338][2338] Fix: follow symlink for libs on ssh connection
97+
- [#2341][2341] Launch GDB correctly in iTerm on Mac
98+
- [#2268][2268] Add a `flatten` argument to `ssh.libs`
99+
- [#2347][2347] Fix/workaround Unicorn Engine 1GB limit that calls exit()
83100
- [#2330][2330] Change `context.newline` when setting `context.os`
84101

85102
[2242]: https://github.com/Gallopsled/pwntools/pull/2242
@@ -92,6 +109,20 @@ The table below shows which release corresponds to each branch, and what date th
92109
[2308]: https://github.com/Gallopsled/pwntools/pull/2308
93110
[2279]: https://github.com/Gallopsled/pwntools/pull/2279
94111
[2310]: https://github.com/Gallopsled/pwntools/pull/2310
112+
[2335]: https://github.com/Gallopsled/pwntools/pull/2335
113+
[2334]: https://github.com/Gallopsled/pwntools/pull/2334
114+
[2328]: https://github.com/Gallopsled/pwntools/pull/2328
115+
[2189]: https://github.com/Gallopsled/pwntools/pull/2189
116+
[2339]: https://github.com/Gallopsled/pwntools/pull/2339
117+
[2323]: https://github.com/Gallopsled/pwntools/pull/2323
118+
[2325]: https://github.com/Gallopsled/pwntools/pull/2325
119+
[2336]: https://github.com/Gallopsled/pwntools/pull/2336
120+
[2161]: https://github.com/Gallopsled/pwntools/pull/2161
121+
[2345]: https://github.com/Gallopsled/pwntools/pull/2345
122+
[2338]: https://github.com/Gallopsled/pwntools/pull/2338
123+
[2341]: https://github.com/Gallopsled/pwntools/pull/2341
124+
[2268]: https://github.com/Gallopsled/pwntools/pull/2268
125+
[2347]: https://github.com/Gallopsled/pwntools/pull/2347
95126
[2330]: https://github.com/Gallopsled/pwntools/pull/2330
96127

97128
## 4.12.0 (`beta`)
@@ -1093,4 +1124,4 @@ are mentioned here.
10931124
- Added a lots of shellcodes
10941125
- Stuff we forgot
10951126
- Lots of documentation fixes
1096-
- Lots of bugfixes
1127+
- Lots of bugfixes

pwnlib/abi.py

+39-6
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ def default():
4848
(32, 'mips', 'linux'): linux_mips,
4949
(32, 'powerpc', 'linux'): linux_ppc,
5050
(64, 'powerpc', 'linux'): linux_ppc64,
51+
(32, 'riscv32', 'linux'): linux_riscv32,
52+
(64, 'riscv64', 'linux'): linux_riscv64,
5153
(32, 'i386', 'freebsd'): freebsd_i386,
5254
(64, 'aarch64', 'freebsd'): freebsd_aarch64,
5355
(64, 'amd64', 'freebsd'): freebsd_amd64,
@@ -58,6 +60,8 @@ def default():
5860
(64, 'powerpc', 'freebsd'): freebsd_ppc64,
5961
(32, 'i386', 'windows'): windows_i386,
6062
(64, 'amd64', 'windows'): windows_amd64,
63+
(64, 'amd64', 'darwin'): darwin_amd64,
64+
(64, 'aarch64', 'darwin'): darwin_aarch64,
6165
}[(context.bits, context.arch, context.os)]
6266

6367
@staticmethod
@@ -76,6 +80,8 @@ def syscall():
7680
(64, 'aarch64', 'linux'): linux_aarch64_syscall,
7781
(32, 'powerpc', 'linux'): linux_ppc_syscall,
7882
(64, 'powerpc', 'linux'): linux_ppc64_syscall,
83+
(32, 'riscv32', 'linux'): linux_riscv32_syscall,
84+
(64, 'riscv64', 'linux'): linux_riscv64_syscall,
7985
(32, 'i386', 'freebsd'): freebsd_i386_syscall,
8086
(64, 'amd64', 'freebsd'): freebsd_amd64_syscall,
8187
(64, 'aarch64', 'freebsd'): freebsd_aarch64_syscall,
@@ -85,6 +91,8 @@ def syscall():
8591
(64, 'aarch64', 'freebsd'): freebsd_aarch64_syscall,
8692
(32, 'powerpc', 'freebsd'): freebsd_ppc_syscall,
8793
(64, 'powerpc', 'freebsd'): freebsd_ppc64_syscall,
94+
(64, 'amd64', 'darwin'): darwin_amd64_syscall,
95+
(64, 'aarch64', 'darwin'): darwin_aarch64_syscall,
8896
}[(context.bits, context.arch, context.os)]
8997

9098
@staticmethod
@@ -99,13 +107,18 @@ def sigreturn():
99107
(32, 'arm', 'linux'): linux_arm_sigreturn,
100108
(32, 'thumb', 'linux'): linux_arm_sigreturn,
101109
(64, 'aarch64', 'linux'): linux_aarch64_sigreturn,
110+
(32, 'riscv32', 'linux'): linux_riscv32_sigreturn,
111+
(64, 'riscv64', 'linux'): linux_riscv64_sigreturn,
102112
(32, 'i386', 'freebsd'): freebsd_i386_sigreturn,
103113
(64, 'amd64', 'freebsd'): freebsd_amd64_sigreturn,
104114
(32, 'arm', 'freebsd'): freebsd_arm_sigreturn,
105115
(32, 'thumb', 'freebsd'): freebsd_arm_sigreturn,
106116
(64, 'aarch64', 'freebsd'): freebsd_aarch64_sigreturn,
117+
(64, 'amd64', 'darwin'): darwin_amd64_sigreturn,
118+
(64, 'aarch64', 'darwin'): darwin_aarch64_sigreturn,
107119
}[(context.bits, context.arch, context.os)]
108120

121+
109122
class SyscallABI(ABI):
110123
"""
111124
The syscall ABI treats the syscall number as the zeroth argument,
@@ -115,6 +128,7 @@ def __init__(self, *a, **kw):
115128
super(SyscallABI, self).__init__(*a, **kw)
116129
self.syscall_register = self.register_arguments[0]
117130

131+
118132
class SigreturnABI(SyscallABI):
119133
"""
120134
The sigreturn ABI is similar to the syscall ABI, except that
@@ -132,6 +146,8 @@ class SigreturnABI(SyscallABI):
132146
linux_mips = ABI('$sp', ['$a0','$a1','$a2','$a3'], 4, 0)
133147
linux_ppc = ABI('sp', ['r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10'], 4, 0)
134148
linux_ppc64 = ABI('sp', ['r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10'], 8, 0)
149+
linux_riscv32 = ABI('sp', ['a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7'], 8, 0)
150+
linux_riscv64 = ABI('sp', ['a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7'], 8, 0)
135151

136152
sysv_i386 = linux_i386
137153
sysv_amd64 = linux_amd64
@@ -140,24 +156,33 @@ class SigreturnABI(SyscallABI):
140156
sysv_mips = linux_mips
141157
sysv_ppc = linux_ppc
142158
sysv_ppc64 = linux_ppc64
159+
sysv_riscv32 = linux_riscv32
160+
sysv_riscv64 = linux_riscv64
143161

162+
# Docs: https://man7.org/linux/man-pages/man2/syscall.2.html
144163
linux_i386_syscall = SyscallABI('esp', ['eax', 'ebx', 'ecx', 'edx', 'esi', 'edi', 'ebp'], 4, 0)
145164
linux_amd64_syscall = SyscallABI('rsp', ['rax', 'rdi', 'rsi', 'rdx', 'r10', 'r8', 'r9'], 8, 0)
146-
linux_arm_syscall = SyscallABI('sp', ['r7', 'r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6'], 4, 0)
147-
linux_aarch64_syscall = SyscallABI('sp', ['x8', 'x0', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6'], 16, 0)
165+
linux_arm_syscall = SyscallABI('sp', ['r7', 'r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6'], 4, 0)
166+
linux_aarch64_syscall = SyscallABI('sp', ['x8', 'x0', 'x1', 'x2', 'x3', 'x4', 'x5'], 16, 0)
148167
linux_mips_syscall = SyscallABI('$sp', ['$v0','$a0','$a1','$a2','$a3'], 4, 0)
149-
linux_ppc_syscall = ABI('sp', ['r0', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9'], 4, 0)
150-
linux_ppc64_syscall = ABI('sp', ['r0', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9'], 8, 0)
168+
linux_ppc_syscall = SyscallABI('sp', ['r0', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9'], 4, 0)
169+
linux_ppc64_syscall = SyscallABI('sp', ['r0', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8'], 8, 0)
170+
linux_riscv32_syscall = SyscallABI('sp', ['a7', 'a0', 'a1', 'a2', 'a3', 'a4', 'a5'], 4, 0)
171+
linux_riscv64_syscall = SyscallABI('sp', ['a7', 'a0', 'a1', 'a2', 'a3', 'a4', 'a5'], 8, 0)
151172

152173
linux_i386_sigreturn = SigreturnABI('esp', ['eax'], 4, 0)
153-
linux_amd64_sigreturn = SigreturnABI('rsp', ['rax'], 4, 0)
174+
linux_amd64_sigreturn = SigreturnABI('rsp', ['rax'], 8, 0)
154175
linux_arm_sigreturn = SigreturnABI('sp', ['r7'], 4, 0)
155176
linux_aarch64_sigreturn = SigreturnABI('sp', ['x8'], 16, 0)
177+
linux_riscv32_sigreturn = SigreturnABI('sp', ['a7'], 4, 0)
178+
linux_riscv64_sigreturn = SigreturnABI('sp', ['a7'], 8, 0)
156179

157180
sysv_i386_sigreturn = linux_i386_sigreturn
158181
sysv_amd64_sigreturn = linux_amd64_sigreturn
159182
sysv_arm_sigreturn = linux_arm_sigreturn
160183
sysv_aarch64_sigreturn = linux_aarch64_sigreturn
184+
sysv_riscv32_sigreturn = linux_riscv32_sigreturn
185+
sysv_riscv64_sigreturn = linux_riscv64_sigreturn
161186

162187
freebsd_i386 = sysv_i386
163188
freebsd_amd64 = sysv_amd64
@@ -168,7 +193,7 @@ class SigreturnABI(SyscallABI):
168193
freebsd_ppc64 = sysv_ppc64
169194

170195
freebsd_i386_syscall = SyscallABI('esp', ['eax'], 4, 0)
171-
freebsd_amd64_syscall = SyscallABI('rsp', ['rax','rdi','rsi','rdx','rcx','r8','r9'], 8, 0)
196+
freebsd_amd64_syscall = SyscallABI('rsp', ['rax','rdi','rsi','rdx','r10','r8','r9'], 8, 0)
172197
freebsd_arm_syscall = SyscallABI('sp', ['r7', 'r0', 'r1', 'r2', 'r3'], 8, 0)
173198
freebsd_aarch64_syscall = SyscallABI('sp', ['x8', 'x0', 'x1', 'x2', 'x3'], 16, 0)
174199
freebsd_mips_syscall = SyscallABI('$sp', ['$v0','$a0','$a1','$a2','$a3'], 4, 0)
@@ -182,3 +207,11 @@ class SigreturnABI(SyscallABI):
182207

183208
windows_i386 = ABI('esp', [], 4, 0)
184209
windows_amd64 = ABI('rsp', ['rcx','rdx','r8','r9'], 32, 32)
210+
211+
darwin_aarch64 = sysv_aarch64
212+
darwin_aarch64_syscall = SyscallABI('sp', ['x16', 'x0', 'x1', 'x2', 'x3', 'x4', 'x5'], 16, 0)
213+
darwin_aarch64_sigreturn = SigreturnABI('sp', ['x16'], 16, 0)
214+
215+
darwin_amd64 = sysv_amd64
216+
darwin_amd64_syscall = SyscallABI('rsp', ['rax', 'rdi', 'rsi', 'rdx', 'r10', 'r8', 'r9'], 8, 0)
217+
darwin_amd64_sigreturn = SigreturnABI('rsp', ['rax'], 8, 0)

pwnlib/asm.py

+65
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ def cpp(shellcode):
469469
]
470470
return _run(cmd, code).strip('\n').rstrip() + '\n'
471471

472+
472473
@LocalContext
473474
def make_elf_from_assembly(assembly,
474475
vma=None,
@@ -651,6 +652,68 @@ def make_elf(data,
651652

652653
return retval
653654

655+
656+
@LocalContext
657+
def make_macho_from_assembly(shellcode):
658+
return make_macho(shellcode, is_shellcode=True)
659+
660+
661+
@LocalContext
662+
def make_macho(data, is_shellcode=False):
663+
prefix = []
664+
if context.arch == 'amd64':
665+
prefix = [
666+
'.intel_syntax noprefix',
667+
]
668+
prefix.extend([
669+
'.text',
670+
'.global _start',
671+
'_start:',
672+
'.p2align 2',
673+
])
674+
code = ''
675+
code += '\n'.join(prefix) + '\n'
676+
if is_shellcode:
677+
code += cpp(data)
678+
else:
679+
code += '.string "%s"' % ''.join('\\x%02x' % c for c in bytearray(data))
680+
681+
log.debug('Assembling\n%s' % code)
682+
683+
tmpdir = tempfile.mkdtemp(prefix = 'pwn-asm-')
684+
step1 = path.join(tmpdir, 'step1')
685+
step2 = path.join(tmpdir, 'step2')
686+
step3 = path.join(tmpdir, 'step3')
687+
688+
with open(step1, 'w') as fd:
689+
fd.write(code)
690+
691+
assembler = [
692+
'/usr/bin/as',
693+
]
694+
asflags = [
695+
'-mmacosx-version-min=11.0',
696+
'-o', step2, step1,
697+
]
698+
_run(assembler + asflags)
699+
700+
linker = [
701+
'/usr/bin/ld',
702+
]
703+
ldflags = [
704+
'-macos_version_min', '11.0',
705+
'-l', 'System',
706+
'-e', '_start',
707+
'-L', '/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib',
708+
'-o', step3, step2,
709+
]
710+
_run(linker + ldflags)
711+
712+
os.chmod(step3, 0o755)
713+
714+
return step3
715+
716+
654717
@LocalContext
655718
def asm(shellcode, vma = 0, extract = True, shared = False):
656719
r"""asm(code, vma = 0, extract = True, shared = False, ...) -> str
@@ -860,6 +923,8 @@ def disasm(data, vma = 0, byte = True, offset = True, instructions = True):
860923

861924

862925
lines = []
926+
927+
# Note: those patterns are also used in pwnlib/commandline/disasm.py
863928
pattern = '^( *[0-9a-f]+: *)', '((?:[0-9a-f]+ )+ *)', '(.*)'
864929
if not byte:
865930
pattern = pattern[::2]

pwnlib/commandline/checksec.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import argparse
55
import sys
66

7-
from pwn import *
7+
from pwnlib.elf import ELF
88
from pwnlib.commandline import common
99

1010
parser = common.parser_commands.add_parser(
@@ -38,4 +38,4 @@ def main(args):
3838
e = ELF(f.name)
3939

4040
if __name__ == '__main__':
41-
pwnlib.commandline.common.main(__file__)
41+
common.main(__file__)

pwnlib/commandline/constgrep.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,13 @@ def main(args):
9191
if not matcher.search(k):
9292
continue
9393

94+
# Check if the value has proper type
95+
val = getattr(mod, k)
96+
if not isinstance(val, pwnlib.constants.constant.Constant):
97+
continue
98+
9499
# Check the constant
95100
if constant is not None:
96-
val = getattr(mod, k)
97101
if args.mask_mode:
98102
if constant & val != val:
99103
continue
@@ -102,7 +106,7 @@ def main(args):
102106
continue
103107

104108
# Append it
105-
out.append((getattr(mod, k), k))
109+
out.append((val, k))
106110
maxlen = max(len(k), maxlen)
107111

108112
# Output all matching constants

0 commit comments

Comments
 (0)