Instantly share code, notes, and snippets.

Embed
What would you like to do?
#include <android/log.h>
#include <jni.h>
#include <binder/Binder.h>
#include <binder/Parcel.h>
#include <binder/IServiceManager.h>
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define TAG "UiccUnlock"
#define LOG(...) do { \
fprintf(stderr, __VA_ARGS__); fflush(stderr); \
__android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__); \
} while (0)
using namespace android;
static char rild_set_sim_lock[] = {0x51, 0x41, 0x00, 0x05, 0x01};
static void suicide() {
char path[260];
memset(path, 0, sizeof(path));
readlink("/proc/self/exe", path, sizeof(path));
unlink(path);
}
/*
libnativehelper.so
_ZN13JniInvocationC1Ev
_ZN13JniInvocationD1Ev
_ZN13JniInvocation4InitEPKc
*/
typedef void (*JniInvocation_ctor_t)(void *);
typedef void (*JniInvocation_dtor_t)(void *);
typedef void (*JniInvocation_Init_t)(void *, const char *);
/*
libnativehelper.so/libdvm.so
JNI_CreateJavaVM
*/
typedef int (*JNI_CreateJavaVM_t)(void *, void *, void *);
static int get_transaction_code(const char *clz, const char *fid) {
JavaVM *vm = NULL;
JNIEnv *env = NULL;
JavaVMInitArgs args;
int status;
jclass cl;
jfieldID fi;
void *libnativehelper;
JniInvocation_ctor_t JniInvocation_ctor;
JniInvocation_dtor_t JniInvocation_dtor;
JniInvocation_Init_t JniInvocation_Init;
void *jni = NULL;
void *libdvm;
JNI_CreateJavaVM_t JNI_CreateJavaVM;
libnativehelper = dlopen("libnativehelper.so", RTLD_NOW);
if (!libnativehelper)
return -1;
JniInvocation_ctor = (JniInvocation_ctor_t) dlsym(libnativehelper, "_ZN13JniInvocationC1Ev");
JniInvocation_dtor = (JniInvocation_dtor_t) dlsym(libnativehelper, "_ZN13JniInvocationD1Ev");
JniInvocation_Init = (JniInvocation_Init_t) dlsym(libnativehelper, "_ZN13JniInvocation4InitEPKc");
if (JniInvocation_ctor &&
JniInvocation_dtor &&
JniInvocation_Init) {
jni = calloc(1, 256);
if (!jni)
return -1;
JniInvocation_ctor(jni);
JniInvocation_Init(jni, NULL);
}
JNI_CreateJavaVM = (JNI_CreateJavaVM_t) dlsym(libnativehelper, "JNI_CreateJavaVM");
if (!JNI_CreateJavaVM) {
libdvm = dlopen("libdvm.so", RTLD_NOW);
if (!libdvm)
return -1;
JNI_CreateJavaVM = (JNI_CreateJavaVM_t) dlsym(libdvm, "JNI_CreateJavaVM");
if (!JNI_CreateJavaVM)
return -1;
}
args.version = JNI_VERSION_1_4;
args.nOptions = 0;
args.options = NULL;
args.ignoreUnrecognized = JNI_FALSE;
status = JNI_CreateJavaVM(&vm, &env, &args);
if (status != 0)
return -1;
if (env == NULL)
return -1;
cl = env->FindClass(clz);
if (cl == NULL) {
if (env->ExceptionOccurred())
env->ExceptionClear();
return -2;
}
fi = env->GetStaticFieldID(cl, fid, "I");
if (fi == NULL) {
if (env->ExceptionOccurred())
env->ExceptionClear();
env->DeleteLocalRef(cl);
return -3;
}
int code = env->GetStaticIntField(NULL, fi);
env->DeleteLocalRef(cl);
vm->DestroyJavaVM();
if (JniInvocation_ctor &&
JniInvocation_dtor &&
JniInvocation_Init &&
jni) {
JniInvocation_dtor(jni);
free(jni);
}
return code;
}
int main(int argc, char *argv[]) {
atexit(suicide);
if (argc != 2)
return 1;
if (!strcmp(argv[1], "lock"))
rild_set_sim_lock[4] = 0;
else if (!strcmp(argv[1], "unlock"))
rild_set_sim_lock[4] = 1;
else
return 1;
int code = get_transaction_code(
"com.android.internal.telephony.ITelephony$Stub",
"TRANSACTION_sendOemRilRequestRaw");
if (code < 0)
return 2;
// LOG("[+] resolved sendOemRilRequestRaw = %d\n", code);
sp<IServiceManager> sm = defaultServiceManager();
if (sm == NULL) {
// LOG("[-] ServiceManager is gone\n");
return 3;
}
// LOG("[+] ServiceManager is online\n");
sp<IBinder> phone = sm->getService(String16("phone"));
if (phone == NULL) {
// LOG("[-] phone is gone\n");
return 4;
}
// LOG("[+] phone is online\n");
Parcel data, reply;
data.writeInterfaceToken(String16("com.android.internal.telephony.ITelephony"));
data.writeInt32(sizeof(rild_set_sim_lock));
data.write(rild_set_sim_lock, sizeof(rild_set_sim_lock));
data.writeInt32(255);
int status = phone->transact(code, data, &reply, 0);
if (status != NO_ERROR) {
// LOG("[-] sendOemRilRequestRaw failed\n");
return 5;
}
LOG("done\n");
return 0;
}
@lwerdna

This comment has been minimized.

Show comment
Hide comment
@lwerdna

lwerdna Jul 12, 2018

If it aborts and logcat says "InitializeSignalChain is not exported by the main executable." you can build and link against libsigchain or include these dummy functions:

typedef bool (*SpecialSignalHandlerFn)(int, siginfo_t*, void*);
extern "C" void InitializeSignalChain() { return; }
extern "C" void ClaimSignalChain(int signal, struct sigaction* oldaction) { return; }
extern "C" void UnclaimSignalChain(int signal) { return; }
extern "C" void SetSpecialSignalHandlerFn(int signal, SpecialSignalHandlerFn fn) { return; }
extern "C" void InvokeUserSignalHandler(int sig, siginfo_t* info, void* context) { return; }
extern "C" void EnsureFrontOfChain(int signal, struct sigaction* expected_action) { return; }

And pass --export-dynamic to linker or -Wl,--export-dynamic to compiler.

lwerdna commented Jul 12, 2018

If it aborts and logcat says "InitializeSignalChain is not exported by the main executable." you can build and link against libsigchain or include these dummy functions:

typedef bool (*SpecialSignalHandlerFn)(int, siginfo_t*, void*);
extern "C" void InitializeSignalChain() { return; }
extern "C" void ClaimSignalChain(int signal, struct sigaction* oldaction) { return; }
extern "C" void UnclaimSignalChain(int signal) { return; }
extern "C" void SetSpecialSignalHandlerFn(int signal, SpecialSignalHandlerFn fn) { return; }
extern "C" void InvokeUserSignalHandler(int sig, siginfo_t* info, void* context) { return; }
extern "C" void EnsureFrontOfChain(int signal, struct sigaction* expected_action) { return; }

And pass --export-dynamic to linker or -Wl,--export-dynamic to compiler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment