当时做这题一步步动态调,花了7 8个小时做出来了...

用的是x32dbg调试,为了跟动态调试的时候一致,把基址改为了0xA90000。

如何找按钮对应的函数

如何找到这些按钮按下时对应的消息处理函数呢?

3EBC093E-E081-4A08-B991-C5E87493DF42.png (23.28 KB, 下载次数: 0)

2020-11-5 14:50 上传

在MFC中,程序是使用消息机制来实现操作响应的,下面是消息映射表的结构。其中我们想要的某个控件的消息处理函数,就存放在该结构体的pfn中。nID与控件的ID相同。

struct AFX_MSGMAP{

AFX_MSGMAP * pBaseMessageMap;

AFX_MSGMAP_ENTRY * lpEntries;

}

struct AFX_MSGMAP_ENTRY{

UINT nMessage;    //Windows Message

UINT nCode        //Control code or WM_NOTIFY code

UINT nID;         //control ID (or 0 for windows messages)

UINT nLastID;     //used for entries specifying a range of control id's

UINT nSig;        //signature type(action) or pointer to message

AFX_PMSG pfn;     //routine to call (or specical value)

}

502E6304-2DE9-49EE-AD5C-04560BB28F0A.png (142.36 KB, 下载次数: 1)

2020-11-5 14:50 上传

用resource hacker查找资源。得到资源对应的编号。

例如:确定对应1,取消对应2,输入框对应1000。

于是我们在IDA中搜索立即数1000。

8BD93F26-5C1D-4E04-9DC2-5D04E5C9BA72.png (70.66 KB, 下载次数: 1)

2020-11-5 14:50 上传

在.rdata段里找一找。符合上述结构体的数据

99A341C7-EF2B-415F-88E7-7501A6F6EDB0.png (166.22 KB, 下载次数: 0)

2020-11-5 14:50 上传

struct AFX_MSGMAP_ENTRY

{

UINT nMessage;

UINT nCode;

UINT nID;

UINT nLastID;

UINT_PTR nSig;

void (*pfn)(void);

};

struct AFX_MSGMAP

{

const AFX_MSGMAP *(__stdcall *pfnGetBaseMap)();

const AFX_MSGMAP_ENTRY *lpEntries;

};

将上面两个结构体插入到Local Types。再同步到idb。

91964DAB-87FF-4A57-8D97-28A8F4B7920F.png (200.02 KB, 下载次数: 0)

2020-11-5 14:50 上传

在edit-struct var中,将上述数据组织成结构体。

于是,我们找到了按钮对应的函数。

6200297C-37B4-48D3-9384-51AA470D06A5.png (88.69 KB, 下载次数: 1)

2020-11-5 14:50 上传

确认键按不了?

F713DE1F-E3BF-4F99-9063-DBFE31E59260.png (166.65 KB, 下载次数: 0)

2020-11-5 14:50 上传

在消息框对应的函数中,有一个与66的比较。可以猜测,我们需要让输入长度为66。果然可以按下确定了。

两个藏得很深的函数

sub_C29C80 SMC函数

在生成消息框之前会运行

sub_C29E40 改变check1里面的cmp_str

#include

#include

int main(int argc, char const *argv[])

{

char key[] = "fuck";

char plain[45] = "B=.NI;&3JBZ;$;?(I72x0&4GLZDS2V6&%AF.!5#+J[F^";

plain[19] = 0x27;

for(int i =0;i<0x2c;i++)

{

plain[i] ^= key[i%4];

printf("%c",plain[i] );

}

printf("\n");

return 0;

}

所以check1里面的cmp_str = $HM%/NEX,79PBN\C/BQLVSW,*/'8T#UMC4%EG@@@,.%5

按下确认键会发生的事情

0D2E24F0-4254-4C9E-963D-829224E4ED41.png (303.78 KB, 下载次数: 1)

2020-11-5 14:50 上传

之前一大堆函数大概就是在获取消息框的内容、检查有没有是否有输入之类的。值得注意的一个函数是sub_C017A9,拿ida自己命名的参数(lpMultiByteStr, lpWideCharStr, 2 * v17, CodePage)去搜了下,发现神似WideCharToMultiByte这个函数。作用:因为我们的输入存到内存中都是一个字符两字节,会把两字节的字符转换为一字节。经过动态调试,确实是这个函数。

