Delphi xe5 exec root command conversion

落花浮王杯 提交于 2019-12-07 22:32:19

问题


i tried to covert Runtime and Process to send shell command to the rooted phone i don't understand why i had segmentation fault. On internet i found java code like:

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

for linux root privileges.

I tried only to send the "su" command with a function after the conversion but i think i wrong something... I think that one possible problem can be the array of Jstring conversion from java type.

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.

回答1:


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'));



回答2:


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.


来源:https://stackoverflow.com/questions/19857021/delphi-xe5-exec-root-command-conversion

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