:这个CM 和上一个Afkayas.1 类似,但是算法有一点点不同,并且这里还需要去除一个Nag

逆向算法

首先还是通过关键的字符串的进行定位,不会的看我的上一篇文章。

然后前面还是一样len(UserName) * 88888 + ascii(UserName[0])

image-20231126214431909

但是的去尝试的时候发现密码不是这个。

我们接着往下看。

image-20231126215208214

发现这里有一个新的数字,当尝试这个数字的时候,发现就是需要的PassWord

所以我们就需要跟进这个计算出这个数据的call

这里 我们跟进的时候发现,好像是这么的简单。

我们重新分析,因为上面好想有点点错误。。。

这里是将上面计算出来的值+2

image-20231126233222423

然后往下:

image-20231126233335766

将上面计算出来的值*3 然后再减2

image-20231126233415447

然后减去-(-15)也就是+15

经过这些计算最后就得到了PassWord

后面就是一个cmp

中间用到了很多浮点数来计算,然后又转整数

我们用python来实现一下:

1
2
3
4
5
6
7
8
9
10
UserName = input("请输入你的用户名:")
#第一个地方
Password1 = len(UserName) * 88888 + ord(UserName[0])
#第二个地方
Password2 = Password1 + 2
#第三个地方
Password3 = Password2 * 3 - 2
#第四个地方
Password4 = Password3 - (-15)
print("生成的密码是:", Password4)

image-20231126233953645

去除Nag

这个是我破的第三个程序,我也不会。还好有大佬些的帖子:

https://bbs.kanxue.com/thread-249719.htm

image-20231127221654146

这里我们知道在call 后就会调用这个Nag窗口。

image-20231127221754447

在程序载入到入口点之后的第一个push也就是VBHeader的位置,数据窗口跟随。

image-20231127221911688

这里当一下搬运工:

TVBHeader结构定义

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
Signature                array[1..4] of char;        //00H签名,必须为VB5!
Flagl WORD; //04H.未知标志
LanguageDll array[1..14] of char; //06H语言链接库名,通常为”*"或者vb6chsdll
BackLanguageDll array[1..14] of char; //14H.后备语言链接库名
RuntimeDLLVersion WORD; //22H运行库版本
Languageld DWORD: //24H语言标识
BackupLanguageID DWORD; //28H,未知标志
aSubMain DWORD; //2CH,不为00000000则指向Sub MainO指针
aProjectlnfo DWORD //30H.指针,指向tProjeclnfo结构
Plag2 WORD; //34H未知标志
Flag3 WORD; //36H.未知标志
Flag4 DWORD; //38H未知标志
ThreadSpace DWORD; //3CH.线程空间
Flag5 DWORD; //14H未知标志
ResCount WORD; //44H.数量,表示form与cls文件个数
ImportCount WORD; //46H.数量,引用的ocx、dll文件个数
Flag6 BYTE: //48H未知,可能代表运行时程序所占内存大小
Flag7 BYTE; //49H未知,可能与程序启动时花费时间有关
Flag8 WORD; //4AH.未知
AGUTTable DWORD; //4CH.指针,指向Form GuI描述表
AExdCompTrble DWORD; //50H指针,指向“引入的ocx、dll文件描述表
Aproicclpescrinion DWORD; //54H,指针;指向tProjectDescriptionTable的指针
OProjectExename DWORD //58H.偏移,Offset ProjectExename
OProjectTitle DWORD; //5CH,偏移,Offset Projectitle
OHelpFile DWORD; //60H.偏移,Ofset Helpile
OProjectName DWORD. //64H.偏移,Offset ProjectName
AGUTTable(4C的位置)结构定义
Signature DWORD //00H.必须是50000000
FomID TGUID //04,可能是以GUID方式命名的formID
Index BYTE //24H 窗体的序号
Flag1 BYTE //28H 第一个窗体的启动标志,可能是90 也可能是10
AGUIDescriptionTable DWORD //48H指针指向以“FFCC…“开始的FormGUI表
Flag3 Dword //4CH.意义不明

其对应每个字节的含义如下表

offset 含义
00H VB5!
04H
06H 语言链接库名
14H
22H 04代表msvbvm50.dll版本
24H 语言标识
28H
2CH 00000000表示非由sub_main启动
30H 指向ProjectInfo结构
34H
36H
38H
3CH
40H
44H 只有2个FROM
46H 引用的OCX DLL文件个数为0
48H
49H
4AH
4CH Ptr 0040126C
50H 若没有引入的ocx,dll文件,此指针无效
54H 指向tProjectDescriptionTable的指针
58H ProjectExename
5CH ProjectTitle
60H HelpFile
64H ProjectName

4CH : Ptr 0040126C

就可以在头的位置+4C

然后在数据窗口输入刚才的地址+4C,找到form GUI描述表的指针

image-20231127224821453

image-20231127224838210

因为是指针所以这里存放的是地址。我们跟随一下:

image-20231127231354778

这些16进制下面有横线的就说明他们双击某个函数的入口点。

我们跟进看看【大小端绪】:00406868 0040117C

image-20231127231816616

接着会来到一块有规律的数据区域,每一个小块的数据是每一个窗体的信息,其中00和01是窗体的序号 而10是第一个窗体的启动标志。

:[这里抄个图]

image-20231127231732007

所以 我们只要把第一个窗体数据块的00改成10 然后把第二个窗体的数据块的10改成00,或者将窗体的序号调换。即可去除neg。

image-20231127232424340

就发现去除了Nag