Skip to content

Commit 99f8dc1

Browse files
committed
feat: segfault the app when opening
1 parent dc86c02 commit 99f8dc1

File tree

6 files changed

+372
-121
lines changed

6 files changed

+372
-121
lines changed

app/src/main/cpp/NativeTrack.cpp

+132-64
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,20 @@
44
#include <dlfcn.h>
55
#include <cstring>
66
#include <android/log_macros.h>
7+
#include <bits/timespec.h>
8+
#include "helpers.h"
79

810
extern void *libaudioclient_handle;
911
extern void *libpermission_handle;
1012
extern void *libandroid_runtime_handle;
13+
extern void *libutils_handle;
1114
extern bool initLib(JNIEnv *env);
1215

16+
typedef void*(*ZN7android7RefBaseC2Ev_t)(void* thisptr);
17+
static ZN7android7RefBaseC2Ev_t ZN7android7RefBaseC2Ev = nullptr;
18+
typedef void*(*ZN7android7RefBaseD2Ev_t)(void* thisptr);
19+
static ZN7android7RefBaseD2Ev_t ZN7android7RefBaseD2Ev = nullptr;
20+
#include "aosp_stubs.h"
1321
typedef void*(*ZN7android19parcelForJavaObjectEP7_JNIEnvP8_jobject_t)(_JNIEnv*, _jobject*);
1422
static ZN7android19parcelForJavaObjectEP7_JNIEnvP8_jobject_t ZN7android19parcelForJavaObjectEP7_JNIEnvP8_jobject = nullptr;
1523
typedef int32_t(*ZN7android7content22AttributionSourceState14readFromParcelEPKNS_6ParcelE_t)(void* thisptr, void* parcel);
@@ -18,92 +26,152 @@ typedef void*(*ZN7android10AudioTrackC1ERKNS_7content22AttributionSourceStateE_t
1826
static ZN7android10AudioTrackC1ERKNS_7content22AttributionSourceStateE_t ZN7android10AudioTrackC1ERKNS_7content22AttributionSourceStateE = nullptr;
1927
typedef void*(*ZN7android10AudioTrackC1Ev_t)(void* thisptr);
2028
static ZN7android10AudioTrackC1Ev_t ZN7android10AudioTrackC1Ev = nullptr;
29+
typedef void(*ZNK7android7RefBase9incStrongEPKv_t)(void* thisptr, void* id);
30+
static ZNK7android7RefBase9incStrongEPKv_t ZNK7android7RefBase9incStrongEPKv = nullptr;
31+
typedef void(*ZNK7android7RefBase9decStrongEPKv_t)(void* thisptr, void* id);
32+
static ZNK7android7RefBase9decStrongEPKv_t ZNK7android7RefBase9decStrongEPKv = nullptr;
33+
typedef void*(*ZNK7android7RefBase10createWeakEPKv_t)(void* thisptr, void* id);
34+
static ZNK7android7RefBase10createWeakEPKv_t ZNK7android7RefBase10createWeakEPKv = nullptr;
35+
typedef void(*ZN7android7RefBase12weakref_type7decWeakEPKv_t)(void* thisptr, void* id);
36+
static ZN7android7RefBase12weakref_type7decWeakEPKv_t ZN7android7RefBase12weakref_type7decWeakEPKv = nullptr;
37+
typedef int32_t(*ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi_t)
38+
(void* thisptr, int32_t streamType, uint32_t sampleRate, uint32_t format, uint32_t channelMask, size_t frameCount /* = 0 */, uint32_t flags /* = 0 */, fake_wp callback /* = nullptr */, int32_t notificationFrames /* = 0 */, fake_sp sharedMemory /* = nullptr */, bool threadCanCallJava /* = false */, int32_t audioSessionId /* = 0 */, transfer_type transferType /* = TRANSFER_DEFAULT */, void* offloadInfo /* = nullptr */, void* attributionSource, void* attributes /* = nullptr */, bool doNotReconnect /* = false */, float maxRequiredSpeed /* = 1.0f */, int selectedDeviceId /* = 0 */);
39+
static ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi_t ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi = nullptr;
2140

22-
// last observed AOSP size (arm64) was 1312
23-
#define AUDIO_TRACK_SIZE 5000
24-
// last observed AOSP size (arm64) was 152
25-
#define ATTRIBUTION_SOURCE_SIZE 500
26-
#define FAKE_PTR_SIZE 32
41+
/*class MyCallback : virtual android::AudioTrack::IAudioTrackCallback {
42+
public:
43+
MyCallback() : RefBase() {};
44+
void onUnderrun() override {
45+
ALOGI("MyCallback::onMoreData called");
46+
}
47+
void onMarker(uint32_t markerPosition) override {
48+
ALOGI("MyCallback::onMarker called");
49+
}
50+
void onNewPos(uint32_t newPos) override {
51+
ALOGI("MyCallback::onNewPos called");
52+
}
53+
void onNewIAudioTrack() override {
54+
ALOGI("MyCallback::onNewIAudioTrack called");
55+
}
56+
void onStreamEnd() override {
57+
ALOGI("MyCallback::onStreamEnd called");
58+
}
59+
};*/
2760

28-
// make sure to call RefBase::incStrong on thePtr before giving fake_sp away, and call
29-
// decStrong when you don't need it anymore :)
30-
struct fake_sp {
31-
void* thePtr;
32-
};
33-
// make sure to call RefBase::createWeak(thePtr, <arbitrary unique id>) and save returned pointer
34-
// to refs, then call RefBase::weakref_type::decWeak(refs) when you don't need it anymore
35-
struct fake_wp {
36-
void* thePtr;
37-
void* refs;
61+
struct track_holder {
62+
void* track;
63+
void* callback;
64+
void* ats;
3865
};
3966

67+
extern "C" JNIEXPORT jboolean JNICALL
68+
Java_org_akanework_gramophone_logic_utils_NativeTrack_initDlsym(JNIEnv* env, jobject) {
69+
if (!initLib(env))
70+
return false;
71+
if (android_get_device_api_level() >= 31) {
72+
DLSYM_OR_RETURN(libandroid_runtime, ZN7android19parcelForJavaObjectEP7_JNIEnvP8_jobject, false)
73+
DLSYM_OR_RETURN(libpermission, ZN7android7content22AttributionSourceState14readFromParcelEPKNS_6ParcelE, false)
74+
DLSYM_OR_RETURN(libaudioclient, ZN7android10AudioTrackC1ERKNS_7content22AttributionSourceStateE, false)
75+
} else {
76+
DLSYM_OR_RETURN(libaudioclient, ZN7android10AudioTrackC1Ev, false)
77+
}
78+
DLSYM_OR_RETURN(libutils, ZN7android7RefBaseC2Ev, false)
79+
DLSYM_OR_RETURN(libutils, ZN7android7RefBaseD2Ev, false)
80+
DLSYM_OR_RETURN(libutils, ZNK7android7RefBase9incStrongEPKv, false)
81+
DLSYM_OR_RETURN(libutils, ZNK7android7RefBase9decStrongEPKv, false)
82+
DLSYM_OR_RETURN(libutils, ZNK7android7RefBase10createWeakEPKv, false)
83+
DLSYM_OR_RETURN(libutils, ZN7android7RefBase12weakref_type7decWeakEPKv, false)
84+
// TODO support all 5 gazillion variants of set()
85+
if (ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi == nullptr) {
86+
ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi =
87+
(ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi_t)
88+
dlsym(libaudioclient_handle, "_ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi");
89+
if (ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi == nullptr) {
90+
ALOGE("dlsym returned nullptr for _ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi: %s",
91+
dlerror());
92+
return false;
93+
}
94+
}
95+
return true;
96+
}
97+
4098
extern "C" JNIEXPORT jlong JNICALL
4199
Java_org_akanework_gramophone_logic_utils_NativeTrack_create(
42100
JNIEnv *env, jobject, jobject parcel) {
43-
if (!initLib(env))
44-
return NULL;
45101
auto theTrack = ::operator new(AUDIO_TRACK_SIZE);
46-
memset(theTrack, 0, AUDIO_TRACK_SIZE);
102+
memset(theTrack, 0xdeadbeef, AUDIO_TRACK_SIZE);
103+
auto holder = new track_holder();
47104
if (parcel != nullptr) { // implies SDK >= 31
48-
auto ats = ::operator new(ATTRIBUTION_SOURCE_SIZE);
49-
memset(ats, 0, ATTRIBUTION_SOURCE_SIZE);
50-
if (!ZN7android19parcelForJavaObjectEP7_JNIEnvP8_jobject) {
51-
ZN7android19parcelForJavaObjectEP7_JNIEnvP8_jobject =
52-
(ZN7android19parcelForJavaObjectEP7_JNIEnvP8_jobject_t)
53-
dlsym(libandroid_runtime_handle,"_ZN7android19parcelForJavaObjectEP7_JNIEnvP8_jobject");
54-
if (ZN7android19parcelForJavaObjectEP7_JNIEnvP8_jobject == nullptr) {
55-
ALOGE("dlsym returned nullptr for _ZN7android19parcelForJavaObjectEP7_JNIEnvP8_jobject: %s",
56-
dlerror());
57-
return NULL;
58-
}
59-
}
105+
// I'm too cool to call AttributionSourceState ctor before using it.
60106
auto myParcel = ZN7android19parcelForJavaObjectEP7_JNIEnvP8_jobject(env, parcel);
61107
if (myParcel == nullptr) {
62108
ALOGE("myParcel is NULL");
109+
::operator delete(theTrack);
63110
return NULL;
64111
}
65-
if (!ZN7android7content22AttributionSourceState14readFromParcelEPKNS_6ParcelE) {
66-
ZN7android7content22AttributionSourceState14readFromParcelEPKNS_6ParcelE =
67-
(ZN7android7content22AttributionSourceState14readFromParcelEPKNS_6ParcelE_t)
68-
dlsym(libpermission_handle,"_ZN7android7content22AttributionSourceState14readFromParcelEPKNS_6ParcelE");
69-
if (ZN7android7content22AttributionSourceState14readFromParcelEPKNS_6ParcelE == nullptr) {
70-
ALOGE("dlsym returned nullptr for _ZN7android7content22AttributionSourceState14readFromParcelEPKNS_6ParcelE: %s",
71-
dlerror());
72-
return NULL;
73-
}
74-
}
75-
// I'm too cool to call AttributionSourceState ctor before using it.
112+
auto ats = ::operator new(ATTRIBUTION_SOURCE_SIZE);
113+
memset(ats, 0, ATTRIBUTION_SOURCE_SIZE);
76114
ZN7android7content22AttributionSourceState14readFromParcelEPKNS_6ParcelE(ats, myParcel);
77-
if (!ZN7android10AudioTrackC1ERKNS_7content22AttributionSourceStateE) {
78-
ZN7android10AudioTrackC1ERKNS_7content22AttributionSourceStateE =
79-
(ZN7android10AudioTrackC1ERKNS_7content22AttributionSourceStateE_t)
80-
dlsym(libaudioclient_handle,"_ZN7android10AudioTrackC1ERKNS_7content22AttributionSourceStateE");
81-
if (ZN7android10AudioTrackC1ERKNS_7content22AttributionSourceStateE == nullptr) {
82-
ALOGE("dlsym returned nullptr for _ZN7android10AudioTrackC1ERKNS_7content22AttributionSourceStateE: %s",
83-
dlerror());
84-
return NULL;
85-
}
86-
}
87115
ZN7android10AudioTrackC1ERKNS_7content22AttributionSourceStateE(theTrack, ats);
88-
::operator delete(ats); // copied by AudioTrack ctor
116+
//ZN7android7RefBaseC2Ev(theTrack); // TODO
117+
holder->ats = ats;
89118
} else {
90-
if (!ZN7android10AudioTrackC1Ev) {
91-
ZN7android10AudioTrackC1Ev = (ZN7android10AudioTrackC1Ev_t)
92-
dlsym(libaudioclient_handle,"_ZN7android10AudioTrackC1Ev");
93-
if (ZN7android10AudioTrackC1Ev == nullptr) {
94-
ALOGE("dlsym returned nullptr for _ZN7android10AudioTrackC1Ev: %s",
95-
dlerror());
96-
return NULL;
97-
}
98-
}
99119
ZN7android10AudioTrackC1Ev(theTrack);
100120
}
101-
return (intptr_t)theTrack;
121+
ALOGE("0");
122+
auto callback = nullptr;//new MyCallback();
123+
//ZN7android7RefBaseC2Ev(callback); // TODO
124+
ALOGE("1");
125+
ZNK7android7RefBase9incStrongEPKv(theTrack, holder);
126+
ALOGE("2");
127+
//ZNK7android7RefBase9incStrongEPKv(callback, holder);
128+
ALOGE("3");
129+
holder->track = theTrack;
130+
holder->callback = callback;
131+
return (intptr_t)holder;
102132
}
103133

104134
extern "C" JNIEXPORT jint JNICALL
105135
Java_org_akanework_gramophone_logic_utils_NativeTrack_doSet(
106-
JNIEnv *env, jobject, jlong ptr) {
107-
// TODO support all 5 gazillion variants of set()
136+
JNIEnv *, jobject, jlong ptr) {
137+
return 0;
138+
auto holder = (track_holder*) ptr;
139+
auto refs = ZNK7android7RefBase10createWeakEPKv(holder->callback, holder);
140+
auto ret = ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi(
141+
holder->track,
142+
/* streamType = */ 3 /* AUDIO_STREAM_MUSIC */,
143+
/* sampleRate = */ 13370,
144+
/* format = */ 1,
145+
/* channelMask = */ 1,
146+
/* frameCount = */ 0 /* default */,
147+
/* flags = */ 0 /* AUDIO_OUTPUT_FLAG_NONE */,
148+
/* callback = */ { .thePtr = holder->callback, .refs = refs },
149+
/* notificationFrames = */ 0 /* default */,
150+
/* sharedBuffer = */ { .thePtr = nullptr },
151+
/* threadCanCallJava = */ true,
152+
/* sessionId = */ 0 /* default */,
153+
/* transferType = */ TRANSFER_SYNC,
154+
/* offloadInfo = */ nullptr,
155+
/* attributionSource = */ holder->ats,
156+
/* pAttributes = */ nullptr,
157+
/* doNotReconnect = */ true, // for emulating DIRECT track developer UX
158+
/* maxRequiredSpeed = */ 1.0f,
159+
/* selectedDeviceId = */ 0 /* default */
160+
);
161+
// wp copy constructor increased weak with it's own id, so we're done here
162+
ZN7android7RefBase12weakref_type7decWeakEPKv(refs /* yes, refs */, holder);
163+
// we own attributionSource, so get rid of it
164+
::operator delete(holder->ats);
165+
holder->ats = nullptr;
166+
return ret;
167+
}
108168

169+
extern "C" JNIEXPORT void JNICALL
170+
Java_org_akanework_gramophone_logic_utils_NativeTrack_dtor(
171+
JNIEnv *, jobject, jlong ptr) {
172+
auto holder = (track_holder*) ptr;
173+
// RefBase will call the dtor
174+
ZNK7android7RefBase9decStrongEPKv(holder->track, holder);
175+
ZNK7android7RefBase9decStrongEPKv(holder->callback, holder);
176+
delete holder;
109177
}

0 commit comments

Comments
 (0)