sub_BFDD48这个是个strlen,emmmmm如果不动调的话,真的看不出来。

9577AE81-FB3A-488E-B3D5-056CC7FBFF72.png (110.79 KB, 下载次数: 1)

2020-11-5 14:50 上传

然后分别check输入的前33个和后33个字符。

一个魔改了的RC4

sub_C0971F对输入的前33位做了一个魔改的rc4加密

int main()

{

char key[] = "sorry_you_are_wrong";

unsigned char T[256]={0};

unsigned char S[] = {196, 120, 53, 239, 86, 152, 45, 254, 98, 81, 138, 177, 186, 121, 127, 37, 169, 181, 73, 189, 137, 159, 19, 228, 60, 235, 26, 90, 204, 174, 191, 212, 243, 106, 203, 83, 35, 117, 236, 149, 247, 221, 88, 51, 31, 193, 151, 249, 94, 58, 77, 207, 146, 142, 14, 126, 54, 136, 76, 165, 24, 158, 5, 124, 1, 44, 49, 194, 209, 199, 55, 104, 132, 229, 180, 178, 216, 72, 8, 41, 198, 114, 108, 128, 139, 46, 231, 79, 52, 99, 131, 100, 224, 154, 57, 34, 237, 129, 80, 43, 17, 222, 233, 238, 48, 11, 170, 230, 59, 96, 242, 150, 195, 42, 119, 12, 173, 0, 18, 68, 97, 252, 167, 140, 118, 47, 182, 160, 219, 6, 25, 208, 107, 226, 187, 102, 2, 15, 232, 153, 40, 29, 10, 190, 141, 255, 69, 103, 143, 71, 27, 163, 50, 33, 234, 161, 157, 225, 112, 245, 211, 125, 188, 122, 3, 135, 145, 240, 38, 65, 113, 7, 93, 168, 22, 16, 179, 36, 223, 87, 95, 162, 23, 200, 192, 171, 213, 148, 116, 185, 214, 70, 155, 220, 244, 101, 202, 156, 201, 32, 197, 85, 215, 175, 30, 246, 206, 130, 218, 164, 205, 62, 9, 241, 133, 183, 91, 67, 134, 75, 210, 105, 82, 250, 217, 20, 63, 61, 64, 115, 84, 166, 28, 39, 227, 110, 147, 66, 74, 123, 13, 78, 184, 111, 4, 172, 92, 89, 144, 109, 251, 176, 21, 248, 56, 253};

int j=0;

int i=0;

int temp;

for(i=0; i< 256; i++)

{

T[i] = key[i % 19];

}

for(i=0; i<256;i++)

{

j = (T[i] + j +S[i])%256;

temp = S[i];

S[i] = S[j];

S[j] = temp;

}

i = j = 0;

int t;

for(int r=0; r<0x21;r++)

{

i = (i+1) % 256;

j = (j+S[i]) % 256;

temp = S[i];

S[i] = S[j];

S[j] = temp;

t = (S[j]+S[i]) % 256;

printf("key = %x %d\n",S[t],S[t]);

}

return 0;

}

所以输入会与0x40,0x28,0xb6,0x5c,0xd3,0x84,0x5c,0x1a,0xe0,0x18,0xfd,0x3f,0x5d,0xce,0xf6,0xbb,0x3d,0x46,0x43,0x82,0x7a,0xa9,0x5c,0xe3,0xe4,0x48,0xfd,0xa5,0xb9,0x39,0x7b,0xd4,0xfe进行异或。

类BASE32

经过rc4加密后,来到0xF05188。在内存中dump出真正的代码,再写脚本patch。虽然这个函数经过了混淆(各种jmp)但是ida还是能F5出结果。

0D758B86-AF8B-428B-B765-F725E34A7049.png (69.08 KB, 下载次数: 0)

2020-11-5 14:50 上传

(其中参数a1为dest,a2为src,a3为src的length)

这左移右移的,加3加4的,再联系到输入长度33,cmp_str的长度44,这不就是base系列吗。

#include

int main(int argc, char const *argv[])

