Skip to content

Commit 276eb63

Browse files
docs: switch Chinese comments to English comments and add jni_trace comments
1 parent 7fa4f6e commit 276eb63

21 files changed

+251
-167
lines changed

fakelinker-test/src/main/cpp/test/test_fakelinker.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ TEST(FakeLinker, namespaceTest) {
224224
EXPECT_EQ(g_fakelinker_export.android_namespace_add_ld_library_path(thiz_np, "/data/local/add_ld_library"),
225225
FakeLinkerError::kErrorNo)
226226
<< "android_namespace_add_ld_library_path";
227-
// 目前还不能修改 default_library permitted_library
227+
// Currently unable to modify default_library and permitted_library
228228
EXPECT_EQ(g_fakelinker_export.android_namespace_add_default_library_path(thiz_np, "data/local/add_default_library"),
229229
FakeLinkerError::kErrorUnavailable)
230230
<< "android_namespace_add_default_library_path";

library/src/main/cpp/common/maps_util.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ bool MapsHelper::ReadLibraryMap() {
6666
} else if (!FormatLine()) {
6767
break;
6868
}
69-
// 库映射可能是不连续的, 但不会出现交叉
69+
// Library mapping may be discontinuous, but there will be no crossing
7070
if (found_inode != inode_ && inode_ != 0) {
71-
// 严格判断库是否正确, 一个库至少有读执行内存段
71+
// Strictly check if library is correct, a library must have at least read-execute memory segment
7272
if ((protect & (kMPRead | kMPExecute)) == (kMPRead | kMPExecute)) {
7373
break;
7474
} else {
@@ -91,7 +91,7 @@ bool MapsHelper::ReadLibraryMap() {
9191
page_.push_back(page);
9292
}
9393
if (page_.empty()) {
94-
// 文件已读取完
94+
// File has been read completely
9595
return true;
9696
}
9797
return VerifyLibraryMap();
@@ -300,9 +300,9 @@ bool MapsHelper::FormatLine() {
300300
if (num == 5) {
301301
path_[0] = '\0';
302302
}
303-
// 验证权限字符串是否有效
303+
// Verify if permission string is valid
304304
if (FormatProtect() == kMPInvalid) {
305-
// 由于maps文件常常改变,有可能读取到无效类型
305+
// Since maps file changes frequently, invalid types may be read
306306
return false;
307307
}
308308
return num == 6 || num == 5;
@@ -371,12 +371,12 @@ bool MapsHelper::MakeLibraryName(const char *library_name) {
371371
}
372372

373373
/**
374-
* @brief 验证一个库的有效映射是包含 可执行段
374+
* @brief Verify that a library's valid mapping contains executable segments
375375
*
376376
*/
377377
bool MapsHelper::VerifyLibraryMap() {
378378
for (auto &page : page_) {
379-
// 模拟器下查找arm库没有可执行权限
379+
// ARM libraries found under emulator have no executable permissions
380380
if ((page.old_protect & (kMPExecute | kMPWrite)) != 0) {
381381
return true;
382382
}

library/src/main/cpp/include/fakelinker/art_symbol.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class DamagedRuntime {
4545
ANDROID_GE_R std::unique_ptr<void *> jni_id_manager_;
4646
std::unique_ptr<JavaVMExt> java_vm_;
4747

48-
// Runtime 类中的偏移,使用前应设置
48+
// Offset in Runtime class, should be set before use
4949
static size_t jvm_offset_;
5050
};
5151

library/src/main/cpp/include/fakelinker/elf_reader.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ class MapsHelper;
2525

2626
struct ElfDiskInfo {
2727
Address section_strtab_offset;
28-
Address section_strtab_addr = 0; // 实际内存中的地址
29-
uintptr_t section_strtab_size; // 节区大小
28+
Address section_strtab_addr = 0; // Actual address in memory
29+
uintptr_t section_strtab_size; // Section size
3030
uintptr_t str_addralign;
3131

3232
Address section_symtab_offset;
@@ -60,7 +60,7 @@ class ElfReader {
6060
bool Load(address_space_params *address_space);
6161
bool LoadFromMemory(const char *name);
6262
bool LoadFromDisk(const char *library_name);
63-
// 缓存内部符号,加速查找
63+
// Cache internal symbols to accelerate lookup
6464
bool CacheInternalSymbols();
6565
bool DecompressDebugData();
6666

@@ -103,12 +103,15 @@ class ElfReader {
103103
uint64_t FindInternalSymbolByPrefix(std::string_view prefix);
104104

105105
/**
106-
* 查找内部符号地址,可支持正则表达式,正则表达式使用默认 std::regex 因此需要调用者保证正则表达式合法,
107-
* 注意: 虽然支持正则表达式但也优先匹配符号名称,这是方便完全符号匹配与正则匹配一起查找,避免多次遍历符号表
106+
* Find internal symbol addresses, supports regular expressions. Regular expressions use default std::regex
107+
* so callers must ensure regex expressions are valid.
108+
* Note: Although regex is supported, symbol names are matched first for convenience of exact symbol
109+
* matching and regex matching together, avoiding multiple traversals of the symbol table.
108110
*
109-
* @param symbols 查找的内部符号名称或正则表达式集合,保证非空避免查找整个符号表
110-
* @param useRegex 开启正则匹配支持
111-
* @return 返回地址集合,找到则对应地址非0
111+
* @param symbols Collection of internal symbol names or regex expressions to find, ensure non-empty to avoid
112+
* searching entire symbol table
113+
* @param useRegex Enable regex matching support
114+
* @return Return address collection, found addresses are non-zero
112115
*/
113116
std::vector<Address> FindInternalSymbols(const std::vector<std::string> &symbols, bool useRegex = false);
114117

@@ -175,7 +178,7 @@ class ElfReader {
175178
// Size in bytes of the gap mapping.
176179
size_t gap_size_;
177180
// Load bias.
178-
// 库加载基址,通常就是 load_start_ 因为第一个页通常虚拟地址为0
181+
// Library load base address, usually same as load_start_ because first page typically has virtual address 0
179182
ElfW(Addr) load_bias_;
180183

181184
// Loaded phdr.

library/src/main/cpp/include/fakelinker/fake_linker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ typedef void *(*DlsymFun)(void *handle, const char *symbol_name, void *caller_ad
136136

137137
ANDROID_GE_N enum NamespaceFindType {
138138
kNPOriginal, /**< It is already a namespace, do not query */
139-
kNPSoinfo, /**< Specifiy the namespace in which soinfo looks for it */
139+
kNPSoinfo, /**< Specify the namespace in which soinfo looks for it */
140140
kNPNamespaceName, /**< Find the namespace with the specified name */
141141
};
142142

library/src/main/cpp/include/fakelinker/maps_util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ enum MapsProt {
2626
kMPRead = PROT_READ,
2727
kMPWrite = PROT_WRITE,
2828
kMPExecute = PROT_EXEC,
29-
// mman.h 中不同
29+
// Different from mman.h
3030
kMPShared = 8,
3131
kMPPrivate = 16,
3232
kMPReadWrite = kMPRead | kMPWrite,

library/src/main/cpp/include/fakelinker/symbol_resolver.h

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ namespace fakelinker {
88
class SymbolResolver {
99
public:
1010
struct SymbolResult {
11-
// 解析的库/地方范围的起始地址
11+
// Start address of the resolved library/location range
1212
uintptr_t start;
13-
// 解析的库/地方范围的结束地址
13+
// End address of the resolved library/location range
1414
uintptr_t end;
15-
// 当前地址相对于 start 的偏移
15+
// Offset of the current address relative to start
1616
uintptr_t offset = UINTPTR_MAX;
17-
// 库名称
17+
// Library name
1818
const char *name;
1919
};
2020

@@ -23,26 +23,26 @@ class SymbolResolver {
2323
bool AddAddressRange(const std::string &name, uintptr_t start, uintptr_t end);
2424

2525
/**
26-
* @brief 格式化地址如下:
27-
* head 地址 [库名!偏移]
26+
* @brief Format address as follows:
27+
* head address [library_name!offset]
2828
*
29-
* @param address 待格式化地址
30-
* @param default_format 如果不再监控范围内是否格式化为 head 地址
31-
* @param head 添加指定头
29+
* @param address Address to be formatted
30+
* @param default_format Whether to format as head address if not in monitoring range
31+
* @param head Add specified header
3232
* @return std::string
3333
*/
3434
std::string FormatAddress(uintptr_t address, bool default_format, const std::string &head = "");
3535

3636
/**
37-
* @brief 指定buffer处格式化地址,避免内存拷贝
37+
* @brief Format address at specified buffer location to avoid memory copying
3838
*
39-
* @param buffer 指定缓冲区
40-
* @param max_length 最大缓冲区大小
41-
* @param address 待格式化的地址
42-
* @param default_format 如果不再监控范围内是否格式化为 head 地址
43-
* @param head 添加指定头
44-
* @return true 在地址范围内
45-
* @return false 不在地址范围内
39+
* @param buffer Specify the buffer to be written, which will be updated after writing
40+
* @param max_length Maximum buffer size
41+
* @param address Address to be formatted
42+
* @param default_format Whether to format as head address if not in monitoring range
43+
* @param head Add specified header
44+
* @return true Within address range
45+
* @return false Not within address range
4646
*/
4747
bool FormatAddressFromBuffer(char *&buffer, size_t max_length, uintptr_t address, bool default_format,
4848
const std::string &head = "");

library/src/main/cpp/include/fakelinker/trace_jni.h

Lines changed: 85 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,37 @@ struct _is_valid_container<
3030
: std::is_same<typename T::value_type, size_t> {};
3131

3232

33+
/**
34+
* @struct TraceInvokeContext
35+
* @brief Context structure for tracing JNI method invocations.
36+
*
37+
* This structure holds information relevant to a JNI method invocation trace,
38+
* including the JNI environment, caller address, result type, method ID (for
39+
* varargs), and a message buffer for logging or debugging purposes.
40+
*
41+
* Members:
42+
* - env: Pointer to the JNI environment associated with the current thread.
43+
* - caller: Address of the entity invoking the JNI method.
44+
* - result: The result type of the JNI call, if applicable.
45+
* - method: The JNI method ID, used when the method has variable arguments.
46+
* - message: Buffer to store trace or debug messages (up to 4096 characters).
47+
* - message_length: The current length of the message stored in the buffer.
48+
*
49+
* Constructor:
50+
* - Initializes the context with the given result type, JNI environment, and caller address.
51+
* The method ID is initialized to nullptr.
52+
*/
3353
template <typename jtype, bool AllowAccessArgs = true>
3454
struct TraceInvokeContext {
35-
// JNIEnv 对象
55+
// JNIEnv object pointer, note: it contains function pointers after our Hook
3656
JNIEnv *env;
37-
// 调用者的地址
57+
// Caller's address
3858
void *caller;
39-
// 如果有返回值,则是
59+
// JNI call return value
4060
jtype result;
41-
// 当有可变参数 va_list 时则为具体的方法
61+
// Specific method when there are variable arguments va_list
4262
jmethodID method;
43-
// 保存消息
63+
// Store messages
4464
char message[4096];
4565
uint32_t message_length = 0;
4666

@@ -50,9 +70,9 @@ struct TraceInvokeContext {
5070

5171
template <>
5272
struct TraceInvokeContext<void, true> {
53-
// JNIEnv 对象
73+
// JNIEnv object pointer, note: it contains function pointers after our Hook
5474
JNIEnv *env;
55-
// 调用者的地址
75+
// Caller's address
5676
void *caller;
5777
jmethodID method;
5878
char message[4096];
@@ -81,7 +101,7 @@ template <typename Derived>
81101
class BaseTraceJNICallback;
82102

83103
namespace jni_trace {
84-
// 直接申明全局变量避免增加寻址操作
104+
// Directly declare global variables to avoid adding addressing operations
85105
extern JNINativeInterface backup_jni;
86106
extern JNINativeInterface *org_jni;
87107
extern JNINativeInterface hook_jni;
@@ -1160,7 +1180,63 @@ class JNIMonitor {
11601180
DISALLOW_COPY_AND_ASSIGN(JNIMonitor);
11611181
};
11621182

1163-
1183+
/**
1184+
* @class BaseTraceJNICallback
1185+
* @brief A base class for tracing and logging JNI calls in a custom JNIEnv wrapper.
1186+
*
1187+
* This template class provides a comprehensive framework for intercepting, tracing, and logging
1188+
* JNI function calls. It is designed to be inherited by user-defined callback classes, such as
1189+
* DefaultTraceJNICallback, to customize tracing behavior for JNI environments.
1190+
*
1191+
* @tparam Derived The derived callback class implementing custom trace logic.
1192+
*
1193+
* ## Features
1194+
* - Intercepts all major JNI function calls, including method/field access, object creation, array operations, etc.
1195+
* - Formats and logs method/field IDs, arguments, return values, and JNI object types.
1196+
* - Supports strict mode for enhanced safety and validation.
1197+
* - Maintains caches for method and field descriptions to improve performance.
1198+
* - Provides utilities for formatting JNI types, classes, strings, and objects.
1199+
* - Integrates with Android logging via __android_log_print.
1200+
* - Supports registration of trace hooks for a wide range of JNI functions.
1201+
* - Allows derived classes to override trace formatting and logging behavior.
1202+
*
1203+
* ## Usage
1204+
* 1. Inherit from BaseTraceJNICallback in your callback class:
1205+
* @code
1206+
* class DefaultTraceJNICallback : public BaseTraceJNICallback<DefaultTraceJNICallback> {
1207+
* public:
1208+
* explicit DefaultTraceJNICallback(bool strict) : BaseTraceJNICallback(strict) {}
1209+
* };
1210+
* @endcode
1211+
*
1212+
* 2. Instantiate your callback and initialize tracing:
1213+
* @code
1214+
* DefaultTraceJNICallback tracer(true);
1215+
* tracer.InitTrace(env); // env is a pointer to JNIEnv
1216+
* tracer->AddMonitorAddress(0x1000, 0x2000); // Add address to monitor
1217+
* tracer->AddLibraryMonitor("libexample.so", false); // Add library to monitor
1218+
* tracer.DefaultRegister(); // Registers default JNI functions and start tracing
1219+
* @endcode
1220+
*
1221+
* 3. Optionally, use SetStrictMode, SetOriginalEnv, or ClearCache as needed.
1222+
*
1223+
* ## Important Methods
1224+
* - InitTrace(JNIEnv* env): Initializes tracing and hooks JNI functions.
1225+
* - DefaultRegister(): Registers a default set of JNI functions and start tracing.
1226+
* - FormatMethodID/FormatFieldID: Returns human-readable descriptions for method/field IDs.
1227+
* - FormatJNIArguments/FormatReturnValue: Formats and logs JNI call arguments and return values.
1228+
* - TraceLog/TraceLine: Logging utilities for trace output.
1229+
*
1230+
* ## Thread Safety
1231+
* JNI callbacks use independent Context instances to achieve thread safety, but
1232+
* JNIMonitor element addition is not thread-safe. It is recommended to complete
1233+
* adding monitoring addresses before starting the trace.
1234+
*
1235+
* ## Example
1236+
* See DefaultTraceJNICallback in default_trace_jni.h for a minimal implementation.
1237+
*
1238+
* @see DefaultTraceJNICallback
1239+
*/
11641240
template <typename Derived>
11651241
class BaseTraceJNICallback : public HookJNIEnv<Derived> {
11661242
friend class HookJNIEnv<Derived>;

library/src/main/cpp/linker/art/hook_jni_native_interface_impl.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ int HookJniNativeInterfaces(HookJniUnit *items, int len) {
7979
if (item->offset < min || item->offset > max || item->hook_method == nullptr) {
8080
continue;
8181
}
82-
// 这里再判断下是否已经Hook,避免存在多次相同调用陷入死循环
82+
// Check if the method is already hooked to prevent infinite loops from multiple identical calls
8383
target = reinterpret_cast<void **>((char *)original_functions + item->offset);
8484
if (*target == item->hook_method) {
8585
continue;
@@ -241,8 +241,9 @@ static void *GetOriginalNativeFunction(const uintptr_t *art_method) {
241241
}
242242

243243
/*
244-
* 由于手动修改 jni入口点没有加锁,因此尽量做到每次读写
245-
* */
244+
* Since manual modification of JNI entry points is not locked,
245+
* try to achieve atomic read/write operations for each access.
246+
*/
246247
inline static uint32_t GetAccessFlags(const char *art_method) {
247248
return *reinterpret_cast<const uint32_t *>(art_method + access_flags_art_method_offset);
248249
}
@@ -270,7 +271,7 @@ inline static bool HasAccessFlag(char *art_method, uint32_t flag) {
270271
}
271272

272273
inline static bool ClearFastNativeFlag(char *art_method) {
273-
// Android 9.0以上没有判断 FastNative 标志
274+
// Android 9.0+ does not check FastNative flag
274275
return api < __ANDROID_API_P__ && ClearAccessFlag(art_method, kAccFastNative);
275276
}
276277

@@ -322,9 +323,10 @@ int HookJavaNativeFunctions(JNIEnv *env, jclass clazz, HookRegisterNativeUnit *i
322323
if (env->RegisterNatives(clazz, methods, 1) == JNI_OK) {
323324
success++;
324325
/*
325-
* Android 8.0 ,8.1 必须清除 FastNative 标志才能注册成功,所以如果原来包含
326-
* FastNative 标志还得恢复, 否者调用原方法可能会出现问题
327-
* */
326+
* Android 8.0, 8.1 must clear the FastNative flag to register successfully,
327+
* so if it originally contained the FastNative flag, it must be restored,
328+
* otherwise calling the original method may cause problems
329+
*/
328330
if (restore && (api == __ANDROID_API_O__ || api == __ANDROID_API_O_MR1__)) {
329331
AddAccessFlag(reinterpret_cast<char *>(artMethod), kAccFastNative);
330332
}

0 commit comments

Comments
 (0)