首页
社区
课程
招聘
[讨论][原创]第二题 lelfeiCM的writeup
发表于: 2017-6-4 09:27 5350

[讨论][原创]第二题 lelfeiCM的writeup

2017-6-4 09:27
5350

使用IDA工具装入lelfeiCM.exe很容易来到main函数,粗略阅读汇编代码,得出注册序号的格式的长度满足整数区间[8,20],且ASCII码满足整数区间[1,9]。

我使用InputKey辅助标记输入的字符串变量

先观察第一个重要的函数调用

发现使用了ecx,并且接下来的汇编大量使用了ecx寄存器传输数据结构地址,可以反推出这个数据结构是一个类,猜测如下:

先来看bignumber变量与InputKey的第一次交集,最后一行标记的Assign_char_调用的作用是将InputKey表示的数字依次放到BigNumber数据结构中,

还原一下函数形式BigNumber::Assign(char* input), 表现为bignumber = '123456789'

进入Assign_char_发现有两个直接调用,

第一个调用的作用就是SetVal(INDEX,VALUE),val [ idx [ Index ] ] = InputKey [ Index ] - '0'

第二个调用就是为了进位计算的,当某一位大于或等于10时,向前进位

来到第一个关键的调用,经过分析,该函数作用是计算BigNumber与数字乘法运算的

还原一下形式BigNumber::Multiply(int multiplier)

必然还有另外一个函数BigNumber::Multiply(BigNumber multiplier)

恰好下一部分就是对BigNumber::Multiply(BigNumber multiplier)的调用,

首先使用构造函数初始化TmpHandler,然后调用 this->MultiplySelfKey(TmpHandler),MultiplySelfKey就是乘法运算的实现

MultiplySelfKey与MultiplyWith_9的汇编代码大同小异。

紧接着又是一个MultiplyWith_9

看到这里就是为了计算 Number = Origin*9*Origin*9,然后判断大数长度是否是奇数,

最后是判断两个子数字的海明距离 HammingDist

当满足bigNumber.HammingDist(TmpHandler,...)判断大数前部分和后部分与原始数的海明距离之和为0时则转到well done的打印输出。


[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 1
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  CCkicker   +1.00 2017/06/06
最新回复 (3)
雪    币: 3757
活跃值: (1757)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
2
楼主你好,我想问一下,这个类的结构是怎么分析出来的?
我分析的时候也是分析出有一个类,但对于怎么分析它的结构就没办法了
2017-6-5 17:06
0
雪    币: 187
活跃值: (70)
能力值: ( LV5,RANK:155 )
在线值:
发帖
回帖
粉丝
3

C++和C我理解中的类class与结构structure的成员变量的内存布局是没有任何区别的,类多了一个通过编译器控制类的成员变量的访问。

先假设这个structure是一个很大的数组,这个数组可以存放任意类型的值。

类的地址通常是通过ecx传值的,

.text:004012C1                 mov     esi, ecx                                ;esi = this_class
.text:004012C3                 mov     dword ptr [esi], offset off_4080C8      ;this_class[0] = offset off_4080C8      
.text:004012C9                 call    ds:GetTickCount                          
.text:004012CF                 mov     ecx, esi                                 
.text:004012D1                 mov     [esi+200Ch], eax                        ;this_class[200C] = eax, tickcount
.text:004012D7                 mov     [esi+2008h], eax                        ;this_class[2008] = eax, tickcount
.text:004012DD                 call    shuffle_2_array

接下来分析 shuffle_2_array

.text:00401A66                 lea     edi, [esi+1008h]                        ;this_class[1008]
.text:00401A6C                 mov     ecx, edi
.text:00401A6E
.text:00401A6E loc_401A6E:                             ; CODE XREF: shuffle_2_array+22j
.text:00401A6E                 mov     edx, eax                                ;接下来的几行就是从this_class+1008开始使用0-400H依次初始化
.text:00401A70                 add     ecx, 4
.text:00401A73                 and     edx, 3FFh
.text:00401A79                 inc     eax
.text:00401A7A                 mov     [ecx-4], edx
.text:00401A7D                 cmp     eax, 400h
.text:00401A82                 jl      short loc_401A6E

分析类结构的关键是不要把它看成是一个类,要知道C++的类原型就是C的结构,C++的类就是C结构的语法升级版。

C++类的成员变量布局是按照类定义的顺序,加上对齐布局的,访问某一个变量时,通常是通过 [esi+offset member]的形式

当访问成员变量数组的某个位置时,通过 [esi + offset array + 4* index]的形式

当访问成员变量指针指向的对象时,通过 [ [ esi + offset pointer] ]的形式

等等

2017-6-7 12:51
0
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
厉害
2017-11-26 14:08
0
游客
登录 | 注册 方可回帖
返回