{

unsigned char encoded[] ="$HM%/NEX,79PBN\\C/BQLVSW,*/'8T#UMC4%EG@@@,.%5";

unsigned char result[44];

int xor_arr[] = {0x40,0x28,0xb6,0x5c,0xd3,0x84,0x5c,0x1a,0xe0,0x18,0xfd,0x3f,0x5d,0xce,0xf6,0xbb,0x3d,0x46,0x43,0x82,0x7a,0xa9,0x5c,0xe3,0xe4,0x48,0xfd,0xa5,0xb9,0x39,0x7b,0xd4,0xfe};

int result_ptr = 0;

int encoded_ptr = 0;

for(int i = 0; i <44;i++)

{

encoded[i] -= 0x23;

}

for(int i=0;i<11;i++)

{

result[result_ptr] = ((unsigned char)encoded[encoded_ptr] <<2) | ((unsigned char)encoded[encoded_ptr+1] >>4);

result[result_ptr+1] = ((unsigned char)encoded[encoded_ptr+1] <<4) | ((unsigned char)encoded[encoded_ptr+2] >>2);

result[result_ptr+2] = ((unsigned char)encoded[encoded_ptr+2] <<6) | ((unsigned char)encoded[encoded_ptr+3]);

encoded_ptr += 4;

result_ptr += 3;

}

for(int i = 0; i <33;i++)

{

printf("%c",(result[i]^xor_arr[i]));

}

printf("\n");

return 0;

}

//Fr4nk1y_MfC_l5_t0O_ComPIeX_4nd_dl

魔改的TEA

check2里面有一个改了delta的TEA加密算法。

首先会验证flag[33]=='f'

sub_C051B5的作用是将8个字符组成2个32位的int。

sub_F05420便是TEA加密了。密钥存在dword_F05048中。

F1ED74B5-9260-46BC-91AA-CB51E5923C50.png (52.57 KB, 下载次数: 1)

2020-11-5 14:50 上传

for循环剩下的内容没看太懂,经过动态调试得知是交换密文c0,c1的位置。

#include

#include

//解密函数

void decrypt (uint32_t* v, uint32_t* k) {

uint32_t x0=v[0], x1=v[1], sum=0x86772b40, i;  /* set up */

uint32_t delta=0x2433B95A;                     /* 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 */

x1 -= ((x0<<4) + k2) ^ (x0 + sum) ^ ((x0>>5) + k3);

x0 -= ((x1<<4) + k0) ^ (x1 + sum) ^ ((x1>>5) + k1);

sum -= delta;

}                                              /* end cycle */

v[0]=x0; v[1]=x1;

}

int main()

{

uint32_t v[2]={0x2d46347f,0x5e79f6f4},k[4]={0x0D9610D02,0x2AADA57D,0x0A37537F1,0x0C29E3913};

// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位

printf("原始数据:%x %x\n",v[0],v[1]);

decrypt(v, k);

printf("解密后的数据:%x %x\n",v[0],v[1]);

return 0;

}

妙用Z3

这个方程涉及到了进位和借位的操作?手算算不出来,经过了2个小时,想到了z3,直接秒出...

57B81FFD-8B15-4097-88DE-8573C001F256.png (20.81 KB, 下载次数: 1)

2020-11-5 14:50 上传

from z3 import *

c54 = BitVec('c54',64)

c10 = BitVec('c10',64)

c76 = BitVec('c76',64)

s = Solver()

s.add(c54 - c10 == 0x3F66B755B4490579)

s.add(c10 + c76 == 0x162F924623D2CAE0)

s.add(c76 - c54 == 0x7C3C71F1B295D77F)

s.check()

print(s.model())

[c54 = 7830893152465779821,

c10 = 3262352701727045364,

c76 = 16783048594668704748]

再加上c3 = 0x2F9970FF

c2 = 0xDF3634AE

用TEA解密就得到flag。注意字节序。

flag

Fr4nk1y_MfC_l5_t0O_ComPIeX_4nd_dlff1cUlt_foR_THe_r0Ok1E_t0_REver5e

Matlab unravel函数,XNUCA2020-RE-UnravelMFC复现相关推荐

  1. Matlab unravel函数,求助!如何将C语言的unravel函数转换为matlab版本?十分紧急!...

    这是在网上找的程序 #include "mex.h" void unravel(unsigned short *hx, double *link, double *x, doubl ...

  2. Matlab unravel函数,有没有更好的方法在python中执行“unravel”函数?

    我面临的问题是执行n个并发事件,这些事件都将迭代器返回到它们获得的结果.但是,有一个可选的limit参数,基本上是合并所有迭代器并返回limit结果.在 因此,例如:我在8个线程上执行2000个url ...

  3. matlab rng函数使用说明

    matlab rng函数使用说明 作用 控制随机数的产生.也就是对于参入了随机变量的一个实验结果,通过rng函数可以将其复现 随机数的产生是Monte Carlo 方法的基础. rand('seed' ...

  4. matlab matlabpool,Matlab matlabpool函数undefined

    我尝试使用matlab并行计算功能. 我先输入"版本"来检查,如果我已经安装了并行计算工具箱,它确实Matlab matlabpool函数undefined >> ve ...

  5. MATLAB常用函数, 常见问题

    MATLAB常用函数 1.常用取整函数 round(x):四舍五入函数 floor(x) : 向下取整, 即 floor(1.2)=1,  floor(1.8) = 1 ceil(x) : 向上取整, ...

  6. matlab doc函数,matlab常用函数.doc

    matlab常用函数.doc MatLab 常用函数 1. 特殊变量与常数 ans 计算结果的变量名 computer 确定运行的计算机 eps 浮点相对精度 Inf 无穷大 I 虚数单位 name ...

  7. matlab中imresize函数的用法,为何 MATLAB imresize 函数和 OpenCV resize 函数结果不同

    为何 MATLAB imresize 函数和 OpenCV resize 函数结果不同?今年 4 月,我在依照 MATLAB 代码自己写一个卷积神经网络 C++ 实现的过程中,就发现了这个问题,不过那 ...

  8. matlab 数学库,matlab数学函数库

    (n) 求 n 的阶乘 如何用 matlab 配方 没有发现 matlab 有这一命令,不过我们可以调用 maple 的命令,调用方法如下: 首先加载 maple 中的 student 函数库,加载. ...

  9. matlab freqz函数使用

    Matlab freqz函数使用 (2012-10-22 13:42:03) 转载▼ 标签: 杂谈 freqz函数计算线性系统的频率响应,包括幅频响应和相频响应,基本输入为线性系统的AMMA模型系数向 ...

最新文章

  1. java使用ssh连接Linux并执行命令
  2. Linux系统下配置Java环境
  3. OAuth 2.0中的scope和RBAC中的role有什么关系
  4. [云炬商业计划书阅读分享]无水洗车市场推广策划书
  5. IOS-awakeFromNib和viewDidLoad
  6. es6 --- 解构赋值的简洁性
  7. Android 第二十课 广播机制(大喇叭)----发送自定义广播(包括发送标准广播和发送有序广播)
  8. 漫步微积分十八——变化率问题
  9. MySQL Workbench Failed to Connect to MySQL at 127.0.0.1:3306 with user root Bad handshake
  10. html在线时间24小时代码,每24小时弹一次的HTML代码
  11. 草根站长的创业之路(真实纪实)
  12. 安装Sarge(六) 安装开发环境
  13. php $path_info,PHP $_SERVER['PATH_INFO'] 无法获取到内容怎么办?
  14. 阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第1节 常用函数接口_4_使用Lambda优化日志案例...
  15. Android11_图片处理
  16. iphone双重认证关闭不了怎么办_怎么关闭iPhone双重认证?苹果手机关闭双重认证的两种操作方法 ... ......
  17. 服务器阵列卡缓存显示错误,服务器阵列卡(缓存)
  18. 河北安新复合型水稻 国稻种芯·中国水稻节:雄安生态示范区
  19. linux ps1 配色,bashrc - PS1(提示符配色)
  20. android textview 淡入淡出,TextView淡入淡出效果

热门文章

  1. php 制图教程下载,autocad制图教学视频全集免费百度云下载(初学入门到精通)...
  2. SHOPEX快递物流单号查询插件
  3. JS 中for、while、for in、for of、for each效率对比
  4. 教育APP开发的费用由哪些因素决定?
  5. Photoshop 绘图
  6. 交插二五条码(交叉25码)详解
  7. jsp中如何使1和0再页面中显示为男和女
  8. ElementUI中的el-form怎样格式化显示1和0为男和女
  9. wxml修改样式_微信小程序wxml和wxss样式
  10. Unity Gizmos可视化辅助工具