Italian Edit File binario

klingon467

Member
Licensed User
Longtime User
Ciao a tutti,
ho il seguente problema ho creato un semplice editor in B4J per editare un file apk in cui devo inserire (alla fine del file possibilemente) dei parametri per poi leggerli quando viene eseguita l'apk sul dispositivo. vi posto il sorgente di quello che sono riuscito a fare...
B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Dim raf As RandomAccessFile
    Private btnWrite As Button
    Private btnRead As Button
    Dim txtHost As TextField
    Dim txtPort As TextField
    Dim MsgBox As Msgboxes
    Private btnRead As Button
    Private btnOpen As Button
    Dim txtPath As TextField
   
    'blocco dialog

    Dim stubName As String
    Dim stubPath As String


End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("Main") 'Load the layout file.
    MainForm.Show
    stubName = "myar.apk.bak"
    stubPath = File.DirApp
    If File.Exists(stubPath, "myar.apk") = True Then
    File.Delete(stubPath, "myar.apk")
    Else
    File.Copy(stubPath, stubName, stubPath, "myar.apk")
    End If
    raf.Initialize(stubPath, "myar.apk", False)
End Sub
Public Sub Write (whost As String, wport As String)
Dim whostB() As Byte
Dim wportB() As Byte

whostB = whost.GetBytes("UTF8")
wportB = wport.GetBytes("UTF8")

raf.WriteBytes(wportB, 0,  wportB.Length, 8850)'write the port + split on position 8850
raf.WriteBytes(whostB, 0, whostB.Length, 8858)'write the hostname + split on position 8858

End Sub
Sub btnWrite_Action
Try
Dim host As String
Dim port As String
host = txtHost.Text & "SPLT"
port = txtPort.Text & "SPLT"
    Write(host, port)
    MsgBox.Show("Done!","Info")
    Catch
    Log(LastException.Message)
    End Try
End Sub
Sub btnRead_Action
    Read
End Sub
Public Sub Read
Dim buffer(48) As Byte
Dim str As String
Dim strArr() As String

For i = 0 To buffer.Length
raf.ReadBytes(buffer, 0, buffer.Length, 8850)
str = BytesToString(buffer, 0, buffer.Length, "UTF8")
strArr = Regex.Split("SPLT", str)

Next
Log(strArr(0)) 'read port
Log(strArr(1)) 'read host
End Sub
Questo funziona bene ma l'apk risulta corrotta perchè scrivo in un offset apparentemente con byte nulli ma a quanto pare corrompe l'app.
Ho notato che editando l'apk con un editor esadecimale (es: HexWorkshop) ed aggiungendo a mano i parametri alla fine l'apk funziona in pratica esiste un equivalente di:

visual studio 6 code:
B4X:
Function WriteFile(PathToWFile As String, WriteData As String) As String 'simple Function to write the Data in a File
Open PathToWFile For Binary As #2
Put #2, , WriteData
Close #2
End Function

grazie in anticipo
 

iz0ndg

Active Member
Licensed User
Longtime User
Scusami, magari dico una sciocchezza, ma da quello che so io un file apk è un file compresso e se appendi direttamente a questo file qualcosa è normale che ti si corrompa. Credo che la procedura giusta sia di scompattarlo, aggiungerci un file con quello che ti serve e ricompattarlo.
Preciso che non ho mai provato.
 

picenainformatica

Active Member
Licensed User
Longtime User
Penso di aver capito. Aggiunge in coda al file APK (senza modificarne il contenuto) un qualche cosa tipo numero di serie dal leggere dall'APK originale e non dentro le installazioni. In Windows funziona(va), non ho più usato questo metodo da anni.
 

klingon467

Member
Licensed User
Longtime User
Penso di aver capito. Aggiunge in coda al file APK (senza modificarne il contenuto) un qualche cosa tipo numero di serie dal leggere dall'APK originale e non dentro le installazioni. In Windows funziona(va), non ho più usato questo metodo da anni.
Bravo! esattamente il file apk è formato compresso quindi si può aggiungere dati solo in fondo (EOF) e funziona perfettamente fatto la prova utilizzando HexWorkshop (screen.JPG) inserendolo manualmente. Il problema ora è capire come scrivere in fondo all'apk tramite b4j ma con la funzione:

B4X:
raf.WriteBytes(wportB, 0,  wportB.Length, 8850)
chiede chiaramente di specificare un offset dove iniziare a scrivere i dati

in visual basic puro è piuttosto banale:

editor:
B4X:
Private Sub Command1_Click()
Dim myStub As String
Dim ResourceFile As String
Dim ResultFile As String
Dim message As String

message = "Hello Word!"


myStub = App.Path & "\stub.exe" 'my resource
ResourceFile = LoadFile(myStub) 'read my resource


ResultFile = App.Path & "\result.exe" 'final results

'write data into resource file
Call WriteFile(ResultFile, ResourceFile & "####" & message & "####")

MsgBox ("Done")
End Sub
Function LoadFile(PathToFile As String) As String 'simple Function to Read the Data of the File
Open PathToFile For Binary As #1
LoadFile = Space(LOF(1))
Get #1, , LoadFile
Close #1
End Function
Function WriteFile(PathToWFile As String, WriteData As String) As String 'simple Function to write the Data in a File
Open PathToWFile For Binary As #2
Put #2, , WriteData
Close #2
End Function

stub:

B4X:
Private Sub Form_Load()
Dim Datos As String
Dim sData() As String

Datos = LoadFile(App.Path & "\" & App.EXEName & ".exe")

sData = Split(Datos, "####") 'split data

MsgBox (sData(1))
Unload Me

End Sub
Function LoadFile(PathToFile As String) As String 'simple Function to Read the Data of the File
Open PathToFile For Binary As #1
LoadFile = Space(LOF(1))
Get #1, , LoadFile
Close #1
End Function
 

Attachments

  • screen.JPG
    screen.JPG
    113 KB · Views: 168

picenainformatica

Active Member
Licensed User
Longtime User
come offset dai la lunghezza del file apk. se non sbaglio lof(1) corrisponde a basestream.length

@maxware, tu non vieni da Klingon
 

klingon467

Member
Licensed User
Longtime User
come offset dai la lunghezza del file apk. se non sbaglio lof(1) corrisponde a basestream.length

@maxware, tu non vieni da Klingon
Quasi! modificando così:
B4X:
Public Sub Write (whost As String, wport As String)
Dim whostB() As Byte
Dim wportB() As Byte

whostB = whost.GetBytes("UTF8")
wportB = wport.GetBytes("UTF8")

raf.WriteBytes(wportB, 0,  wportB.Length, wportB.Length)'write the port + split
raf.WriteBytes(whostB, 0, whostB.Length, wportB.Length + 8)'write the hostname + split
End Sub

ma scrive in testa al file! :eek:
 

Attachments

  • azz!.JPG
    azz!.JPG
    111.9 KB · Views: 167

LucaMs

Expert
Licensed User
Longtime User
Quasi! modificando così:
B4X:
Public Sub Write (whost As String, wport As String)
Dim whostB() As Byte
Dim wportB() As Byte

whostB = whost.GetBytes("UTF8")
wportB = wport.GetBytes("UTF8")

raf.WriteBytes(wportB, 0,  wportB.Length, wportB.Length)'write the port + split
raf.WriteBytes(whostB, 0, whostB.Length, wportB.Length + 8)'write the hostname + split
End Sub

ma scrive in testa al file! :eek:


Dovresti usare raf.Size, nella WriteBytes

upload_2015-7-10_11-12-32.png


raf.Size al posto di Position
 

picenainformatica

Active Member
Licensed User
Longtime User
@LucaMs Il tuo APK è dentro il terminale. Qualcuno (MyAPK) li estrae e li salva all'esterno. Dentro la cartella "data/system" trovi "packages.xml" con dentro l'elenco degli APK sparsi nel tablet con il nome ed il percorso completo.
 

picenainformatica

Active Member
Licensed User
Longtime User
Ci fai quello che vuoi, compreso tirarle fuori, decompilarle o metterle da parte. @klingon467 rileggerà i suoi dati e saprà che strada ha fatto l'APK ad entrare nel tablet (ossia da quale canale è stato scaricato o se è stato estratto da qualcuno per passarlo a qualcun altro).
 

klingon467

Member
Licensed User
Longtime User
Io sono invece curioso di sapere come farai poi a leggere quei dati a runtime, da dentro l'app (se non è questo lo scopo, allora... non ho capito lo scopo :D)
Ottima intuizione! è proprio questo lo scopo!
infatti già cercavo un surrogato di Application.Startupath

+Rep per LucaMs funziona a meraviglia utilizzando raf.size

ora rimane come da te intuito leggere dati in runtime.... e trovare un equivalente in (b4a) di application.startupath o se preferisci app.path & "\" & EXEname & ".exe"

grazie per la dritta comunque!
 

Attachments

  • ok!.JPG
    ok!.JPG
    59.5 KB · Views: 169
Last edited:

klingon467

Member
Licensed User
Longtime User
Non riesco a leggerli per ora sempre con b4j la funzione che utilizzo è:

B4X:
Public Sub Read
Dim buffer() As Byte
Dim str As String
Dim strArr() As String

For i = 0 To buffer.Length
raf.ReadBytes(buffer, 0, buffer.Length, raf.Size)
str = BytesToString(buffer, 0, buffer.Length, "UTF8")
strArr = Regex.Split("SPLT", str)

Next
Log(strArr(0)) 'read port
Log(strArr(1)) 'read host
End Sub
lo split "SPLT" per definire i vari blocchi da leggere

strArr(0) porta
strArr(1) l'host

ma mi restituisce un eccezione:
Program started.
main._read (java line: 191)
java.lang.ArrayIndexOutOfBoundsException: 1
at b4j.example.main._read(main.java:191)
at b4j.example.main._btnread_action(main.java:88)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
at anywheresoftware.b4a.BA$2.run(BA.java:165)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:182)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:179)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:179)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:17)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:67)
at java.lang.Thread.run(Thread.java:745)
avete idee?
 

picenainformatica

Active Member
Licensed User
Longtime User
Usa la libreria RandomAccessFile. Usa la stessa logica del tuo esempio in VB6.
 
Top