文件无壳 拖入ida
查看主函数 F5查看伪c代码
mprotect
是一个系统调用,用于改变一个内存区域的保护属性。这些保护属性决定了进程是否可以读取、写入或执行该内存区域的内容。
这段代码通过一个循环,对某个函数(sub_402219
)的前224字节(每个字节异或0x99)进行修改。
mprotect将400000位置的代码修改为可读可改可执行代码,sub_402219的代码异或0x99自修改(SMC自修改)。修改后的代码形成函数sub_402219。
什么是SMC自修改
所谓SMC(Self Modifying Code)技术,就是一种将可执行文件中的代码或数据进行加密,防止别人使用逆向工程工具对程序进行静态分析的方法,只有程序运行时才对代码和数据进行解 密,从而正常运行程序和访问数据。
继续跟进sub_402219函数 看到有很多数据
将sub_402219按D转换为数据
用idc脚本还原数据,用shif+f2调出脚本编辑器,编辑idc脚本
run执行完成后,右键要修改的所有数据->Analyze selected area->force
再在函数开头按P,变为函数。
回到main函数 发现这些函数已经可以进去了
sub_402219()该函数能打开了 ,可以发现这是md5加密
char v2[16];
:声明了一个16字节的字符数组,用作临时缓冲区或存储中间结果。__int64 v3, v4, v5;
:声明了三个64位整数变量,可能用于存储某些函数调用的结果或作为临时变量。unsigned __int64 v6;
:声明了一个64位无符号整数变量,用于存储和比较调用栈保护状态(可能是FS寄存器中的值,用于检测栈溢出)。
之后是sub_402219()
跟进sub_4007C6
可以发现这个是AES加密的s盒,所以这个函数的作用就是将unk_603170(base64表进行了两次md5加密后的结果)
传入作为了密钥
byte_6030a0=BC0AADC0147C5ECCE0B140BC9C51D52B46B2B9434DE5324BAD7FB4B39CDB4B5B
现在我们需要来求密钥unk_603170.linux远程动态调试(输入一个长为32位的字符串)
借鉴这位师傅的代码
from Crypto.Cipher import AES
from Crypto.Util.number import *
key = long_to_bytes(0xcb8d493521b47a4cc1ae7e62229266ce) #密钥
mi = long_to_bytes(0xbc0aadc0147c5ecce0b140bc9c51d52b46b2b9434de5324bad7fb4b39cdb4b5b) #密文
lun = AES.new(key, mode=AES.MODE_ECB)
flag = lun.decrypt(mi)
print(flag)
得到flag
flag{924a9ab2163d390410d0a1f670}