签到
看到if(v6)就知道v6需要==0
看到do while 循环,需要v8 ^ v7 ^ (v7 + (v7 ^ v9[v7])) == 0
1
| v8 = v7 ^ (v7 + (v7 ^ v9[v7])) //每次v7+1
|
1 2 3 4 5 6 7 8
| v9 = [102,109,99,98,127,58,85,106,57,82,122,55,81,19,51,35,67,70,41,61,41,32,127,28,38,77,49,20,80,94,-24] flag = "" v7 = 0 for i in v9: v8 = v7 ^ (v7 + (v7 ^ i)) v7 = v7+1 flag += chr(v8) print(flag)
|
flag{A_s1mpLe&E4sy_RE_i5Nt_1t}
神光
看主函数
看第一个字符串操作1
肯定不能返回0三,所以这个Str1就应该==wangzherongyao。因为我们知道后面有一个MessageBoxA,想看一下会弹什么窗,所以就先去运行该程序试验一下。
发现是进了一步。
我们要相信没有无缘无故的爱,所以我们来看一下MessageBoxA上面的sub_41141A();这个函数
这个函数是一个CreateThread 函数为进程创建新线程
不是很懂【看了其他WP有说是反调试的玩意{不懂}】
现在来看看对字符串操作2
我是真垃圾,看不懂,但是有感觉是简单的^。【看了WP原来是动调。】
这里用吾爱破解的OD就能简单的出flag
但是用其他的就莫名奇妙的退出去了
BBBigEqSet
发现main函数太大了不能F5。还好原理比较简单还是能看懂的
输入字符串,然后对每个字符串和一个立即数进行了乘法imul。结果然后add到edx里面。
1 2 3
| .text:00000000000011C7 0F B6 85 00 FF FF FF movzx eax, [rbp+s] .text:00000000000011CE 0F BE C0 movsx eax, al .text:00000000000011D1 69 D0 21 94 00 00 imul edx, eax, 9421h
|
最后add到eax里面在进行cmp一个立即数,需要相等。ax1+bx2+c*x3+…=常数的形式
但是这里的数很多,需要用IDApython来将里面的立即数都遍历出来。【目前还不会】
Emmm 最后还是看了Wp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| def u32(a): return a[3]<<24 | a[2]<<16 | a[1]<<8 | a[0]
data = open('BBBigEqSet', 'rb').read()[0x11c7:0x11c7+ 0x909*0x80] print(hex(len(data))) taba = [] tabb = [] for i in range(0x80): stab=[0]*0x80 ptr = 12 for j in range(0x80): stab[j] = u32(data[ptr: ptr+4]) ptr+=18 if j==0: ptr-=2 ptr -= 11 taba.append(stab) tabb.append(u32(data[ptr: ptr+4])) data = data[0x909:] print(taba, tabb)
import numpy as np an = np.array(taba) bn = np.array(tabb) x = np.linalg.solve(an,bn) print(x) print(bytes([round(i) for i in x]))
|
tiny
看了WP知道后,这个得需要用pwntools来反编译。
010打开,0x20后才是代码段:
1 2 3 4 5 6 7 8 9
|
a = open('tiny','rb').read()[0x20:] print(a) from pwn import * context.arch='i386' print(disasm(a))
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| 0: 5b pop ebx 1: 5b pop ebx 2: 5b pop ebx 3: 31 c9 xor ecx,ecx 5: 51 push ecx 6: 41 inc ecx 7: 41 inc ecx ;ecx == 2 8: eb 04 jmp 0xe ---------------------------------------------- a: 20 00 and BYTE PTR [eax],al c: 01 00 add DWORD PTR [eax],eax ----------------------------------------------;这2局没啥用 e: 58 pop eax ;eax == 0 f: 68 07 52 f4 8a push 0x8af45207 14: 68 63 9a 3f 09 push 0x93f9a63 ---- 19: 8b 7c 8b fc mov edi,DWORD PTR [ebx+ecx*4-0x4];感觉这里就是flag 1d: c1 cf 03 ror edi,0x3 ;ror是循环右移,3次【右边的到左边去】【edi】 20: 68 29 94 d9 05 push 0x5d99429 25: 5a pop edx ;edx == 0x5d99429【先进后出】 26: 5e pop esi ;esi == 0x93f9a63 27: 31 fe xor esi,edi; esi ^= edi, edi是flag 29: 31 f2 xor edx,esi; edx ^= esi 2b: 09 d0 or eax,edx; eax |= edx eax最开始是==0的,猜测最后也得是0 2d: e2 ea loop 0x19 ;这里是一个循环ecx = 2 ,所以循环2次 ;先push3个pop出2个,然后push1个,再pop2个。 ;0x8af45207 后 push 0x5d99429 最后 pop出来 --- 2f: 31 db xor ebx,ebx 31: 85 c0 test eax,eax ;eax进行按位于操作 33: 0f 95 c3 setne bl ; SETNE取得ZF值后, 取反, 再放到bl中. 36: 31 c0 xor eax,eax 38: 40 inc eax 39: cd 80 int 0x80
|
1 2 3 4 5 6 7 8 9
| a = 0x5d99429^0x93f9a63 flag = hex((a<<3) & 0xFFFFFFFF) print(bytes.fromhex(flag[2:])[::-1])
b = 0x8af45207^0x5d99429 flag2 = hex((b<<3)&0xFFFFFFFF) print(bytes.fromhex(flag2[2:])[::-1])
|
& 0xFFFFFFFF):
print(bytes.fromhex(flag[2:])[::-1])
这个类似一个公式吧
hex(a)
:这一部分将整数 a
转换为其十六进制表示形式,并返回一个字符串。例如,如果 a
是10,那么 hex(a)
返回的将是字符串 ‘0xa’。
hex(a)[2:]
:这一部分使用切片操作去掉字符串 ‘0x’,留下了整数的十六进制表示。在上面的例子中,它会返回 ‘a’。
bytes.fromhex(hex(a)[2:])
:这一部分将上一步得到的十六进制字符串转换为字节数组。例如,如果 a
是10,那么它会将 ‘a’ 转换为包含一个字节的字节数组,即 b’\x0a’。
[::-1]
:这是一个切片操作,用于反转字节数组的顺序。例如,如果字节数组是 b’\x0a’,那么它将返回 b’\x0a’ 的逆序,也就是 b’\x0a’。
这个地方可以不用pwntool 就能看到反编译内容
使用diw win64