Skip to content

Crash in constructor #13

@ssstylish

Description

@ssstylish

I'm trying to hook a function in a library that isn't loaded into memory yet, but as soon as it's loaded into memory, it crashes:

__attribute__((__constructor__)) void start() {
	GlossInit(true);
	GlossHookAddrByName("libunity.so", 0x3865100, Replace(hstart), Result(ostart), false, I_ARM64, [](const GlossHookCallback_t info) {
		__android_log_print(ANDROID_LOG_INFO, "tfest", "%s", info.path);
	});
}

But the fix for the crash would be to call the hook in a separate thread, but this leads to the problem of infinite library loading (libunity.so, apparently):

__attribute__((__constructor__)) void start() {
	GlossInit(true);
	std::thread([]() {
		GlossHookAddrByName("libunity.so", 0x3865100, Replace(hstart), Result(ostart), false, I_ARM64, [](const GlossHookCallback_t info) {
			__android_log_print(ANDROID_LOG_INFO, "tfest", "%s", info.path);
		});
	}).detach();
}

It's possible that the code inside the GlossHookAddrByName call is calling or hooking functions from the main zygote thread, resulting in an infinite loop, since I'm testing this in the zygisk module and loading my library with dlopen in the preAppSpecialize method:

void Module::preAppSpecialize(zygisk::AppSpecializeArgs* args) {
	const char* process = env->GetStringUTFChars(args->nice_name, nullptr);
	if (strcmp(process, "com.axlebolt.standoff2") == 0) {
		dlopen(pathtolib, RTLD_GLOBAL | RTLD_NOW);
	} else {
		api->setOption(zygisk::Option::DLCLOSE_MODULE_LIBRARY);
	}
	env->ReleaseStringUTFChars(args->nice_name, process);
}

Please add a function that will call 2 callback functions before and after initializing the library constructors (as is done in shadowhook):

// register and unregister callbacks for executing dynamic library's .init .init_array / .fini .fini_array
typedef void (*shadowhook_dl_info_t)(struct dl_phdr_info *info, size_t size, void *data);
int shadowhook_register_dl_init_callback(shadowhook_dl_info_t pre, shadowhook_dl_info_t post, void *data);
int shadowhook_unregister_dl_init_callback(shadowhook_dl_info_t pre, shadowhook_dl_info_t post, void *data);

To allow quick register of pre and post callbacks without affecting the main execution of the program:

#include "Gloss.h"

typedef void (*gloss_dl_info_t)(struct dl_phdr_info *info, size_t size, void *data);
int GlossRegisterDlInitCallbacks(gloss_dl_info_t pre, gloss_dl_info_t post, void* data);

__attribute__((__constructor__)) void start() {
    // Fast:
	GlossInit(false);
    // Fast:
	GlossRegisterDlInitCallbacks([](struct dl_phdr_info *info, size_t size, void *data) {
		if (strstr(info->path, "libunity.so")) {
			GlossHookAddrByName("libunity.so", 0x3865100, Replace(hstart), Result(ostart), false, I_ARM64, [](const GlossHookCallback_t info) {
				__android_log_print(ANDROID_LOG_INFO, "tfest", "%s", info->path);
			});

			/// ... other hooks
		}
	}, nullptr, nullptr);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions