Delphi xe5 exec root command conversion

别来无恙 提交于 2019-12-06 05:39:44

Several of your exec overrides are not marked cdecl.

That won't help - the stack will get messed up and potentially lead to segmentation faults.

However the one you call is marked cdecl.

On the other hand, you are calling a method of the root object/interface reference, which you have not initialised. That sort of action is sure to give you a segmentation fault.

getRuntime looks to be a class method of the Runtime class, so you've put in the wrong interface. When you've moved it to the right one, I'd imagine something like this might do it:

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

This code was checked in Delphi Berlin

For execute as root :

1) Add in AndroidManifest.template.xml this string

android:sharedUserId="android.uid.system"

2) sign APK as System by platform.x509.pem and platform.pk8 certificates

java.lang.Process, java.lang.Runtime hire

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.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!