Skip to content

Instantly share code, notes, and snippets.

@SeeFlowerX
Forked from tewilove/UiccUnlock.cpp
Created November 19, 2021 07:12
Show Gist options
  • Save SeeFlowerX/298061be106333479abefb5b8e0799ae to your computer and use it in GitHub Desktop.
Save SeeFlowerX/298061be106333479abefb5b8e0799ae to your computer and use it in GitHub Desktop.
#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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment