• Курсы Академии Кодебай, стартующие в мае - июне, от команды The Codeby

    1. Цифровая криминалистика и реагирование на инциденты
    2. ОС Linux (DFIR) Старт: 16 мая
    3. Анализ фишинговых атак Старт: 16 мая Устройства для тестирования на проникновение Старт: 16 мая

    Скидки до 10%

    Полный список ближайших курсов ...

Решено LS2J - CreateObject - передать массив строк?

duchan

Green Team
20.09.2006
127
11
BIT
118
День добрый.
необходимо через бридж ls2j при создании объекта из класса, передать массив строк.

в конструкторе java класса String[].
в LS в arg - массив строк
Код:
jClass.CreateObject("(Ljava/lang/String;)V", arg)
- это передает строку (понятно не работает)

как правильно написать сигнатуру для передачи именно массива и вообще это можно сделать?

Код:
jClass.CreateObject("([Ljava/lang/String;)V", arg)
или
Код:
jClass.CreateObject("(Ljava/lang/String[];)V", arg)
- не работает
 

savl

Lotus Team
28.10.2011
2 607
313
BIT
259
как правильно написать сигнатуру для передачи именно массива и вообще это можно сделать?
есть вот такой код, который для класса все методы с сигнатурами выводит.

Visual Basic:
    Function getMethodSignatures(jClass As Javaclass, l As noteslog)
        Dim msg$
        Dim methods As JavaMethodCollection
        Set methods = jclass.Getclassmethods()
        ForAll meth In methods
            msg$ = meth.Methodname & " - SIG: " & meth.Signature
            If Not(l Is Nothing) Then Call l.logaction(msg$)
            Print msg$
        End ForAll
    
    End Function
 

duchan

Green Team
20.09.2006
127
11
BIT
118
Спасибо, это упрощает многое.
Но, проблема в том что этот код не показывает конструктор, а затык в нем при CreateObject: "Java constructor failed to execute".
jClass.CreateObject("(Ljava/util/List;)V", arg)
Попробывал и "Ljava/util/List" и "Ljava/util/Map", и аргумент, который массивом передавать нельзя, но можно Variant, пробовал и через redim и split (что бы массив в вариант получить)... Ошибка...

суть кода в том что пытаюсь через ls2j "подружится" с "java.lang.ProcessBuilder" - надо из кода запустить консольную программу и получить то что она выводит в консоль (stdout).
через java библиотеку это делается и вроде работает, из ls-кода через ls2j её подтягиваю и запускаю.
Java:
import java.lang.ProcessBuilder;
import java.io.*;

public class ProcRun {
    public String Runs(String[] command ) throws IOException{
        //String[] command ={cmd};
        ProcessBuilder builder = new ProcessBuilder(command);
        builder.redirectErrorStream(true);
        Process p = builder.start();
        BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));

        StringBuffer response = new StringBuffer();
        String inputLine;
        while ((inputLine = r.readLine()) != null) {
            response.append(inputLine);
        }
        String result = response.toString();
        return result;
    }
}
Visual Basic:
    Set SysClass=jSession.GetClass("ProcRun")
    Set System = sysClass.CreateObject()
    v = System.Runs(arg)

Но, тут встал вопрос, а нельзя ли сделать без дополнительной java библиотеки всё на ls2j . Вот и экспериментирую.

Может кто подскажет?
 

garrick

Lotus Team
26.10.2009
1 352
151
BIT
205
Мутное какое-то описание, но из него следует, что массив строк нельзя никак.
Если сам конструктор класса модифицировать нельзя, то я б предложил написать какой-нибудь класс-бридж и использовать его. Массив строк можно передать в виде одной строки или собрать из последовательных вызовов какого-то метода, как add() в ArrayList. И уже в этом классе вызвать конструктор нужного.
 

garrick

Lotus Team
26.10.2009
1 352
151
BIT
205
если речь о методе command, то есть вариант без массива
 

duchan

Green Team
20.09.2006
127
11
BIT
118
Это я видел, но CreateObject() без параметров так же выдает ошибку:
Код:
    Set SysClass=jSession.GetClass("java/lang/ProcessBuilder")
    Set System = sysClass.CreateObject() '<- ERROR
 

savl

Lotus Team
28.10.2011
2 607
313
BIT
259
Это я видел, но CreateObject() без параметров так же выдает ошибку:
Код:
    Set SysClass=jSession.GetClass("java/lang/ProcessBuilder")
    Set System = sysClass.CreateObject() '<- ERROR
Так у ProcessBuilder нет конструктора без параметра, согласно тому же javadoc:
1707477102845.png


