ADB传参启动Activity报Permission Denial错误排查方案
问题背景
下述代码为DIVA安卓靶场硬编码校验关卡的实现逻辑:读取界面输入框ID为hcKey的取值,和硬编码字符串vendorsecretkey比对,匹配则放行访问,否则拒绝。需求是通过ADB命令直接传参完成校验。
package jakhar.aseem.diva; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.EditText; import android.widget.Toast; public class HardcodeActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_hardcode); } public void access(View view) { if (((EditText) findViewById(R.id.hcKey)).getText().toString().equals("vendorsecretkey")) { Toast.makeText(this, "Access granted! See you on the other side :)", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "Access denied! See you in hell :D", Toast.LENGTH_SHORT).show(); } } }
尝试执行如下ADB命令传参启动失败:
adb shell am start -n jakhar.aseem.diva/.HardcodeActivity --es "hckey" "vendorsecretkey"
执行后抛出权限报错:
Starting: Intent { cmp=jakhar.aseem.diva/.HardcodeActivity (has extras) } Exception occurred while executing 'start': java.lang.SecurityException: Permission Denial: starting Intent { flg=0x10000000 cmp=jakhar.aseem.diva/.HardcodeActivity (has extras) } from null (pid=2845, uid=2000) not exported from uid 10105 at com.android.server.wm.ActivityTaskSupervisor.checkStartAnyActivityPermission(ActivityTaskSupervisor.java:1047) at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:975) at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:665) at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1201) at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1173) at com.android.server.am.ActivityManagerService.startActivityAsUserWithFeature(ActivityManagerService.java:2926) at com.android.server.am.ActivityManagerShellCommand.runStartActivity(ActivityManagerShellCommand.java:562) at com.android.server.am.ActivityManagerShellCommand.onCommand(ActivityManagerShellCommand.java:193) at com.android.modules.utils.BasicShellCommandHandler.exec(BasicShellCommandHandler.java:97) at android.os.ShellCommand.exec(ShellCommand.java:38) at com.android.server.am.ActivityManagerService.onShellCommand(ActivityManagerService.java:8620) at android.os.Binder.shellCommand(Binder.java:950) at android.os.Binder.onTransact(Binder.java:834) at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:5106) at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2498) at android.os.Binder.execTransactInternal(Binder.java:1184) at android.os.Binder.execTransact(Binder.java:1143)
将参数类型标识--es替换为--ei后仍然报相同错误,参考配置截图确认Activity支持外部调用,寻求正确的ADB传参启动方法。
问题根因
两个核心问题导致操作失败:
- 传参逻辑从根源不成立:原代码的校验逻辑直接读取布局内EditText控件的文本内容,全程没有调用
getIntent().getXxxExtra()读取Intent携带参数的逻辑,不管往Intent里塞什么类型的参数,代码根本不会接收,完全无效。 - 权限报错是实际配置与截图不符:报错明确提示组件
not exported,说明设备上安装的DIVA版本中,HardcodeActivity的exported实际属性为false,参考的截图和本地安装包版本不匹配,不要依赖外部截图判断配置,可执行adb shell dumpsys package jakhar.aseem.diva查看本地安装包的真实Manifest配置。
可行解决方案
方案1:无需修改APK,ADB模拟操作直接过校验(推荐)
不需要改包、不需要纠结组件导出属性,直接模拟人工操作流程即可:
- 第一步:启动DIVA主应用,进入硬编码校验页面
adb shell am start -n jakhar.aseem.diva/.MainActivity - 第二步:页面加载完成后,直接向输入框注入校验密钥
adb shell input text "vendorsecretkey" - 第三步:模拟点击校验按钮触发access校验逻辑
# 坐标替换为设备上"Check"按钮的实际屏幕坐标,可开启开发者选项的指针位置获取 adb shell input tap 540 1100
执行完成后会直接弹出访问通过的提示。
方案2:重打包APK实现Intent传参直接启动
如果必须实现启动Activity时传参直接过校验,需要反编译APK修改两处逻辑后重打包签名:
- 将Manifest中
HardcodeActivity的android:exported属性改为true - 在
HardcodeActivity的onCreate方法中新增读取Intent参数、自动填充并触发校验的逻辑:@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_hardcode); // 新增读取Intent传参逻辑 String injectKey = getIntent().getStringExtra("hcKey"); if (injectKey != null) { EditText keyInput = findViewById(R.id.hcKey); keyInput.setText(injectKey); // 自动触发校验 access(keyInput); } }
修改完成后重打包、签名安装到设备,即可执行命令直接启动过校验:
adb shell am start -n jakhar.aseem.diva/.HardcodeActivity --es hcKey "vendorsecretkey"
注:命令中传递的参数key名和代码里
getStringExtra读取的key名保持一致即可,和控件IDhcKey的大小写没有关联。
内容的提问来源于stack exchange,提问作者uday shibainu
相关产品推荐
相关产品推荐

