1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef HOOK_MANAGER_H
17 #define HOOK_MANAGER_H
18 
19 #include <map>
20 #include <memory>
21 #include <string>
22 #include <vector>
23 
24 #include "buffer_writer.h"
25 #include "manager_interface.h"
26 #include "epoll_event_poller.h"
27 #include "share_memory_allocator.h"
28 #include "event_notifier.h"
29 #include "native_hook_config.pb.h"
30 #include "native_hook_result.pb.h"
31 #include "virtual_runtime.h"
32 #include "stack_data_repeater.h"
33 #include "stack_preprocess.h"
34 #include "native_memory_profiler_sa_config.h"
35 #include "writer_adapter.h"
36 
37 using BatchNativeHookDataPtr = STD_PTR(shared, BatchNativeHookData);
38 class ProfilerPluginConfig;
39 class PluginResult;
40 class CommandPoller;
41 
42 struct HookContext {
43     int type;
44     pid_t pid;
45     pid_t tid;
46     void* addr;
47     uint32_t mallocSize;
48 };
49 
50 struct NmdParam {
51     uint32_t fd = 0;
52     uint32_t type = -1;
53 };
54 
55 namespace OHOS::Developtools::NativeDaemon {
56 class HookService;
57 class HookManager : public ManagerInterface, public std::enable_shared_from_this<HookManager> {
58 public:
59     struct HookManagerCtx {
HookManagerCtxOHOS::Developtools::NativeDaemon::HookManager::HookManagerCtx60         HookManagerCtx(int32_t pid) : pid(pid) {}
HookManagerCtxOHOS::Developtools::NativeDaemon::HookManager::HookManagerCtx61         HookManagerCtx(const std::string& name) : processName(name) {}
~HookManagerCtxOHOS::Developtools::NativeDaemon::HookManager::HookManagerCtx62         ~HookManagerCtx() {}
63         int32_t pid = -1;
64         std::string processName;
65         std::string smbName;
66         std::shared_ptr<ShareMemoryBlock> shareMemoryBlock = nullptr;
67         std::shared_ptr<EventNotifier> eventNotifier = nullptr;
68         std::unique_ptr<EpollEventPoller> eventPoller = nullptr;
69         std::shared_ptr<StackDataRepeater> stackData = nullptr;
70         std::shared_ptr<StackPreprocess> stackPreprocess = nullptr;
71         bool isRecordAccurately = false;
72         std::array<std::shared_ptr<StackDataRepeater::RawStack>, CACHE_ARRAY_SIZE> rawDataArray = {};
73         uint32_t rawStackCount = 0;
74         void FlushStackArray();
75     };
76     HookManager() = default;
77     ~HookManager();
78     bool RegisterAgentPlugin(const std::string& pluginPath);
79     bool UnregisterAgentPlugin(const std::string& pluginPath);
80 
81     bool LoadPlugin(const std::string& pluginPath) override;
82     bool UnloadPlugin(const std::string& pluginPath) override;
83     bool UnloadPlugin(const uint32_t pluginId) override;
84 
85     // CommandPoller will call the following four interfaces after receiving the command
86     bool CreatePluginSession(const std::vector<ProfilerPluginConfig>& config) override;
87     bool DestroyPluginSession(const std::vector<uint32_t>& pluginIds) override;
88     bool StartPluginSession(const std::vector<uint32_t>& pluginIds,
89                             const std::vector<ProfilerPluginConfig>& config, PluginResult& result) override;
90     bool StopPluginSession(const std::vector<uint32_t>& pluginIds) override;
91     bool ReportPluginBasicData(const std::vector<uint32_t>& pluginIds) override;
92 
93     bool CreateWriter(std::string pluginName, uint32_t bufferSize, int smbFd, int eventFd,
94                         bool isProtobufSerialize = true) override;
95     bool ResetWriter(uint32_t pluginId) override;
96     void SetCommandPoller(const std::shared_ptr<CommandPoller>& p) override;
97     void ResetStartupParam();
98     void SethookStandalone(bool);
99     bool HandleHookContext(const std::shared_ptr<HookManagerCtx>& ctx);
100     void StartPluginSession();
101     void ReadShareMemory(const std::shared_ptr<HookManagerCtx>& hookCtx);
102     void SetHookConfig(const NativeHookConfig& hookConfig);
103     void SetHookConfig(const std::shared_ptr<NativeMemoryProfilerSaConfig>& config);
104     int32_t CreatePluginSession();
105     void RegisterWriter(const std::shared_ptr<Writer> writer);
106     void WriteHookConfig();
107     std::pair<int, int> GetFds(int32_t pid, const std::string& name);
SetSaServiceConfig(bool saFlag, bool isProtobufSerialize)108     inline void SetSaServiceConfig(bool saFlag, bool isProtobufSerialize)
109     {
110         isSaService_ = saFlag;
111         isProtobufSerialize_ = isProtobufSerialize;
112     }
113     void GetClientConfig(ClientConfig& clientConfig);
GetNoDataQueueFlag()114     bool GetNoDataQueueFlag()
115     {
116         return noDataQueue_;
117     }
SetPid(int pid)118     void SetPid(int pid)
119     {
120         pid_ = pid;
121     }
GetPid()122     int GetPid()
123     {
124         return pid_;
125     }
SetSaMode(bool saMode)126     void SetSaMode(bool saMode)
127     {
128         saMode_ = saMode;
129     }
130     void SetNmdInfo(std::pair<uint32_t, uint32_t>);
131     void FlushRawStackArray(const std::shared_ptr<HookManagerCtx>& hookCtx,
132                             std::shared_ptr<StackDataRepeater::RawStack>& rawStack);
133 
134 private:
135     int pid_ = -1; // for SA mode
136     bool printMallocNmd_ = false;
137     bool saMode_ = false;
138     bool CheckProcess();
139     bool CheckProcessName();
140     void CheckHapEncryped();
141     void SetHookData(HookContext& hookContext, struct timespec ts,
142         std::vector<OHOS::Developtools::NativeDaemon::CallFrame>& callFrames,
143         BatchNativeHookDataPtr& batchNativeHookData);
144     void CreateWriter();
145 
146     std::shared_ptr<HookService> hookService_;
147     std::shared_ptr<CommandPoller> commandPoller_;
148     int agentIndex_ = -1;
149     std::string agentPluginName_;
150     NativeHookConfig hookConfig_;
151     std::unique_ptr<uint8_t[]> buffer_;
152     bool isHookStandalone_ {false};
153     FILE* fpHookData_ {nullptr};
154     std::vector<std::shared_ptr<HookManagerCtx>> hookCtx_;
155     bool isSaService_{false};
156     bool noDataQueue_{false};
157     std::shared_ptr<WriterAdapter> writerAdapter_{nullptr};
158     bool isProtobufSerialize_{true};
159     std::shared_ptr<Writer> writer_{nullptr};
160     constexpr static uint32_t MAX_BUFFER_SIZE = 100 * 1024 * 1024;
161     uint64_t shareMemorySize_{MAX_BUFFER_SIZE};
162     NmdParam nmdParamInfo_;
163 };
164 }
165 #endif // AGENT_MANAGER_H