Java Delphi xe5 exec根命令转换

Java Delphi xe5 exec根命令转换,java,android,linux,delphi,delphi-xe5,Java,Android,Linux,Delphi,Delphi Xe5,我试着隐蔽起来 要向根手机发送shell命令,我不明白为什么会出现分段错误。 在互联网上,我发现了如下java代码: Runtime.getRuntime().exec(new String[]{"/system/bin/su","-c","reboot now"});` for reboot of the phone or `Runtime.getRuntime().exec("su"); 对于linux根权限 我试着在转换后只发送带有函数的“su”命令,但我想我搞错了。。。我认为一个可能的

我试着隐蔽起来 要向根手机发送shell命令,我不明白为什么会出现分段错误。 在互联网上,我发现了如下java代码:

Runtime.getRuntime().exec(new String[]{"/system/bin/su","-c","reboot now"});` for reboot of the phone or `Runtime.getRuntime().exec("su");
对于linux根权限

我试着在转换后只发送带有函数的“su”命令,但我想我搞错了。。。我认为一个可能的问题是java类型的Jstring转换数组

unit Androidapi.JNI.Root;

interface
    procedure AskRoot;
implementation
   uses  System.SysUtils,
  Androidapi.JNIBridge,
  Androidapi.JNI.GraphicsContentViewText,
  Androidapi.JNI.JavaTypes,
  FMX.Helpers.Android;

 type
  JProcess = interface;
  JRuntime = interface;
 //----------------------------------JProcess----------------------
  JProcessClass = interface(JObjectClass)
  ['{7BFD2CCB-89B6-4382-A00B-A7B5BB0BC7C9}']

  end;
  [JavaSignature('java/lang/Process')]
  JProcess = interface(JObject)
  ['{476414FD-570F-4EDF-B678-A2FE459EA6EB}']
    {Methods}
    procedure destroy; cdecl;
    function exitValue:integer;cdecl;
    function getErrorStream:JInputStream; cdecl;
    function getInputStream:JOutputStream; cdecl;
    function waitFor:integer;cdecl;
  end;
  TJProcess = class(TJavaGenericImport<JProcessClass, JProcess>) end;
  //----------------------------------Jruntime----------------------
  JRuntimeClass = interface(JObjectClass)
    ['{3F2E949D-E97C-4AD8-B5B9-19CB0A6A29F3}']
    {costant}
  end;
  [JavaSignature('java/lang/Runtime')]
  JRuntime = interface(JObject)
  ['{C097A7EC-677B-4BCB-A4BD-7227160750A5}']
       {Methods}
      procedure addShutdownHook(hook:JThread);cdecl;
      function availableProcessors:integer; cdecl;
      function exec(progArray,envp:array of JString):Jprocess; overload;
      function exec(progArray:Jstring; envp:array of JString;directory:JFile):Jprocess; overload;
      function exec(progArray,envp:array of JString;directory:JFile):Jprocess; overload;
      function exec(prog:JString;envp:array of JString):Jprocess;  cdecl; overload;
      function exec(progArray:array of JString):Jprocess; overload;
      function exec(prog:JString):Jprocess;  cdecl; overload;
      procedure Exit(code:Integer);cdecl;
      function freeMemory:LongInt;cdecl;
      procedure gc; cdecl;
      function getLocalizedInputStream(stream:JInputStream):JInputStream; cdecl;
      function getLocalizedOutputStream(stream:JOutputStream):JOutputStream; cdecl;
      function getRuntime:JRuntime;cdecl;
      procedure halt(code:Integer);cdecl;
      procedure load(pathName:JString);cdecl;
      procedure loadLibrary(libName:JString); cdecl;
      function maxMemory:LongInt;cdecl;
      function RemoveShutdownHook(hook:JThread):Boolean;cdecl;
      procedure runFinalization;cdecl;
      procedure runFinalizersOnExit(run:Boolean);cdecl;
      function totalMemory:LongInt;cdecl;
      procedure traceInstructions(enable:Boolean);cdecl;
      procedure traceMethodCalls(enable:Boolean); cdecl;
  end;
  TJRuntime = class(TJavaGenericImport<JRuntimeClass, JRuntime>) end;

  procedure AskRoot;
  var root:JRuntime;
  begin
    root.getRuntime.exec(StringToJString('su'));
  end;
end.
unitandroidapi.JNI.Root;
接口
AskRoot程序;
实施
使用System.SysUtils,
Androidapi.JNIBridge,
Androidapi.JNI.GraphicsContentViewText,
Androidapi.JNI.JavaTypes,
FMX.Helpers.Android;
类型
j进程=接口;
JRuntime=接口;
//----------------------------------JProces----------------------
JProcessClass=接口(JObjectClass)
[{7BFD2CCB-89B6-4382-A00B-A7B5BB0BC7C9}]
结束;
[JavaSignature('java/lang/Process')]
JProcess=接口(JObject)
[{476414FD-570F-4EDF-B678-A2FE459EA6EB}]
{Methods}
程序破坏;cdecl;
函数exitValue:整数;cdecl;
函数getErrorStream:JInputStream;cdecl;
函数getInputStream:JOutputStream;cdecl;
函数waitFor:integer;cdecl;
结束;
TJProcess=类(TJavaGenericImport)结束;
//----------------------------------Jruntime----------------------
JRuntimeClass=接口(JObjectClass)
['{3F2E949D-E97C-4AD8-B5B9-19CB0A6A29F3}']
{costant}
结束;
[JavaSignature('java/lang/Runtime')]
JRuntime=接口(JObject)
[{C097A7EC-677B-4BCB-A4BD-7227160750A5}]
{Methods}
程序addShutdownHook(hook:JThread);cdecl;
函数可用处理器:整数;cdecl;
函数exec(prograrray,envp:JString的数组):Jprocess;超载;
函数exec(prograray:Jstring;envp:Jstring的数组;目录:JFile):Jprocess;超载;
函数exec(prograrray,envp:JString的数组;目录:JFile):Jprocess;超载;
函数exec(prog:JString;envp:JString数组):Jprocess;cdecl;超载;
函数exec(prograrray:JString的数组):Jprocess;超载;
函数exec(prog:JString):Jprocess;cdecl;超载;
程序退出(代码:整数);cdecl;
功能自由记忆:长记忆;cdecl;
程序gc;cdecl;
函数getLocalizedInputStream(stream:JInputStream):JInputStream;cdecl;
函数getLocalizeDoutpStream(stream:JOutputStream):JOutputStream;cdecl;
函数getRuntime:JRuntime;cdecl;
过程暂停(代码:整数);cdecl;
过程加载(路径名:JString);cdecl;
过程装入库(libName:JString);cdecl;
函数maxMemory:LongInt;cdecl;
函数RemoveShutdownHook(hook:JThread):布尔;cdecl;
程序运行结束;cdecl;
过程runFinalizersOnExit(run:Boolean);cdecl;
功能总记忆:长记忆;cdecl;
过程跟踪指令(启用:布尔值);cdecl;
过程跟踪方法调用(启用:布尔);cdecl;
结束;
TJRuntime=类(TJavaGenericImport)结束;
AskRoot程序;
var根:JRuntime;
开始
root.getRuntime.exec(StringToJString('su');
结束;
结束。

您的一些
exec
覆盖未标记为
cdecl

这不会有帮助-堆栈将变得混乱,并可能导致分段错误

但是,您调用的一个被标记为
cdecl

另一方面,您正在调用未初始化的
root
对象/接口引用的方法。这种行为肯定会给你一个细分错误

getRuntime
看起来是
Runtime
类的类方法,因此您输入了错误的接口。当你把它移到正确的位置时,我会想象这样的事情可能会发生:

TJRuntime.JavaClass.getRuntime.exec(StringToJString('su'));

此代码是在Delphi Berlin中检查的

对于以根用户身份执行:

1) 将此字符串添加到AndroidManifest.template.xml中

android:sharedUserId=“android.uid.system”

2) 通过platform.x509.pem和platform.pk8证书将APK签署为系统

