我在java中得到了一个代码:
InputStream stream = null;
OutputStream output = null;
for(String fileName : this.getAssets().list("www"))
{
stream = this.getAssets().open("directoryName/" + fileName);
output = new BufferedOutputStream(new FileOutputStream("/mnt/sdcard/www/" + fileName));
byte data[] = new byte[1024];
int count;
while((count = stream.read(data)) != -1)
{
output.write(data, 0, count);
}
output.flush();
output.close();
stream.close();
stream = null;
output = null;
}
它工作得很完美...但是我需要将它重写为smali / dex,所以我可以将它编译成反编译应用程序(通过apktool)......它甚至可能吗?有人可以帮我吗?
答案 0 :(得分:2)
将Java翻译成Smali是:
Java -(javac)-> Java bytecode -(dx)-> Dex bytecode -(baksmali)-> Smali
如果您还没有,请下载Android SDK。
由于您的代码调用this.getAssets()
,因此它需要位于Activity类中。如果您还没有Eclipse设置来构建Android项目,那么您应该从这里开始:Setting up the ADT Bundle。设置完成后,创建一个新的Android项目。然后,将此代码添加到主活动中的方法。像这样:
public void copyAssets() throws IOException {
InputStream stream = null;
OutputStream output = null;
for (String fileName : this.getAssets().list("www")) {
stream = this.getAssets().open("directoryName/" + fileName);
output = new BufferedOutputStream(new FileOutputStream("/mnt/sdcard/www/" + fileName));
byte data[] = new byte[1024];
int count;
while ((count = stream.read(data)) != -1) {
output.write(data, 0, count);
}
output.flush();
output.close();
stream.close();
stream = null;
output = null;
}
}
然后,将项目导出到APK。最后,baksmali APK获得你的Smali。它必须添加到Activity类或具有this.getResources()
访问权限的内容中。 Smali看起来像:
.method public copyAssets()V
.registers 13
.annotation system Ldalvik/annotation/Throws;
value = {
Ljava/io/IOException;
}
.end annotation
.prologue
const/4 v6, 0x0
.line 41
const/4 v4, 0x0
.line 42
.local v4, "stream":Ljava/io/InputStream;
const/4 v3, 0x0
.line 44
.local v3, "output":Ljava/io/OutputStream;
invoke-virtual {p0}, Lcom/lookout/sauronprobe/MainActivity;->getAssets()Landroid/content/res/AssetManager;
move-result-object v5
const-string v7, "www"
invoke-virtual {v5, v7}, Landroid/content/res/AssetManager;->list(Ljava/lang/String;)[Ljava/lang/String;
move-result-object v7
array-length v8, v7
move v5, v6
:goto_f
if-lt v5, v8, :cond_12
.line 62
return-void
.line 44
:cond_12
aget-object v2, v7, v5
.line 45
.local v2, "fileName":Ljava/lang/String;
invoke-virtual {p0}, Lcom/lookout/sauronprobe/MainActivity;->getAssets()Landroid/content/res/AssetManager;
move-result-object v9
new-instance v10, Ljava/lang/StringBuilder;
const-string v11, "directoryName/"
invoke-direct {v10, v11}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
invoke-virtual {v10, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v10
invoke-virtual {v10}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v10
invoke-virtual {v9, v10}, Landroid/content/res/AssetManager;->open(Ljava/lang/String;)Ljava/io/InputStream;
move-result-object v4
.line 46
new-instance v3, Ljava/io/BufferedOutputStream;
.end local v3 # "output":Ljava/io/OutputStream;
new-instance v9, Ljava/io/FileOutputStream;
new-instance v10, Ljava/lang/StringBuilder;
const-string v11, "/mnt/sdcard/www/"
invoke-direct {v10, v11}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
invoke-virtual {v10, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v10
invoke-virtual {v10}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v10
invoke-direct {v9, v10}, Ljava/io/FileOutputStream;-><init>(Ljava/lang/String;)V
invoke-direct {v3, v9}, Ljava/io/BufferedOutputStream;-><init>(Ljava/io/OutputStream;)V
.line 48
.restart local v3 # "output":Ljava/io/OutputStream;
const/16 v9, 0x400
new-array v1, v9, [B
.line 51
.local v1, "data":[B
:goto_48
invoke-virtual {v4, v1}, Ljava/io/InputStream;->read([B)I
move-result v0
.local v0, "count":I
const/4 v9, -0x1
if-ne v0, v9, :cond_5d
.line 55
invoke-virtual {v3}, Ljava/io/OutputStream;->flush()V
.line 56
invoke-virtual {v3}, Ljava/io/OutputStream;->close()V
.line 57
invoke-virtual {v4}, Ljava/io/InputStream;->close()V
.line 59
const/4 v4, 0x0
.line 60
const/4 v3, 0x0
.line 44
add-int/lit8 v5, v5, 0x1
goto :goto_f
.line 52
:cond_5d
invoke-virtual {v3, v1, v6, v0}, Ljava/io/OutputStream;->write([BII)V
goto :goto_48
.end method
.method protected onCreate(Landroid/os/Bundle;)V
.registers 6
.param p1, "savedInstanceState" # Landroid/os/Bundle;
.prologue
.line 24
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
.line 25
const/high16 v1, 0x7f030000
invoke-virtual {p0, v1}, Lcom/lookout/sauronprobe/MainActivity;->setContentView(I)V
.line 27
invoke-static {}, Lcom/lookout/sauronprobe/MonitorHub;->instance()Lcom/lookout/sauronprobe/MonitorHub;
move-result-object v0
.line 28
.local v0, "hub":Lcom/lookout/sauronprobe/MonitorHub;
invoke-virtual {v0}, Lcom/lookout/sauronprobe/MonitorHub;->start()V
.line 30
new-instance v1, Landroid/content/Intent;
sget-object v2, Lcom/lookout/sauronprobe/Sauron;->instance:Landroid/app/Application;
const-class v3, Lcom/lookout/sauronprobe/telemetry/mq/MessagingService;
invoke-direct {v1, v2, v3}, Landroid/content/Intent;-><init>(Landroid/content/Context;Ljava/lang/Class;)V
invoke-virtual {p0, v1}, Lcom/lookout/sauronprobe/MainActivity;->startService(Landroid/content/Intent;)Landroid/content/ComponentName;
.line 31
return-void
.end method
预先做了很多工作,但是一旦完成它或者你已经有Eclipse设置就很容易。
首先,重构代码,使其可以作为静态方法独立存在。它将需要一个上下文参数来访问getAssets()
。使用与类名相同的文件名保存它。在这种情况下, CopyAssets.java 。代码如下所示:
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
public class CopyAssets {
public static void copyAssets(android.content.Context ctx) throws IOException {
InputStream stream = null;
OutputStream output = null;
for (String fileName : ctx.getAssets().list("www")) {
stream = ctx.getAssets().open("directoryName/" + fileName);
output = new BufferedOutputStream(new FileOutputStream("/mnt/sdcard/www/" + fileName));
byte data[] = new byte[1024];
int count;
while ((count = stream.read(data)) != -1) {
output.write(data, 0, count);
}
output.flush();
output.close();
stream.close();
stream = null;
output = null;
}
}
}
其次,确保您使用SDK下载了Android平台。在这种情况下,我将Android-18下载到〜/ android / sdk / platforms。编译命令是:
javac -cp ~/android/sdk/platforms/android-18/android.jar CopyAssets.java
然后,您将拥有一个CopyAssets.class。使用以下命令将其转换为Dex:
dx --dex --no-strict --output copyassets.dex CopyAssets.class
--no-strict
告诉dx
不要担心文件结构。
最后,使用baksmali将Dex文件转换为Smali:
baksmali copyassets.dex
您将通过静态方法获得Smali,您可以轻松添加。必须先通过Activity.getBaseContext()
获取上下文来调用它。你会得到这个Smali:
.class public LCopyAssets;
.super Ljava/lang/Object;
.source "CopyAssets.java"
# direct methods
.method public constructor <init>()V
.registers 1
.prologue
.line 11
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method public static copyAssets(Landroid/content/Context;)V
.registers 11
.annotation system Ldalvik/annotation/Throws;
value = {
Ljava/io/IOException;
}
.end annotation
.prologue
const/4 v1, 0x0
.line 13
.line 16
invoke-virtual {p0}, Landroid/content/Context;->getAssets()Landroid/content/res/AssetManager;
move-result-object v0
const-string v2, "www"
invoke-virtual {v0, v2}, Landroid/content/res/AssetManager;->list(Ljava/lang/String;)[Ljava/lang/String;
move-result-object v2
array-length v3, v2
move v0, v1
:goto_d
if-ge v0, v3, :cond_64
aget-object v4, v2, v0
.line 17
invoke-virtual {p0}, Landroid/content/Context;->getAssets()Landroid/content/res/AssetManager;
move-result-object v5
new-instance v6, Ljava/lang/StringBuilder;
invoke-direct {v6}, Ljava/lang/StringBuilder;-><init>()V
const-string v7, "directoryName/"
invoke-virtual {v6, v7}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v6
invoke-virtual {v6, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v6
invoke-virtual {v6}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v6
invoke-virtual {v5, v6}, Landroid/content/res/AssetManager;->open(Ljava/lang/String;)Ljava/io/InputStream;
move-result-object v5
.line 18
new-instance v6, Ljava/io/BufferedOutputStream;
new-instance v7, Ljava/io/FileOutputStream;
new-instance v8, Ljava/lang/StringBuilder;
invoke-direct {v8}, Ljava/lang/StringBuilder;-><init>()V
const-string v9, "/mnt/sdcard/www/"
invoke-virtual {v8, v9}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v8
invoke-virtual {v8, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v4
invoke-virtual {v4}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v4
invoke-direct {v7, v4}, Ljava/io/FileOutputStream;-><init>(Ljava/lang/String;)V
invoke-direct {v6, v7}, Ljava/io/BufferedOutputStream;-><init>(Ljava/io/OutputStream;)V
.line 20
const/16 v4, 0x400
new-array v4, v4, [B
.line 23
:goto_4d
invoke-virtual {v5, v4}, Ljava/io/InputStream;->read([B)I
move-result v7
const/4 v8, -0x1
if-eq v7, v8, :cond_58
.line 24
invoke-virtual {v6, v4, v1, v7}, Ljava/io/OutputStream;->write([BII)V
goto :goto_4d
.line 27
:cond_58
invoke-virtual {v6}, Ljava/io/OutputStream;->flush()V
.line 28
invoke-virtual {v6}, Ljava/io/OutputStream;->close()V
.line 29
invoke-virtual {v5}, Ljava/io/InputStream;->close()V
.line 16
add-int/lit8 v0, v0, 0x1
goto :goto_d
.line 34
:cond_64
return-void
.end method
这是将所有这些结合在一起的有用别名:
function func_java2smali() {
if [ -z "${1}" ]; then
echo "usage: java2smali <java file>"
return
fi
filename=$(basename $1 .java)
outDir=$(shasum $1 | awk '{print $1}')
javac -cp ~/android/sdk/platforms/android-18/android.jar $1
dx --dex --no-strict --output=$filename.dex $filename.class
baksmali --sequential-labels --use-locals $filename.dex -o $outDir
cp -R $outDir/**/*.smali .
rm -r $outDir
rm $filename.class
rm $filename.dex
}
alias java2smali=func_java2smali
答案 1 :(得分:1)
使用此代码编译自己的应用程序并对其进行反编译以检索smali代码会不会更容易?