首页
社区
课程
招聘
[原创]lcweik的第一第二题writeup
2015-10-21 04:55 16383

[原创]lcweik的第一第二题writeup

2015-10-21 04:55
16383
第一题write up
拿到题目,首先是反编译和dex2jar
在jad-gui里看不到关键类check的java源码,
然后在smali代码基础上,去掉所有的synthetic字段,并把所以有的.catch替换为#.catch,
再重新生成dex文件,就可以在jad-gui里看到check类的java源码。

在jad-gui中看代码时,发现,它还做了混淆,有大量的数组赋值语句及反射调用,无法阅读,
但可以看到代码结构基本上是线性的,所以,只要盯着保存有用户输入的密码的那几个寄存器及if语句下断点,就能跟踪到关键逻辑。

关键逻辑有三个:
1、将用户输入数据转化为数字num1,所以密码一定是数字
2、将num1与1 5 9 ... 1001相加,但在下一步比较中发现是与124750相加,得num2
3、将num2与答案的密文520676做比较,如果相同,则密码正确,

将答案密文520676减去124750,得到答案395926

第二题write up
拿到题目,首先反编译,发现java层里有签名检验,判定密码的关键函数是so里的ch函数,
对于签名检验,使用幸运破解器去可以让签名检验失效。
这样子,只要不改变META-INF里的rsa文件,就不会影响签名检验逻辑了。

将so文件拖入ida,寻找符号Java_k2015_a2_Ch_ch,发现ch函数是静态注删的。
attach上去时,发现有反调试,之后定位到反调试有三种:
1、init_array里的最后一个函数是反调试,将dynamic节里的init_array_size减8,
并将init_array节的最后一个offset置0,可以去掉它
2、开一个新线程,不断从/proc/xxx/status里判断是否有进程ptrace自已,并发送信号量来校验线程没有关闭
我修改了getpid函数,让它一直返回1,这样子就检测不到ptrace了
3、代码逻辑中,包括加密后的代码多处从/proc/self/status中判断是否有进程ptrace自己,
对此,我把这些地方用于搞崩溃进程的两行汇编码改成无用的汇编码,密文的部分也一起改了再重加密回写到so文件。

过了反调试后,分析ch函数共有五层
第一层:就是寻找符号Java_k2015_a2_Ch_ch,什么都不干
第二层:反调试,解密并调用第三层,
好像在这层将输入数据写到一个原本是 0x0 0x1 0x2 0x3 0x4 ... 0xf的内存区域mem1
第三层:反调试,解密调用第四层函数,将mem1里的每一个字节分别加上0x0 0x1 0x2 0x3 ... 0xf
第四层:反调试,加密第二层,将第二层的密文的前16字节
0x1F, 0xBC, 0xDA, 0xFF, 0xE6, 0x4C, 0xBC, 0x44, 0xF5, 0xB8, 0x13, 0xC8, 0xEC, 0xA8, 0xCD, 0xBD
与mem1相加,解密调用第五层加密mem1,
并将结果与5C DA 77 2F A3 C6 3E 39  B6 F0 F3 ED 51 5A 99 86比较,如果相同说明密码正确。
第五层:有一个类似aes的算法,我将该算法逆了出来,再推出其解密算法,代码附在最后面,
后来发现,原来是标准的aes算法。
使用以下的代码,将5C DA 77 2F A3 C6 3E 39  B6 F0 F3 ED 51 5A 99 86解密后是
0x8A, 0x1F, 0x4B, 0x6E, 0x59, 0xCA, 0xF2, 0x52, 0x05, 0xCA, 0x27, 0xDE, 0x04, 0xC2, 0xE9, 0xDB
然后,按字节减去
0x1F, 0xBC, 0xDA, 0xFF, 0xE6, 0x4C, 0xBC, 0x44, 0xF5, 0xB8, 0x13, 0xC8, 0xEC, 0xA8, 0xCD, 0xBD
再减去
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
再把抹尾的填充字0x07 0x08 ... 0x0f去掉,得到最终答案
kboloy0

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

typedef unsigned u4;
typedef unsigned short u2;
typedef unsigned char u1;

int K;

const int Nb = 4;

int Nk;

int Nr;

static uint8_t mytable[512] = {
        0x63, 0xC6, 0x7C, 0xF8, 0x77, 0xEE, 0x7B, 0xF6, 0xF2, 0xFF, 0x6B, 0xD6, 0x6F, 0xDE, 0xC5, 0x91,
        0x30, 0x60, 0x01, 0x02, 0x67, 0xCE, 0x2B, 0x56, 0xFE, 0xE7, 0xD7, 0xB5, 0xAB, 0x4D, 0x76, 0xEC,
        0xCA, 0x8F, 0x82, 0x1F, 0xC9, 0x89, 0x7D, 0xFA, 0xFA, 0xEF, 0x59, 0xB2, 0x47, 0x8E, 0xF0, 0xFB,
        0xAD, 0x41, 0xD4, 0xB3, 0xA2, 0x5F, 0xAF, 0x45, 0x9C, 0x23, 0xA4, 0x53, 0x72, 0xE4, 0xC0, 0x9B,
        0xB7, 0x75, 0xFD, 0xE1, 0x93, 0x3D, 0x26, 0x4C, 0x36, 0x6C, 0x3F, 0x7E, 0xF7, 0xF5, 0xCC, 0x83,
        0x34, 0x68, 0xA5, 0x51, 0xE5, 0xD1, 0xF1, 0xF9, 0x71, 0xE2, 0xD8, 0xAB, 0x31, 0x62, 0x15, 0x2A,
        0x04, 0x08, 0xC7, 0x95, 0x23, 0x46, 0xC3, 0x9D, 0x18, 0x30, 0x96, 0x37, 0x05, 0x0A, 0x9A, 0x2F,
        0x07, 0x0E, 0x12, 0x24, 0x80, 0x1B, 0xE2, 0xDF, 0xEB, 0xCD, 0x27, 0x4E, 0xB2, 0x7F, 0x75, 0xEA,
        0x09, 0x12, 0x83, 0x1D, 0x2C, 0x58, 0x1A, 0x34, 0x1B, 0x36, 0x6E, 0xDC, 0x5A, 0xB4, 0xA0, 0x5B,
        0x52, 0xA4, 0x3B, 0x76, 0xD6, 0xB7, 0xB3, 0x7D, 0x29, 0x52, 0xE3, 0xDD, 0x2F, 0x5E, 0x84, 0x13,
        0x53, 0xA6, 0xD1, 0xB9, 0x00, 0x00, 0xED, 0xC1, 0x20, 0x40, 0xFC, 0xE3, 0xB1, 0x79, 0x5B, 0xB6,
        0x6A, 0xD4, 0xCB, 0x8D, 0xBE, 0x67, 0x39, 0x72, 0x4A, 0x94, 0x4C, 0x98, 0x58, 0xB0, 0xCF, 0x85,
        0xD0, 0xBB, 0xEF, 0xC5, 0xAA, 0x4F, 0xFB, 0xED, 0x43, 0x86, 0x4D, 0x9A, 0x33, 0x66, 0x85, 0x11,
        0x45, 0x8A, 0xF9, 0xE9, 0x02, 0x04, 0x7F, 0xFE, 0x50, 0xA0, 0x3C, 0x78, 0x9F, 0x25, 0xA8, 0x4B,
        0x51, 0xA2, 0xA3, 0x5D, 0x40, 0x80, 0x8F, 0x05, 0x92, 0x3F, 0x9D, 0x21, 0x38, 0x70, 0xF5, 0xF1,
        0xBC, 0x63, 0xB6, 0x77, 0xDA, 0xAF, 0x21, 0x42, 0x10, 0x20, 0xFF, 0xE5, 0xF3, 0xFD, 0xD2, 0xBF,
        0xCD, 0x81, 0x0C, 0x18, 0x13, 0x26, 0xEC, 0xC3, 0x5F, 0xBE, 0x97, 0x35, 0x44, 0x88, 0x17, 0x2E,
        0xC4, 0x93, 0xA7, 0x55, 0x7E, 0xFC, 0x3D, 0x7A, 0x64, 0xC8, 0x5D, 0xBA, 0x19, 0x32, 0x73, 0xE6,
        0x60, 0xC0, 0x81, 0x19, 0x4F, 0x9E, 0xDC, 0xA3, 0x22, 0x44, 0x2A, 0x54, 0x90, 0x3B, 0x88, 0x0B,
        0x46, 0x8C, 0xEE, 0xC7, 0xB8, 0x6B, 0x14, 0x28, 0xDE, 0xA7, 0x5E, 0xBC, 0x0B, 0x16, 0xDB, 0xAD,
        0xE0, 0xDB, 0x32, 0x64, 0x3A, 0x74, 0x0A, 0x14, 0x49, 0x92, 0x06, 0x0C, 0x24, 0x48, 0x5C, 0xB8,
        0xC2, 0x9F, 0xD3, 0xBD, 0xAC, 0x43, 0x62, 0xC4, 0x91, 0x39, 0x95, 0x31, 0xE4, 0xD3, 0x79, 0xF2,
        0xE7, 0xD5, 0xC8, 0x8B, 0x37, 0x6E, 0x6D, 0xDA, 0x8D, 0x01, 0xD5, 0xB1, 0x4E, 0x9C, 0xA9, 0x49,
        0x6C, 0xD8, 0x56, 0xAC, 0xF4, 0xF3, 0xEA, 0xCF, 0x65, 0xCA, 0x7A, 0xF4, 0xAE, 0x47, 0x08, 0x10,
        0xBA, 0x6F, 0x78, 0xF0, 0x25, 0x4A, 0x2E, 0x5C, 0x1C, 0x38, 0xA6, 0x57, 0xB4, 0x73, 0xC6, 0x97,
        0xE8, 0xCB, 0xDD, 0xA1, 0x74, 0xE8, 0x1F, 0x3E, 0x4B, 0x96, 0xBD, 0x61, 0x8B, 0x0D, 0x8A, 0x0F,
        0x70, 0xE0, 0x3E, 0x7C, 0xB5, 0x71, 0x66, 0xCC, 0x48, 0x90, 0x03, 0x06, 0xF6, 0xF7, 0x0E, 0x1C,
        0x61, 0xC2, 0x35, 0x6A, 0x57, 0xAE, 0xB9, 0x69, 0x86, 0x17, 0xC1, 0x99, 0x1D, 0x3A, 0x9E, 0x27,
        0xE1, 0xD9, 0xF8, 0xEB, 0x98, 0x2B, 0x11, 0x22, 0x69, 0xD2, 0xD9, 0xA9, 0x8E, 0x07, 0x94, 0x33,
        0x9B, 0x2D, 0x1E, 0x3C, 0x87, 0x15, 0xE9, 0xC9, 0xCE, 0x87, 0x55, 0xAA, 0x28, 0x50, 0xDF, 0xA5,
        0x8C, 0x03, 0xA1, 0x59, 0x89, 0x09, 0x0D, 0x1A, 0xBF, 0x65, 0xE6, 0xD7, 0x42, 0x84, 0x68, 0xD0,
        0x41, 0x82, 0x99, 0x29, 0x2D, 0x5A, 0x0F, 0x1E, 0xB0, 0x7B, 0x54, 0xA8, 0xBB, 0x6D, 0x16, 0x2C
};

