iyzyi 发表于 2020-9-1 12:24

GACTF的几道逆向和MISC

本帖最后由 iyzyi 于 2020-9-1 15:03 编辑

## RE

### checkin

题目说推荐虚拟机做。

首先尝试xp,结果报错,报错信息中意外得知这是调用的ruby.exe。



然后试了下win7,可以正常运行。

如果输入flag的时候,不输入,直接回车,也会有下面的报错:



所以直接来到报错中出现的目录下,找到ruby脚本。

注意程序运行完之后会删除上面解压出来的那个目录,所以运行程序后,停在输入flag的那一步,接着去找上面的目录中的ruby脚本。

虚拟机没安装vmware,直接把ruby脚本截个图吧:



然后在线解aes就可以了。

队友用了一个叫processmonitor的工具,比我这碰巧遇到报错信息的方法要高明的多,欢迎去看一下[他的题解](https://ljzjsc.com/index.php/archives/85/#0x2checkin)。

### EasyRe

一个vm。

动调来到vm指令的相关代码处,并分析各个操作码的含义:

```c
int __cdecl sub_8048838(_DWORD *a1)
{
int v1; // ecx
_BYTE *v2; // ST28_4
int result; // eax
unsigned int v4; // et1
unsigned int v5; //

v5 = __readgsdword(0x14u);
while ( 1 )
{
    if ( *(_BYTE *)a1 == 113 )                   // 没用到
    {
      a1 -= 4;
      *(_DWORD *)a1 = *(_DWORD *)(a1 + 1);
      a1 += 5;
    }
    if ( *(_BYTE *)a1 == 65 )                  // a1 += a1
    {
      a1 += a1;
      ++a1;
    }
    if ( *(_BYTE *)a1 == 66 )                  // a1 -= a1
    {
      a1 -= a1;
      ++a1;
    }
    if ( *(_BYTE *)a1 == 67 )                  // a1 *= a1
    {
      a1 *= a1;
      ++a1;
    }
    if ( *(_BYTE *)a1 == 68 )                  // a1 /= a1
    {
      a1 /= a1;
      ++a1;
    }
    if ( *(_BYTE *)a1 == 128 )                   // op ? (int)num            a1 = num             opn += 6
    {
      a1 = *(_DWORD *)(a1 + 2);
      a1 += 6;
    }
    if ( *(_BYTE *)a1 == 119 )                   // a1 ^= a1
    {
      a1 ^= a1;
      ++a1;
    }
    if ( *(_BYTE *)a1 == 83 )                  // 没用到
    {
      sub_80485F0(*(char *)a1);
      a1 += 2;
    }
    if ( *(_BYTE *)a1 == 34 )                  // a1 >>= a1
    {
      v1 = a1;
      a1 >>= v1;
      ++a1;
    }
    if ( *(_BYTE *)a1 == 35 )                  // a1 <<= a1
    {
      v1 = a1;
      a1 <<= v1;
      ++a1;
    }
    if ( *(_BYTE *)a1 == 153 )                   // 跳出循环
      break;
    if ( *(_BYTE *)a1 == 118 )                   // 没用到
    {
      a1 = *(_DWORD *)a1;
      *(_DWORD *)a1 = 0;
      a1 += 4;
      a1 += 5;
    }
    if ( *(_BYTE *)a1 == 84 )                  // 没用到
    {
      v2 = (_BYTE *)a1;
      *v2 = sub_8048580();
      a1 += 2;
    }
    if ( *(_BYTE *)a1 == 48 )                  // a1 |= a1
    {
      a1 |= a1;
      ++a1;
    }
    if ( *(_BYTE *)a1 == 49 )                  // a1 &= a1
    {
      a1 &= a1;
      ++a1;
    }
    if ( *(_BYTE *)a1 == 9 )                     //a1 = 输入int64
    {
      a1 = dword_804B28C;
      ++a1;
    }
    if ( *(_BYTE *)a1 == 16 )                  // a1 = a1
    {
      a1 = a1;
      ++a1;
    }
    if ( *(_BYTE *)a1 == 17 )                  // printf("%p\n", a1)
    {
      printf((const char *)&unk_804920C, a1);
      ++a1;
    }
    if ( *(_BYTE *)a1 == 160 )                   // if (a1 == 0x26F8D100) opn++ else exit()
    {
      if ( a1 == 653840640 )
      ++a1;
      else
      exit();
    }
    if ( *(_BYTE *)a1 == 161 )                   // 输入flag, flag = byte_804B2E0
    {
      printf("flag:");
      sub_8048560(0, (int)byte_804B2E0, 40);
      if ( strlen((int)byte_804B2E0) != 33 )
      exit();
      ++a1;
    }
    if ( *(_BYTE *)a1 == 177 )                   // a1 = dword_804B2A0
    {
      a1 = dword_804B2A0;
      ++a1;
    }
    if ( *(_BYTE *)a1 == 178 )                   // a1 = dword_804B2A4
    {
      a1 = dword_804B2A4;
      ++a1;
    }
    if ( *(_BYTE *)a1 == 164 )                   // op byte(num) ? ?         dword_804B2A0 = a1             opn += 4(后两字节无效)
    {
      dword_804B2A0[*(unsigned __int8 *)(a1 + 1)] = a1;
      a1 += 4;
    }
    if ( *(_BYTE *)a1 == 179 )                   // a1 = dword_804B2A8
    {
      a1 = dword_804B2A8;
      ++a1;
    }
    if ( *(_BYTE *)a1 == 180 )                   // a1 = dword_804B2AC
    {
      a1 = dword_804B2AC;
      ++a1;
    }
    if ( *(_BYTE *)a1 == 193 )                   // op byte(num)         a1 = byte_804B2E0               opn += 2
    {
      a1 = byte_804B2E0[*(unsigned __int8 *)(a1 + 1)];
      a1 += 2;
    }
    if ( *(_BYTE *)a1 == 194 )                   // op (int)num         if (a1 == num)                      opn += 5
    {
      if ( a1 != *(_DWORD *)(a1 + 1) )
      exit();
      a1 += 5;
    }
}
v4 = __readgsdword(0x14u);
result = v4 ^ v5;
if ( v4 != v5 )
    result = sub_8048590(v1);
return result;
}
```

同样是动调拿到vm的代码,并dump出来,然后用下面的脚本分析vm:

```python
dic = [
    (65, 'a1 += a1', 1),
    (66, 'a1 -= a1', 1),
    (67, 'a1 *= a1', 1),
    (68, 'a1 /= a1', 1),
    (128, 'a1[?] = %d', 6),
    (119, 'a1 ^= a1', 1),
    (34, 'a1 >>= a1', 1),
    (35, 'a1 <<= a1', 1),
    (153, '跳出循环', 1),
    (48, 'a1 |= a1', 1),
    (49, 'a1 &= a1', 1),
    (9, 'a1 = 输入int', 1),
    (16, 'a1 = a1', 1),
    (17, 'printf("%p\n", a1)', 1),
    (160, 'if (a1 == 0x26F8D100) opn++ else exit()', 1),
    (161, '输入flag, flag = byte_804B2E0', 1),
    (177, 'a1 = dword_804B2A0', 1),
    (178, 'a1 = dword_804B2A4', 1),
    (164, 'dword_804B2A0[%d] = a1', 4),
    (179, 'a1 = dword_804B2A8', 1),
    (180, 'a1 = dword_804B2AC', 1),
    (193, 'a1 = byte_804B2E0[%d]', 2),
    (194, 'if (a1 == %d)', 5)
]

def get_int(b):
    import struct
    return struct.unpack('I', b)

with open('dump', 'rb')as f:
    b = f.read()

opn = 0
while (True):
    op = b
    for i in range(len(dic)):
      if op == dic:
            code = dic

            if op == 128:
                num = get_int(b)
                print(code % num)
            elif op == 164 or op == 193:
                num = b
                print(code % num)
            elif op == 194:
                num = get_int(b)
                print(code % num)
            else:
                print(code)

            opn += dic
            break
```

分析输出的结果:

```c
a1 = 输入int

a1 = a1   
a1 = 13      
a1 >>= a1   
a1 ^= a1                            //a1 = a1 ^ (a1 >> 13)
a1 = a1                           //a1 = a1

a1 = 9
a1 <<= a1
a1 = 2029229568
a1 &= a1
a1 ^= a1                            //a1 = ((a1 << 9) & 0x78f39600) ^ a1
a1 = a1                           //a1 = a1
       
a1 = 17      
a1 <<= a1   
a1 = 2245263360
a1 &= a1   
a1 ^= a1                            //a1 = ((a1 << 17) & 0x85d40000) ^ a1
a1 = a1                           //a1 = a1

a1 = 19
a1 >>= a1
a1 ^= a1                                //a1 = (a1 >> 19) ^ a1

if (a1 == 0x26F8D100) opn++ else exit()
       


a1 = 输入int
a1[?] = 255
a1 &= a1
a1[?] = 2
a1 *= a1
a1[?] = 24
a1 += a1
dword_804B2A0 = a1        // (a1 & 255) * 2 + 24

a1 = 输入int
a1[?] = 8
a1 >>= a1
a1[?] = 255
a1 &= a1
a1[?] = 7
a1 /= a1
a1[?] = 33
a1 += a1
dword_804B2A0 = a1        // ((a1 >> 8) & 255) / 7 + 33

a1 = 输入int
a1[?] = 16
a1 >>= a1
a1[?] = 255
a1 &= a1
a1[?] = 187
a1 ^= a1
a1[?] = 255
a1 += a1
dword_804B2A0 = a1        // (((a1 >> 16) & 255) ^ 187) + 255

a1 = 输入int
a1[?] = 24
a1 >>= a1
a1[?] = 255
a1 &= a1
a1[?] = 160
a1 -= a1
a1[?] = 119
a1 += a1       
dword_804B2A0 = a1        // ((a1 >> 24) & 255) - 160 + 119



输入flag, flag = byte_804B2E0



a1 = byte_804B2E0
a1 = dword_804B2A0
a1 ^= a1
if (a1 == 267)                        // if (flag ^ dword_804B2A0 == 267)
       
a1 = byte_804B2E0
a1 = dword_804B2A4
a1 ^= a1
if (a1 == 122)                        // if (flag ^ dword_804B2A0 == 122)
       
a1 = byte_804B2E0
a1 = dword_804B2AC
a1 ^= a1
if (a1 == 149)                        // if (flag ^ dword_804B2A0 == 149)
       
a1 = byte_804B2E0
a1 = dword_804B2A8
a1 ^= a1
if (a1 == 262)                        // if (flag ^ dword_804B2A0 == 262)
       
a1 = byte_804B2E0
a1 = dword_804B2A4
a1 ^= a1
if (a1 == 125)                        // if (flag ^ dword_804B2A0 == 125)
       
a1 = byte_804B2E0
a1 = dword_804B2AC
a1 ^= a1
if (a1 == 173)
       
a1 = byte_804B2E0
a1 = dword_804B2A0
a1 ^= a1
if (a1 == 303)
       
a1 = byte_804B2E0
a1 = dword_804B2A8
a1 ^= a1
if (a1 == 357)
       
a1 = byte_804B2E0
a1 = dword_804B2A0
a1 ^= a1
if (a1 == 301)
       
a1 = byte_804B2E0
a1 = dword_804B2A0
a1 ^= a1
if (a1 == 303)
       
a1 = byte_804B2E0
a1 = dword_804B2A8
a1 ^= a1
if (a1 == 313)
       
a1 = byte_804B2E0
a1 = dword_804B2A8
a1 ^= a1
if (a1 == 269)
       
a1 = byte_804B2E0
a1 = dword_804B2AC
a1 ^= a1
if (a1 == 187)
       
a1 = byte_804B2E0
a1 = dword_804B2A4
a1 ^= a1
if (a1 == 8)
       
a1 = byte_804B2E0
a1 = dword_804B2A8
a1 ^= a1
if (a1 == 269)
       
a1 = byte_804B2E0
a1 = dword_804B2A0
a1 ^= a1
if (a1 == 319)
       
a1 = byte_804B2E0
a1 = dword_804B2A8
a1 ^= a1
if (a1 == 314)
       
a1 = byte_804B2E0
a1 = dword_804B2A8
a1 ^= a1
if (a1 == 353)
       
a1 = byte_804B2E0
a1 = dword_804B2A4
a1 ^= a1
if (a1 == 87)
       
a1 = byte_804B2E0
a1 = dword_804B2A0
a1 ^= a1
if (a1 == 288)
       
a1 = byte_804B2E0
a1 = dword_804B2A8
a1 ^= a1
if (a1 == 269)
       
a1 = byte_804B2E0
a1 = dword_804B2A0
a1 ^= a1
if (a1 == 319)
       
a1 = byte_804B2E0
a1 = dword_804B2A8
a1 ^= a1
if (a1 == 319)
       
a1 = byte_804B2E0
a1 = dword_804B2AC
a1 ^= a1
if (a1 == 181)
       
a1 = byte_804B2E0
a1 = dword_804B2A0
a1 ^= a1
if (a1 == 275)
       
a1 = byte_804B2E0
a1 = dword_804B2AC
a1 ^= a1
if (a1 == 160)
       
a1 = byte_804B2E0
a1 = dword_804B2A0
a1 ^= a1
if (a1 == 289)
       
a1 = byte_804B2E0
a1 = dword_804B2A8
a1 ^= a1
if (a1 == 269)
       
a1 = byte_804B2E0
a1 = dword_804B2A4
a1 ^= a1
if (a1 == 11)
       
a1 = byte_804B2E0
a1 = dword_804B2A8
a1 ^= a1
if (a1 == 313)
       
a1 = byte_804B2E0
a1 = dword_804B2A0
a1 ^= a1
if (a1 == 371)
       
a1 = byte_804B2E0
a1 = dword_804B2A4
a1 ^= a1
if (a1 == 70)
       
跳出循环
```

可以看出首先是输入一个数,依次经过下面的运算后判断是否和 0x26F8D100相等。

```
a1 = a1 ^ (a1 >> 13)
a1 = ((a1 << 9) & 0x78f39600) ^ a1
a1 = ((a1 << 17) & 0x85d40000) ^ a1
a1 = (a1 >> 19) ^ a1
```

很巧的是,前几天的七夕,我闲得没事干,随手写了个加解密的小程序,关键逻辑简直和本题的一模一样,我是万万没想到啊。

文章发在了看雪上,[一个有趣的加密小算法及其逆向](https://bbs.pediy.com/thread-261646.htm),里面有分析这个类型的算式如何逆向,同时做了一定的推广,也提供了加解密的c语言代码(本题甚至可以直接把我那篇文章提供的c代码修改一下即可)。建议大家先去看一下。

有一点不同的是,本题多了个 `& 0x78f39600`。其实不过是稍微进一步的拓展而已,看完上面的那篇博文,你应该能够想明白这个应该怎么处理。如果不明白,那么将下面的脚本和上面提到的我的那篇博文中的脚本对比下差异,就应该会懂了。

下面的脚本修改自上面提到的我的那篇博文,可以求出这个输入的数来:

```c
#include <stdio.h>
#include <math.h>

unsigned int getAnsOfPowerOfTwo(int a, int b){
    //求2的幂的和
    unsigned int ans = 0;
    int i;
    for (i = a; i < b; i++){
      ans += pow(2, i);
    }
    return ans;
}

unsigned int getBit(const unsigned int n, int i){
    //取某一位的bit
    unsigned int t =pow(2, i);
    return (t & n) >> i;
}

unsigned int rightShiftXor(const unsigned int n, int m){
    unsigned int r = n & getAnsOfPowerOfTwo(0, 32 - m);
    unsigned int l = n & getAnsOfPowerOfTwo(32 - m, 32);
    unsigned int t = l;
    int i, t_i;
    for (i = 31 - m; i >= 0; i--){
      t_i = getBit(t, i + m) ^ getBit(n, i);
      t += t_i << i;
    }
    return t;
}

unsigned int leftShiftAndXor(const unsigned int n, int m, unsigned int x){
    unsigned int r = n & getAnsOfPowerOfTwo(0, m);
    unsigned int l = n & getAnsOfPowerOfTwo(m, 32);
    unsigned int t = r;
    int i, t_i;
    for (i = m; i < 32; i++){
            if (getBit(x, i) == 1){
                    t_i = getBit(t, i - m) ^ getBit(n, i);
              t += t_i << i;
                }
      else{
              t_i = getBit(n, i);
              t += t_i << i;
                }
    }
    return t;
}

unsigned int decrypt(c){
        unsigned int o = rightShiftXor(c, 19);
    unsigned int p = leftShiftAndXor(o, 17, 0x85d40000);
    unsigned int q = leftShiftAndXor(p, 9, 0x78f39600);
    unsigned int r = rightShiftXor(q, 13);
    return r;
}

int main(){
    unsigned int c = 0x26F8D100;
    unsigned int p = decrypt(c);
    printf("\ndecrypt(0x%x) = 0x%x\n", c, p);
   
    return 0;
}
```

当然,这个输入只是个int而已,我觉得可以用angr搞,不过我没试过,不太清楚具体行不行。

后面的逻辑就很简单了,直接写脚本:

```python
a = 4293442714
a = 0xffe8bc9a

l = * 4
l = (a & 255) * 2 + 24
l = ((a >> 8) & 255) // 7 + 33
l = (((a >> 16) & 255) ^ 187) + 255
l = ((a >> 24) & 255) - 160 + 119

print(l)

flag = * 32

flag = l ^ 267
flag = l ^ 122
flag = l ^ 149
flag = l ^ 262
flag = l ^ 125
flag = l ^ 173
flag = l ^ 303
flag = l ^ 357
flag = l ^ 301
flag = l ^ 303
flag = l ^ 313
flag = l ^ 269
flag = l ^ 187
flag = l ^ 8
flag = l ^ 269
flag = l ^ 319
flag = l ^ 314
flag = l ^ 353
flag = l ^ 87
flag = l ^ 288
flag = l ^ 269
flag = l ^ 319
flag = l ^ 319
flag = l ^ 181
flag = l ^ 275
flag = l ^ 160
flag = l ^ 289
flag = l ^ 269
flag = l ^ 11
flag = l ^ 313
flag = l ^ 371
flag = l ^ 70

print(flag)
print(''.join(map(chr, flag)))
```

### WannaFlag



本题文本框内开玩笑说6666RMB联系出题人买密钥,我闲得慌,还真去加了haivk大佬的QQ,哈哈。



界面看着很炫酷,其实不看花里胡哨的东西的话,逻辑炒鸡简单,签到题难度。

别跑偏了,不需要你看懂那个解密函数。只需要看sub_402280的关键代码:



上图黄框中的代码也不需要看,不要想复杂了。密钥长度不会超过64的,直接看后面的一小段即可。

加解密需要用到v38,v38与v37有关,而v37的值我们不清楚到底是啥意思,但好在v37的取值是0~6,所以爆破即可。

后面一小段的逻辑就是签到题难度,应该不需要我多说什么吧。

```python
def __ROL1__(value, k):
    k %= 8
    return (((value << k)&0xff) | ((value >> (8-k))&0xff))&0xff

def __ROR1__(value, k):
    k %= 8
    return (((value >> k)&0xff) | ((value << (8-k))&0xff))&0xff


#with open(r'd:\dump', 'rb')as f:
#    b = f.read()
b = b'N\xaea\xba\xe4+U\xaaY\xfcM\x02\x17k\x13\xa1A\xfe5\x0b\xb4\x0bR/F\xcc5\x82\xe5\x88P\x00'
byte_420AE0 = b"ANNAWGALFYBKVIAHMXTFCAACLAAAAYK\x00"

v58 = * 32
for i in range(32):
    v58 = __ROR1__(b, i) ^ byte_420AE0

v58_2 = * 32
for i in range(0, 7):
    v38 = 1
    if (i > 2):
      for j in range(2, i):
            v38 *= j
    print(v38)
    for k in range(32):
      v58_2 = v38 ^ v58
    print(v58_2)

a =
print(''.join(map(chr, a)))
```

当然赛后完全可以再翻出解密函数来学习一波。

读入flag.bin:



创建一个CS模块中的密钥容器:



创建一个hash对象,0x8004表示采用的散列算法是SHA。等下生成key时,要用到这个hash对象:



计算密钥散列:



生成密钥,0x6801表示加密算法为RC4:



解密数据,写入文件:



归纳一下就是:

1. (https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontextw)生成CSP句柄
2. (https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptcreatehash)创建hash对象,第二个参数指定散列算法
3. (https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-crypthashdata)计算密钥的散列,第一个参数是上一步生成的hash对象
4. (https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptderivekey)生成密钥,第二个参数指定加密算法(是的,加密算法是在这一步指定的),第三个参数就是前面生成的散列对象。与之类似的还有个(https://docs.microsoft.com/en-us/windows/desktop/api/wincrypt/nf-wincrypt-cryptgenkey),不过这个是随机生成密钥而非指定。
5. (https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdecrypt)解密
6. 除此之外还有(https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptreleasecontext)释放CSP句柄,(https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdestroykey)释放密钥句柄,(https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdestroyhash)释放hash对象。

### Simulator

给了一个很小的obj文件,里面发现有lc3的字眼。

搜了下,lc3是一套精简指令集,风格类似arm。

官网有windows下的调试器。(愚蠢的我一开始居然打算在ubuntu里编译这个工具)

大概是这样的:


一个控制台,一个调试器。

ctrl+L导入题目的obj文件:



我不擅长动调,顺便打算利用这次机会,学习一下arm风格的汇编。

所以直接将结果导出,静态分析:



开始分析之前,我觉得有必要放几个题目中出现的指令:







然后是比较重要的跳转指令BR系列:



很重要的一个知识点:

> The assembly language opcode BR is interpreted the same as BRnzp; that is, always branch to the target address.

也就是说本题中常见的BRnzp,和BR指令是一样的,相当于x86的jmp。

然后慢慢分析吧(建议把下面的分析复制到本地再看),我觉得已经炒鸡详细了,几乎每一步都注释了。当然量太大了,错误在所难免,不过应该不会影响理解。

```asm
Registers:
R0   x00000
R1   x00000
R2   x00000
R3   x00000
R4   x00000
R5   x00000
R6   x00000
R7   x00000
PC   x300012288
IR   x00000
CC   Z

Memory:
x30001110000001111010xE07A            LEA    R0, x307B      ;WELCOME TO WORLD OF LC3
x30011111000000100010xF022            TRAP   PUTS         
x30020010000001110111x2077            LD   R0, x307A      ;0x0A,换行
x30031111000000100001xF021            TRAP   OUT            
x30041110000010010010xE092            LEA    R0, x3097      ;PLEASE INPUT YOUR FLAG:
x30051111000000100010xF022            TRAP   PUTS         
x30060010011011011110x26DE            LD   R3, x30E5      ;R3 = = 0x18                ;flag长度
x30071111000000100000xF020            TRAP   GETC         ;从缓冲区接收一个字符
x30081111000000100001xF021            TRAP   OUT            ;输出这个字符
x30090010001011011010x22DA            LD   R1, x30E4      ;R1 = = 0x4000
x300A0001001001000011x1243            ADD    R1, R1, R3   ;R1 = R1 + R3
x300B0111000001000000x7040            STR    R0, R1, #0   ; = R0                                ; = R0,字符串存储在0x4000
x300C0001011011111111x16FF            ADD    R3, R3, #-1    ;R3 = R3 - 1                                ;所以输入后的字符串的存储是倒序的
x300D0000100000000001x0801            BRN    x300F         
x300E0000111111111000x0FF8            BRNZPx3007      





x300F1110100011101111xE8EF            LEA    R4, x30FF      ;R4 = 0x30FF
x30100101010010100000x54A0            AND    R2, R2, #0   ;R2 = 0

x30110001001010000100x1284            ADD    R1, R2, R4   ;R1 = 0x30FF + R2
x30120110001001000000x6240            LDR    R1, R1, #0   ;R1 = =
x30130101000000100000x5020            AND    R0, R0, #0   ;R0 = 0

x30140010000001100010x2062            LD   R0, x3077      ;R0 =
x30151001000000111111x903F            NOT    R0, R0         ;R0 = ~R0 = ~
x30160001000000100001x1021            ADD    R0, R0, #1   ;R0 = ~ + 1
x30170001000001000000x1040            ADD    R0, R1, R0   ;R0 = + (~ + 1) = -
x30180000010000001010x040A            BRZ    x3023                    ;意思是若R0等于0( == = 0x11),则一直跳转到0x3023
      
x30190010000001011110x205E            LD   R0, x3078      
x301A1001000000111111x903F            NOT    R0, R0         
x301B0001000000100001x1021            ADD    R0, R0, #1   
x301C0001000001000000x1040            ADD    R0, R1, R0   
x301D0000010000010111x0417            BRZ    x3035                   ; == = 0x13
   
x301E0010000001011010x205A            LD   R0, x3079      
x301F1001000000111111x903F            NOT    R0, R0         
x30200001000000100001x1021            ADD    R0, R0, #1   
x30210001000001000000x1040            ADD    R0, R1, R0   
x30220000010000100101x0425            BRZ    x3048               ; == = 0x14
   
   
   
   
   
x30230001001010100001x12A1            ADD    R1, R2, #1   ;R1 = R2 + 1
x30240001001100000001x1301            ADD    R1, R4, R1   ;R1 = R4 + R2 + 1                        ;R4 = 0x30FF
x30250110001001000000x6240            LDR    R1, R1, #0   ;R1 =
x30260001110001100000x1C60            ADD    R6, R1, #0   ;R6 = R1
x30270001001010100010x12A2            ADD    R1, R2, #2   ;R1 = R2 + 2
x30280001001100000001x1301            ADD    R1, R4, R1   ;R1 = R4 + (R2 + 2)
x30290110001001000000x6240            LDR    R1, R1, #0   ;R1 =
x302A0010000010111001x20B9            LD   R0, x30E4      ;R0 =                                 ;flag基址0x4000
x302B0001000001100000x1060            ADD    R0, R1, #0   ;R0 = +
x302C0110000000000000x6000            LDR    R0, R0, #0   ;R0 = [ + ] = flag[]
x302D0001111000100000x1E20            ADD    R7, R0, #0   ;R7 = flag[]
x302E0001101001100000x1A60            ADD    R5, R1, #0   ;R5 =
x302F0000111000101001x0E29            BRNZPx3059         


x30300010001010110011x22B3            LD   R1, x30E4      ;R1 = = 0x4000
x30310001001101000001x1341            ADD    R1, R5, R1   ;R1 = 0x4000 +
x30320111000001000000x7040            STR    R0, R1, #0   ; = R0                                        ;flag[] = + flag[]
x30330001010010100011x14A3            ADD    R2, R2, #3   ;R2 += 3
x30340000111111011100x0FDC            BRNZPx3011         



x30350001001010100001x12A1            ADD    R1, R2, #1   ;R1 = R2 + 1
x30360001001100000001x1301            ADD    R1, R4, R1   ;R1 = R4 + R2 + 1
x30370110001001000000x6240            LDR    R1, R1, #0   ;R1 =
x30380010000010101011x20AB            LD   R0, x30E4      ;R0 = 0x4000
x30390001000000000001x1001            ADD    R0, R0, R1   ;R0 = 0X4000 +
x303A0110110000000000x6C00            LDR    R6, R0, #0   ;R6 = = FLAG[]
x303B0001001010100010x12A2            ADD    R1, R2, #2   ;R1 = R2 + 2
x303C0001001100000001x1301            ADD    R1, R4, R1   ;R1 = R4 + R1 = R4 + R2 + 2
x303D0110001001000000x6240            LDR    R1, R1, #0   ;R1 =
x303E0010000010100101x20A5            LD   R0, x30E4      ;R0 = 0X4000
x303F0001000000000001x1001            ADD    R0, R0, R1   ;R0 = 0X4000 +
x30400001101001100000x1A60            ADD    R5, R1, #0   ;R5 =
x30410110111000000000x6E00            LDR    R7, R0, #0   ;R7 = ] = FLAG[]
x30420000111000011000x0E18            BRNZPx305B         


x30430010001010100000x22A0            LD   R1, x30E4      ;R1 = 0X4000
x30440001001001000101x1245            ADD    R1, R1, R5   ;R1 = 0X4000 +
x30450111000001000000x7040            STR    R0, R1, #0   ; = R0                ;FLAG[] = ((FLAG[]) & (~(FLAG[]))) + ((~FLAG[]) & (FLAG[]))
x30460001010010100011x14A3            ADD    R2, R2, #3   ;R2 = R2 + 3
x30470000111111001001x0FC9            BRNZPx3011         



x30480001001010100001x12A1            ADD    R1, R2, #1   ;R1 = R2 + 1
x30490001001100000001x1301            ADD    R1, R4, R1   ;R1 = R4 + R2 + 1
x304A0110001001000000x6240            LDR    R1, R1, #0   ;R1 =
x304B0001110001100000x1C60            ADD    R6, R1, #0   ;R6 = R1 =
x304C0001001010100010x12A2            ADD    R1, R2, #2   ;R1 = R2 + 2
x304D0001001100000001x1301            ADD    R1, R4, R1   ;R1 = R4 + R2 + 2
x304E0110001001000000x6240            LDR    R1, R1, #0   ;R1 =
x304F0010101010010101x2A95            LD   R5, x30E5      ;R5 = 0x18
x30501001001001111111x927F            NOT    R1, R1         ;R1 = ~R1                        ;R1 = ~
x30510001001001100001x1261            ADD    R1, R1, #1   ;R1 = ~ + 1
x30520001101101000001x1B41            ADD    R5, R5, R1   ;R5 = 0x18 + (~ + 1)                                ;取非再加一的数学含义是取相反数,R5是用来标志循环是否结束的变量,初值0x18,终值为0.
x30530001111101100000x1F60            ADD    R7, R5, #0   ;R7 = R5 = 0x18 + (~ + 1)                ;考虑到的值为0x0~0x18,所以结果是0x18 - i,同时别忘了前面说过的字符串是倒序存储的
x30540000111000001100x0E0C            BRNZPx3061


x30550001101101100000x1B60            ADD    R5, R5, #0   ;if (R5 == 0)        ????可能会影响标志位????
x30560000010000010101x0415            BRZ    x306C          ;GOTO SUCCESS
x30570001010010100011x14A3            ADD    R2, R2, #3   ;R2 += 3
x30580000111110111000x0FB8            BRNZPx3011         





x30590001000110000111x1187            ADD    R0, R6, R7   ;R0 = + flag[]
x305A0000111111010101x0FD5            BRNZPx3030         


x305B1001000110111111x91BF            NOT    R0, R6         ;R0 = ~R6 = ~FLAG[]
x305C0101000000000111x5007            AND    R0, R0, R7   ;R0 = (~FLAG[]) & (FLAG[])
x305D1001001111111111x93FF            NOT    R1, R7         ;R1 = ~(FLAG[])
x305E0101001110000001x5381            AND    R1, R6, R1   ;R1 = (FLAG[]) & (~(FLAG[]))
x305F0001000001000000x1040            ADD    R0, R1, R0   ;R0 = ((FLAG[]) & (~(FLAG[]))) + ((~FLAG[]) & (FLAG[]))
x30600000111111100010x0FE2            BRNZPx3043         


x30610010000010000010x2082            LD   R0, x30E4      ;R0 = 0X4000
x30620001000000000110x1006            ADD    R0, R0, R6   ;R0 = 0X4000 +
x30630110000000000000x6000            LDR    R0, R0, #0   ;R0 = ] = FLAG[]
x30641110001010000001xE281            LEA    R1, x30E6      ;R1 = 0x30E6                                ;这里是LEA,不是LDR,我个老花眼看错了,怪不得下一条指令不太对劲。
x30650001001001000111x1247            ADD    R1, R1, R7   ;R1 = 0x30E6 + 0x18 + (~ + 1)
x30660110001001000000x6240            LDR    R1, R1, #0   ;R1 = + 1)]
x30671001001001111111x927F            NOT    R1, R1         ;R1 = ~ + 1)]
x30680001001001100001x1261            ADD    R1, R1, #1   ;R1 = ~ + 1)] + 1                ;取 + 1)]的相反数
x30690001000000000001x1001            ADD    R0, R0, R1   ;R0 = FLAG[] + (~ + 1)] + 1) = FLAG[] - + 1)],flag密文比较
x306A0000010111101010x05EA            BRZ    x3055          ;二者相等则继续

x306B0000111000000101x0E05            BRNZPx3071          ;不相等说明flag不对,GOTO try again





x306C0010000000001101x200D            LD   R0, x307A      ;换行
x306D1111000000100001xF021            TRAP   OUT            
x306E1110000001000000xE040            LEA    R0, x30AF      ;SUCCESS!
x306F1111000000100010xF022            TRAP   PUTS         
x30700000111000000101x0E05            BRNZPx3076         
x30710010000000001000x2008            LD   R0, x307A      ;换行
x30721111000000100001xF021            TRAP   OUT            
x30731110000001100101xE065            LEA    R0, x30D9      ;TRY AGAIN!
x30741111000000100010xF022            TRAP   PUTS         
x30750000111000000000x0E00            BRNZPx3076         
x30761111000000100101xF025            TRAP   HALT      




   
x30770000000000010001x0011            NOP                  
x30780000000000010011x0013            NOP                  
x30790000000000010100x0014            NOP                  
x307A0000000000001010x000A            NOP                  
x307B0000000001010111x0057            NOP                   ;W
x307C0000000001100101x0065            NOP                   ;e
x307D0000000001101100x006C            NOP                   ;l
x307E0000000001100011x0063            NOP                   ;c
x307F0000000001101111x006F            NOP                   ;o
x30800000000001101101x006D            NOP                   ;m
x30810000000001100101x0065            NOP                   ;e
x30820000000000100000x0020            NOP                  
x30830000000001110100x0074            NOP                  
x30840000000001101111x006F            NOP                  
x30850000000000100000x0020            NOP                  
x30860000000001110100x0074            NOP                  
x30870000000001101000x0068            NOP                  
x30880000000001100101x0065            NOP                  
x30890000000000100000x0020            NOP                  
x308A0000000001110111x0077            NOP                  
x308B0000000001101111x006F            NOP                  
x308C0000000001110010x0072            NOP                  
x308D0000000001101100x006C            NOP                  
x308E0000000001100100x0064            NOP                  
x308F0000000000100000x0020            NOP                  
x30900000000001101111x006F            NOP                  
x30910000000001100110x0066            NOP                  
x30920000000000100000x0020            NOP                  
x30930000000001001100x004C            NOP                  
x30940000000001000011x0043            NOP                  
x30950000000000110011x0033            NOP                  
x30960000000000000000x0000            NOP                  
x30970000000001010000x0050            NOP                  
x30980000000001101100x006C            NOP                  
x30990000000001100101x0065            NOP                  
x309A0000000001100001x0061            NOP                  
x309B0000000001110011x0073            NOP                  
x309C0000000001100101x0065            NOP                  
x309D0000000000100000x0020            NOP                  
x309E0000000001101001x0069            NOP                  
x309F0000000001101110x006E            NOP                  
x30A00000000001110101x0075            NOP                  
x30A10000000001110000x0070            NOP                  
x30A20000000001110100x0074            NOP                  
x30A30000000000100000x0020            NOP                  
x30A40000000001111001x0079            NOP                  
x30A50000000001101111x006F            NOP                  
x30A60000000001110101x0075            NOP                  
x30A70000000001110010x0072            NOP                  
x30A80000000000100000x0020            NOP                  
x30A90000000001100110x0066            NOP                  
x30AA0000000001101100x006C            NOP                  
x30AB0000000001100001x0061            NOP                  
x30AC0000000001100111x0067            NOP                  
x30AD0000000000111010x003A            NOP                  
x30AE0000000000000000x0000            NOP                  
x30AF0000000001010011x0053            NOP                  
x30B00000000001110101x0075            NOP                  
x30B10000000001100011x0063            NOP                  
x30B20000000001100011x0063            NOP                  
x30B30000000001100101x0065            NOP                  
x30B40000000001110011x0073            NOP                  
x30B50000000001110011x0073            NOP                  
x30B60000000000100001x0021            NOP                  
x30B70000000000100000x0020            NOP                  
x30B80000000001011001x0059            NOP                  
x30B90000000001101111x006F            NOP                  
x30BA0000000001110101x0075            NOP                  
x30BB0000000001110010x0072            NOP                  
x30BC0000000000100000x0020            NOP                  
x30BD0000000001100110x0066            NOP                  
x30BE0000000001101100x006C            NOP                  
x30BF0000000001100001x0061            NOP                  
x30C00000000001100111x0067            NOP                  
x30C10000000000100000x0020            NOP                  
x30C20000000001101001x0069            NOP                  
x30C30000000001110011x0073            NOP                  
x30C40000000000100000x0020            NOP                  
x30C50000000001111000x0078            NOP                  
x30C60000000001101101x006D            NOP                  
x30C70000000001100011x0063            NOP                  
x30C80000000001110100x0074            NOP                  
x30C90000000001100110x0066            NOP                  
x30CA0000000001111011x007B            NOP                  
x30CB0000000001111011x007B            NOP                  
x30CC0000000001111001x0079            NOP                  
x30CD0000000001101111x006F            NOP                  
x30CE0000000001110101x0075            NOP                  
x30CF0000000001110010x0072            NOP                  
x30D00000000000100000x0020            NOP                  
x30D10000000001101001x0069            NOP                  
x30D20000000001101110x006E            NOP                  
x30D30000000001110000x0070            NOP                  
x30D40000000001110101x0075            NOP                  
x30D50000000001110100x0074            NOP                  
x30D60000000001111101x007D            NOP                  
x30D70000000001111101x007D            NOP                  
x30D80000000000000000x0000            NOP                  
x30D90000000001010100x0054            NOP                  
x30DA0000000001110010x0072            NOP                  
x30DB0000000001111001x0079            NOP                  
x30DC0000000000100000x0020            NOP                  
x30DD0000000001100001x0061            NOP                   ;a
x30DE0000000001100111x0067            NOP                   ;g
x30DF0000000001100001x0061            NOP                   ;a
x30E00000000001101001x0069            NOP                   ;i
x30E10000000001101110x006E            NOP                   ;n
x30E20000000000100001x0021            NOP                   ;!
x30E30000000000000000x0000            NOP                  
x30E40100000000000000x4000            JSRR   R0            
x30E50000000000011000x0018            NOP                  
x30E60000000001101100x006C            NOP                  
x30E70000000000001111x000F            NOP                  
x30E80000000001010000x0050            NOP                  
x30E90000000001101100x006C            NOP                  
x30EA0000000001101110x006E            NOP                  
x30EB0000000001000010x0042            NOP                  
x30EC0000000000101100x002C            NOP                  
x30ED0000000000101100x002C            NOP                  
x30EE0000000000011110x001E            NOP                  
x30EF0000000000001100x000C            NOP                  
x30F00000000000001101x000D            NOP                  
x30F10000000000000000x0000            NOP                  
x30F20000000000110011x0033            NOP                  
x30F30000000000111101x003D            NOP                  
x30F40000000000010111x0017            NOP                  
x30F50000000000000001x0001            NOP                  
x30F60000000000101011x002B            NOP                  
x30F70000000000111100x003C            NOP                  
x30F80000000000001100x000C            NOP                  
x30F90000000000000010x0002            NOP                  
x30FA0000000000011101x001D            NOP                  
x30FB0000000000011100x001C            NOP                  
x30FC0000000000001001x0009            NOP                  
x30FD0000000000010001x0011            NOP                  
x30FE0000000000010001x0011            NOP                  
x30FF0000000000010011x0013            NOP                  
x31000000000000000001x0001            NOP                  
x31010000000000000000x0000            NOP                  
x31020000000000010100x0014            NOP                  
x31030000000000000000x0000            NOP                  
x31040000000000000000x0000            NOP                  
x31050000000000010011x0013            NOP                  
x31060000000000000010x0002            NOP                  
x31070000000000000001x0001            NOP                  
x31080000000000010100x0014            NOP                  
x31090000000000000001x0001            NOP                  
x310A0000000000000001x0001            NOP                  
x310B0000000000010011x0013            NOP                  
x310C0000000000000011x0003            NOP                  
x310D0000000000000010x0002            NOP                  
x310E0000000000010100x0014            NOP                  
x310F0000000000000010x0002            NOP                  
x31100000000000000010x0002            NOP                  
x31110000000000010011x0013            NOP                  
x31120000000000000100x0004            NOP                  
x31130000000000000011x0003            NOP                  
x31140000000000010100x0014            NOP                  
x31150000000000000011x0003            NOP                  
x31160000000000000011x0003            NOP                  
x31170000000000010011x0013            NOP                  
x31180000000000000101x0005            NOP                  
x31190000000000000100x0004            NOP                  
x311A0000000000010100x0014            NOP                  
x311B0000000000000100x0004            NOP                  
x311C0000000000000100x0004            NOP                  
x311D0000000000010011x0013            NOP                  
x311E0000000000000110x0006            NOP                  
x311F0000000000000101x0005            NOP                  
x31200000000000010100x0014            NOP                  
x31210000000000000101x0005            NOP                  
x31220000000000000101x0005            NOP                  
x31230000000000010011x0013            NOP                  
x31240000000000000111x0007            NOP                  
x31250000000000000110x0006            NOP                  
x31260000000000010100x0014            NOP                  
x31270000000000000110x0006            NOP                  
x31280000000000000110x0006            NOP                  
x31290000000000010011x0013            NOP                  
x312A0000000000001000x0008            NOP                  
x312B0000000000000111x0007            NOP                  
x312C0000000000010100x0014            NOP                  
x312D0000000000000111x0007            NOP                  
x312E0000000000000111x0007            NOP                  
x312F0000000000010011x0013            NOP                  
x31300000000000001001x0009            NOP                  
x31310000000000001000x0008            NOP                  
x31320000000000010100x0014            NOP                  
x31330000000000001000x0008            NOP                  
x31340000000000001000x0008            NOP                  
x31350000000000010011x0013            NOP                  
x31360000000000001010x000A            NOP                  
x31370000000000001001x0009            NOP                  
x31380000000000010100x0014            NOP                  
x31390000000000001001x0009            NOP                  
x313A0000000000001001x0009            NOP                  
x313B0000000000010011x0013            NOP                  
x313C0000000000001011x000B            NOP                  
x313D0000000000001010x000A            NOP                  
x313E0000000000010100x0014            NOP                  
x313F0000000000001010x000A            NOP                  
x31400000000000001010x000A            NOP                  
x31410000000000010011x0013            NOP                  
x31420000000000001100x000C            NOP                  
x31430000000000001011x000B            NOP                  
x31440000000000010100x0014            NOP                  
x31450000000000001011x000B            NOP                  
x31460000000000001011x000B            NOP                  
x31470000000000010011x0013            NOP                  
x31480000000000001101x000D            NOP                  
x31490000000000001100x000C            NOP                  
x314A0000000000010100x0014            NOP                  
x314B0000000000001100x000C            NOP                  
x314C0000000000001100x000C            NOP                  
x314D0000000000010011x0013            NOP                  
x314E0000000000001110x000E            NOP                  
x314F0000000000001101x000D            NOP                  
x31500000000000010100x0014            NOP                  
x31510000000000001101x000D            NOP                  
x31520000000000001101x000D            NOP                  
x31530000000000010011x0013            NOP                  
x31540000000000001111x000F            NOP                  
x31550000000000001110x000E            NOP                  
x31560000000000010100x0014            NOP                  
x31570000000000001110x000E            NOP                  
x31580000000000001110x000E            NOP                  
x31590000000000010011x0013            NOP                  
x315A0000000000010000x0010            NOP                  
x315B0000000000001111x000F            NOP                  
x315C0000000000010100x0014            NOP                  
x315D0000000000001111x000F            NOP                  
x315E0000000000001111x000F            NOP                  
x315F0000000000010011x0013            NOP                  
x31600000000000010001x0011            NOP                  
x31610000000000010000x0010            NOP                  
x31620000000000010100x0014            NOP                  
x31630000000000010000x0010            NOP                  
x31640000000000010000x0010            NOP                  
x31650000000000010011x0013            NOP                  
x31660000000000010010x0012            NOP                  
x31670000000000010001x0011            NOP                  
x31680000000000010100x0014            NOP                  
x31690000000000010001x0011            NOP                  
x316A0000000000010001x0011            NOP                  
x316B0000000000010011x0013            NOP                  
x316C0000000000010011x0013            NOP                  
x316D0000000000010010x0012            NOP                  
x316E0000000000010100x0014            NOP                  
x316F0000000000010010x0012            NOP                  
x31700000000000010010x0012            NOP                  
x31710000000000010011x0013            NOP                  
x31720000000000010100x0014            NOP                  
x31730000000000010011x0013            NOP                  
x31740000000000010100x0014            NOP                  
x31750000000000010011x0013            NOP                  
x31760000000000010011x0013            NOP                  
x31770000000000010011x0013            NOP                  
x31780000000000010101x0015            NOP                  
x31790000000000010100x0014            NOP                  
x317A0000000000010100x0014            NOP                  
x317B0000000000010100x0014            NOP                  
x317C0000000000010100x0014            NOP                  
x317D0000000000010011x0013            NOP                  
x317E0000000000010110x0016            NOP                  
x317F0000000000010101x0015            NOP                  
x31800000000000010100x0014            NOP                  
x31810000000000010101x0015            NOP                  
x31820000000000010101x0015            NOP                  
x31830000000000010011x0013            NOP                  
x31840000000000010111x0017            NOP                  
x31850000000000010110x0016            NOP                  
x31860000000000010100x0014            NOP                  
x31870000000000010110x0016            NOP                  
x31880000000000010110x0016            NOP                  
x31890000000000010011x0013            NOP                  
x318A0000000000011000x0018            NOP                  
x318B0000000000010111x0017            NOP                  
x318C0000000000010100x0014            NOP                  
x318D0000000000010111x0017            NOP                  
x318E0000000000010111x0017            NOP                  
x318F0000000000010100x0014            NOP                  
x31900000000000011000x0018            NOP                  
x31910000000000011000x0018            NOP                  
x31920000000000000000x0000            NOP                  
x31930000000000000000x0000            NOP                  
x31940000000000000000x0000            NOP                  
x31950000000000000000x0000            NOP                  
x31960000000000000000x0000            NOP                  
x31970000000000000000x0000            NOP                  
x31980000000000000000x0000            NOP                  
x31990000000000000000x0000            NOP                  
x319A0000000000000000x0000            NOP                  
x319B0000000000000000x0000            NOP                  
x319C0000000000000000x0000            NOP                  
x319D0000000000000000x0000            NOP                  
x319E0000000000000000x0000            NOP                  
x319F0000000000000000x0000            NOP                  
```

选择静态分析汇编的话,最重要的一件事就是确定程序流程。不然寄存器的值绝对会乱。

程序输入flag后,连续有三块跳转,流程分别为:

* 0x3023 -> 0x3059 -> 0x3030 -> 0x3011
* 0x3035 -> 0x305b -> 0x3043 -> 0x3011
* 0x3048 -> 0x3061 -> 0x3055 -> 0x3011

然后说一下程序的几个数据:

* 0x30E4处的值是0x4000,这是flag存储的位置

* 0x30E5是0x18,flag的长度

* 0x30E6开始的0x18个数据就是flag的密文了

* 0x30FF开始的数据,每三个一组,分别记为a,b,c,a是操作码,可以是0x11,0x13,0x14,b和c是操作数。

前面提到过连续的三块跳转,其实就是三个操作码对应的case。当然你要是把0x30FF的数据提取出来,会发现根本没有0x11的操作码,所以第一个case其实从未执行过。

```
0x13 1 0
0x14 0 0
0x13 2 1
0x14 1 1
0x13 3 2
0x14 2 2
0x13 4 3
0x14 3 3
0x13 5 4
0x14 4 4
0x13 6 5
0x14 5 5
0x13 7 6
0x14 6 6
0x13 8 7
0x14 7 7
0x13 9 8
0x14 8 8
0x13 10 9
0x14 9 9
0x13 11 10
0x14 10 10
0x13 12 11
0x14 11 11
0x13 13 12
0x14 12 12
0x13 14 13
0x14 13 13
0x13 15 14
0x14 14 14
0x13 16 15
0x14 15 15
0x13 17 16
0x14 16 16
0x13 18 17
0x14 17 17
0x13 19 18
0x14 18 18
0x13 20 19
0x14 19 19
0x13 21 20
0x14 20 20
0x13 22 21
0x14 21 21
0x13 23 22
0x14 22 22
0x13 24 23
0x14 23 23
0x14 24 24
```

然后我们分别分析下三个case的逻辑吧。

* 0x11的case,对应0x3023的代码,flag = b + flag
* 0x13的case,对应0x3035的代码,flag = (flag & ~(flag)) + ((~flag) & flag)
* 0x14的case,对应0x3048的代码,验证flag == cipher

需要注意一点,有意思的是~n + 1表示的是n的相反数,所以m + (~n + 1)表示的是m-n,利用结果是否等于0,可以选择是否进行跳转(BRZ)

回到主要的逻辑上来,结合上面的0x30FF的数据,你会发现其实是类似这样的:

```python
#a,b,c是0x30FF的第i组
for i in range(24):
        flag = (flag & ~(flag)) + ((~flag) & flag)
        if flag != cipher:
                exit()
if flag != cipher:
    exit()
print('正确')
```

那行等式我没想出怎么逆,好像也逆不了??所以直接爆破了。可以写出下面的脚本:

> 几个小时后的补充:
>
> 看了看队友的博客,他的脚本居然只有异或??
>
> 试了下,发现`(~a & b) + (a & ~b) = a ^ b`,哇,居然还有这种化简。
>
> 其实仔细想想,确实是这样的。
>
> 因为a和~a的存在,导致针对具体的某一bit,(~a & b)和(a & ~b)二者必不可能同时为1,所以加法进位的问题不复存在。
>
> 不过脚本我就不改啦,你们自己写的时候就不用爆破了,直接用异或解就行。

```python
code = '''x30E40100000000000000x4000            JSRR   R0            
x30E50000000000011000x0018            NOP                  
x30E60000000001101100x006C            NOP                  
x30E70000000000001111x000F            NOP                  
x30E80000000001010000x0050            NOP                  
x30E90000000001101100x006C            NOP                  
x30EA0000000001101110x006E            NOP                  
x30EB0000000001000010x0042            NOP                  
x30EC0000000000101100x002C            NOP                  
x30ED0000000000101100x002C            NOP                  
x30EE0000000000011110x001E            NOP                  
x30EF0000000000001100x000C            NOP                  
x30F00000000000001101x000D            NOP                  
x30F10000000000000000x0000            NOP                  
x30F20000000000110011x0033            NOP                  
x30F30000000000111101x003D            NOP                  
x30F40000000000010111x0017            NOP                  
x30F50000000000000001x0001            NOP                  
x30F60000000000101011x002B            NOP                  
x30F70000000000111100x003C            NOP                  
x30F80000000000001100x000C            NOP                  
x30F90000000000000010x0002            NOP                  
x30FA0000000000011101x001D            NOP                  
x30FB0000000000011100x001C            NOP                  
x30FC0000000000001001x0009            NOP                  
x30FD0000000000010001x0011            NOP                  
x30FE0000000000010001x0011            NOP                  
x30FF0000000000010011x0013            NOP                  
x31000000000000000001x0001            NOP                  
x31010000000000000000x0000            NOP                  
x31020000000000010100x0014            NOP                  
x31030000000000000000x0000            NOP                  
x31040000000000000000x0000            NOP                  
x31050000000000010011x0013            NOP                  
x31060000000000000010x0002            NOP                  
x31070000000000000001x0001            NOP                  
x31080000000000010100x0014            NOP                  
x31090000000000000001x0001            NOP                  
x310A0000000000000001x0001            NOP                  
x310B0000000000010011x0013            NOP                  
x310C0000000000000011x0003            NOP                  
x310D0000000000000010x0002            NOP                  
x310E0000000000010100x0014            NOP                  
x310F0000000000000010x0002            NOP                  
x31100000000000000010x0002            NOP                  
x31110000000000010011x0013            NOP                  
x31120000000000000100x0004            NOP                  
x31130000000000000011x0003            NOP                  
x31140000000000010100x0014            NOP                  
x31150000000000000011x0003            NOP                  
x31160000000000000011x0003            NOP                  
x31170000000000010011x0013            NOP                  
x31180000000000000101x0005            NOP                  
x31190000000000000100x0004            NOP                  
x311A0000000000010100x0014            NOP                  
x311B0000000000000100x0004            NOP                  
x311C0000000000000100x0004            NOP                  
x311D0000000000010011x0013            NOP                  
x311E0000000000000110x0006            NOP                  
x311F0000000000000101x0005            NOP                  
x31200000000000010100x0014            NOP                  
x31210000000000000101x0005            NOP                  
x31220000000000000101x0005            NOP                  
x31230000000000010011x0013            NOP                  
x31240000000000000111x0007            NOP                  
x31250000000000000110x0006            NOP                  
x31260000000000010100x0014            NOP                  
x31270000000000000110x0006            NOP                  
x31280000000000000110x0006            NOP                  
x31290000000000010011x0013            NOP                  
x312A0000000000001000x0008            NOP                  
x312B0000000000000111x0007            NOP                  
x312C0000000000010100x0014            NOP                  
x312D0000000000000111x0007            NOP                  
x312E0000000000000111x0007            NOP                  
x312F0000000000010011x0013            NOP                  
x31300000000000001001x0009            NOP                  
x31310000000000001000x0008            NOP                  
x31320000000000010100x0014            NOP                  
x31330000000000001000x0008            NOP                  
x31340000000000001000x0008            NOP                  
x31350000000000010011x0013            NOP                  
x31360000000000001010x000A            NOP                  
x31370000000000001001x0009            NOP                  
x31380000000000010100x0014            NOP                  
x31390000000000001001x0009            NOP                  
x313A0000000000001001x0009            NOP                  
x313B0000000000010011x0013            NOP                  
x313C0000000000001011x000B            NOP                  
x313D0000000000001010x000A            NOP                  
x313E0000000000010100x0014            NOP                  
x313F0000000000001010x000A            NOP                  
x31400000000000001010x000A            NOP                  
x31410000000000010011x0013            NOP                  
x31420000000000001100x000C            NOP                  
x31430000000000001011x000B            NOP                  
x31440000000000010100x0014            NOP                  
x31450000000000001011x000B            NOP                  
x31460000000000001011x000B            NOP                  
x31470000000000010011x0013            NOP                  
x31480000000000001101x000D            NOP                  
x31490000000000001100x000C            NOP                  
x314A0000000000010100x0014            NOP                  
x314B0000000000001100x000C            NOP                  
x314C0000000000001100x000C            NOP                  
x314D0000000000010011x0013            NOP                  
x314E0000000000001110x000E            NOP                  
x314F0000000000001101x000D            NOP                  
x31500000000000010100x0014            NOP                  
x31510000000000001101x000D            NOP                  
x31520000000000001101x000D            NOP                  
x31530000000000010011x0013            NOP                  
x31540000000000001111x000F            NOP                  
x31550000000000001110x000E            NOP                  
x31560000000000010100x0014            NOP                  
x31570000000000001110x000E            NOP                  
x31580000000000001110x000E            NOP                  
x31590000000000010011x0013            NOP                  
x315A0000000000010000x0010            NOP                  
x315B0000000000001111x000F            NOP                  
x315C0000000000010100x0014            NOP                  
x315D0000000000001111x000F            NOP                  
x315E0000000000001111x000F            NOP                  
x315F0000000000010011x0013            NOP                  
x31600000000000010001x0011            NOP                  
x31610000000000010000x0010            NOP                  
x31620000000000010100x0014            NOP                  
x31630000000000010000x0010            NOP                  
x31640000000000010000x0010            NOP                  
x31650000000000010011x0013            NOP                  
x31660000000000010010x0012            NOP                  
x31670000000000010001x0011            NOP                  
x31680000000000010100x0014            NOP                  
x31690000000000010001x0011            NOP                  
x316A0000000000010001x0011            NOP                  
x316B0000000000010011x0013            NOP                  
x316C0000000000010011x0013            NOP                  
x316D0000000000010010x0012            NOP                  
x316E0000000000010100x0014            NOP                  
x316F0000000000010010x0012            NOP                  
x31700000000000010010x0012            NOP                  
x31710000000000010011x0013            NOP                  
x31720000000000010100x0014            NOP                  
x31730000000000010011x0013            NOP                  
x31740000000000010100x0014            NOP                  
x31750000000000010011x0013            NOP                  
x31760000000000010011x0013            NOP                  
x31770000000000010011x0013            NOP                  
x31780000000000010101x0015            NOP                  
x31790000000000010100x0014            NOP                  
x317A0000000000010100x0014            NOP                  
x317B0000000000010100x0014            NOP                  
x317C0000000000010100x0014            NOP                  
x317D0000000000010011x0013            NOP                  
x317E0000000000010110x0016            NOP                  
x317F0000000000010101x0015            NOP                  
x31800000000000010100x0014            NOP                  
x31810000000000010101x0015            NOP                  
x31820000000000010101x0015            NOP                  
x31830000000000010011x0013            NOP                  
x31840000000000010111x0017            NOP                  
x31850000000000010110x0016            NOP                  
x31860000000000010100x0014            NOP                  
x31870000000000010110x0016            NOP                  
x31880000000000010110x0016            NOP                  
x31890000000000010011x0013            NOP                  
x318A0000000000011000x0018            NOP                  
x318B0000000000010111x0017            NOP                  
x318C0000000000010100x0014            NOP                  
x318D0000000000010111x0017            NOP                  
x318E0000000000010111x0017            NOP                  
x318F0000000000010100x0014            NOP                  
x31900000000000011000x0018            NOP                  
x31910000000000011000x0018            NOP   '''

import re
lines = code.split('\n')
data = []
for line in lines:
    r = re.search(r'x{4} *?\d{16} *?x{2}({2})', line)
    data.append(int(r.group(1), 16))

cipher = data

'''
op = data
for i in range(len(op)//3):
    t = op
    a, b, c = t, t, t
    #print(hex(a), b, c)
'''

flag = * 25
flag = cipher
for i in range(23, -1, -1):
    for j in range(32, 127):
      if cipher == (flag & (~j)) + ((~flag) & j):
            flag = j
            #print(j,end= ' ')
    print()
print(flag[::-1])
print(''.join(map(chr, flag[::-1])))
```

## Misc

###GACTF FeedBack

问卷,直接拍主办方马屁即可。

### trihistory

给出一个docker,运行后发现只有80端口开放。端口转发一下并访问网站,就一个普通的html。

`docker run -it -p 50050:80 impakho/trihistory`

exec进入容器内部`docker exec -it (容器ID) /bin/bash`

`find / -name flag`

发现一个flag.html,但是它说flag已经删了。可以想到docker文件恢复。

首先`docker history --no-trunc (容器ID)`看看操作历史(输出结果不好排版,所以我就不粘贴了),然后`docker inspect (容器ID)`显示镜像详情。

```
# docker inspect f8
[
    {
      "Id": "sha256:f8f0608cd1a4334c15aa7f37598f5aa1ba7aca9556897a1d119a2e8432424238",
      "RepoTags": [
            "impakho/trihistory:latest"
      ],
      "RepoDigests": [
            "impakho/trihistory@sha256:17297590f715c03d277b0587bedfd471b1cef1270903751c978e72dd0de570f5"
      ],
      "Parent": "",
      "Comment": "",
      "Created": "2020-05-20T10:57:23.1669636Z",
      "Container": "1d4ee6c290809d39f5c3b9796d35db94a128ed59cb146fc07ff8bbad529ba4a8",
      "ContainerConfig": {
            "Hostname": "1d4ee6c29080",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "ENTRYPOINT [\"/start.sh\"]"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:eea8459418cdd2ad3e0ce40ac4b828a62eedc4d654bc7af9ff8cf528b8ebec09",
            "Volumes": null,
            "WorkingDir": "/",
            "Entrypoint": [
                "/start.sh"
            ],
            "OnBuild": null,
            "Labels": {}
      },
      "DockerVersion": "18.06.1-ce",
      "Author": "",
      "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": null,
            "ArgsEscaped": true,
            "Image": "sha256:eea8459418cdd2ad3e0ce40ac4b828a62eedc4d654bc7af9ff8cf528b8ebec09",
            "Volumes": null,
            "WorkingDir": "/",
            "Entrypoint": [
                "/start.sh"
            ],
            "OnBuild": null,
            "Labels": null
      },
      "Architecture": "amd64",
      "Os": "linux",
      "Size": 158201380,
      "VirtualSize": 158201380,
      "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/2f7214b86ceab0536712adb11af6a68719533e2a9221f54df0302d5aa3e26e37/diff:/var/lib/docker/overlay2/e84985e750d316e6239f05939c7ada004483cb539512379c7ac9eef00692980e/diff:/var/lib/docker/overlay2/727fd216638fe9de4331070a077f6f649b8cf66f57126967f317b6424ec56581/diff:/var/lib/docker/overlay2/4d171d3ce743841b0734f25fde902b4d3bf18bb3c7183d2593549fe555ab23aa/diff:/var/lib/docker/overlay2/39bcdfc0de7f149254ba02f2dd3ac61b20167953268a6989f3b4e9e5997533b3/diff:/var/lib/docker/overlay2/0f06c00bcdf99960a4488995f31203f57be0ad2c7180feb5f6ce22eabe143702/diff:/var/lib/docker/overlay2/ebd1261fadfad7d548bdf7ebcff5d5c67e2d0bd85693e2a322d2a8a71e4d7c86/diff:/var/lib/docker/overlay2/88c0f970c53e169fd89da0d622d8604a45aec80c7221b59dce917e7867c58f14/diff:/var/lib/docker/overlay2/b6b397a4be86157bf545028bbb3fa51445e0263577bb516cebe041e86305cd13/diff",
                "MergedDir": "/var/lib/docker/overlay2/962c512dbe97a4da4ede6833e4796ce80ddf8de8f9322b4cee94820e46447427/merged",
                "UpperDir": "/var/lib/docker/overlay2/962c512dbe97a4da4ede6833e4796ce80ddf8de8f9322b4cee94820e46447427/diff",
                "WorkDir": "/var/lib/docker/overlay2/962c512dbe97a4da4ede6833e4796ce80ddf8de8f9322b4cee94820e46447427/work"
            },
            "Name": "overlay2"
      },
      "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:b7f7d2967507ba709dbd1dd0426a5b0cdbe1ff936c131f8958c8d0f910eea19e",
                "sha256:a6ebef4a95c345c844c2bf43ffda8e36dd6e053887dd6e283ad616dcc2376be6",
                "sha256:838a37a24627f72df512926fc846dd97c93781cf145690516e23335cc0c27794",
                "sha256:28ba7458d04b8551ff45d2e17dc2abb768bf6ed1a46bb262f26a24d21d8d7233",
                "sha256:8108c9bd0bf43db0fed516a8f8484c2ecd938ec9bd8ea1334b88b9ef8bdf8053",
                "sha256:ca6b45f562603630ba96c849823ac1f1b4be17fe95899ba7ee817f24590e9c19",
                "sha256:4c2307ccb6c66b7ee5b0df2b28ace1c53dd52f834adaa30606450393ef28fee6",
                "sha256:343896badf0a77e212b0ff3e05c67b6bc6fef467bc83e519fa1b4f8059d1a6bd",
                "sha256:f41e1512553f003a733275dcd77494c67c5eda32d9ce5fee8d680c9877b2598c",
                "sha256:af63a460580b4b088fb3a4bd2d9a9c7eae28621844a1df10b5c2aa9bfc9db93d"
            ]
      },
      "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
      }
    }
]
```

注意上面信息中的:

```
"LowerDir": "/var/lib/docker/overlay2/2f7214b86ceab0536712adb11af6a68719533e2a9221f54df0302d5aa3e26e37/diff:/var/lib/docker/overlay2/e84985e750d316e6239f05939c7ada004483cb539512379c7ac9eef00692980e/diff:/var/lib/docker/overlay2/727fd216638fe9de4331070a077f6f649b8cf66f57126967f317b6424ec56581/diff:/var/lib/docker/overlay2/4d171d3ce743841b0734f25fde902b4d3bf18bb3c7183d2593549fe555ab23aa/diff:/var/lib/docker/overlay2/39bcdfc0de7f149254ba02f2dd3ac61b20167953268a6989f3b4e9e5997533b3/diff:/var/lib/docker/overlay2/0f06c00bcdf99960a4488995f31203f57be0ad2c7180feb5f6ce22eabe143702/diff:/var/lib/docker/overlay2/ebd1261fadfad7d548bdf7ebcff5d5c67e2d0bd85693e2a322d2a8a71e4d7c86/diff:/var/lib/docker/overlay2/88c0f970c53e169fd89da0d622d8604a45aec80c7221b59dce917e7867c58f14/diff:/var/lib/docker/overlay2/b6b397a4be86157bf545028bbb3fa51445e0263577bb516cebe041e86305cd13/diff"
```

分别去这几个路径看看。

其中有一个路径中包含着一个git项目。



然后导入到本地,发现git的历史中有`.flag.html.swp`



那就进行版本回滚吧。

```
D:\桌面\root - 副本\history>git log                                                                                     commit a6ed84884a71afaa7a4e34f1b46af69cc773d6ce (HEAD -> master)                                                      Author: impakho <pakho@sent.com>                                                                                        Date:   Wed May 20 18:38:07 2020 +0800                                                                                                                                                                                                            add w3.css                                                                                                                                                                                                                                  commit 4f19a2121a27dc54d85408b99a04d14e6424aacf                                                                         Author: impakho <pakho@sent.com>                                                                                        Date:   Wed May 20 18:27:52 2020 +0800                                                                                                                                                                                                            update init.sh                                                                                                                                                                                                                              commit e9418116088aefc0d7238d32cd96f0f3d36a0fc1                                                                         Author: impakho <pakho@sent.com>                                                                                        Date:   Wed May 20 16:56:41 2020 +0800                                                                                                                                                                                                            remove file                                                                                                                                                                                                                                 commit 47a5ffbd63f271bc627af973d7a949232cfb47c6                                                                         Author: impakho <pakho@sent.com>                                                                                        Date:   Wed May 20 16:55:57 2020 +0800                                                                                                                                                                                                            add wwwroot                                                                                                                                                                                                                                 commit 40954a24d572eff1ecf97257ec96baa899addeb4                                                                         Author: impakho <pakho@sent.com>                                                                                        Date:   Wed May 20 16:29:38 2020 +0800                                                                                                                                                                                                            init commit                                                                                                                                                                                                                        


D:\桌面\root - 副本\history>git revert e9418116088aefc0d7238d32cd96f0f3d36a0fc1                                        Revert "remove file"
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 wwwroot/.flag.html.swp
```

拿到`.flag.html.swp`,打开后在末尾发现flag。

参考:

* (https://www.cnblogs.com/zejin2008/p/13460498.html)
* 随便一篇git历史回滚的文章

### capture

提取坐标:

```python
import re

with open(r'captured (1).txt', 'r')as f:
    text = f.read()
lines = text.split()
with open('capout.txt', 'w')as f:
    for line in lines:
      r = re.search(r',(\d+?),(\d+?)$', line)
      if r:
            #print(r.group(1), r.group(2))
            #out += r.group(1) + ' ' + r.group(2) + '\n'
            f.write(r.group(1) + ' ' + r.group(2) + '\n')
      else:
            r = re.search(r'U(\d+?),(\d+?)$', line)
            if r:
                f.write(r.group(1) + ' ' + r.group(2) + '\n')
            else:
                r = re.search(r'D(\d+?),(\d+?)$', line)
                if r:
                  f.write(r.group(1) + ' ' + r.group(2) + '\n')
```

然后kali下用gnuplot画图,这个需要选取合适的散点的大小和连线的粗细,不然很难分别出字母。

我用的是`plot "capout.txt" with linespoints lw 1 pt 7 ps 0.3`

lw是线的宽度,ps是点的大小,pt是点线类型,可以参考:





绘制出

用photoshop顺时针旋转180度,并进行合适的拉伸和压缩,如果看不清的话可以考虑锐化。

最终好不容易调出这么张勉强能分辨flag的图片:



有的字母真的不好分辨,自己慢慢调吧,我调了五六张。

`gactf{33ffb710eaae052d8b2f7a3955b6517c}`

参考:(https://blog.csdn.net/lwb102063/article/details/50782696)

### oldmodem

首先安装minimodem:

Ubuntu installation:

```
sudo add-apt-repository ppa:kamalmostafa/minimodem
sudo apt-get update
sudo apt-get install minimodem
```

Debian installation:

```
sudo apt-get install minimodem
```

Fedora installation:

```
sudo yum install minimodem
```

然后直接一行指令就可以拿到flag:

`minimodem -r -f encoded 1200 > output`

bell202是1200Hz。



flag就在output的文末

参考:

* [官网](http://www.whence.com/minimodem/)
* [类似的题1](https://ctftime.org/writeup/8689)

* [类似的题2](https://tuanlinh.gitbook.io/ctf/matesctf-2018-round-3)

iyzyi 发表于 2020-9-2 01:07

小朋友呢 发表于 2020-9-1 22:44
师傅tql,师傅是如何分析这个easy_re这个是VM的,解这个VM需要了解什么相关的基础

1、我也是菜鸡一个。
2、看到读取操作码这一行为,可以判断出这是VM.
3、也不需要啥基础吧,多看几道VM,就慢慢了解了。我也是刚接触VM没多久。

iyzyi 发表于 2020-9-2 12:17

小朋友呢 发表于 2020-9-2 10:46
师傅有推荐逆vm这种题练手的这种网站吗

没有专门的网站,不过网上有很多vm的题解,跟着做做也行。
我是看令则大佬的这篇博客入的vm的门:https://bbs.pediy.com/thread-259116.htm

iyzyi 发表于 2020-9-1 13:36

同样是markdown,为啥这里就看不到图片了?这还能跨域不成?
文章同时发在我的博客http://blog.iyzyi.com/index.php/archives/1625/

Hmily 发表于 2020-9-1 14:42

iyzyi 发表于 2020-9-1 13:36
同样是markdown,为啥这里就看不到图片了?这还能跨域不成?
文章同时发在我的博客http://blog.iyzyi.com/ ...

https禁止加载http的请求了吧,直接上传本地吧。

小朋友呢 发表于 2020-9-1 22:44

师傅tql,师傅是如何分析这个easy_re这个是VM的,解这个VM需要了解什么相关的基础

Airey 发表于 2020-9-2 09:46

大佬太强了{:1_893:}

小朋友呢 发表于 2020-9-2 10:46

iyzyi 发表于 2020-9-2 01:07
1、我也是菜鸡一个。
2、看到读取操作码这一行为,可以判断出这是VM.
3、也不需要啥基础吧,多看几道VM ...

师傅有推荐逆vm这种题练手的这种网站吗

Zmacro 发表于 2020-9-2 13:08

厉害了,大佬

凜冬将至 发表于 2020-9-2 18:07

大佬太强了
页: [1] 2 3 4 5
查看完整版本: GACTF的几道逆向和MISC