Android 5.0以下系统进程守活
来源:互联网 发布:顶级域名的两大类 编辑:程序博客网 时间:2024/05/16 13:41
由于Andoid NDK守护进程只适用于5.0的系统以下,所以分开来写。
#include <android/log.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <dirent.h>#include <sys/types.h> // for opendir(), readdir(), closedir()#include <sys/stat.h> // for stat()#include <stdarg.h>#define BUFFER_LENGTH 1024#define MAX_TIME 15#define TAG "monitor"#define PACKET_NAME "应用的包名"#define PATH "/data/data/应用的包名"#define RESTART_PATH "/data/data/应用的包名/restart"#define SERVICE_NAME "应用的包名/应用的包名.service.MonitorService"#define RUN_SERVICE "am startservice --user 0 -n 应用的包名/应用的包名.service.MonitorService"#define LOGE(...) __android_log_print(2,TAG,__VA_ARGS__)#define PROC_DIRECTORY "/proc/"#define CASE_SENSITIVE 1#define CASE_INSENSITIVE 0#define EXACT_MATCH 1#define INEXACT_MATCH 0int main(int argc, char* argv[]) {FILE *fp1;char ch;int count = 0;LOGE("start run");int pid=fork();while (1) {if (access(PATH, 0) == -1) {LOGE("android unistall,program will quit");exit(-1);}if (access(RESTART_PATH, 0) != -1) {LOGE("need restart");exit(-1);}if (count > MAX_TIME) {count = 0;pid_t pid = GetPIDbyName_Wrapper(PACKET_NAME) ; // If -1 = not found, if -2 = proc fs access errorif(pid!=-1 && pid!=-2){LOGE("process exists ");}else{LOGE("process not exists ");myexec(RUN_SERVICE);}}count = count + 1;sleep(1);}return 0;}int32_t myexec(const char *cmd) {FILE *pp = popen(cmd, "r");if (!pp) {//LOGE("run cmd fail");return -1;}//char tmp[1024];//while (fgets(tmp, sizeof(tmp), pp) != NULL ) {//if (tmp[strlen(tmp) - 1] == '\n') {//tmp[strlen(tmp) - 1] = '\0';//}//}pclose(pp);LOGE("run cmd success");return 0;}int findProcess(char *processName) {FILE *ptr;char buff[512];char ps[128];sprintf(ps, "ps | grep -c %s", processName);strcpy(buff, "ABNORMAL");if ((ptr = popen(ps, "r")) != NULL) {while (fgets(buff, 512, ptr) != NULL ) {if (atoi(buff) >= 2) {pclose(ptr);return 1;}}}if (strcmp(buff, "ABNORMAL") == 0) /*ps command error*/return 0;pclose(ptr);return 2;}//是不是数字int IsNumeric(const char* ccharptr_CharacterList){ for ( ; *ccharptr_CharacterList; ccharptr_CharacterList++) if (*ccharptr_CharacterList < '0' || *ccharptr_CharacterList > '9') return 0; // false return 1; // true}//intCaseSensitive=0大小写不敏感int strcmp_Wrapper(const char *s1, const char *s2, int intCaseSensitive){ if (intCaseSensitive) return !strcmp(s1, s2); else return !strcasecmp(s1, s2);}//intCaseSensitive=0大小写不敏感int strstr_Wrapper(const char* haystack, const char* needle, int intCaseSensitive){ if (intCaseSensitive) return (int) strstr(haystack, needle); else return (int) strcasestr(haystack, needle);}pid_t GetPIDbyName_implements(const char* cchrptr_ProcessName, int intCaseSensitiveness, int intExactMatch){ char chrarry_CommandLinePath[1000] ; char chrarry_NameOfProcess[1000] ; char* chrptr_StringToCompare = NULL ; pid_t pid_ProcessIdentifier = (pid_t) -1 ; struct dirent* de_DirEntity = NULL ; DIR* dir_proc = NULL ; int (*CompareFunction) (const char*, const char*, int) ; if (intExactMatch) CompareFunction = &strcmp_Wrapper; else CompareFunction = &strstr_Wrapper; dir_proc = opendir(PROC_DIRECTORY) ; if (dir_proc == NULL) { perror("Couldn't open the " PROC_DIRECTORY " directory") ; return (pid_t) -2 ; } // Loop while not NULL while ( (de_DirEntity = readdir(dir_proc)) ) { if (de_DirEntity->d_type == DT_DIR) { if (IsNumeric(de_DirEntity->d_name)) { strcpy(chrarry_CommandLinePath, PROC_DIRECTORY) ; strcat(chrarry_CommandLinePath, de_DirEntity->d_name) ; strcat(chrarry_CommandLinePath, "/cmdline") ; FILE* fd_CmdLineFile = fopen (chrarry_CommandLinePath, "rt") ; //open the file for reading text if (fd_CmdLineFile) { fscanf(fd_CmdLineFile, "%s", chrarry_NameOfProcess) ; //read from /proc/<NR>/cmdline fclose(fd_CmdLineFile); //close the file prior to exiting the routine if (strrchr(chrarry_NameOfProcess, '/')) chrptr_StringToCompare = strrchr(chrarry_NameOfProcess, '/') +1 ; else chrptr_StringToCompare = chrarry_NameOfProcess ; //printf("Process name: %s\n", chrarry_NameOfProcess); //这个是全路径,比如/bin/ls //printf("Pure Process name: %s\n", chrptr_StringToCompare ); //这个是纯进程名,比如ls //这里可以比较全路径名,设置为chrarry_NameOfProcess即可 if ( CompareFunction(chrptr_StringToCompare, cchrptr_ProcessName, intCaseSensitiveness) ) { pid_ProcessIdentifier = (pid_t) atoi(de_DirEntity->d_name) ; closedir(dir_proc) ; return pid_ProcessIdentifier ; } } } } } closedir(dir_proc) ; return pid_ProcessIdentifier ;} //简单实现 pid_t GetPIDbyName_Wrapper(const char* cchrptr_ProcessName) { return GetPIDbyName_implements(cchrptr_ProcessName, 0,0);//大小写不敏感 }编译此代码生成SO文件,并将SO文件放入资产文件中。
Android Service代码
</pre><p><pre name="code" class="java">import android.app.Service;import android.content.Intent;import android.os.Handler;import android.os.IBinder;import android.os.Looper;import java.io.DataOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;/** * Created by liyan on 15/3/9. */public class MonitorService extends Service { private static final String PROCESS_NAME = "monitor"; @Override public void onCreate() { super.onCreate(); restartMonitor(); } private void restartMonitor() { final File file = new File("/data/data/" + getPackageName() + "/restart"); if (!file.exists()) { file.mkdir(); } new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { @Override public void run() { try { file.delete();// //运行监控程序 runMonitor(); } catch (Exception e) { } } }, 1500); } private void runMonitor() { try { copy(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } runWatcher(); } private void runWatcher() { String path = "/data/data/" + getPackageName() + "/files"; String cmd2 = path + "/" + PROCESS_NAME; String cmd3 = "chmod 777 " + cmd2; rootCommand(cmd3); rootCommand(cmd2); } public void copy() throws IOException { // 看这里,设置你要copy到的路径,下面是我举的一个例子 File file = new File("/data/data/" + getPackageName() + "/files"); file.mkdir(); InputStream is = this.getAssets().open(PROCESS_NAME); // 打开文件 FileOutputStream os = new FileOutputStream( "/data/data/" + getPackageName() + "/files/" + PROCESS_NAME); byte[] buffer = new byte[1024]; int count = 0; // 将文件拷贝到目的地 while ((count = is.read(buffer)) > 0) { // 写入即拷贝 os.write(buffer, 0, count); } is.close(); os.close(); } public boolean rootCommand(String command) { boolean result = false; java.lang.Process process = null; DataOutputStream outputStream = null; try { process = Runtime.getRuntime().exec("sh"); //获得shell. outputStream = new DataOutputStream(process.getOutputStream()); outputStream.writeBytes("cd /data/data/" + getPackageName() + "\n"); //保证在command在自己的数据目录里执行,才有权限写文件到当前目录 outputStream.writeBytes(command + " &\n"); //让程序在后台运行,前台马上返回 outputStream.writeBytes("exit\n"); outputStream.flush(); process.waitFor(); result = true; } catch (Exception e) { e.printStackTrace(); result = false; } finally { if (outputStream != null) { try { outputStream.close(); } catch (Exception ex) { ex.printStackTrace(); } } } return result; } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); } @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; } @Override public void onDestroy() { super.onDestroy(); }}
原理就是MonitorService 从资产文件中复制出守护程序到FILES目录,并启动守护Monitor,Monitor负责15秒检查一下主进程是否被杀死,如果被杀死,则重新启动MonitorService
1 0
- Android 5.0以下系统进程守活
- Android 5.0 以下Native进程保活尝试
- Android 进程常驻(3)----native保活5.0以下方案推演过程以及代码详述
- Android 进程常驻(3)----native保活5.0以下方案推演过程以及代码
- Android 进程常驻(3)----native保活5.0以下方案推演过程以及代码详述
- android-2.2以下杀进程方法:restartPackage();
- Android 6.0 以下系统的权限检测
- linux启动后,默认有以下系统进程
- Linux系统的进程通常有以下几种状态
- Linux系统的进程通常有以下几种状态:
- Linux系统的进程通常有以下几种状态
- Android中创建杀不死的APP进程(5.0以下)
- Android Material Design 详解(使用support v7兼容5.0以下系统)
- Android Material Design 详解(使用support v7兼容5.0以下系统)
- Android Material Design 详解(使用support v7兼容5.0以下系统(部分功能))
- 解决 cocos android 接入友盟推送 sdk 在5.0以下的系统出现UnsatisfiedLinkError 错误
- Android Material Design 详解(使用support v7兼容5.0以下系统)
- android 5.0以下系统Intent传递序列化对象的bug
- hdu 1711 Number Sequence (kmp)
- The 'Apple Developer Program License Agreement' has been updated. In order to access certain members
- RxJava中create源码
- Ubuntu虚拟机NAT模式无法上网解决方案
- Java泛型应用之打造Android万能ViewHolder-超简洁写法
- Android 5.0以下系统进程守活
- scanf()取地址
- Android Studio 配置Terminal
- 简单地一个DOS端口映射程序
- Json数据结构比对
- VC++60 第一章 创建应用程序的四个步骤
- [IDA Plugin] 改善IDA6.8对中文等非英语国家的ANSI字符串显示支持不佳的问题
- 调用系统打电话的方法
- adf和FB