tamatoa
tamatoa copied to clipboard
Patching Commandline Arguments
+------------------------+ | Describe Your Question | +------------------------+
Hello,
I was wondering if there was a way we could patch command line arguments in the shellcode during the make process. I'm not very knowledgeable in assembly but would love to help with this if you could point me in the right direction!
Here is how to implement argument handling step by step:
- Get the total size of the argv
- Mmap a new section with that size
- Copy that much from argv to the mmap section
- Store the resulting pointer to the mmap section and the argc in registers that get passed all the way into the program
- Munmap the section after the execution
I will take a look at implementing this.
I have pushed an update to implement this.
To make with arguments: make all -- argv0 argv1 argv2 ...
Let me know if you have any questions.
Finally got some time to testing this.
So I have a simple Mach-O that prints the arguments using CommandLine.arguments in Swift.
When I use make with the command line arguments, I get the command line arguments of the current program. Is this expected? Could I somehow get the command line arguments that I passed into make?
Hmm, my guess is that swift is reading the arguments from the process address space. The following code from Stack Overflow worked for me:
import Foundation
print("Hello.")
let argc = CommandLine.argc
let argv = UnsafeMutableRawPointer(CommandLine.unsafeArgv).bindMemory(to: UnsafeMutablePointer<Int8>.self, capacity: Int(CommandLine.argc))
NSLog("ARGC: %i", argc);
NSLog("ARGV[0]: %s", argv[0]);
NSLog("ARGV[1]: %s", argv[1]);
Yep, that works for me as well. But is it possible for tamatoa to take in "arg1" and "arg2" during the make phase?
For example, could we pass in "arg1" and "arg2" and have those be used within the Mach-O being loaded in-memory?
Let me know if my question doesn't make sense, I may not be wording it well!
Your question does make sense.
I used Ghidra to analyze the swift macho. The entrypoint does not take any arguments. (entry(void)
vs _main(int argc, char *argv[]
)
I will have to copy the argc and argv to the pointers that swift retrieves them from.
The following C program will work:
#include <stdio.h>
int main (int argc, char *argv[])
{
int count;
for (count=0; count<argc; count++)
puts (argv[count]);
}
You can keep this issue open.
I've been messing with patching arguments for in-memory loading as well. Got it working for C/ObjC with the method you mentioned above ^ If you figure it out on macOS, I'd love to see how you did it to try and recreate :D
Thank you for reviewing and helping out with development. This project has been lots of fun and I would enjoy a quick chat to share context on my interests. See email.
Thank you for reviewing and helping out with development. This project has been lots of fun and I would enjoy a quick chat to share context on my interests. See email.
I can hardly call my debugging efforts "helping out with development", but you're welcome! Did you send me an e-mail? You can contact me at [email protected] or on Twitter @slyd0g :D
Well, the email I sent to [email protected] bounced. So I sent an email to [email protected]. Sorry, I don't use Twitter. Is there a different email I can contact you at?
Awesome work @usiegl00! I just saw your blogpost and wanted to test it out. I'm unable to get arguments to work with a Swift Mach-O still. I've also noticed 3 arguments causes the problem to segfault but 2 does not
Try make swift
, I am looking to improve the build system in the future.
I will take a look at the argument patcher to see why 3 arguments cause it to crash.
make swift
works with 1 argument but doesn't appear to work with more than 1