unitandroid.ExecuteShell;
//柏林德尔福酒店
//执行为SU
//将此字符串添加到AndroidManifest.template.xml中
//android:sharedUserId=“android.uid.system”
//通过platform.x509.pem和platform.pk8证书将APK签署为系统
//java.lang.Process,java.lang.Runtime下载路径为
//https://github.com/FMXExpress/android-object-pascal-wrapper/tree/master/android-23
接口
使用
System.SysUtils、System.class、,
Androidapi.Helpers、Androidapi.JNI.JavaTypes、Androidapi.JNIBridge、,
java.lang.Process,java.lang.Runtime;
函数ExecuteShell(sCmd:string;sOut,sErr:TStringList;const-AsSu:boolean=false):整数;
实施
函数ExecuteShell(sCmd:string;sOut,sErr:TStringList;const-AsSu:boolean=false):整数;
变量
进程:JProcess;
运行时:JRuntime;
输出:JOutputstream;
函数StrToJA(st:string):TJavaArray;
变量
len,i:整数;
开始
长度:=长度(st)+1;
结果:=TJavaArray.Create(len);
对于i:=0到len-2,开始
结果[i]:=ord(st[i])和$ff;
结束;
结果[len-1]:=$a;
结束;
程序流程列表(str:JInputStream;ls:TStringList);
变量
x、 bufflen:整数;
s:字符串;
buff:TJavaArray;
开始
bufflen:=str.available;
buff:=TJavaArray.Create(bufflen);
str.read(buff);
s:='';
对于x:=0到bufflen-1 do
s:=s+chr(buff[x]);
ls.加入(s);
结束;
开始
尝试
如果是AsSu,那么开始
进程:=TJRuntime.JavaClass.getRuntime.exec(StringToJString('su');
输出:=Process.getOutputStream;
输出写入(StrToJA(sCmd));
Output.write(StrToJA('exit'));
结束其他
进程:=TJRuntime.JavaClass.getRuntime.exec(StringToJString(sCmd));
结果:=Process.waitFor;
结果:=Process.exitValue;
如果分配(sOut),则
StreamToList(Process.getInputStream,sOut);
如果分配(sErr),则
StreamToList(Process.getErrorStream,sErr);
除了
在…上
unit Android.ExecuteShell;

//Checked in Delphi Berlin
// for execute as SU
//Add in AndroidManifest.template.xml this string
//    android:sharedUserId="android.uid.system"
//sign APK as System by platform.x509.pem and platform.pk8 certificates

//java.lang.Process, java.lang.Runtime download path is
//https://github.com/FMXExpress/android-object-pascal-wrapper/tree/master/android-23

interface

uses
    System.SysUtils, System.Classes,
    Androidapi.Helpers, Androidapi.JNI.JavaTypes, Androidapi.JNIBridge,
    java.lang.Process, java.lang.Runtime;

function ExecuteShell(sCmd: string; sOut, sErr : TStringList; const AsSu:boolean=false):integer;

implementation

function ExecuteShell(sCmd: string; sOut, sErr : TStringList; const AsSu:boolean=false):integer;
var
 Process : JProcess;
 Runtime : JRuntime;
 Output  : JOutputstream;

 function StrToJA(st:string):TJavaArray<Byte>;
 var
   len, i:integer;
 begin
   len:=length(st)+1;
   result := TJavaArray<Byte>.Create(len);
   for i := 0 to len - 2 do begin
     result[i]:= ord(st[i]) and $ff;
   end;
   result[len-1]:=$a;
 end;

 procedure StreamToList(str:JInputStream; ls:TStringList);
 var
   x, bufflen: Integer;
   s: string;
   buff : TJavaArray<Byte>;
 begin
   bufflen := str.available;
   buff := TJavaArray<Byte>.Create(bufflen);
   str.read(buff);
   s := '';
   for x := 0 to bufflen - 1 do
      s := s + chr(buff[x]);
   ls.Add(s);
 end;


begin
  try
    if AsSu then begin
      Process := TJRuntime.JavaClass.getRuntime.exec(StringToJString('su'));
      Output:=Process.getOutputStream;
      Output.write(StrToJA(sCmd));
      Output.write(StrToJA('exit'));
    end else
      Process := TJRuntime.JavaClass.getRuntime.exec(StringToJString(sCmd));
    Result:=Process.waitFor;
    Result:=Process.exitValue;
    if Assigned(sOut) then
       StreamToList(Process.getInputStream, sOut);
    if Assigned(sErr) then
       StreamToList(Process.getErrorStream, sErr);
  except
     on e:exception do
       if Assigned(sErr) then
             sErr.Add(e.message);
  end;
end;

end.