1. crackme
package com.j.crackme;
import android.content.pm.ApplicationInfo;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Base64;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.j.ctz.IMyClass;
import dalvik.system.DexClassLoader;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class MainActivity
extends AppCompatActivity
{
private Class clazz = null;
private void a()
{
if (this.clazz == null)
{
// 调用c方法
if (!c()) {
return;
}
Object localObject = new StringBuilder();
((StringBuilder)localObject).append(getApplicationInfo().dataDir);
((StringBuilder)localObject).append(File.separator);
((StringBuilder)localObject).append("files");
((StringBuilder)localObject).append(File.separator);
((StringBuilder)localObject).append("plugin.jar");
localObject = new File(((StringBuilder)localObject).toString()).getAbsolutePath();
String str = getApplicationInfo().dataDir;
try
{
DexClassLoader localDexClassLoader = new dalvik/system/DexClassLoader;
localDexClassLoader.<init>((String)localObject, str, null, getClassLoader());
// 加载plugin.jar里的class给clazz
this.clazz = localDexClassLoader.loadClass("com.j.base.MyClass");
}
catch (Exception localException)
{
localException.printStackTrace();
return;
}
}
}
// c方法功能:先对每个字节异或,再传入plugin.jar
private boolean c()
{
try
{
// 调用d方法
byte[] arrayOfByte = d(getAssets().open("plugin"));
if (arrayOfByte == null) {
return false;
}
// 每个字节异或0xEF
for (int i = 0; i < arrayOfByte.length; i++) {
arrayOfByte[i] = ((byte)(byte)(arrayOfByte[i] ^ 0xEF));
}
BufferedOutputStream localBufferedOutputStream = new java/io/BufferedOutputStream;
localBufferedOutputStream.<init>(openFileOutput("plugin.jar", 0));
// 再写入到plugin.jar
localBufferedOutputStream.write(arrayOfByte);
localBufferedOutputStream.flush();
localBufferedOutputStream.close();
return true;
}
catch (Exception localException)
{
localException.printStackTrace();
}
return false;
}
// d方法功能:传入一个数据流, 将其转换为字节数组
public byte[] d(InputStream paramInputStream)
{
try
{
ByteArrayOutputStream localByteArrayOutputStream = new java/io/ByteArrayOutputStream;
localByteArrayOutputStream.<init>();
byte[] arrayOfByte = new byte[1024];
for (;;)
{
int i = paramInputStream.read(arrayOfByte);
if (i == -1) {
break;
}
localByteArrayOutputStream.write(arrayOfByte, 0, i);
}
localByteArrayOutputStream.flush();
localByteArrayOutputStream.close();
paramInputStream.close();
paramInputStream = localByteArrayOutputStream.toByteArray();
}
catch (IOException paramInputStream)
{
paramInputStream.printStackTrace();
paramInputStream = null;
}
return paramInputStream;
}
protected void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
setContentView(2131296283);
((Button)findViewById(2131165218)).setOnClickListener(new View.OnClickListener()
{
public void onClick(View paramAnonymousView)
{
// 调用a方法
MainActivity.this.a();
EditText localEditText = (EditText)MainActivity.this.findViewById(2131165234);
paramAnonymousView = localEditText.getText().toString();
if (MainActivity.this.clazz != null) {
try
{
// 经过Myclass加密之后,再base64encode
if
(Base64.encodeToString(((IMyClass)MainActivity.this.clazz.newInstance()).check(paramAnonymousView), 0).equals("+sfQ39PX3eGOzOGNyt/Kj90=\n"))
{
Toast.makeText(MainActivity.this.getApplicationContext(), "Good job", 0).show();
localEditText.setText(String.format("flag{%s}", new Object[] { paramAnonymousView }));
}
else
{
Toast.makeText(MainActivity.this.getApplicationContext(), "Why you say so", 0).show();
}
}
catch (Exception paramAnonymousView)
{
paramAnonymousView.printStackTrace();
return;
}
}
}
});
}
}
程序生成plugin.jar之后直接从/data/data/$(packagename)/
找到plugin.jar , 代码如下:
package com.j.base;
import com.j.ctz.IMyClass;
public class MyClass implements IMyClass {
public MyClass() {
super();
}
// 只是做了简单的异或操作
public byte[] check(String arg4) {
byte[] v0 = arg4.getBytes();
int v1;
for(v1 = 0; v1 < v0.length; ++v1) {
v0[v1] = ((byte)(v0[v1] ^ 190));
}
return v0;
}
}
import base64
print ''.join(map(lambda x:chr(ord(x)^190), list(base64.b64decode("+sfQ39PX3eGOzOGNyt/Kj90="))))
flag:
Flag{Dynamic_0r_3tat1c}
2.hiddendata
思路: Java层没做什么处理, 直接调用so层的check函数. 分析so层, 发现main函数没做什么处理, 分析onLoad能得到结果.
#-*-coding = utf-8-*-
ori = [0x41, 0xFF, 0xF3, 0xDB, 0x06, 0xB3, 0x69, 0xC2, 0x90, 0xA3,
0x21, 0x8F, 0x7B, 0x6D, 0x32, 0x8C]
keys = [0x56, 0xFC, 0xD8, 0x66]
final = [0x64, 0x32, 0x4A, 0xCD, 0x34, 0xE6, 0x5D, 0x82, 0xB6, 0x53,
0x0B, 0x39, 0xC8, 0xE7, 0x21, 0x71]
after = [i for i in range(len(final))]
v = [i for i in range(len(final))]
flag = ""
for i in range(len(after)):
key = keys[i % 4];
v[i] = ((((ori[i] >> i % 4) | (ori[i] << i / 4)) & 0xff) ^ key ^ final[i])
flag += chr(v[i])
print flag
python脚本比较坑的一点要注意: 左移的时候可能大于32位(int 是32位) 即64bit. 所以要与上0xff.
import sys
i = sys.maxint
print i # 查看int变量的最大值
3. hide
#coding=utf-8
import struct
import string
def u32(data):
return struct.unpack("<I",data)[0]
def p32(data):
return struct.pack("<I",data)
def u64(data):
return struct.unpack("<Q",data)[0]
def p64(data):
return struct.pack("<Q",data)
input1 = '1234567890123456'
input1 = bytearray(input1)
CONST_STR = 's1IpP3rEv3Ryd4Y3'
CONST = 0X676E696C
v4 = 0
v4_4=0
v4_4_arr = [0 for i in range(0,9)]
for i in range(1,9):
v4_4_arr[i] = (v4_4_arr[i-1]+CONST)&0XFFFFFFFF
def re_block(byte_arr_8):
i = 0
v3 = u32(byte_arr_8[0:4])
v4 = u32(byte_arr_8[4:8])
print 'round', v3, v4
for i in range(7,-1,-1):
v30 = (v3 << 4) & 0xffffffff
v2c = v3 >> 5
edx = v30 ^ v2c
v30 = (v3 + edx) & 0xffffffff
v28 = (v4_4_arr[i+1] >> 11) & 3
edx = u32(CONST_STR[v28 * 4:(v28 + 1) * 4])
v2c = (v4_4_arr[i+1] + edx) & 0xffffffff # xxxx
# print 'v2c',hex(v2c)
print v30 ^ v2c
v4 = (v4+0x100000000-(v30 ^ v2c)) & 0xffffffff
v30 = (v4 << 4) & 0xffffffff
v2c = v4 >> 5
edx = v30 ^ v2c
v30 = (v4 + edx) & 0xffffffff
v28 = v4_4_arr[i] & 3
edx = u32(CONST_STR[v28 * 4:(v28 + 1) * 4])
v2c = (v4_4_arr[i] + edx) & 0xffffffff
v3 = (v3+0x100000000-(v30 ^ v2c)) & 0xffffffff
print 'round',i,v3,v4
byte_arr_8[0:4] = p32(v3)
byte_arr_8[4:8] = p32(v4)
return byte_arr_8
def xor16(byte_arr_16):
for i in range(0,16):
byte_arr_16[i]^=i
def re_all(str16):
byte_arr = bytearray(str16)
xor16(byte_arr)#传入整个bytearray,就是传入地址
byte_arr[0:8] = re_block(byte_arr[0:8])#传入部分bytearray,就是复制之后再传入
byte_arr[8:16] = re_block(byte_arr[8:16])
xor16(byte_arr)
byte_arr[0:8] = re_block(byte_arr[0:8])
byte_arr[8:16] = re_block(byte_arr[8:16])
xor16(byte_arr)
byte_arr[0:8] = re_block(byte_arr[0:8])
byte_arr[8:16] = re_block(byte_arr[8:16])
return str(byte_arr)
def block(str8):
i=0
input1=bytearray(str8)
v3 = u32(input1[8 * i:8 * i + 4])
v4 = u32(input1[8 * i + 4:8 * (i + 1)])
v4_4 = 0 ##0000
for j in range(0, 8):
v30 = (v4 << 4) & 0xffffffff
v2c = v4 >> 5
edx = v30 ^ v2c
v30 = (v4 + edx) & 0xffffffff
v28 = v4_4 & 3
edx = u32(CONST_STR[v28 * 4:(v28 + 1) * 4])
v2c = (v4_4 + edx) & 0xffffffff
v3 = ((v30 ^ v2c) + v3) & 0xffffffff
v4_4 = (v4_4 + CONST) & 0xffffffff
v30 = (v3 << 4) & 0xffffffff
v2c = v3 >> 5
edx = v30 ^ v2c
v30 = (v3 + edx) & 0xffffffff
v28 = (v4_4 >> 11) & 3
edx = u32(CONST_STR[v28 * 4:(v28 + 1) * 4])
v2c = (v4_4 + edx) & 0xffffffff # xxxx
print v30 ^ v2c
v4 = ((v30 ^ v2c) + v4) & 0xffffffff
print 'round', j, v3, v4
input1[8 * i:8 * i + 4] = p32(v3)
input1[8 * i + 4:8 * (i + 1)] = p32(v4)
str8_1=str(input1)
return str8_1
def block2(str8):
input1 = bytearray(str8)
for i in range(0,8):
input1[i]=input1[1]^i
return str(input1)
des = ('52B8137F358CF21B'+'F46386D2734F1E31').decode('hex')
print len(des)
print block('12345678').encode('hex')
des1 = '5b90ef3f91b58fe6'.decode('hex')
print re_all(bytearray(des))
4. re0_0
for循环是解密解密之后就能正常F5
解密之后可看到逻辑简单
# import idc_bytes
# buf = ida_bytes.get_bytes(0x600B00, 182)
# patch = ""
# for i in buf:
# patch += chr(ord(i) ^ 0x0C)
# ida_bytes.patch_bytes(0x600B00,patch)
enc = [0x66, 0x6D, 0x63, 0x64, 0x7F, 0x6B, 0x37, 0x64, 0x3B, 0x56, 0x60, 0x3B, 0x6E, 0x70]
flag = ""
for i in range(len(enc)):
flag += chr(i ^ enc[i])
print flag
5. re1_0
思路: 找到关键比较下断读寄存器或直接patch
6. EVR
思路: 爆破
1533210933799.pngflag_enc = [30, 21, 2, 16, 13, 72, 72, 111, 221, 221, 72, 100, 99, 215, 46, 44, 254, 106, 109, 42, 242, 111, 154, 77, 139, 75, 10, 138, 79, 69, 23, 70, 79, 20, 11]
flag=""
for i in range(7):
flag += chr(flag_enc[i]^0x76)
for i in range(7):
for j in range(32,127):
a = j ^ 0x76 ^ 0xad
a = (2 * a) & 0xaa | (( a & 0xaa) >> 1)
if(a==flag_enc[i+7]):
flag += chr(j)
for i in range(7):
for j in range(32,127):
a = j ^ 0x76 ^ 0xbe
a = (4 * a) & 0xcc | (( a & 0xcc) >> 2)
if(a==flag_enc[i+14]):
flag += chr(j)
for i in range(7):
for j in range(32,127):
a = j ^ 0x76 ^ 0xef
a = (16 * a) & 0xf0 | (( a & 0xf0) >> 4)
if(a==flag_enc[i+21]):
flag += chr(j)
for i in range(7):
flag += chr(flag_enc[i+28]^0x76)
print flag
7. Magic
https://4hou.win/wordpress/?p=20989
https://www.52pojie.cn/thread-742361-1-1.html
8. apl
apl语言非常简介,当然,看他也像看天书一样.
简介: https://zh.wikipedia.org/wiki/APL%E8%AA%9E%E8%A8%80
https://monosource.github.io/writeup/2018/05/08/plaidctf-aplunatics/
⎕IO←0⋄'BIE°?½>IL½E.!!<E!:E84¥¸²E23Å8»968'{{⍵(~⍵)/'success' 'fail'}⊃(+/⍺= 13+{+/⍵/⌽2*⍳⍴⍵}¨,/33 8⍴(8×⍴⍵)⍴7⌽⍉(-⌊(⍴'f0xtr0t')÷2)⌽⍉11 24⍴∊{a≠8↑(0,a←(8⍴2)⊤⍵)}¨⌽⎕⎕UCSUCS ⍵)=⍴⍺}'INPUT HERE'
⎕IO←0⋄
是多余的.
网友评论