Возврат ошибок java из ls2j:
Visual Basic:
Dim getLastError As String
 Dim jError As JavaError
 
    If Not jSession Is Nothing Then
        Set jError = jSession.getLastJavaError()
        getLastError = jError.errorMsg
        jSession.ClearJavaError
    End If
 

duchan

Green Team
20.09.2006
127
11
BIT
118
конструктор без параметров, это уже было в качестве бреда.... ;)

но по декларация в самом лотусе следующее:
Java:
// Method descriptor #110 (Ljava/util/List;)V
  // Signature: (Ljava/util/List<Ljava/lang/String;>;)V
  // Stack: 2, Locals: 2
  public ProcessBuilder(java.util.List arg0);
и
Java:
// Method descriptor #107 ([Ljava/lang/String;)V
  // Stack: 4, Locals: 6
  public ProcessBuilder(java.lang.String... arg0);
у второго почему-то не описана сигнатура "Signature:", но он соответствует тому что я использовал в java-библиотеки выше.

в LS2J
Visual Basic:
Dim arg As Variant
arg= Split("MyAPP.exe|parametr", "|")
Set System = SysClass.CreateObject("([Ljava/lang/String;)V", arg)
выдает ошибку конструктора (без on error), при этом код из предыдущего поста по обработке ошибок (jSession.getLastJavaError().errorMsg), возвращает пустую строку...

может кто-нибудь знает как передать "(Ljava/util/List<Ljava/lang/String;>;)V"? что это должно быть в LS?
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 948
609
BIT
252
а что мешает создать джава объект List его заполнить поэлементно и передать?
массивы стрингов передаются (нотацию не помню), есть только момент с динамическими массивами
кмк фиксированной длинны - норм
ещё можно взять класс StringBuilder и его наполнить, а потом вызвать метод в массив стрингов...
ини сделать обвязку в в джава либе: класс без параметров, метод принимающий String[] - в него массив (опять мб затык с Variant и dynamic array)
короче - если нет Dim arr(size) As String - то только поэлементно, либо одной строкой и split уже в джава
 
Последнее редактирование:

duchan

Green Team
20.09.2006
127
11
BIT
118
а что мешает создать джава объект List его заполнить поэлементно и передать?
Огромное спасибо на наводку...
Всё получилось.
Вот результат тестового агента на LS (для истории):
Visual Basic:
UseLSX "*javacon"
Sub Initialize
    Dim jSession As JavaSession
    Dim ProcessBuilder As JavaClass
    Dim builder As JavaObject
    Dim Proc  As JavaObject
    Dim ListCL  As JavaClass
    Dim ListObj  As JavaObject
    Dim InputStreamReaderCL  As JavaClass
    Dim InputStreamReader  As JavaObject
    Dim BufferedReaderCL  As JavaClass
    Dim BufferedReader  As JavaObject

    Dim inputLine As String
    Dim v As Variant
  
    On Error GoTo m1
    'создаем java сессию
    Set jSession = New JavaSession

    ' создаем используемые классы
    Set ListCL =jSession.GetClass("java/util/ArrayList" )
    Set InputStreamReaderCL = jSession.Getclass({java/io/InputStreamReader})
    Set BufferedReaderCL = jSession.Getclass({java/io/BufferedReader})
    Set ProcessBuilder=jSession.GetClass("java/lang/ProcessBuilder")
  
    ' создаем список с параметрами запуска
    Set ListObj = ListCL.Createobject() ' создали объект
    Call ListObj.add("<тут ваше приложение>") ' первым приложение для запуска
    Call ListObj.add("<тут параметры>") ' далее добавляем передаваемые приложению параметры
                                        ' если надо несколько параметров добавляем в список через add
  
    ' создаем объект ProcessBuilder, которые и запускает приложение
    Set builder = ProcessBuilder.CreateObject("(Ljava/util/List;)V", ListObj)

    Call builder.redirectErrorStream(True) ' перенаправляем поток вывода ошибок, если хотите отдельно, то читаейте его отдельно - принцип ниже описан
    Set Proc = builder.start() ' запускаем приложение
  
    ' создаем потоки для чтения результатов вывода в консоль
    Set InputStreamReader = InputStreamReaderCL.CreateObject("(Ljava/io/InputStream;)V", Proc.getInputStream())
    Set BufferedReader = BufferedReaderCL.CreateObject("(Ljava/io/Reader;)V", InputStreamReader)
  
    ' читаем из потока
    v = BufferedReader.readLine()
    Do
        inputLine = inputLine+CStr(v)+Chr$(10) ' добавляем отрезанный перевод строки
        v = BufferedReader.readLine()
    Loop While Not IsEmpty(v) ' пока не вернет "null"
  
    ' Всё в inputLine у нас результат вывода в консоль...
    Print inputLine
    MsgBox  inputLine

    Exit Sub
