1 /* 2 * Copyright 2023, Trung Nguyen, trungnt282910@gmail.com. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <string.h> 8 9 #include <AutoDeleter.h> 10 11 #include "strace.h" 12 #include "Context.h" 13 #include "MemoryReader.h" 14 #include "TypeHandler.h" 15 16 17 using BPrivate::AutoDeleter; 18 19 20 class FlatArgsTypeHandler : public TypeHandler { 21 public: 22 string GetParameterValue(Context &context, Parameter *param, 23 const void *address) 24 { 25 size_t flatArgsSize; 26 int32 argCount, envCount; 27 char *flatArgs, *flatArgsEnd; 28 int32 bytesRead; 29 status_t err; 30 ArrayDeleter<char> flatArgsDeleter; 31 string r; 32 33 if (!context.GetContents(Context::COMPLEX_STRUCTS)) 34 goto fallback; 35 36 param = context.GetNextSibling(param); 37 if (param == NULL) 38 goto fallback; 39 flatArgsSize = context.ReadValue<size_t>(param); 40 41 param = context.GetNextSibling(param); 42 if (param == NULL) 43 goto fallback; 44 argCount = context.ReadValue<int32>(param); 45 46 param = context.GetNextSibling(param); 47 if (param == NULL) 48 goto fallback; 49 envCount = context.ReadValue<int32>(param); 50 51 flatArgs = new (std::nothrow) char[flatArgsSize + 1]; 52 if (flatArgs == NULL) 53 goto fallback; 54 55 flatArgsDeleter.SetTo(flatArgs); 56 57 // Guard with a null byte to prevent faulty buffers. 58 flatArgsEnd = flatArgs + flatArgsSize; 59 *flatArgsEnd = '\0'; 60 61 err = context.Reader().Read(*(void **)address, flatArgs, flatArgsSize, 62 bytesRead); 63 if (err != B_OK) 64 goto fallback; 65 66 flatArgs += sizeof(void *) * (argCount + envCount + 2); 67 68 r = "{args = ["; 69 70 for (int32 i = 0; i < argCount && flatArgs < flatArgsEnd; i++) { 71 if (i > 0) 72 r += ", "; 73 size_t currentLen = strlen(flatArgs); 74 r += "\""; 75 r += flatArgs; 76 r += "\""; 77 flatArgs += currentLen + 1; 78 } 79 80 r += "], env = ["; 81 82 for (int32 i = 0; i < envCount && flatArgs < flatArgsEnd; i++) { 83 if (i > 0) 84 r += ", "; 85 size_t currentLen = strlen(flatArgs); 86 r += "\""; 87 r += flatArgs; 88 r += "\""; 89 flatArgs += currentLen + 1; 90 } 91 92 r += "]}"; 93 94 return r; 95 fallback: 96 return context.FormatPointer(address); 97 } 98 99 string GetReturnValue(Context &context, uint64 value) 100 { 101 return context.FormatPointer((void *)value); 102 } 103 }; 104 105 106 void 107 patch_exec() 108 { 109 Syscall *exec = get_syscall("_kern_exec"); 110 exec->GetParameter("flatArgs")->SetHandler(new FlatArgsTypeHandler()); 111 112 Syscall *load_image = get_syscall("_kern_load_image"); 113 load_image->GetParameter("flatArgs")->SetHandler(new FlatArgsTypeHandler()); 114 } 115