Repository: Gallopsled/pwntools

Issue:
shellcraft: mips syscall with 6 arguments ignores arg4 and arg5
When trying to call a syscall with more than 4 arguments, the excess arguments are silently ignored instead of pushing them to the stack.

```asm
$ shellcraft -f asm mips.linux.syscall SYS_sendto 3 0x123456 0x100 0 0xabcdefff 0x10
    /* call sendto(3, 0x123456, 0x100, 0, 0xabcdefff, 0x10) */
    li $t9, ~3
    not $a0, $t9
    li $t9, ~0x123456
    not $a1, $t9
    li $t9, ~0x100
    not $a2, $t9
    slti $a3, $zero, 0xFFFF /* $a3 = 0 */
    ori $v0, $zero, SYS_sendto
    syscall 0x40404
```

The expected output would include the last two arguments on the stack:

```asm
/* call sendto(3, 0x123456, 0x100, 0, 0xabcdefff, 0x10) */
addiu $sp, $sp, -0x18
li $v0, 0xabcdefff
sw $v0, 0x10($sp)
li $t9, ~0x10
not $v0, $t9
sw $v0, 0x14($sp)

li $t9, ~3
not $a0, $t9
li $t9, ~0x123456
not $a1, $t9
li $t9, ~0x100
not $a2, $t9
slti $a3, $zero, 0xFFFF /* $a3 = 0 */
/* call sendto() */
ori $v0, $zero, SYS_sendto
syscall 0x40404
```
shellcraft: mips syscall with 6 arguments ignores arg4 and arg5
When trying to call a syscall with more than 4 arguments, the excess arguments are silently ignored instead of pushing them to the stack.

```asm
$ shellcraft -f asm mips.linux.syscall SYS_sendto 3 0x123456 0x100 0 0xabcdefff 0x10
    /* call sendto(3, 0x123456, 0x100, 0, 0xabcdefff, 0x10) */
    li $t9, ~3
    not $a0, $t9
    li $t9, ~0x123456
    not $a1, $t9
    li $t9, ~0x100
    not $a2, $t9
    slti $a3, $zero, 0xFFFF /* $a3 = 0 */
    ori $v0, $zero, SYS_sendto
    syscall 0x40404
```

The expected output would include the last two arguments on the stack:

```asm
/* call sendto(3, 0x123456, 0x100, 0, 0xabcdefff, 0x10) */
addiu $sp, $sp, -0x18
li $v0, 0xabcdefff
sw $v0, 0x10($sp)
li $t9, ~0x10
not $v0, $t9
sw $v0, 0x14($sp)

li $t9, ~3
not $a0, $t9
li $t9, ~0x123456
not $a1, $t9
li $t9, ~0x100
not $a2, $t9
slti $a3, $zero, 0xFFFF /* $a3 = 0 */
/* call sendto() */
ori $v0, $zero, SYS_sendto
syscall 0x40404
```


Discussion:
Sure, mind submitting a PR? the generic syscall template should have the pushing functionality already, well, using the pwntools.abi should be better, but IDK, I did not look into this module's code for a year now.
Sure, mind submitting a PR? the generic syscall template should have the pushing functionality already, well, using the pwntools.abi should be better, but IDK, I did not look into this module's code for a year now.

Resolving patch:
diff --git a/pwnlib/data/syscalls/generate.py b/pwnlib/data/syscalls/generate.py
--- a/pwnlib/data/syscalls/generate.py
+++ b/pwnlib/data/syscalls/generate.py
@@ -72,7 +72,7 @@
                 target = regs[index]
                 register_arguments[target] = arg
             elif arg is not None:
-                stack_arguments[index] = arg
+                stack_arguments[name] = arg
 
         # The argument is not a register.  It is a string value, and we
         # are expecting a string value
@@ -100,7 +100,7 @@
                 target = regs[index]
                 register_arguments[target] = arg
             elif arg is not None:
-                stack_arguments[target] = arg
+                stack_arguments[name] = arg
 
     # Some syscalls have different names on various architectures.
     # Determine which syscall number to use for the current architecture.
@@ -108,7 +108,7 @@
         if hasattr(pwnlib.constants, syscall):
             break
     else:
-        raise Exception("Could not locate any syscalls: %r" % syscalls)
+        raise Exception("Could not locate any syscalls: %r" % {syscalls!r})
 %>
     /* {name}(${{', '.join(syscall_repr)}}) */
 %for name, arg in string_arguments.items():
@@ -249,7 +249,7 @@ def generate_one(target):
             # Mako is unable to use *vararg and *kwarg, so we just stub in
             # a whole bunch of additional arguments.
             if argname == 'vararg':
-                for j in range(5):
+                for j in range(6):
                     argname = 'vararg_%i' % j
                     argument_names.append(argname)
                     argument_names_.append(argname)


Test patch: