一道VT题
题目给了一个exe程序和一个.sys文件
.sys文件可以在winxp系统下开启VT
出题人好像参考了周壑老师的代码,驱动程序相似度极高
这个exe程序很古怪,作者用vs2017开发包进行编译,最后没有进行静态打包,导致不能直接运行在winxp上,我们需要补齐很多的dll依赖才能正常运行,很麻烦,感情作者一开始就没打算让我们动调?
一、分析题目
之前接触过VT,借用周壑老师的代码,手动回复函数名
.sys文件的核心部分在这里:
我们参考代码回复这些宏的名字
比较三环代码和驱动代码
三环的vm指令和驱动的宏名称是一 一定义的,就像一个小型的vm混淆
二、分析算法
算法上只有rc4加密和魔改的tea加密
分别在sub_401250 和 sub_4019C0函数中
三、exp
魔改tea解密
// VT
#include <stdio.h>
#include <stdint.h>
void conver_to_hex(uint32_t* v){
uint32_t v0=v[0], v1=v[1];
printf("%02x",v[0] & 0x000000ff);
printf("%02x",(v[0] & 0x0000ff00) >> 8);
printf("%02x",(v[0] & 0x00ff0000) >> 16);
printf("%02x",(v[0] & 0xff000000) >> 24);
printf("%02x",v[1] & 0x000000ff);
printf("%02x",(v[1] & 0x0000ff00) >> 8);
printf("%02x",(v[1] & 0x00ff0000) >> 16);
printf("%02x",(v[1] & 0xff000000) >> 24);
puts("");
}
//解密函数
//void decrypt (uint32_t* v, uint32_t* k) {
// uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
// uint32_t delta=0x9e3779b9; /* a key schedule constant */
// uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
// for (i=0; i<32; i++) { /* basic cycle start */
// v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
// v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
// sum -= delta;
// } /* end cycle */
// v[0]=v0; v[1]=v1;
//}
// 魔改部分:
//1、 sum=0x20000000
//2、 delta=0xC95D6ABF
//3、 v0 += ... => v0 -= ... ; v1 -= ... => v1+= ...
//4、等号右边 => v0 => v1 ; v1 => v0
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0x20000000, i; /* set up */
uint32_t delta=0xC95D6ABF; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v0 -= ((v1<<4) + k2) ^ (v1 + sum) ^ ((v1>>5) + k3); // k2 => Get_key_3_2_1 // k3 => Get_key_2_1_3
v1 += ((v0<<4) + k0) ^ (v0 + sum) ^ ((v0>>5) + k1); // k1 => Get_key_1_0_0 // k0 => Get_key_0_3_2
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}
//
//void encrypt (uint32_t* v, uint32_t* k) {
// uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
// uint32_t delta=0x9e3779b9; /* a key schedule constant */
// uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
// for (i=0; i < 32; i++) { /* basic cycle start */
// sum += delta;
// v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
// v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
// } /* end cycle */
// v[0]=v0; v[1]=v1;
//}
// 写出解密脚本:
//加密函数
void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0x20000000, i; /* set up */
uint32_t delta=0xC95D6ABF; /* a key schedule constant */
for( i = 0;i<32;i++){
sum -= delta;
}
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i < 32; i++) { /* basic cycle start */
sum += delta;
v1 -= ((v0<<4) + k0) ^ (v0 + sum) ^ ((v0>>5) + k1);
v0 += ((v1<<4) + k2) ^ (v1 + sum) ^ ((v1>>5) + k3); //出错原因: 想当然的写成: v0 += ... // v1 -= ... // 而没有认真的考虑加密逻辑
} /* end cycle */
v[0]=v0; v[1]=v1;
}
void Tea()
{
unsigned int cip[8] = {
0x5C073994, 0x0D805CB3, 0x87DDA586, 0x0317FB8E, 0x6520EF29, 0x5A4987AF, 0xEB2DC2A4, 0x38CF470E
};
unsigned int key[4] = {
0x00102030, 0x40506070, 0x8090A0B0, 0xC0D0E0F0
};
for(int i = 0;i<4;i++){
uint32_t v[2]={1,2},k[4]={2,2,3,4};
v[0] = cip[i*2];
v[1] = cip[i*2+1];
k[0] = key[2];
k[1] = key[0];
k[2] = key[1];
k[3] = key[3];
encrypt(v, k);
// conver_to_hex(v);
printf("0x%x 0x%x\n",v[1],v[0]);
}
}
int main(){
Tea();
return 0;
}
rc4解密
flag即为:
81920c3758be43705ba154bb8f599846
ps
这道题基本不需要什么VT知识,只需要捋清逻辑,写出解密脚本即可
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现