Skip to content

Commit 61f3a62

Browse files
committed
test: exercise strict W^X runtime paths
1 parent 089cff0 commit 61f3a62

3 files changed

Lines changed: 38 additions & 3 deletions

File tree

scripts/android_smoke.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def analyze_proc_maps(text: str) -> dict[str, int]:
113113
report["executable"] += 1
114114
if permissions.startswith("rwx"):
115115
report["rwx"] += 1
116-
if not path or path.startswith("[anon:"):
116+
if not path or path.startswith("["):
117117
report["anonymous_rwx"] += 1
118118
if "(deleted)" in path:
119119
report["deleted_executable"] += 1

test_comprehensive.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,38 @@ setTimeout(function () {
8989
fail('agent export lookup failed', error);
9090
}
9191

92+
// 5. Native hook execution (exercises Gum's executable-code allocator).
93+
var getpidListener = null;
94+
try {
95+
var getpidAddress = Module.findGlobalExportByName('getpid');
96+
if (getpidAddress === null) {
97+
fail('getpid export unavailable');
98+
} else {
99+
var getpidObserved = false;
100+
getpidListener = Interceptor.attach(getpidAddress, {
101+
onEnter() {
102+
getpidObserved = true;
103+
}
104+
});
105+
Interceptor.flush();
106+
107+
var getpid = new NativeFunction(getpidAddress, 'int', []);
108+
var observedPid = getpid();
109+
if (!getpidObserved) {
110+
fail('native getpid hook did not execute');
111+
}
112+
if (observedPid !== Process.id) {
113+
fail('native getpid returned unexpected pid', observedPid);
114+
}
115+
}
116+
} catch (error) {
117+
fail('native hook acceptance failed', error);
118+
} finally {
119+
if (getpidListener !== null) {
120+
getpidListener.detach();
121+
}
122+
}
123+
92124
if (!javaAvailable) {
93125
fail('Java bridge unavailable');
94126
finish();

tests/test_android_smoke.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ def test_proc_maps_report_distinguishes_anonymous_rwx_from_art_jit() -> None:
6464
}
6565

6666

67-
def test_proc_maps_report_treats_named_anon_rwx_as_anonymous() -> None:
68-
report = android_smoke.analyze_proc_maps("7000-8000 rwxp 00000000 00:00 0 [anon:gum-code]\n")
67+
@pytest.mark.parametrize("path", ["[anon:gum-code]", "[stack]"])
68+
def test_proc_maps_report_treats_bracketed_rwx_as_anonymous(path: str) -> None:
69+
report = android_smoke.analyze_proc_maps(f"7000-8000 rwxp 00000000 00:00 0 {path}\n")
6970

7071
assert report["anonymous_rwx"] == 1
7172

@@ -636,6 +637,8 @@ def test_acceptance_agent_uses_frida_17_file_and_java_wrapper_apis() -> None:
636637
assert "Java.cast(iterator.next(), Thread).getName()" in source
637638
assert "rpc.exports" in source
638639
assert "add(left, right)" in source
640+
assert "Interceptor.attach" in source
641+
assert "new NativeFunction" in source
639642

640643

641644
def test_report_writer_omits_device_serial(tmp_path: Path) -> None:

0 commit comments

Comments
 (0)