Android 逆向入门

Android 逆向入门,第1张

概述AndroidRe入门必备工具:IDA:反编译.so文件AndroidKiller:反编译apk文件及再次编译为apkjd-gui:将.jar文件反编译为java代码dex2jar:反编译.dex文件apktool:能够反编译及回编译apk夜神模拟器:运行apk文件例题1[easy-so]下载来源:攻防世界使用夜神模拟器运 AndroID Re 入门必备工具:

IDA : 反编译.so文件

AndroIDKiller: 反编译apk文件及再次编译为apk

jd-gui : 将.jar文件反编译为java代码

dex2jar: 反编译.dex文件

apktool: 能够反编译及回编译apk

夜神模拟器: 运行apk文件

例题 1 [easy-so]

下载

来源:攻防世界

使用夜神模拟器运行该apk文件, 发现需要输入flag

zip解压apk文件, 用 dex2jar反编译 classes.dex文件得到classes-dex2jar.jar,

d2j-dex2jar.bat classes.dex

再用jd-gui打开classes-dex2jar.jar反编译为java代码.

public class MainActivity extends AppCompatActivity {  protected voID onCreate(Bundle paramBundle) {    super.onCreate(paramBundle);    setContentVIEw(2131296283);    ((button)findVIEwByID(2131165218)).setonClickListener(new VIEw.OnClickListener() {          public voID onClick(VIEw param1VIEw) {            if (cyberpeace.CheckString(((EditText)MainActivity.this.findVIEwByID(2131165233)).getText().toString()) == 1) {              Toast.makeText((Context)MainActivity.this, ", 1).show();              return;            }             Toast.makeText((Context)MainActivity.this, ", 1).show();          }        });  }}

在这里可以发现, cyberpeace加载了'cyberpeace'动态库, CheckString函数是native层的, 这个函数的实现就在libcyberpeace.so文件中

package com.testjava.jack.Pingan2;public class cyberpeace {  static {    System.loadlibrary("cyberpeace");  }    public static native int CheckString(String paramString);}

使用IDa打开lib/x86/libcyberpeace.so文件, 找到 _BOol4 __cdecl Java_com_testjava_jack_Pingan2_cyberpeace_CheckString(int a1, int a2, int a3)函数, 该函数实现如下:

_BOol4 __cdecl Java_com_testjava_jack_Pingan2_cyberpeace_CheckString(int a1, int a2, int a3){  const char *get_str; // ST1C_4  size_t len; // edi  char *str; // esi  size_t i; // edi  char v7; // al  char v8; // al  size_t v9; // edi  char v10; // al  get_str = (const char *)(*(int (__cdecl **)(int, int, _DWORD))(*(_DWORD *)a1 + 676))(a1, a3, 0); // 从java层获取所输入的字符串  len = strlen(get_str);  str = (char *)malloc(len + 1);  memset(&str[len], 0, len != -1);  memcpy(str, get_str, len);  if ( strlen(str) >= 2 ) // 加密1  {    i = 0;    do    {      v7 = str[i];      str[i] = str[i + 16];      str[i++ + 16] = v7;    }    while ( i < strlen(str) >> 1 );  }  // 加密2  v8 = *str;  if ( *str )  {    *str = str[1];    str[1] = v8;    if ( strlen(str) >= 3 )    {      v9 = 2;      do      {        v10 = str[v9];        str[v9] = str[v9 + 1];        str[v9 + 1] = v10;        v9 += 2;      }      while ( v9 < strlen(str) );    }  }  return strcmp(str, "f72c5a36569418a20907b55be5bf95ad") == 0; // 与字符串作比较}

从以上发现, 对我们所输入的字符串进行了加密, 然后再与f72c5a36569418a20907b55be5bf95ad进行比较. 现在只需逆一下以上代码即可得到flag, exp代码如下

#include <stdio.h>#include <string.h>int main(voID) {	char str[] = "f72c5a36569418a20907b55be5bf95ad";	int i, v7, v8, v9, v10;	v8 = *str;	if ( *str ) {		*str = str[1];		str[1] = v8;		if ( strlen(str) >= 3 ) {      		v9 = 2;      		do {        		v10 = str[v9];        		str[v9] = str[v9 + 1];        		str[v9 + 1] = v10;        		v9 += 2;      		} while ( v9 < strlen(str) );		}	}		// 交换 	if ( strlen(str) >= 2 )	{   	 i = 0;    	do {      		v7 = str[i];      		str[i] = str[i + 16];     		str[i++ + 16] = v7;   	 	} while ( i < strlen(str) >> 1 );	}	printf("%s", str);  	return 0;}

运行以上代码即可获取flag

例题 2 [app2]

下载

来源:攻防世界

对输入的账号和密码在SecondActivity类中进行加密判断, 而加密调用了native层的加密函数

protected voID onCreate(Bundle paramBundle) {    super.onCreate(paramBundle);    setContentVIEw(2130903041);    Intent intent = getIntent();    String str1 = intent.getStringExtra("ili");    String str2 = intent.getStringExtra("lil");    if (Encryto.doRawData(this, str1 + str2).equals("VEIzd/V2UPYNdn/bxH3Xig==")) {      intent.setAction("androID.test.action.MoniterInstallService");      intent.setClass((Context)this, MoniterInstallService.class);      intent.putExtra("company", "tencent");      intent.putExtra("name", "Hacker");      intent.putExtra("age", 18);      startActivity(intent);      startService(intent);    }     SharedPreferences.Editor editor = getSharedPreferences("test", 0).edit();    editor.putString("ilil", str1);    editor.putString("lili", str2);    editor.commit();  }

IDA反编译doRawData函数, 因为a为对象, 选择a按下y 键 然后输入 jnienv*就可以显示对象的函数调用, 如下

int __cdecl doRawData(jnienv *a1, int a2, int a3, int a4){  char *v4; // esi  const char *v5; // ST10_4  int result; // eax  char *v7; // esi  Jstring (*v8)(jnienv *, const jchar *, Jsize); // ST10_4  size_t v9; // eax  int v10; // [esp+4h] [ebp-28h]  int v11; // [esp+8h] [ebp-24h]  int v12; // [esp+Ch] [ebp-20h]  int v13; // [esp+10h] [ebp-1Ch]  char v14; // [esp+14h] [ebp-18h]  unsigned int v15; // [esp+18h] [ebp-14h]  v15 = __readgsDWord(0x14u);  if ( checkSignature((int)a1, a2, a3) == 1 )  {    v14 = 0;    v13 = 0x3D3D7965;    v12 = 0x6B747365;    v11 = 0x74617369;    v10 = 0x73696874;    v4 = (char *)(*a1)->GetStringUTFChars(a1, (Jstring)a4, 0);    v5 = (const char *)AES_128_ECB_PKCS5padding_Encrypt(v4, (int)&v10);    (*a1)->ReleaseStringUTFChars(a1, (Jstring)a4, v4);    result = (int)(*a1)->NewStringUTF(a1, v5);  }  else  {    v7 = UNSIGNATURE[0];    v8 = (*a1)->NewString;    v9 = strlen(UNSIGNATURE[0]);    result = (int)v8(a1, (const jchar *)v7, v9);  }  return result;}

可以发现, 加密方式为aes加密, key 为 v10中的内容.为thisisatestkey==

对VEIzd/V2UPYNdn/bxH3Xig== 解密为aimagetencent, 发现提交flag错误, 重新找另一个字符串,在fileDataActivity类中找到如下.

public class fileDataActivity extends a {  private TextVIEw c;    protected voID onCreate(Bundle paramBundle) {    super.onCreate(paramBundle);    setContentVIEw(2130903042);    this.c = (TextVIEw)findVIEwByID(2131165184);    this.c.setText(Encryto.decode(this, "9YuQ2dk8CSaCe7DTAmaqAA=="));  }}

调用了decode函数, 而decode函数与doRawData实现一样, 直接与之前一样的AES ecb解密, 得到flag

总结

以上是内存溢出为你收集整理的Android 逆向入门全部内容,希望文章能够帮你解决Android 逆向入门所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1060020.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存