u1 mytable2[] = {
        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08,
        0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80,
        0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

uint8_t myw[] = { 0x7A, 0xC6, 0xCD, 0x6B, 0x9D, 0x7C, 0x2B, 0x6B, 0xB1, 0x59, 0xA4, 0x8D
, 0x80, 0x06, 0x9D, 0xAB, 0x18, 0x0B, 0xA2, 0x34, 0x85, 0x77, 0x89, 0x5F, 0x34, 0x2E, 0x2D, 0xD2
, 0xB4, 0x28, 0xB0, 0x79, 0xAE, 0x86, 0x96, 0xD1, 0x2B, 0xF1, 0x1F, 0x8E, 0x1F, 0xDF, 0x32, 0x5C
, 0xAB, 0xF7, 0x82, 0x25, 0x91, 0xE4, 0xFE, 0xC6, 0xBA, 0x15, 0xE1, 0x48, 0xA5, 0xCA, 0xD3, 0x14
, 0x0E, 0x3D, 0x51, 0x31, 0x56, 0x4F, 0xD9, 0x1F, 0xEC, 0x5A, 0x38, 0x57, 0x49, 0x90, 0xEB, 0x43
, 0x47, 0xAD, 0xBA, 0x72, 0x16, 0xEF, 0x4C, 0xFB, 0xFA, 0xB5, 0x74, 0xAC, 0xB3, 0x25, 0x9F, 0xEF
, 0xF4, 0x88, 0x25, 0x9D, 0x48, 0x50, 0x88, 0xE4, 0xB2, 0xE5, 0xFC, 0x48, 0x01, 0xC0, 0x63, 0xA7
, 0xF5, 0x48, 0x46, 0x3A, 0xC8, 0xB6, 0xDA, 0xFE, 0x7A, 0x53, 0x26, 0xB6, 0x7B, 0x93, 0x45, 0x11
, 0x8E, 0xDB, 0x03, 0x2B, 0x39, 0xAF, 0x63, 0x05, 0x43, 0xFC, 0x45, 0xB3, 0x38, 0x6F, 0x00, 0xA2
, 0xB6, 0xB4, 0x03, 0x89, 0x9E, 0xE1, 0xEE, 0x65, 0xDD, 0x1D, 0xAB, 0xD6, 0xE5, 0x72, 0xAB, 0x74
, 0x53, 0xC6, 0xA8, 0xFD, 0xCA, 0x0C, 0x5A, 0x91, 0x17, 0x11, 0xF1, 0x47, 0xF2, 0x63, 0x5A, 0x33
, 0xA1, 0xA5, 0xF2, 0xCE };

void mykey_expansion(uint8_t *key, uint8_t *w) {

        uint8_t tmp[4];
        uint8_t i, j;
        uint8_t len = Nb*(Nr + 1);

        unsigned int v2 = 0x6BCDC67A;

        unsigned *pu1 = (unsigned*)w;
        unsigned *pu2 = (unsigned*)key;

        u2 *pt1 = (u2*)mytable;
        u4 *pt2 = (u4*)mytable2;
        u4 *pt3 = (u4*)w;
        u4 v6 = 0;

        for (i = 0; i < 4; ++i) {
                pu1[i] = pu2[i];
        }

        for (i = Nk; i < len; i++) {
                if (i%Nk == 0) {
                        tmp[0] = w[4 * (i - 1) + 0];
                        tmp[1] = w[4 * (i - 1) + 1];
                        tmp[2] = w[4 * (i - 1) + 2];
                        tmp[3] = w[4 * (i - 1) + 3];

                        u1 pb1 = (u1)pt1[tmp[2]];
                        u1 pb2 = (u1)pt1[tmp[1]];
                        u1 pb3 = (u1)pt1[tmp[0]];
                        u1 pb4 = (u1)pt1[tmp[3]];

                        u4 pn1 = pb1 << 24 | pb2 << 16 | pb3 << 8 | pb4;

                        u4 pn2 = pn1 ^ v2;

                        u4 pni = i - Nk;

                        int pn3 = (int)pni / (2 ^ 31);
                        u4 pn4 = (u4)pn3 >> 30;
                        u4 pn5 = pni + pn4;

                        u4 pn6 = pt2[pn5 / 4];
                        v6 = pn6 ^ pn2;
                }
                else {
                        v6 ^= v2;
                }

                pt3[i] = v6;
                v2 = pt3[i - Nk + 1];
        }
}

u4 byteswap(u1 *p) {
        u1 r[4];
        r[3] = p[0];
        r[2] = p[1];
        r[1] = p[2];
        r[0] = p[3];
        return *(u4*)r;
}

u4 getu1(u4 val, u4 i) {
        u1 *va = (u1*)&val;
        return va[i];
}

u2 getTableVal(u4 i) {
        u2 *myu2Table = (u2*)mytable;
        return myu2Table[i];
}

u1 getmix(u2 p) {
        u1 v = (p & 0xff) ^ (p >> 8);
        return v;
}

u4 finda(u1 a) {
        u4 i = 0;
        for (i = 0; i <= 255; ++i) {
                if (mytable[2 * i] == a)
                        return i;
        }
}

u4 findb(u1 b) {
        u4 i = 0;
        for (i = 0; i <= 255; ++i) {
                if (mytable[2 * i + 1] == b)
                        return i;
        }
        return 0;
}

u4 findc(u1 c) {
        u4 i = 0;
        for (i = 0; i <= 255; ++i) {
                if (mytable[2 * i + 1] ^ mytable[2 * i] == c)
                        return i;
        }
        return 0;
}

u4 deRounce(u4 nin) {

        u1 *pin = (u1*)&nin;

        u1 tmp[4] = { 0 };
        u1 t[4] = { 0 };
        u1 all = pin[0] ^ pin[1] ^ pin[2] ^ pin[3];
        tmp[0] = pin[3] ^ all;
        tmp[1] = pin[2] ^ all;
        tmp[2] = pin[1] ^ all;
        tmp[3] = pin[0] ^ all;

        u1 i = 0;
        u1 j = 0;

        for (i = 0; i <= 255; ++i) {
                u1 c1 = mytable[2 * i] ^ mytable[2 * i + 1];
                u1 b2 = tmp[0] ^ c1;
                u1 i2 = findb(b2);
                u1 c2 = mytable[2 * i2] ^ mytable[2 * i2 + 1];
                u1 b3 = tmp[1] ^ c2;
                u1 i3 = findb(b3);
                u1 c3 = mytable[2 * i3] ^ mytable[2 * i3 + 1];
                u1 b4 = tmp[2] ^ c3;
                u1 i4 = findb(b4);
                u1 c4 = mytable[2 * i4] ^ mytable[2 * i4 + 1];
                u1 b1 = tmp[3] ^ c4;
                u1 i1 = findb(b1);
                if (i1 == i) {
                        t[0] = i1;
                        t[1] = i2;
                        t[2] = i3;
                        t[3] = i4;
                        return *(u4*)t;
                }
                else
                        continue;
        }

}

void decrypt(u1 *pin, u1 *pout, u1 *w) {

        u4 *pt1 = (u4*)w;
        u4 ni = 43;
        u4 v77 = byteswap(pin + 12) ^ pt1[ni--];
        u4 v14 = byteswap(pin + 8) ^ pt1[ni--];
        u4 v16 = byteswap(pin + 4) ^ pt1[ni--];
        u4 v18 = byteswap(pin) ^ pt1[ni--];

        u4 v23 = 0;
        u4 v80 = 10;
        u2 tmp = 0;

        u4 ipt = 4;

        u4 v27, v29, v30, v31, v76, v75, v44, v77_2;

        u4 uu1 = finda(getu1(v18, 3)) << 24 | finda(getu1(v16, 0)) | finda(getu1(v14, 1)) << 8 | finda(getu1(v77, 2)) << 16;
        u4 uu2 = finda(getu1(v16, 3)) << 24 | finda(getu1(v14, 0)) | finda(getu1(v77, 1)) << 8 | finda(getu1(v18, 2)) << 16;
        u4 uu3 = finda(getu1(v14, 3)) << 24 | finda(getu1(v77, 0)) | finda(getu1(v18, 1)) << 8 | finda(getu1(v16, 2)) << 16;
        u4 uu4 = finda(getu1(v77, 3)) << 24 | finda(getu1(v18, 0)) | finda(getu1(v16, 1)) << 8 | finda(getu1(v14, 2)) << 16;
        do {
                //uu1 =
                v77 = uu4 ^ pt1[ni--];
                v14 = uu3 ^ pt1[ni--];
                v16 = uu2 ^ pt1[ni--];
                v18 = uu1 ^ pt1[ni--];

                uu1 = deRounce(v18);
                uu2 = deRounce(v16);
                uu3 = deRounce(v14);
                uu4 = deRounce(v77);

                v18 = (uu1 & 0xff) | (uu2 & 0xff000000) | (uu3 & 0xff0000) | (uu4 & 0xff00);
                v18 = byteswap((u1*)&v18);

                v16 = (uu2 & 0xff) | (uu3 & 0xff000000) | (uu4 & 0xff0000) | (uu1 & 0xff00);
                v16 = byteswap((u1*)&v16);

                v14 = (uu3 & 0xff) | (uu4 & 0xff000000) | (uu1 & 0xff0000) | (uu2 & 0xff00);
                v14 = byteswap((u1*)&v14);

                v77 = (uu4 & 0xff) | (uu1 & 0xff000000) | (uu2 & 0xff0000) | (uu3 & 0xff00);
                v77 = byteswap((u1*)&v77);

                uu1 = v18;
                uu2 = v16;
                uu3 = v14;
                uu4 = v77;

        } while (ni >= ipt);

        v77 = uu4 ^ pt1[ni--];
        v14 = uu3 ^ pt1[ni--];
        v16 = uu2 ^ pt1[ni--];
        v18 = uu1 ^ pt1[ni--];

        u4 tmp2 = 0;

        u4 *ptout = (u4*)pout;

        ptout[0] = byteswap((u1*)&v18);

        ptout[1] = byteswap((u1*)&v16);

        ptout[2] = byteswap((u1*)&v14);

        ptout[3] = byteswap((u1*)&v77);

}

void encrypt(u1 *pin, u1 *pout, u1 *w) {
        u4 *pt1 = (u4*)w;
        u4 v77 = byteswap(pin + 12) ^ pt1[3];
        u4 v14 = byteswap(pin + 8) ^ pt1[2];
        u4 v16 = byteswap(pin + 4) ^ pt1[1];
        u4 v18 = byteswap(pin) ^ pt1[0];

        u4 v23 = 0;
        u4 v80 = 10;
        u2 tmp = 0;

        u4 ipt = 4;

        u4 v27, v29, v30, v31, v76, v75, v44, v77_2;

        do {
                tmp = getTableVal(getu1(v18, 3));
                v27 = ((tmp & 0xff) << 8) | (tmp << 16) | getmix(tmp);

                tmp = getTableVal(getu1(v16, 2));
                v29 = (tmp & 0xff) | (tmp << 8) | (getmix(tmp) << 24);

                tmp = getTableVal(getu1(v14, 1));
                v30 = (tmp) | (tmp << 24) | (getmix(tmp) << 16);

                tmp = getTableVal(getu1(v77, 0));
                v31 = ((tmp & 0xff) << 16) | (tmp << 24) | (getmix(tmp) << 8) | (tmp >> 8);

                v76 = pt1[ipt++] ^ v27 ^ v29 ^ v30 ^ v31;
                //printf("show %p %p %p %p\n", v18, v27 ^ v29 ^ v30 ^ v31, pt1[ipt - 1], v76);
                u4 myv = deRounce(v76 ^ pt1[ipt - 1]);

                tmp = getTableVal(getu1(v16, 3));
                v27 = ((tmp & 0xff) << 8) | (tmp << 16) | getmix(tmp);

                tmp = getTableVal(getu1(v14, 2));
                v29 = (tmp & 0xff) | (tmp << 8) | (getmix(tmp) << 24);

                tmp = getTableVal(getu1(v77, 1));
                v30 = (tmp) | (tmp << 24) | (getmix(tmp) << 16);

                tmp = getTableVal(getu1(v18, 0));
                v31 = ((tmp & 0xff) << 16) | (tmp << 24) | (getmix(tmp) << 8) | (tmp >> 8);

                v75 = pt1[ipt++] ^ v27 ^ v29 ^ v30 ^ v31;
                //printf("show %p %p %p %p\n", v16, v27 ^ v29 ^ v30 ^ v31, pt1[ipt - 1], v75);

                tmp = getTableVal(getu1(v14, 3));
                v27 = ((tmp & 0xff) << 8) | (tmp << 16) | getmix(tmp);

                tmp = getTableVal(getu1(v77, 2));
                v29 = (tmp & 0xff) | (tmp << 8) | (getmix(tmp) << 24);

                tmp = getTableVal(getu1(v18, 1));
                v30 = (tmp) | (tmp << 24) | (getmix(tmp) << 16);

                tmp = getTableVal(getu1(v16, 0));
                v31 = ((tmp & 0xff) << 16) | (tmp << 24) | (getmix(tmp) << 8) | (tmp >> 8);

                v44 = pt1[ipt++] ^ v27 ^ v29 ^ v30 ^ v31;
                //printf("show %p %p %p %p\n", v14, v27 ^ v29 ^ v30 ^ v31, pt1[ipt - 1], v44);

                tmp = getTableVal(getu1(v77, 3));
                v27 = ((tmp & 0xff) << 8) | (tmp << 16) | getmix(tmp);

                tmp = getTableVal(getu1(v18, 2));
                v29 = (tmp & 0xff) | (tmp << 8) | (getmix(tmp) << 24);

                tmp = getTableVal(getu1(v16, 1));
                v30 = (tmp) | (tmp << 24) | (getmix(tmp) << 16);

                tmp = getTableVal(getu1(v14, 0));
                v31 = ((tmp & 0xff) << 16) | (tmp << 24) | (getmix(tmp) << 8) | (tmp >> 8);

                v77_2 = pt1[ipt++] ^ v27 ^ v29 ^ v30 ^ v31;
                //printf("show %p %p %p %p\n", v77, v27 ^ v29 ^ v30 ^ v31, pt1[ipt-1], v77_2);

                v77 = v77_2;
                v14 = v44;
                v16 = v75;
                v18 = v76;

                v23++;

        } while (v23 + 1 < v80); //*/

        u4 tmp2 = 0;

        u4 *ptout = (u4*)pout;

        tmp2 = (getTableVal(getu1(v18, 3)) & 0xff) << 24;
        tmp2 |= (getTableVal(getu1(v16, 2)) & 0xff) << 16;
        tmp2 |= (getTableVal(getu1(v14, 1)) & 0xff) << 8;
        tmp2 |= (getTableVal(getu1(v77, 0)) & 0xff);
        tmp2 ^= pt1[ipt++];

        ptout[0] = byteswap((u1*)&tmp2);

        tmp2 = (getTableVal(getu1(v16, 3)) & 0xff) << 24;
        tmp2 |= (getTableVal(getu1(v14, 2)) & 0xff) << 16;
        tmp2 |= (getTableVal(getu1(v77, 1)) & 0xff) << 8;
        tmp2 |= (getTableVal(getu1(v18, 0)) & 0xff);
        tmp2 ^= pt1[ipt++];

        ptout[1] = byteswap((u1*)&tmp2);

        tmp2 = (getTableVal(getu1(v14, 3)) & 0xff) << 24;
        tmp2 |= (getTableVal(getu1(v77, 2)) & 0xff) << 16;
        tmp2 |= (getTableVal(getu1(v18, 1)) & 0xff) << 8;
        tmp2 |= (getTableVal(getu1(v16, 0)) & 0xff);
        tmp2 ^= pt1[ipt++];

        ptout[2] = byteswap((u1*)&tmp2);

        tmp2 = (getTableVal(getu1(v77, 3)) & 0xff) << 24;
        tmp2 |= (getTableVal(getu1(v18, 2)) & 0xff) << 16;
        tmp2 |= (getTableVal(getu1(v16, 1)) & 0xff) << 8;
        tmp2 |= (getTableVal(getu1(v14, 0)) & 0xff);
        tmp2 ^= pt1[ipt++];

        ptout[3] = byteswap((u1*)&tmp2);

        return;
}

u1 cr[256] = { 0 };

void printc(){
        int i = 0;
        for (i = 0; i < 256; ++i) {
                u1 t = mytable[2 * i] ^ mytable[2 * i + 1];

                if (cr[t]) {
                        printf("haha");
                }
                else {
                        cr[t] = 1;
                }
                printf("%02x ", t);
                if ((i + 1) % 16 == 0) {
                        printf("\n");
                }
        }
}

int main(int argc, char *argv[]) {

        uint8_t i;

        u1 sub_key[] = { 0x1F, 0xBC, 0xDA, 0xFF, 0xE6, 0x4C, 0xBC, 0x44,
                0xF5, 0xB8, 0x13, 0xC8, 0xEC, 0xA8, 0xCD, 0xBD }; //第四层的相加密钥

        uint8_t key[] = {
                0x7A, 0xC6, 0xCD, 0x6B, 0x9D, 0x7C, 0x2B, 0x6B, 0xB1, 0x59, 0xA4, 0x8D, 0x80, 0x06, 0x9D, 0xAB
        };  //第五层的密钥

        /*
                uint8_t in[] = { //第五层加密前的明文
                0x8A, 0x1F, 0x4B, 0x6E, 0x59, 0xCA, 0xF2, 0x52, 0x05, 0xCA, 0x27, 0xDE, 0x04, 0xC2, 0xE9, 0xDB };
        //*/

        /*
        uint8_t in[] = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        uint8_t out[] = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        //*/
        uint8_t out[] = {
                0x5C, 0xDA, 0x77, 0x2F, 0xA3, 0xC6, 0x3E, 0x39, 0xB6, 0xF0, 0xF3, 0xED, 0x51, 0x5A, 0x99, 0x86 };
        //*/
        //uint8_t out[16]; // 第五层加密后的密文
        uint8_t in[16];
        uint8_t *w; // expanded key

        Nk = 4; Nr = 10;

        //printc();

        w = (uint8_t*)malloc(Nb*(Nr + 1) * 4);

        //w = myw;
        mykey_expansion(key, w);    //可以省去,改成直接从内存dump出的myw数组

        //memset(w, 0, 44);

        //encrypt(in /* in */, out /* out */, w /* expanded key */);
        decrypt(out, in, w);  //从第五层密文还原第五层明文

        for (i = 0; i < 16; ++i) {
                in[i] -= (sub_key[i] + (u1)i);  //第四层与第三层解密
                if (in[i] == (u1)i)  //去掉未尾的填充数据
                        in[i] = 0;
        }

        printf("answer is %s\n", in);

        getchar();

}

[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回