m1:
    ' ну и обработчик ошибок до кучи....
    Dim getLastError As String
    Dim jError As JavaError
  
    If Not jSession Is Nothing Then
        Set jError = jSession.getLastJavaError()
        getLastError = jError.errorMsg
        jSession.ClearJavaError
    End If
    MsgBox Error() +Chr$(13)+ getLastError
    Exit Sub
End Sub

чем хорош: (по идее) кроссплатформенность, запускаем и ждем завершения консольной программы, получаем результат вывода в консоль и можем обрабатывать, при запуске не появляется "черное окно" консоли...
 
Последнее редактирование:

duchan

Green Team
20.09.2006
127
11
BIT
118
выяснилось, что на винде, если консоль выдает русский текст, то получаем "кракозябры", решается установкой для InputStreamReader charset в CP866

Set InputStreamReader = InputStreamReaderCL.CreateObject("(Ljava/io/InputStream;Ljava/lang/String;)V", Proc.getInputStream(), "CP866")

cp866 (!), а не win1251, (хотя System.getProperty("file.encoding") "ibm.system.encoding" - выдает cp1251, а "os.encoding"=UTF8) - виндовая консоль это DOS, но как-то это уж совсем...
интересно как на линухе будет... пока корректно с русскими буквами негде проверить, очень стойкое подозрение, что UTF-8, или он совпадет таки с каким-то из System.getProperty....
Может кто подскажет? ;)
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 948
609
BIT
252
выяснилось, что на винде, если консоль выдает русский текст, то получаем "кракозябры", решается установкой для InputStreamReader charset в CP866

Set InputStreamReader = InputStreamReaderCL.CreateObject("(Ljava/io/InputStream;Ljava/lang/String;)V", Proc.getInputStream(), "CP866")

cp866 (!), а не win1251, (хотя System.getProperty("file.encoding") "ibm.system.encoding" - выдает cp1251, а "os.encoding"=UTF8) - виндовая консоль это DOS, но как-то это уж совсем...
интересно как на линухе будет... пока корректно с русскими буквами негде проверить, очень стойкое подозрение, что UTF-8, или он совпадет таки с каким-то из System.getProperty....
Может кто подскажет? ;)
решаешь уже давно пройденное :) и готовое и это (кодировка в джава налету: по ссылке - ссылка) там тоже решено...
для не джава программ - chcp (для шинды)
например для UTF-8
chcp 65001; bash -c "mosh remoteserver sudo ssh 192.168.0.10"
в линухе обычно UTF-8 , для символьного соответствия отображения (на экране) ещё локаль настраивают (если надо, форматы там разные... ещё)

также "там" (по ссылке) есть регэкспы для фильтра вывода и использование Scanner для контроля строк
будут вопросы по коду - объясню
 
Последнее редактирование:
  • Нравится
Реакции: duchan

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 948
609
BIT
252
и ждем завершения консольной программы
ваще ниразу ждать не нужно, работает "параллельно" (как и обычный | в консоли) - ну то есть, каждая строка считывается не дожидаясь окончания проги
а если замутить и ввод (в отдельном потоке, коммутацией) - будет круче, но у меня не было надобности
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 948
609
BIT
252
у мя по принципу через консоль уже не один проект был
код (один и тотже) работает как на никсовых серверах так и на шиндовых клиентах (внешний jar)
причём жвм может юзать внешнюю, а может доминошную (с поправкой на версию кода и жвм)
джава проге можно указывать при старте, в опциях, какую кодировку юзать, вне зависимости от платформы
 
Последнее редактирование:

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 948
609
BIT
252
выяснилось, что на винде, если консоль выдает русский текст, то получаем "кракозябры", решается установкой для InputStreamReader charset в CP866

Set InputStreamReader = InputStreamReaderCL.CreateObject("(Ljava/io/InputStream;Ljava/lang/String;)V", Proc.getInputStream(), "CP866")

cp866 (!), а не win1251, (хотя System.getProperty("file.encoding") "ibm.system.encoding" - выдает cp1251, а "os.encoding"=UTF8) - виндовая консоль это DOS, но как-то это уж совсем...
интересно как на линухе будет... пока корректно с русскими буквами негде проверить, очень стойкое подозрение, что UTF-8, или он совпадет таки с каким-то из System.getProperty....
Может кто подскажет? ;)
в шинде ещё вот это можно
1708791523238.png
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!