Rev_Dizzy
xuenixiang.com上的一道题
F5 反编译失败提示
这里可以展开查看汇编代码
一种方法是直接手撸汇编代码,因为汇编代码中只有add,sub,xor三种操作,
可以尝试手撸汇编,或者交给Chat_GPT
搜索一番后学到还有一种解决方法
可以通过修改IDA配置文件\cfg\hexrays.cfg
将里面的MAX_FUNCSIZE改大一点例如1024
可以看到注释里面也说明了若函数大于64K的话会无法反汇编,所以我们将它改大
反汇编后逻辑很简单就是5000多行的加减异或操作后与密文比较
只需要将加替换成减,减替换成加然后倒着跑一遍密文就行
将加密的5000多行复制下来保存为data.txt
注意跑的时候要& 0xff防止溢出
用exec函数执行字符串代码
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| with open('data.txt', 'rb') as fp: data = fp.read() flag = [0x27,0x3C,0xE3,0xFC,0x2E,0x41,0x07,0x5E,0x62,0xCF, 0xE8,0xF2,0x92,0x80,0xE2,0x36,0xB4,0xB2,0x67,0x77, 0x0F,0xF6,0x0D,0xB6,0xED,0x1C,0x65,0x8A,0x07,0x53, 0xA6,0x66] fp1 = open("ans.txt", "w") data = data.split(b'\n') for i in data[::-1]: tmp = i[2:].decode() if '+' in tmp: tmp = tmp.replace('+', '-') code = tmp + '\n' + tmp[:tmp.find('-')] + "&= 0xff" elif '-' in tmp: tmp = tmp.replace('-', '+') code = tmp + '\n' + tmp[:tmp.find('+')] + "&= 0xff" else: code = tmp + '\n' + tmp[:tmp.find('^')] + "&= 0xff" fp1.write(tmp+'\n') exec(code) fp1.close() fp.close() for i in flag: print(chr(i),end='')
|
flag
flag{Try_R3vers1ng_W1th_ScR!pt!}
[CatCTF]The cat did it
点进来很复杂一个函数图像,猫猫可爱捏
flag是CatCTF{MD5(我离开猫猫的概率)}
我的定义域是[-200,200]拖动一下我
可以发现无论怎么拖都有一部分是在猫猫体内的
所以猜测概率为0%,算一下md5
flag
CatCTF{9f1ef07877f9d85a82bd500f408b4814}
[BUUCTF]rsa
RSA介绍
RSA 加密算法是一种非对称加密算法。在公开密钥加密和电子商业中 RSA 被广泛使用。RSA 是 1977 年由罗纳德 · 李维斯特(Ron Rivest)、阿迪 · 萨莫尔(Adi Shamir)和伦纳德 · 阿德曼(Leonard Adleman)一起提出的。RSA 就是他们三人姓氏开头字母拼在一起组成的。
RSA 算法的可靠性由极大整数因数分解的难度决定。换言之,对一极大整数做因数分解愈困难,RSA 算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用 RSA 加密的信息的可靠性就肯定会极度下降。但找到这样的算法的可能性是非常小的。如今,只有短的 RSA 密钥才可能被强力方式解破。到 2017 年为止,还没有任何可靠的攻击 RSA 算法的方式。
原理
公钥与私钥的生成
- 随机选择两个不同的大质数 $p$ 和 $q$ 计算$N = p \times q$
- 由欧拉函数$\varphi(N)= \varphi§ \cdot \varphi(q)=(p-1)(q-1)$
- 选择一个小于$\varphi(N)$的整数$e$,使得$e$和$\varphi(N)$互质
- 求$e$关于$\varphi(N)$的乘法逆元$d$,即求满足$ed=1(\text{mod}\enspace \varphi(N))$
- 将$p$和$q$的记录销毁
- $(N,e)$即为公钥,$(N,d)$即为私钥
加密
首先需要将消息 以一个双方约定好的格式转化为一个小于$N$,且与$N$互质的整数$m$。如果消息太长,可以将消息分为几段,这也就是我们所说的块加密,后对于每一部分利用如下公式加密:
$$m^{e}\equiv c(\text{mod}\enspace N)$$
解密
用d可以解密
$$c^{d}\equiv m(\text{mod}\enspace N)$$
解题过程
公钥解析
法一
在线公钥解析
在线分解质因数
法二
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| from Crypto.Util.number import * from Crypto.PublicKey import RSA import gmpy2 import rsa from factordb.factordb import FactorDB
with open('pub.key','r') as f: key = RSA.import_key(f.read()) e = key.e n = key.n print('e = %d\nn = %d'%(e,n)) a = FactorDB(n) a.connect() fac = a.get_factor_list()
p,q = fac[0],fac[1] print('p = %d\nn = %d'%(p,q))
|
解密
1 2 3 4 5 6 7 8 9 10 11 12
| phi_n = (p-1)*(q-1) d = gmpy2.invert(e, phi_n) key = rsa.PrivateKey(p*q, e, d, p, q)
with open("flag.enc", 'rb') as file: file = file.read() print(rsa.decrypt(file, key))
|
完整exp
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
| from Crypto.Util.number import * from Crypto.PublicKey import RSA import gmpy2 import rsa from factordb.factordb import FactorDB
with open('pub.key','r') as f: key = RSA.import_key(f.read()) e = key.e n = key.n print('e = %d\nn = %d'%(e,n)) a = FactorDB(n) a.connect() fac = a.get_factor_list() p,q = fac[0],fac[1] print('p = %d\nn = %d'%(p,q)) phi_n = (p-1)*(q-1) d = gmpy2.invert(e, phi_n) key = rsa.PrivateKey(p*q, e, d, p, q)
with open("flag.enc", 'rb') as file: file = file.read() print(rsa.decrypt(file, key))
|
flag
flag{decrypt_256}
[FlareOn4]login
给出一个网页,F12查看源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <!DOCTYPE Html /> <html> <head> <title>FLARE On 2017</title> </head> <body> <input type="text" name="flag" id="flag" value="Enter the flag" /> <input type="button" id="prompt" value="Click to check the flag" /> <script type="text/javascript"> document.getElementById("prompt").onclick = function () { var flag = document.getElementById("flag").value; var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);}); if ("PyvragFvqrYbtvafNerRnfl@syner-ba.pbz" == rotFlag) { alert("Correct flag!"); } else { alert("Incorrect flag, rot again"); } } </script> </body> </html>
|
ROT13加密,直接梭
flag
flag{ClientSideLoginsAreEasy@flare-on.com}
[SUCTF2019]SignIn
无壳直接查看主函数
gmpz函数不知道什么意思没关系,搜索学习一下
是GNU多精度算术库里的函数,GNU是一个提供了很多操作高精度的大整数,浮点数的运算的算术库,函数具体作用写在注释里了
这又是大整数又是取模,直接盲猜RSA
先用yafu先分解v4不要问我为什么不用factordb,就是叛逆喜欢瞎搞学各种方法
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import gmpy2 from Crypto.Util.number import * import rsa import binascii e = 65537 p = 282164587459512124844245113950593348271 q = 366669102002966856876605669837014229419 n = 103461035900816914121390101299049044413950405173712170434161686539878160984549 phi_n = (p-1)*(q-1) d = gmpy2.invert(e,phi_n) c = 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35 m = gmpy2.powmod(c, d, n) print(binascii.a2b_hex(hex(m)[2:].encode()))
|
flag
flag{Pwn_@_hundred_years}
[HDCTF2019]maze
查壳有UPX壳,先脱壳
尝试F5反汇编失败,阅读一下汇编代码
发现有一个jnz跳转到了未知地址
应该是个花指令,nop一下
nop完apply一下,重新打开就可以F5了
或者nop完全选红色地址,按一下P键快速patch
看到是一个简单的走迷宫函数,终点(5,-4)
在data段看到起点在(7,0),并且有迷宫地图,共70个字符,应该是7*10的迷宫
1 2 3 4 5 6 7 8
| *******+** ******* ** **** ** ** ***** ** **F**** ** **** **********
|
手动走一下得到flag
flag
flag{ssaaasaassdddw}
#[津门杯2021]GoodRe
把tea的运算操作都以函数形式呈现,耐心分析每个函数作用
然后重命名简化反汇编结果,以便分析
这是sub_1B30函数内部,通过分析各个函数可推断出是tea
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| def tea_decrypt(data,key): i = 0 delta = 0x830A5376 ^ 0x1D3D2ACF sum = delta * 32 & 0xffffffff while i < 32: i += 1 data[1] -= ((data[0]<<4) + key[2]) ^ (data[0] + sum) ^ ((data[0]>>5) + key[3]) data[1] = data[1] & 0xffffffff data[0] -= ((data[1]<<4) + key[0]) ^ (data[1] + sum) ^ ((data[1]>>5) + key[1]) data[0] = data[0] & 0xffffffff sum -= delta return data code =[0x79AE1A3B, 0x596080D3, 0x80E03E80, 0x846C8D73, 0x21A01CF7,0xC7CACA32, 0x45F9AC14, 0xC5F5F22F] key = [17,17,17,17] flag = '' for j in range(0,8,2): endata = code[j:j+2] dedata = tea_decrypt(endata,key) flag += hex(dedata[0])[2:] flag += hex(dedata[1])[2:] print(flag.upper())
|
flag
flag{7DEA3F6D3B3D6C0C620864ADD2FA2AE1A61F2736F0060DA0B97E8356D017CE59}
[ISCC]answer_to_everything
题目描述:
sha1 得到了一个神秘的二进制文件。寻找文件中的flag,解锁宇宙的秘密。注意:将得到的flag变为flag{XXX}形式提交。
直接定位到关键函数
flag应该就是kdudpeh,怎么提交都不对
回头看了一下题目描述,试一下sha1
对了,提醒我自己注意看题目描述
flag
flag{80ee2a3fe31da904c596d993f7f1de4827c1450a}
[RCTF2019]babyre1
提示:MD5(rctf{your answer}) == 5f8243a662cf71bf31d2b2602638dc1d
先看主函数,不是很复杂
输入正确flag会得到Bingo!
,flag长度为16位
接下来重点就是sub_C00和sub_1180以及sub_13D0
首先sub_C00,理解一下就是把输入转换成16进制,理解不了可以动调验证
在sub_1180函数中调用了sub_CE0,可以根据特征判断是xxtea,
findcrypt插件也识别出了特征值,unk_202010是key
在xxtea加密后读取了结果最后一位,判断是否小于等于4,并根据数值进行操作
例如最后一位为3,则加密后的第6个字节为0,
最后一位为2,则加密后的第7个字节为0.
最后是sub_13D0函数,看不懂,根据特征^0x1021搜索了一下是CRC16校验
检验的是之前被赋值为0的数据之前的数据,则之前赋值为0相当于对数据进行了截断。
CRC16检验后再根据截断位置循环异或0x17
因为最后的输出是bingo!
,长度为6,所以截断的位置是7,所以最后一位应该是02
将bingo!
与0x17异或得到55 7e 79 70 78 36
,所以xxtea加密结果应该是
55 7e 79 70 78 36 xx 02
第七位未知,但是可以通过爆破来得到
根据题目提示提示:MD5(rctf{your answer}) == 5f8243a662cf71bf31d2b2602638dc1d
来检验
或者使用patch文件将加密改成解密后用pwntool的dump功能将255个结果写入文件
详细看这篇博客
exp
1 2 3 4 5 6 7 8 9 10 11 12
| import xxtea import hashlib key = [0xc7,0xe0,0xc7,0xe0,0xd7,0xd3,0xf1,0xc6,0xd3,0xc6,0xd3,0xc6,0xce,0xd2,0xd0,0xc4] text = [0x55,0x7e,0x79,0x70,0x78,0x36,0x0,0x02] for i in range(0xff): text[6] = i encrypt_data = xxtea.encrypt(bytes(text),bytes(key),padding=False) encrypt_data = encrypt_data.hex() flag = "rctf{"+ encrypt_data +"}" if hashlib.md5(flag.encode()).digest().hex() == '5f8243a662cf71bf31d2b2602638dc1d': print(flag)
|
flag
flag{05e8a376e4e0446e}
[HITCON]handcrafted-pyc
这篇博客超详细
首先打开文件是一个python源码
1 2 3 4
|
import marshal, zlib, base64 exec(marshal.loads(zlib.decompress(base64.b64decode('eJyNVktv00AQXm/eL0igiaFA01IO4cIVCUGFBBJwqRAckLhEIQmtRfPwI0QIeio/hRO/hJ/CiStH2M/prj07diGRP43Hs9+MZ2fWMxbnP6mux+oK9xVMHPFViLdCTB0xkeKDFEFfTIU4E8KZq8dCvB4UlN3hGEsdddXU9QTLv1eFiGKGM4cKUgsFCNLFH7dFrS9poayFYmIZm1b0gyqxMOwJaU3r6xs9sW1ooakXuRv+un7Q0sIlLVzOCZq/XtsK2oTSYaZlStogXi1HV0iazoN2CV2HZeXqRQ54TlJRb7FUlKyUatISsdzo+P7UU1Gb1POdMruckepGwk9tIXQTftz2yBaT5JQovWvpSa6poJPuqgao+b9l5Aj/R+mLQIP4f6Q8Vb3g/5TB/TJxWGdZr9EQrmn99fwKtTvAZGU7wzS7GNpZpDm2JgCrr8wrmPoo54UqGampFIeS9ojXjc4E2yI06bq/4DRoUAc0nVnng4k6p7Ks0+j/S8z9V+NZ5dhmrJUM/y7JTJeRtnJ2TSYJvsFq3CQt/vnfqmQXt5KlpuRcIvDAmhnn2E0t9BJ3SvB/SfLWhuOWNiNVZ+h28g4wlwUp00w95si43rZ3r6+fUIEdgOZbQAsyFRRvBR6dla8KCzRdslar7WS+a5HFb39peIAmG7uZTHVm17Czxju4m6bayz8e7J40DzqM0jr0bmv9PmPvk6y5z57HU8wdTDHeiUJvBMAM4+0CpoAZ4BPgJeAYEAHmgAUgAHiAj4AVAGORtwd4AVgC3gEmgBBwCPgMWANOAQ8AbwBHgHuAp4D3gLuARwoGmNUizF/j4yDC5BWM1kNvvlxFA8xikRrBxHIUhutFMBlgQoshhPphGAXe/OggKqqb2cibxwuEXjUcQjccxi5eFRL1fDSbKrUhy2CMb2aLyepkegDWsBwPlrVC0/kLHmeCBQ=='))))
|
先将数据base64解密然后用zlib.decompress将解密后的字符串解压
接着用marshal.load将二进制数据反序列化为Python对象,最后exec执行代码
第一步先获取要执行的python代码
1 2 3 4 5
| import zlib,base64 pyc=zlib.decompress(base64.b64decode('eJyNVktv00AQXm/eL0igiaFA01IO4cIVCUGFBBJwqRAckLhEIQmtRfPwI0QIeio/hRO/hJ/CiStH2M/prj07diGRP43Hs9+MZ2fWMxbnP6mux+oK9xVMHPFViLdCTB0xkeKDFEFfTIU4E8KZq8dCvB4UlN3hGEsdddXU9QTLv1eFiGKGM4cKUgsFCNLFH7dFrS9poayFYmIZm1b0gyqxMOwJaU3r6xs9sW1ooakXuRv+un7Q0sIlLVzOCZq/XtsK2oTSYaZlStogXi1HV0iazoN2CV2HZeXqRQ54TlJRb7FUlKyUatISsdzo+P7UU1Gb1POdMruckepGwk9tIXQTftz2yBaT5JQovWvpSa6poJPuqgao+b9l5Aj/R+mLQIP4f6Q8Vb3g/5TB/TJxWGdZr9EQrmn99fwKtTvAZGU7wzS7GNpZpDm2JgCrr8wrmPoo54UqGampFIeS9ojXjc4E2yI06bq/4DRoUAc0nVnng4k6p7Ks0+j/S8z9V+NZ5dhmrJUM/y7JTJeRtnJ2TSYJvsFq3CQt/vnfqmQXt5KlpuRcIvDAmhnn2E0t9BJ3SvB/SfLWhuOWNiNVZ+h28g4wlwUp00w95si43rZ3r6+fUIEdgOZbQAsyFRRvBR6dla8KCzRdslar7WS+a5HFb39peIAmG7uZTHVm17Czxju4m6bayz8e7J40DzqM0jr0bmv9PmPvk6y5z57HU8wdTDHeiUJvBMAM4+0CpoAZ4BPgJeAYEAHmgAUgAHiAj4AVAGORtwd4AVgC3gEmgBBwCPgMWANOAQ8AbwBHgHuAp4D3gLuARwoGmNUizF/j4yDC5BWM1kNvvlxFA8xikRrBxHIUhutFMBlgQoshhPphGAXe/OggKqqb2cibxwuEXjUcQjccxi5eFRL1fDSbKrUhy2CMb2aLyepkegDWsBwPlrVC0/kLHmeCBQ==')) f=open('handcrafted-pyc.pyc','wb') f.write(pyc) f.close()
|
尝试运行pyc文件,提示bad magic number
用010editor 补齐magic number
用uncompyle6反编译提示失败,文件中有pyc字节码
首先了解一下字节码结构
更多可以查看这篇博客死磕python字节码
源码行号 | 跳转注释符 | 指令在函数中的偏移 | 指令符号(助记符) | 指令参数 | 实际参数值
starts_line(源码行号):以此操作码开头的行(如果有),否则 None
is_jump_target(跳转注释符):True 如果其他代码跳转到这里,否则 False
Offset(指令在函数中的偏移):字节码序列中操作的起始索引
opcode:操作的数字代码,对应于下面列出的操作码值和操作码集合中的字节码值。
opname(指令符号(助记符)):人类可读的操作名称
arg(指令参数):操作的数字参数(如果有),否则 None
argval:解析的 arg 值(如果已知),否则与 arg 相同
Argrepr(实际参数值):操作参数的人类可读描述
例如第一行的1 0 LOAD_GLOBAL 0 ‘chr’表示
该字节码在源码中对应一行,没有其他代码跳转到这里,偏移为0,助记符为LOAD_GLOBAL,指令参数为0,操作参数对应的实际值为’chr’
列举几个常见助记符
- LOAD_CONST加载const变量,比如数值、字符串等等,一般用于传给函数的参数
- LOAD_FAST一般加载局部变量的值,也就是读取值,用于计算或者函数调用传参等。
- STORE_FAST一般用于保存值到局部变量。
- LOAD_GLOBAL用来加载全局变量,包括指定函数名,类名,模块名等全局符号。
- STORE_GLOBAL用来给全局变量赋值。
- POP_JUMP_IF_FALSE表示条件结果为FALSE就跳转到目标偏移指令。
- JUMP_FORWARD直接跳转到目标偏移指令。
差不多了解完字节码,我们直接开始分析,先看第一段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| L. 1 0 LOAD_GLOBAL 0 'chr' 3 LOAD_CONST 108 6 CALL_FUNCTION_1 1 None 9 LOAD_GLOBAL 0 'chr' 12 LOAD_CONST 108 15 CALL_FUNCTION_1 1 None 18 LOAD_GLOBAL 0 'chr' 21 LOAD_CONST 97 24 CALL_FUNCTION_1 1 None 27 LOAD_GLOBAL 0 'chr' 30 LOAD_CONST 67 33 CALL_FUNCTION_1 1 None 36 ROT_TWO 37 BINARY_ADD 38 ROT_TWO 39 BINARY_ADD 40 ROT_TWO 41 BINARY_ADD
|
第一段字节码操作完栈顶为’call’
可以看到接下来的每一段字节码都差不多类似操作
最后字节码再用
PRINT_ITEM
PRINT_NEWLINE_CONT
输出栈顶内容,那我们只要模拟该过程就行
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
| def binary_add(stack): tos = stack.pop() tos1 = stack.pop() stack.append(tos1+tos) return stack
def rot_two(stack): tos = stack.pop() tos1 = stack.pop() stack.append(tos) stack.append(tos1) return stack
with open("out.py", "r") as fp: lines = fp.readlines() flag = '' stack = []
for line in lines: if "LOAD_CONST" in line: line = line.split()[-1] if line.isdigit(): stack.append(chr(int(line))) else: stack.append(0) else: if "BINARY_ADD" in line: stack = binary_add(stack) elif "ROT_TWO" in line: stack = rot_two(stack) print(stack)
|
exp
完整exp
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 35 36
| import zlib,base64 pyc=zlib.decompress(base64.b64decode('eJyNVktv00AQXm/eL0igiaFA01IO4cIVCUGFBBJwqRAckLhEIQmtRfPwI0QIeio/hRO/hJ/CiStH2M/prj07diGRP43Hs9+MZ2fWMxbnP6mux+oK9xVMHPFViLdCTB0xkeKDFEFfTIU4E8KZq8dCvB4UlN3hGEsdddXU9QTLv1eFiGKGM4cKUgsFCNLFH7dFrS9poayFYmIZm1b0gyqxMOwJaU3r6xs9sW1ooakXuRv+un7Q0sIlLVzOCZq/XtsK2oTSYaZlStogXi1HV0iazoN2CV2HZeXqRQ54TlJRb7FUlKyUatISsdzo+P7UU1Gb1POdMruckepGwk9tIXQTftz2yBaT5JQovWvpSa6poJPuqgao+b9l5Aj/R+mLQIP4f6Q8Vb3g/5TB/TJxWGdZr9EQrmn99fwKtTvAZGU7wzS7GNpZpDm2JgCrr8wrmPoo54UqGampFIeS9ojXjc4E2yI06bq/4DRoUAc0nVnng4k6p7Ks0+j/S8z9V+NZ5dhmrJUM/y7JTJeRtnJ2TSYJvsFq3CQt/vnfqmQXt5KlpuRcIvDAmhnn2E0t9BJ3SvB/SfLWhuOWNiNVZ+h28g4wlwUp00w95si43rZ3r6+fUIEdgOZbQAsyFRRvBR6dla8KCzRdslar7WS+a5HFb39peIAmG7uZTHVm17Czxju4m6bayz8e7J40DzqM0jr0bmv9PmPvk6y5z57HU8wdTDHeiUJvBMAM4+0CpoAZ4BPgJeAYEAHmgAUgAHiAj4AVAGORtwd4AVgC3gEmgBBwCPgMWANOAQ8AbwBHgHuAp4D3gLuARwoGmNUizF/j4yDC5BWM1kNvvlxFA8xikRrBxHIUhutFMBlgQoshhPphGAXe/OggKqqb2cibxwuEXjUcQjccxi5eFRL1fDSbKrUhy2CMb2aLyepkegDWsBwPlrVC0/kLHmeCBQ==')) f=open('handcrafted-pyc.pyc','wb') f.write(pyc) f.close() def binary_add(stack): tos = stack.pop() tos1 = stack.pop() stack.append(tos1+tos) return stack
def rot_two(stack): tos = stack.pop() tos1 = stack.pop() stack.append(tos) stack.append(tos1) return stack
with open("out.py", "r") as fp: lines = fp.readlines() flag = '' stack = []
for line in lines: if "LOAD_CONST" in line: line = line.split()[-1] if line.isdigit(): stack.append(chr(int(line))) else: stack.append(0) else: if "BINARY_ADD" in line: stack = binary_add(stack) elif "ROT_TWO" in line: stack = rot_two(stack) print(stack)
|
flag
hitcon{Now you can compile and run Python bytecode in your brain!}
[XSCTF联合招新赛2022]toddler_regs
shift+F12定位到flag
flag形式就是flag{aXp0int[7 * dword_14001FB90]_1s_n1c3_but_aXp0intjnu[10 * dword_14001FB94]_is_we1rd}
关键就是找到aXp0int[7 * dword_14001FB90]和aXp0intjnu[10 * dword_14001FB94]
这个函数里可以看到dword_14001FB94赋值为184
那么只要用aXp0intjnu的首地址加上10*184即加上0x730就可以找到aXp0intjnu[10 * dword_14001FB94]的值
可以看到首地址为14001E1C0
用G键快捷跳转至14001E8F0
获得aXp0intjnu[10 * dword_14001FB94]的值为Xp0intJNU
接下来我们寻找aXp0int[7 * dword_14001FB90]
用X键交叉引用dword_14001FB90
可以看到只有一个W类型(write)的引用,这肯定是对其的赋值,直接跳转
dword_14001FB90被赋值为23
同样的方法aXp0int首地址为14001E000
加上7 * 23即加上0xA1
跳转到14001E0A1,aXp0int[7 * dword_14001FB90]的值即为Xp0int
组合一下得到flag
flag
flag{Xp0int_1s_n1c3_but_Xp0intJNU_is_we1rd}