@@ -129,6 +129,7 @@ def normalize_writes(writes):
129
129
such that all values are raw bytes and consecutive writes are merged to a single key.
130
130
131
131
Examples:
132
+
132
133
>>> context.clear(endian="little", bits=32)
133
134
>>> normalize_writes({0x0: [p32(0xdeadbeef)], 0x4: p32(0xf00dface), 0x10: 0x41414141})
134
135
[(0, b'\xef\xbe\xad\xde\xce\xfa\r\xf0'), (16, b'AAAA')]
@@ -215,6 +216,7 @@ def compute_padding(self, counter):
215
216
given the current format string write counter (how many bytes have been written until now).
216
217
217
218
Examples:
219
+
218
220
>>> hex(pwnlib.fmtstr.AtomWrite(0x0, 0x2, 0x2345).compute_padding(0x1111))
219
221
'0x1234'
220
222
>>> hex(pwnlib.fmtstr.AtomWrite(0x0, 0x2, 0xaa00).compute_padding(0xaabb))
@@ -246,6 +248,7 @@ def union(self, other):
246
248
Combine adjacent writes into a single write.
247
249
248
250
Example:
251
+
249
252
>>> context.clear(endian = "little")
250
253
>>> pwnlib.fmtstr.AtomWrite(0x0, 0x1, 0x1, 0xff).union(pwnlib.fmtstr.AtomWrite(0x1, 0x1, 0x2, 0x77))
251
254
AtomWrite(start=0, size=2, integer=0x201, mask=0x77ff)
@@ -285,11 +288,13 @@ def make_atoms_simple(address, data, badbytes=frozenset()):
285
288
286
289
This function is simple and does not try to minimize the number of atoms. For example, if there are no
287
290
bad bytes, it simply returns one atom for each byte:
291
+
288
292
>>> pwnlib.fmtstr.make_atoms_simple(0x0, b"abc", set())
289
293
[AtomWrite(start=0, size=1, integer=0x61, mask=0xff), AtomWrite(start=1, size=1, integer=0x62, mask=0xff), AtomWrite(start=2, size=1, integer=0x63, mask=0xff)]
290
294
291
295
If there are bad bytes, it will try to bypass by skipping addresses containing bad bytes, otherwise a
292
296
RuntimeError will be raised:
297
+
293
298
>>> pwnlib.fmtstr.make_atoms_simple(0x61, b'abc', b'\x62 ')
294
299
[AtomWrite(start=97, size=2, integer=0x6261, mask=0xffff), AtomWrite(start=99, size=1, integer=0x63, mask=0xff)]
295
300
>>> pwnlib.fmtstr.make_atoms_simple(0x61, b'a'*0x10, b'\x62 \x63 \x64 \x65 \x66 \x67 \x68 ')
@@ -325,6 +330,7 @@ def merge_atoms_writesize(atoms, maxsize):
325
330
This function simply merges adjacent atoms as long as the merged atom's size is not larger than ``maxsize``.
326
331
327
332
Examples:
333
+
328
334
>>> from pwnlib.fmtstr import *
329
335
>>> merge_atoms_writesize([AtomWrite(0, 1, 1), AtomWrite(1, 1, 1), AtomWrite(2, 1, 2)], 2)
330
336
[AtomWrite(start=0, size=2, integer=0x101, mask=0xffff), AtomWrite(start=2, size=1, integer=0x2, mask=0xff)]
@@ -364,6 +370,7 @@ def find_min_hamming_in_range_step(prev, step, carry, strict):
364
370
A tuple (score, value, mask) where score equals the number of matching bytes between the returned value and target.
365
371
366
372
Examples:
373
+
367
374
>>> initial = {(0,0): (0,0,0), (0,1): None, (1,0): None, (1,1): None}
368
375
>>> pwnlib.fmtstr.find_min_hamming_in_range_step(initial, (0, 0xFF, 0x1), 0, 0)
369
376
(1, 1, 255)
@@ -419,6 +426,7 @@ def find_min_hamming_in_range(maxbytes, lower, upper, target):
419
426
target(int): the target value that should be approximated
420
427
421
428
Examples:
429
+
422
430
>>> pp = lambda svm: (svm[0], hex(svm[1]), hex(svm[2]))
423
431
>>> pp(pwnlib.fmtstr.find_min_hamming_in_range(1, 0x0, 0x100, 0xaa))
424
432
(1, '0xaa', '0xff')
@@ -470,6 +478,7 @@ def merge_atoms_overlapping(atoms, sz, szmax, numbwritten, overflows):
470
478
overflows(int): how many extra overflows (of size sz) to tolerate to reduce the number of atoms
471
479
472
480
Examples:
481
+
473
482
>>> from pwnlib.fmtstr import *
474
483
>>> merge_atoms_overlapping([AtomWrite(0, 1, 1), AtomWrite(1, 1, 1)], 2, 8, 0, 1)
475
484
[AtomWrite(start=0, size=2, integer=0x101, mask=0xffff)]
@@ -557,13 +566,15 @@ def overlapping_atoms(atoms):
557
566
Finds pairs of atoms that write to the same address.
558
567
559
568
Basic examples:
569
+
560
570
>>> from pwnlib.fmtstr import *
561
571
>>> list(overlapping_atoms([AtomWrite(0, 2, 0), AtomWrite(2, 10, 1)])) # no overlaps
562
572
[]
563
573
>>> list(overlapping_atoms([AtomWrite(0, 2, 0), AtomWrite(1, 2, 1)])) # single overlap
564
574
[(AtomWrite(start=0, size=2, integer=0x0, mask=0xffff), AtomWrite(start=1, size=2, integer=0x1, mask=0xffff))]
565
575
566
576
When there are transitive overlaps, only the largest overlap is returned. For example:
577
+
567
578
>>> list(overlapping_atoms([AtomWrite(0, 3, 0), AtomWrite(1, 4, 1), AtomWrite(2, 4, 1)]))
568
579
[(AtomWrite(start=0, size=3, integer=0x0, mask=0xffffff), AtomWrite(start=1, size=4, integer=0x1, mask=0xffffffff)), (AtomWrite(start=1, size=4, integer=0x1, mask=0xffffffff), AtomWrite(start=2, size=4, integer=0x1, mask=0xffffffff))]
569
580
@@ -629,6 +640,7 @@ def sort_atoms(atoms, numbwritten):
629
640
numbwritten(int): the value at which the counter starts
630
641
631
642
Examples:
643
+
632
644
>>> from pwnlib.fmtstr import *
633
645
>>> sort_atoms([AtomWrite(0, 1, 0xff), AtomWrite(1, 1, 0xfe)], 0) # the example described above
634
646
[AtomWrite(start=1, size=1, integer=0xfe, mask=0xff), AtomWrite(start=0, size=1, integer=0xff, mask=0xff)]
@@ -694,6 +706,7 @@ def make_payload_dollar(data_offset, atoms, numbwritten=0, countersize=4, no_dol
694
706
no_dollars(bool) : flag to generete the payload with or w/o $ notation
695
707
696
708
Examples:
709
+
697
710
>>> pwnlib.fmtstr.make_payload_dollar(1, [pwnlib.fmtstr.AtomWrite(0x0, 0x1, 0xff)])
698
711
(b'%255c%1$hhn', b'\x00\x00\x00\x00')
699
712
'''
@@ -840,6 +853,7 @@ def fmtstr_payload(offset, writes, numbwritten=0, write_size='byte', write_size_
840
853
The payload in order to do needed writes
841
854
842
855
Examples:
856
+
843
857
>>> context.clear(arch = 'amd64')
844
858
>>> fmtstr_payload(1, {0x0: 0x1337babe}, write_size='int')
845
859
b'%322419390c%4$llnaaaabaa\x00\x00\x00\x00\x00\x00\x00\x00'
0 commit comments