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:
GetParameterValue(Context & context,Parameter * param,const void * address)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
GetReturnValue(Context & context,uint64 value)99 string GetReturnValue(Context &context, uint64 value)
100 {
101 return context.FormatPointer((void *)value);
102 }
103 };
104
105
106 void
patch_exec()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