android修改进程名
16lz
2021-01-23
通过分析Android应用进程的创建启动流程,知道设置应用进程的名称是在http://androidxref.com/4.4_r1/xref/frameworks/base/core/java/android/app/ActivityThread.java#handleBindApplication
private void handleBindApplication(AppBindData data) { mBoundApplication = data; mConfiguration = new Configuration(data.config); mCompatConfiguration = new Configuration(data.config); mProfiler = new Profiler(); mProfiler.profileFile = data.initProfileFile; mProfiler.profileFd = data.initProfileFd; mProfiler.autoStopProfiler = data.initAutoStopProfiler; // send up app name; do this *before* waiting for debugger Process.setArgV0(data.processName); android.ddm.DdmHandleAppName.setAppName(data.processName, UserHandle.myUserId());
所以反射调用即可修改进程名,ddm应该是ddms调试用的,这个不改应该也可以。
try { Method setArgV0 = Process.class.getDeclaredMethod("setArgV0", String.class); setArgV0.setAccessible(true); setArgV0.invoke(null,"com.tencent.mm"); } catch (Throwable e) { e.printStackTrace(); }
结合之前的linux修改进程名,
//字符串包括结尾符号\0不能超过16,而且这个只是改了proc/pid/stat/status中的字符串const char* new_name = "mytest";prctl(PR_SET_NAME, new_name);
或者这样可以改变ps、cmdline的进程名
/*gcc changetitle.c -o changetitle*/#include #include #include #include #include #include # define MAXLINE 2048extern char **environ;static char **g_main_Argv = NULL; /* pointer to argument vector */static char *g_main_LastArgv = NULL; /* end of argv */void setproctitle_init(int argc, char **argv, char **envp){ int i; for (i = 0; envp[i] != NULL; i++) // calc envp num continue; environ = (char **) malloc(sizeof (char *) * (i + 1)); // malloc envp pointer for (i = 0; envp[i] != NULL; i++) { environ[i] = malloc(sizeof(char) * strlen(envp[i])); strcpy(environ[i], envp[i]); } environ[i] = NULL; g_main_Argv = argv; if (i > 0) g_main_LastArgv = envp[i - 1] + strlen(envp[i - 1]); else g_main_LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);}void setproctitle(const char *fmt, ...){ char *p; int i; char buf[MAXLINE]; extern char **g_main_Argv; extern char *g_main_LastArgv; va_list ap; p = buf; va_start(ap, fmt); vsprintf(p, fmt, ap); va_end(ap); i = strlen(buf); if (i > g_main_LastArgv - g_main_Argv[0] - 2) { i = g_main_LastArgv - g_main_Argv[0] - 2; buf[i] = '\0'; } //修改argv[0] (void) strcpy(g_main_Argv[0], buf); p = &g_main_Argv[0][i]; while (p < g_main_LastArgv) *p++ = '\0'; g_main_Argv[1] = NULL; //调用prctl prctl(PR_SET_NAME,buf);}int main(int argc, char *argv[]){ char argv_buf[MAXLINE] = {0}; // save argv paramters int i; for( i = 1; i < argc; i++) { strcat(argv_buf, argv[i]); strcat(argv_buf, " "); } //修改argv[0]所指向的内存空间的内容 setproctitle_init(argc, argv, environ); //调用prctl修改进程名 setproctitle("%[email protected]%s %s", "littlehann-prog", "ip", argv_buf); for (i = 0; environ[i] != NULL; i++) free(environ[i]); getchar(); return 0;}
对比下Android是如果实现的,http://androidxref.com/4.4_r1/xref/frameworks/native/libs/binder/ProcessState.cpp#305
首先把进程名覆盖了mArgV第一个数组,之后也是调用
prctl(PR_SET_NAME, (unsigned long) new_name, 0, 0, 0);
// Global variablesint mArgC;const char* const* mArgV;int mArgLen;void ProcessState::setArgV0(const char* txt){ if (mArgV != NULL) { strncpy((char*)mArgV[0], txt, mArgLen); set_process_name(txt); }}
//http://androidxref.com/4.4_r1/xref/system/core/libcutils/process_name.c#37void set_process_name(const char* new_name) {#ifdef HAVE_ANDROID_OS char propBuf[PROPERTY_VALUE_MAX];#endif if (new_name == NULL) { return; } // We never free the old name. Someone else could be using it. int len = strlen(new_name); char* copy = (char*) malloc(len + 1); strcpy(copy, new_name); process_name = (const char*) copy;#if defined(HAVE_PRCTL) if (len < 16) { prctl(PR_SET_NAME, (unsigned long) new_name, 0, 0, 0); } else { prctl(PR_SET_NAME, (unsigned long) new_name + len - 15, 0, 0, 0); }#endif#ifdef HAVE_ANDROID_OS // If we know we are not running in the emulator, then return. if (running_in_emulator == 0) { return; } // If the "running_in_emulator" variable has not been initialized, // then do it now. if (running_in_emulator == -1) { property_get("ro.kernel.qemu", propBuf, ""); if (propBuf[0] == '1') { running_in_emulator = 1; } else { running_in_emulator = 0; return; } } // If the emulator was started with the "-trace file" command line option // then we want to record the process name in the trace even if we are // not currently tracing instructions (so that we will know the process // name when we do start tracing instructions). We do not need to execute // this code if we are just running in the emulator without the "-trace" // command line option, but we don't know that here and this function // isn't called frequently enough to bother optimizing that case. int fd = open(PROCESS_NAME_DEVICE, O_RDWR); if (fd < 0) return; write(fd, process_name, strlen(process_name) + 1); close(fd);#endif}
从名字上猜应该mArgV应该就是main函数接收的argv,我们知道Android应用进程其实都是fork自zygote,而zygote的可执行文件就是app_process
http://androidxref.com/4.4_r1/xref/frameworks/base/cmds/app_process/app_main.cpp#169
int main(int argc, char* const argv[]){#ifdef __arm__ /* * b/7188322 - Temporarily revert to the compat memory layout * to avoid breaking third party apps. * * THIS WILL GO AWAY IN A FUTURE ANDROID RELEASE. * * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=7dbaa466 * changes the kernel mapping from bottom up to top-down. * This breaks some programs which improperly embed * an out of date copy of Android's linker. */ char value[PROPERTY_VALUE_MAX]; property_get("ro.kernel.qemu", value, ""); bool is_qemu = (strcmp(value, "1") == 0); if ((getenv("NO_ADDR_COMPAT_LAYOUT_FIXUP") == NULL) && !is_qemu) { int current = personality(0xFFFFFFFF); if ((current & ADDR_COMPAT_LAYOUT) == 0) { personality(current | ADDR_COMPAT_LAYOUT); setenv("NO_ADDR_COMPAT_LAYOUT_FIXUP", "1", 1); execv("/system/bin/app_process", argv); return -1; } } unsetenv("NO_ADDR_COMPAT_LAYOUT_FIXUP");#endif // These are global variables in ProcessState.cpp mArgC = argc; mArgV = argv; mArgLen = 0; for (int i=0; i
所以其实Android修改进程名和Linux是一样的。
更多相关文章
- Android进程,任务,服务的信息
- Android进程与线程基本知识
- Android跨进程通信方式(IPC)解析
- Android多进程介绍与用法
- Android 双进程守护
- Android中ListView以及数组适配器(ArrayAdapter)的使用
- Android 面试经验 - Android 进程间的通信
- Android进程间通信--消息机制及IPC机制实现
- Android 8.1 zygote创建新应用进程