WarmUp
Used To Write Docs
1
通过OutputDebugStringA进行调试器验证,如果在调试器内,则不会exception。
通过直接mov eax,1 方式更改跳转,正常运行后
由于 "H" % 64 = 8 "," % 64 = 2c
所以有两个解 [(Hex为奇数字符),44],[(Hex为偶数字符),8]
52
Acid burn
单Serial功能,直接做字符串比较
Name&Serial功能
注册机
package main
import (
"fmt"
)
func main() {
input := "Dawn"
if len(input) > 0 {
firstLetter := input[0] // 获取第一个字母
pass := int(firstLetter)*41*2
hexValue := fmt.Sprintf("CW-%d-CRACKED", pass) // 将字母转换为十六进制字符串
fmt.Println("密码:", hexValue)
}
}
AfKayAs CrackMe #1
判断部分,包含拼接激活码
00402510 | mov eax,dword ptr ss:[ebp-18] | [ebp-18]:L"Type In Your Serial"
00402513 | mov ecx,dword ptr ss:[ebp-1C] | [ebp-1C]:L"1658111"
00402516 | mov edi,dword ptr ds:[<&__vbaStrCat>] | 做结果拼接
0040251C | push eax | eax:L"AKA-1658111"
0040251D | push afkayas.1.401B70 | 401B70:L"AKA-"
00402522 | push ecx |
00402523 | call edi |
00402525 | mov ebx,dword ptr ds:[<&__vbaStrMove>] |
0040252B | mov edx,eax |
0040252D | lea ecx,dword ptr ss:[ebp-20] |
00402530 | call ebx |
00402532 | push eax |
00402533 | call dword ptr ds:[<&__vbaStrCmp>] | 字符串比较
00402539 | mov esi,eax |
从函数入口[00402310]开始,步过,[004024F] 第一次看到生成码
00402412 | push eax | eax:L"Type In Your Name"
00402413 | mov ebx,dword ptr ds:[edx] |
00402415 | call dword ptr ds:[<&__vbaLenBstr>] | 长度
0040241B | mov edi,eax |
0040241D | mov ecx,dword ptr ss:[ebp-18] |
00402420 | imul edi,edi,17CFB | 长度*17CFB
00402426 | push ecx |
00402427 | jo afkayas.1.4026BE |
0040242D | call dword ptr ds:[<&rtcAnsiValueBstr>] | 名字首字母
00402433 | movsx edx,ax |
00402436 | add edi,edx | 首字母+长度*17CFB
00402438 | jo afkayas.1.4026BE |
0040243E | push edi |
0040243F | call dword ptr ds:[<&__vbaStrI4>] | 转换为Dec字符串
00402445 | mov edx,eax |
流程完成
package main
import (
"fmt"
)
func main() {
input := "Dawn"
if len(input) > 0 {
le := len(input)
firstLetter := input[0]
pass := int(firstLetter) + le*97531
hexValue := fmt.Sprintf("AKA-%d", pass)
fmt.Println("密码:", hexValue)
}
}
AfKayAs CrackMe #2
目标:禁用延迟弹窗并注册
能通过VBDec看到相关信息,弹窗取消,一个是更改GUI启动顺序,将弹窗放置注册程序后,另一种是更改Timer时间.
更改弹窗顺序,要通过修改VBGUITable完成,需要从VBHeader找到GUITable的指针,在VBHeader结构中偏移为4C,VBHeader地址来源为程序入口调用ThunRTMain之前的push,相关知识参考链接
Visual Basic程序的逆向分析 - 『脱壳破解区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn
typedef struct{
char Signature[4]; //00H 四个字节的签名符号,和PEHEADER里的那个signature是类似性质的东西,VB文件都是"VB5!"
WORD RtBuild; //04H 运行时创立的变量(类似编译的时间)
BYTE LangDLL[14]; //06H 语言DLL文件的名字(如果是0x2A的话就代表是空或者是默认的)
BYTE BakLangDLL[14]; //14H 备份DLL语言文件的名字(如果是0x7F的话就代表是空或者是默认的,改变这个值堆EXE文件的运行没有作用)
WORD RtDLLVer; //22H 运行时DLL文件的版本
DWORD LangID; //24H 语言的ID
DWORD BakLangID; //28H 备份语言的ID(只有当语言ID存在时它才存在)
DWORD pSubMain; //2CH RVA(实际研究下来是VA) sub main过程的地址指针(3.)(如果时00000000则代表这个EXE时从FORM窗体文件开始运行的)
DWORD pProjInfo; //30H VA 工程信息的地址指针,指向一个ProjectInfo_t结构(2.)
DWORD fMDLIntObjs; //34H ?详细见"MDL 内部组建的标志表"
DWORD fMDLIntObjs2; //36H ?详细见"MDL 内部组建的标志表"
DWORD ThreadFlags; //38H 线程的标志
//* 标记的定义(ThreadFlags数值的含义)
//+-------+----------------+--------------------------------------------------------+
//| 值 | 名字 | 描述
//+-------+----------------+--------------------------------------------------------+
//| 0x01 | ApartmentModel | 特别化的多线程使用一个分开的模型
//| 0x02 | RequireLicense | 特别化需要进行认证(只对OCX)
//| 0x04 | Unattended | 特别化的没有GUI图形界面的元素需要初始化
//| 0x08 | SingleThreaded | 特别化的静态区时单线程的
//| 0x10 | Retained | 特别化的将文件保存在内存中(只对Unattended)
//+-------+----------------+--------------------------------------------------------+
//ex: 如果是0x15就表示是一个既有多线程,内存常驻,并且没有GUI元素要初始化
DWORD ThreadCount; //3CH 线程个数
WORD FrmCount; //41H 窗体个数
WORD pExternalComponentCount; //44H VA 外部引用个数例如WINSOCK组件的引用
DWORD ThunkCount; //48H ?大概是内存对齐相关的东西
DWORD GUITable; //4CH VA GUI元素表的地址指针(指向一个GUITable_t结构)
DWORD pExternalComponentTable; //50H VA 外部引用表的地址指针
// DWORD pProjDep; // VA 工程的描述的地址指针(这个其实没有)
DWORD pComRegData; //54H VA COM注册数据的地址指针
DWORD oProjExename; //58H Offset 指向工程EXE名字的字符串
DWORD oProjTitle; //5CH Offset 指向工程标题的字符串
DWORD oHelpFile; //60H Offset 指向帮助文件的字符串
DWORD oProjName; //64H Offset 指向工程名的字符串
}VBHeader_t;
GUITable部分指向的结构含义如下
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.意义不明
位置可以自行验证
之后是破解注册,后续调试输入为"Type In Your Name",密码有数据输入要求,必须为数字,为"123456",逻辑和上一次有些像,先定位这里
往下看 有别的生成和判断结构
VBDecompliner 的反编译结果和IDA对比分析,#1的计算的部分不再重复
$$ str[0] +len(str)*8888 $$
从+(10/5)的部分开始,其中 10/5是通过vbaR8Str函数将之前的运算存入st ,通过fdiv和faddp完成
$$ str[0] +len(str)*8888+2 $$
004082E3 | mov edx,dword ptr ss:[ebp-18] | [ebp-18]:L"1511180"
004082E6 | push edx |
004082E7 | mov ebx,dword ptr ds:[ecx] |
004082E9 | call dword ptr ds:[<&__vbaR8Str>] | 1511180压入st
004082EF | fld st(0),dword ptr ds:[401008] | 10 压入st
004082F5 | cmp dword ptr ds:[409000],0 |
004082FC | jne afkayas.2.408306 |
004082FE | fdiv st(0),dword ptr ds:[40100C] | 用10/5 存入st0
00408304 | jmp afkayas.2.408311 |
00408306 | push dword ptr ds:[40100C] |
0040830C | call <JMP.&_adj_fdiv_m32> |
00408311 | sub esp,8 |
00408314 | fnstsw ax |
00408316 | test al,D |
00408318 | jne afkayas.2.4087BF |
0040831E | faddp st(1),st(0) | st0=st1+st0
00408320 | fnstsw ax |
00408322 | test al,D |
00408324 | jne afkayas.2.4087BF |
0040832A | fstp qword ptr ss:[esp],st(0) | 保存 "1511182"
0040832D | call dword ptr ds:[<&__vbaStrR8>] |
相同的,在[004083F8]进行了下一次计算,当前逻辑为
$$ (str[0] +len(str)*8888+2)*3-2 $$
004083EF | mov edx,dword ptr ss:[ebp-18] | [ebp-18]:L"1511182"
004083F2 | push edx |
004083F3 | mov ebx,dword ptr ds:[ecx] |
004083F5 | call dword ptr ds:[<&__vbaR8Str>] |
004083FB | fmul st(0),qword ptr ds:[401010] | 1511182*3
00408401 | sub esp,8 |
00408404 | fsub st(0),qword ptr ds:[401018] | 1511182*3-2
0040840A | fnstsw ax |
0040840C | test al,D |
0040840E | jne afkayas.2.4087BF |
00408414 | fstp qword ptr ss:[esp],st(0) | 保存
00408417 | call dword ptr ds:[<&__vbaStrR8>] |
之后又加了一次15
$$ (str[0] +len(str)*8888+2)*3-2- (-15) $$
004084E5 | fsub st(0),qword ptr ds:[401020] | 4533544-(-15)
004084EB | sub esp,8 |
004084EE | fnstsw ax |
004084F0 | test al,D |
004084F2 | jne afkayas.2.4087BF |
004084F8 | fstp qword ptr ss:[esp],st(0) |
最后将结果和用户输入Key相除比较商,通过fdiv,fcomp实现,相关汇编指令知识
004085CE | mov eax,dword ptr ss:[ebp-18] | [ebp-18]:L"123456"
004085D1 | push eax |
004085D2 | call dword ptr ds:[<&__vbaR8Str>] | 123456 压入st
004085D8 | mov ecx,dword ptr ss:[ebp-1C] | [ebp-1C]:L"4533559"
004085DB | fstp qword ptr ss:[ebp-E4],st(0) |
004085E1 | push ecx |
004085E2 | call dword ptr ds:[<&__vbaR8Str>] | 4533559 压入st
004085E8 | cmp dword ptr ds:[409000],0 |
004085EF | jne afkayas.2.4085F9 |
004085F1 | fdivr st(0),qword ptr ss:[ebp-E4] | 123456/4533559
004085F7 | jmp afkayas.2.40860A |
004085F9 | push dword ptr ss:[ebp-E0] |
004085FF | push dword ptr ss:[ebp-E4] |
00408605 | call <JMP.&_adj_fdivr_m64> |
0040860A | fnstsw ax |
0040860C | test al,D |
0040860E | jne afkayas.2.4087BF |
00408614 | call dword ptr ds:[<&__vbaFpR8>] |
0040861A | fcomp st(0),qword ptr ds:[401028] | 与1做比较
00408620 | fnstsw ax | 将结果标志位存至ax
00408622 | test ah,40 | 如果不相等 esi = 0
00408625 | je afkayas.2.40862E |
00408627 | mov esi,1 | 如果相等 es = 1
0040862C | jmp afkayas.2.408630 |
0040862E | xor esi,esi | esi = 0
...........
00408653 | neg esi |
00408655 | add esp,C |
00408658 | mov ecx,80020004 |
0040865D | mov eax,A |
00408662 | mov dword ptr ss:[ebp-64],ecx |
00408665 | test si,si | 判断si
00408668 | mov dword ptr ss:[ebp-6C],eax |
0040866B | mov dword ptr ss:[ebp-54],ecx |
0040866E | mov dword ptr ss:[ebp-5C],eax |
00408671 | mov dword ptr ss:[ebp-44],ecx |
00408674 | mov dword ptr ss:[ebp-4C],eax |
00408677 | je afkayas.2.4086DB | 判断跳转部分
00408679 | mov esi,dword ptr ds:[<&__vbaStrCat>] |
0040867F | push afkayas.2.406FC0 | 406FC0:L"You Get It"
00408684 | push afkayas.2.406FDC |
...........
004086DB | mov esi,dword ptr ds:[<&__vbaStrCat>] |
004086E1 | push afkayas.2.407008 | 407008:L"You Get Wrong"
004086E6 | push afkayas.2.406FDC |
004086EB | call esi |
整体流程结束
package main
import (
"fmt"
)
func main() {
input := "Dawn"
if len(input) > 0 {
le := len(input)
firstLetter := input[0]
pass := (int(firstLetter) + le*88888+2)*3-2+15
hexValue := fmt.Sprintf("%d", pass)
fmt.Println("密码:", hexValue)
}
}
CKme
String看到注册成功
转到代码,没有验证按钮,自循环结构可能是注册判断,跟入
调试看是一个附近代码没有操作过的内存,应该不是在点击验证时生成的注册码
使用工具,查看有相关页面结构,可以双击定位,在工具查看反汇编
2f8偏移存储用户名长度
chkcode[00457c40]为主要验证注册码部分
00457C40 | push ebp |
......
00457C66 | mov esi,dword ptr ds:[ebx+2F8] | 用户名长度
00457C6C | add esi,5 | 长度+5
00457C6F | push dword ptr ds:[ebx+310] | [ebx+310]:"黑头Sun Bird"
00457C75 | lea edx,dword ptr ss:[ebp-8] |
00457C78 | mov eax,esi |
00457C7A | call IntToStr |
00457C7F | push dword ptr ss:[ebp-8] |
00457C82 | push dword ptr ds:[ebx+314] | [ebx+314]:"dseloffc-012-OK"
00457C88 | lea edx,dword ptr ss:[ebp-C] |
00457C8B | mov eax,dword ptr ds:[ebx+2D4] | 输入框1
00457C91 | call TContorl.GetText |
00457C96 | push dword ptr ss:[ebp-C] |
00457C99 | lea eax,dword ptr ds:[ebx+318] |
00457C9F | mov edx,4 |
00457CA4 | call LSTRCATN |
00457CA9 | xor edx,edx |
00457CAB | mov eax,dword ptr ds:[ebx+2F4] | Form1.Label6:Tlable1
00457CB1 | call TControl.SetVisible | 设置图片不可见
00457CB6 | mov edx,dword ptr ds:[ebx+318] | [ebx+318]:"黑头Sun Bird10dseloffc-012-OKtest2"
00457CBC | mov eax,dword ptr ds:[ebx+2F4] |
00457CC2 | call ckme.423378 |
...... 中间的19次循环我认为是脏代码
00457D1E | lea edx,dword ptr ss:[ebp-20] |
00457D21 | mov eax,dword ptr ds:[ebx+2D8] | 输入框2的值
00457D27 | call TControl.GetText |
00457D2C | mov eax,dword ptr ss:[ebp-20] |
00457D2F | mov edx,dword ptr ds:[ebx+318] | [ebx+318]:"黑头Sun Bird10dseloffc-012-OKtest2"
00457D35 | call StrCmp | StrCmp(输入框,[ebx+318])
00457D3A | jne ckme.457D46 | 判断
00457D3C | mov dword ptr ds:[ebx+30C],3E | 相等[ebx+30C] = 3E 注册成功
00457D46 | mov eax,dword ptr ds:[ebx+30C] |
00457D4C | add eax,10 |
00457D4F | mov dword ptr ds:[ebx+2FC],eax | [ebx+2FC] = 4E
00457D55 | add eax,23 |
00457D58 | mov dword ptr ds:[ebx+300],eax | [ebx+300] = 71
...... 依旧是19次循环
00457DB5 | mov eax,dword ptr ds:[ebx+2FC] | 4E
00457DBB | add eax,dword ptr ds:[ebx+300] | 4E+71 = BF
00457DC1 | mov dword ptr ds:[ebx+304],eax | [ebx+304] = BF
00457DC7 | mov edx,dword ptr ds:[ebx+2FC] |
00457DCD | add edx,9 | 4E+9
00457DD0 | add edx,eax | 4E+9+BF = 116
00457DD2 | mov dword ptr ds:[ebx+308],edx | [ebx+308] = 116
$$ “黑头Sun Bird” + (len(str)+5)+“dseloffc-012-OK”+str $$
之后看验证,也解释了为什么需要点击多次才能正常弹框,双击触发初步验证,再单击触发弹出图片,严格逻辑是 先双击再单击
双击触发
...... 脏代码
00457EF5 | cmp dword ptr ds:[esi+30C],3E | 判断是否为3E
00457EFC | jne ckme.457F08 |
00457EFE | mov dword ptr ds:[esi+30C],85 | 是的话,赋值 85
...... 脏代码
单击触发
00458031 | cmp dword ptr ds:[esi+30C],85 | 判断85
0045803B | jne ckme.4580B3 | 不匹配 结束
...... 脏代码
00458096 | mov eax,dword ptr ds:[esi+2F0] | TForm1.Panel1:TPanel
0045809C | call Tcontrol.SetVisible | 设置可见
004580A1 | mov eax,dword ptr ds:[45B820] | TForm1
004580A6 | add eax,70 |
004580A9 | mov edx,ckme.458114 | 恭喜恭喜。注册成功
004580AE | call ckme.403950 |
注册机
package main
import (
"fmt"
)
func main() {
input := "Dawn"
if len(input) > 0 {
le := len(input)+5
Key := fmt.Sprintf("黑头Sun Bird%ddseloffc-012-OK%s",le,input)
fmt.Println("密码:", Key)
}
}
CKMe002
UPX壳,X32Dbg使用Scylla脱壳后,放入IDR
找到注册成功处判断,查看对应的触发函数,是一个OnTimer事件,即定时触发,查看汇编代码,有5处判断逻辑,只有都通过,才能进入成功注册
004473E4 | push ebx |
004473E5 | mov ebx,eax |
004473E7 | cmp dword ptr ds:[ebx+304],C34 | [ebx+304] != C34
004473F1 | je ckme002_dump_scy.44747F |
004473F7 | cmp dword ptr ds:[ebx+308],230D | [ebx+308] != 230D
00447401 | je ckme002_dump_scy.44747F |
00447403 | cmp dword ptr ds:[ebx+310],F94 | [ebx+310] == F94
0044740D | jne ckme002_dump_scy.44747F |
0044740F | mov eax,dword ptr ds:[ebx+318] |
00447415 | cmp eax,dword ptr ds:[ebx+314] | [ebx+314] == [ebx+318]
0044741B | jne ckme002_dump_scy.44747F |
0044741D | cmp dword ptr ds:[ebx+31C],3E7 | [ebx+31C] == 3E7
00447427 | je ckme002_dump_scy.44747F |
00447429 | xor edx,edx |
0044742B | mov eax,dword ptr ds:[ebx+2D8] | TForm1.Iamge1
00447431 | mov ecx,dword ptr ds:[eax] |
00447433 | call TControl.SetEnabled | 取消图片的点击事件
...... 四个图片依次取消,代码相同
0044745D | mov eax,dword ptr ds:[4498A8] |
00447462 | add eax,70 | TForm1.Hint
00447465 | mov edx,ckme002_dump_scy.44748C | 厉害厉害真厉害
0044746A | call @LStrAsg |
0044746F | mov edx,ckme002_dump_scy.4474B8 | 注册了
00447474 | mov eax,dword ptr ds:[ebx+2EC] | TForm1.Button1
0044747A | call TControl.SetText |
转到FormCreate函数,可以看到一些对于提到位置的操作
...... 设置图片不可见blablabla
00446C89 | xor edx,edx |
00446C8B | mov eax,dword ptr ds:[ebx+2F0] | TForm1.Edit2
00446C91 | mov ecx,dword ptr ds:[eax] |
00446C93 | call dword ptr ds:[ecx+5C] | 禁用第二个输入框TControl.SetEnabled
...... 设置图片位置
00446D23 | mov dword ptr ds:[ebx+308],28E | [ebx+308] = 28E
00446D2D | mov dword ptr ds:[ebx+30C],9 | [ebx+30C] = 9
00446D37 | mov dword ptr ds:[ebx+314],B | [ebx+314] = B
00446D41 | xor eax,eax |
00446D43 | mov dword ptr ds:[ebx+318],eax | [ebx+318] = 0
00446D49 | mov edx,ckme002_dump_scy.446DEC | 446DEC:"X:\\ajj.126.c0m\\j\\o\\j\\o\\ok.txt"
00446D4E | lea eax,dword ptr ss:[ebp-1D0] |
00446D54 | call @Assign |
00446D59 | lea eax,dword ptr ss:[ebp-1D0] |
00446D5F | call @ResetText |
00446D64 | call IOResult |
00446D69 | test eax,eax | 如果成功读取文件,eax=0
00446D6B | jne ckme002_dump_scy.446DB8 |
00446D6D | lea edx,dword ptr ss:[ebp-4] |
00446D70 | lea eax,dword ptr ss:[ebp-1D0] |
00446D76 | call @ReadString |
00446D7B | call @_IOTest | 读取文件
00446D80 | mov eax,dword ptr ss:[ebp-4] |
00446D83 | mov edx,ckme002_dump_scy.446E14 | ’ ajj写的CKme真烂!ÿÿ‘
00446D88 | call @LStrCmp |
00446D8D | je ckme002_dump_scy.446D99 |
00446D8F | mov dword ptr ds:[ebx+304],C34 |
00446D99 | lea eax,dword ptr ss:[ebp-1D0] |
00446D9F | call @Close |
00446DA4 | call @_IOTest |
00446DA9 | mov dl,1 |
00446DAB | mov eax,dword ptr ds:[ebx+2F0] | TForm.Edit2
00446DB1 | call TControl.SetVisible | 通过后,显示输入框2
00446DB6 | jmp ckme002_dump_scy.446DC2 |
00446DB8 | mov dword ptr ds:[ebx+304],C34 |
00446DC2 | xor eax,eax |
如果对应文件路径及内容正确,[ebx+304] 为 0,为了方便,我将硬编码的路径盘符换了一下,重新运行后,能够看到第二个输入框,但是无法输入,继续到OnMOuseMove函数
TControl 事件 - C++ Builder 参考手册 - C++ 爱好者
当鼠标在控件里面移动的时候会产生 OnMouseMove 事件,这个事件响应 Windows 消息:WM_MOUSEMOVE。请参考 MouseMove 方法。参数 X 和 Y 为鼠标的位置。
typedef void __fastcall (__closure *TMouseMoveEvent)( System::TObject* Sender, System::Classes::TShiftState Shift, int X, int Y);
004470EC | push ebp |
004470ED | mov ebp,esp |
......
0044710A | mov ecx,dword ptr ds:[ebx+2E0] | TForm1.Image3
00447110 | cmp byte ptr ds:[ecx+47],1 | TImage.FVisible
00447114 | jne ckme002_dump_scy.44712F | 如果图片三可见
00447116 | cmp eax,E2 |
0044711B | jle ckme002_dump_scy.44712F | 鼠标的X坐标 <= E2
0044711D | cmp edx,12C |
00447123 | jle ckme002_dump_scy.44712F | 鼠标的Y坐标 <= 12C
00447125 | mov dword ptr ds:[ebx+310],10 | [ebx+310] = 10
0044712F | mov ecx,dword ptr ds:[ebx+2DC] | TForm1.Image2
00447135 | cmp byte ptr ds:[ecx+47],1 | TImage.FVisible
00447139 | jne ckme002_dump_scy.4471A7 | 如果图片二可见
0044713B | cmp eax,17 |
0044713E | jge ckme002_dump_scy.4471A7 | 鼠标的X坐标 >= 17
00447140 | cmp edx,12C |
00447146 | jle ckme002_dump_scy.4471A7 | 鼠标的Y坐标 <= 12C
00447148 | cmp dword ptr ds:[ebx+310],10 | 如果图片三的判断通过
0044714F | jne ckme002_dump_scy.4471A7 |
00447151 | cmp dword ptr ds:[ebx+30C],9 | [ebx+30C] == 9
00447158 | je ckme002_dump_scy.4471A7 |
0044715A | mov dword ptr ds:[ebx+310],F94 | [ebx+310] = F94
00447164 | mov eax,dword ptr ds:[ebx+30C] |
0044716A | sub eax,1 |
0044716D | jb ckme002_dump_scy.447179 | [ebx+30C] < 9
0044716F | je ckme002_dump_scy.447185 | [ebx+30C] == 9 不会执行
00447171 | dec eax | eax--
00447172 | je ckme002_dump_scy.447191 |
00447174 | dec eax | eax--
00447175 | je ckme002_dump_scy.44719D |
00447177 | jmp ckme002_dump_scy.4471A7 |
00447179 | mov dword ptr ds:[ebx+314],41 | [ebx+314] = 41
00447183 | jmp ckme002_dump_scy.4471A7 |
00447185 | mov dword ptr ds:[ebx+314],3D | [ebx+314] = 3D
0044718F | jmp ckme002_dump_scy.4471A7 |
00447191 | mov dword ptr ds:[ebx+314],34 | [ebx+314] = 34
0044719B | jmp ckme002_dump_scy.4471A7 |
0044719D | mov dword ptr ds:[ebx+314],DF | [ebx+314] = DF
004471A7 | cmp dword ptr ds:[ebx+310],F94 | [ebx+310] == F94
004471B1 | jne ckme002_dump_scy.4471F9 |
004471B3 | lea edx,dword ptr ss:[ebp-4] |
004471B6 | mov eax,dword ptr ds:[ebx+2E8] | TForm1.Edit1
004471BC | call TControl.GetText |
004471C1 | mov eax,dword ptr ss:[ebp-4] |
004471C4 | mov edx,ckme002_dump_scy.447230 | 447230:"ajj"
004471C9 | call @LStrCmp |
004471CE | jne ckme002_dump_scy.4471F9 |
004471D0 | mov dl,1 |
004471D2 | mov eax,dword ptr ds:[ebx+2FC] | TForm1.Label3
004471D8 | call ckme002_dump_scy.423FA4 | TControl.SetVisible
004471DD | lea edx,dword ptr ss:[ebp-8] |
004471E0 | mov eax,dword ptr ds:[ebx+30C] |
004471E6 | call IntToStr |
004471EB | mov edx,dword ptr ss:[ebp-8] |
004471EE | mov eax,dword ptr ds:[ebx+2FC] | TForm1.Label3
004471F4 | call TControl.SetText |
......
读完后主要有两个关键可控值,[ebx+30C],鼠标坐标,为了保证按照预期进行,需要满足条件
Mouse.Y >= 12C && [ebx+30C] != 9
if Image3.FVisible{
Mouse.X >= E2
}
if Image3.FVisible{
MOuse.X <= 17
}
因为在FormCreate后,[ebx+30C]被置为9,不满足,所以需要别的操作触发修改值,在Edit2的OnDbleClock处有修改该位置的代码
下断后发现不触发,应该是之前在Create时Edit2被禁用,所以不触发,再找启用Edit2的触发位置,为Panel1的OnDblClick
00446FDC | cmp dword ptr ds:[eax+308],29D | [eax+308] == 29D
00446FE6 | jne ckme002_dump_scy.446FF5 |
00446FE8 | mov dl,1 |
00446FEA | mov eax,dword ptr ds:[eax+2F0] | TForm1.Edit2
00446FF0 | mov ecx,dword ptr ds:[eax] |
00446FF2 | call dword ptr ds:[ecx+5C] | TControl.SetEnabled
00446FF5 | ret |
再去寻找赋值[eax+308]的位置,会在Button1的MouseDown看到
TControl 事件 - C++ Builder 参考手册 - C++ 爱好者
当鼠标按钮点击了控件会产生这个事件。这个事件响应 Windows 消息:WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN。请参考 MouseDown 方法。 参数 Button 为点击的鼠标按钮,Shift 为组合键的状态,X 和 Y 为鼠标位置
typedef void __fastcall (__closure *TMouseEvent)( System::TObject* Sender, System::Uitypes::TMouseButton Button, System::Classes::TShiftState Shift, int X, int Y);
这里是fastcall所以传入的Button存在ecx
00446FA4 | push ebp |
00446FA5 | mov ebp,esp |
00446FA7 | mov edx,dword ptr ds:[eax+308] | 第一次点击,为初始值28E
00446FAD | cmp edx,230D |
00446FB3 | je ckme002_dump_scy.446FD5 |
00446FB5 | cmp cl,1 | 左键点击,ecx为0,右键为1
00446FB8 | jne ckme002_dump_scy.446FC3 |
00446FBA | add dword ptr ds:[eax+308],3 | 如果右键,[eax+308] += 3
00446FC1 | jmp ckme002_dump_scy.446FD5 |
00446FC3 | cmp edx,294 | 如果左键,去和294做cmp
00446FC9 | jge ckme002_dump_scy.446FD5 | [eax+308] >= 294
00446FCB | mov dword ptr ds:[eax+308],230D | 满足条件不赋值
00446FD5 | pop ebp |
00446FD6 | ret C |
所以需要点击Button1正确赋值[eax+308]为29D后,才能进行DblClick动作
(29D-28E)/3=5 右键点击注册5次后,点不点左键都可以,但是不能在右键五次之前点击左键
成功启用Edit2后,继续触发DblClick来更改[ebx+30C]的值,使00447158处的代码按预期继续执行。
00446FF8 | push ebp |
......
00447013 | lea edx,dword ptr ss:[ebp-4] |
00447016 | mov eax,dword ptr ds:[ebx+2F0] | TForm1.Edit2
0044701C | call TControl.GetText |
00447021 | mov eax,dword ptr ss:[ebp-4] |
00447024 | call @LStrLen |
00447029 | cmp eax,8 | len(Edit2) == 8
0044702C | jne ckme002_dump_scy.4470C4 |
00447032 | lea edx,dword ptr ss:[ebp-8] |
00447035 | mov eax,dword ptr ds:[ebx+2F0] | TForm1.Edit2
0044703B | call TControl.GetText |
00447040 | mov eax,dword ptr ss:[ebp-8] |
00447043 | cmp byte ptr ds:[eax+1],5F | Edit2[1] == '_'
00447047 | jne ckme002_dump_scy.4470C4 |
00447049 | lea edx,dword ptr ss:[ebp-C] |
0044704C | mov eax,dword ptr ds:[ebx+2F0] | TForm1.Edit2
00447052 | call TControl.GetText |
00447057 | mov eax,dword ptr ss:[ebp-C] |
0044705A | cmp byte ptr ds:[eax+5],2C | Edit2[5] == ','
0044705E | jne ckme002_dump_scy.4470C4 |
00447060 | lea edx,dword ptr ss:[ebp-10] |
00447063 | mov eax,dword ptr ds:[ebx+2E8] | TForm1.Edit1
00447069 | call TControl.GetText |
0044706E | mov eax,dword ptr ss:[ebp-10] |
00447071 | call @LStrLen |
00447076 | add eax,3 | len(Edit1) += 3
00447079 | mov ecx,3 |
0044707E | cdq |
0044707F | idiv ecx | (Edit1+3) % 3
00447081 | test edx,edx |
00447083 | jne ckme002_dump_scy.4470C4 |
00447085 | push 0 |
00447087 | push 4 |
00447089 | lea edx,dword ptr ss:[ebp-14] |
0044708C | mov eax,dword ptr ds:[ebx+2E8] | TForm1.Edit1
00447092 | call TControl.GetText |
00447097 | mov eax,dword ptr ss:[ebp-14] |
0044709A | call @LStrLen |
0044709F | cdq |
004470A0 | push edx |
004470A1 | push eax |
004470A2 | xor eax,eax |
004470A4 | call DiskFree |
004470A9 | add eax,dword ptr ss:[esp] |
004470AC | adc edx,dword ptr ss:[esp+4] |
004470B0 | add esp,8 |
004470B3 | add eax,2 |
004470B6 | adc edx,0 |
004470B9 | call @_llmod |
004470BE | mov dword ptr ds:[ebx+30C],eax | [ebx+30C] = 1 || 0
......
004470EA | ret
当Edit2的长度为8,第二位是"_",第6位为",“且Edit1长度能被3整除时,[ebx+30C]会被赋值为1或0。
当我输入长度为3的倍数的名字时,[ebx+30C]会被赋值为0,Label3不会显示
具体原因得看下@_llmod的返回定义,
由于赋值为0,在0044716D处的判断赋值也会发生变化,[ebx+314]赋值为41,
之后点击图片的次数也需要重新计算,不过逻辑相同
回到OnMouseMove,按照要求,用户名输入ajj,第三张图片时,右下角移动鼠标,然后第二张图片,左下角移动鼠标,按照预期执行。[ebx+310]被赋值为0F94,[ebx+314]被赋值为3D,Label3显示[ebx+30C],即1
此时验证判断逻辑(Timer2)按照预期走到了00447403,之后查找[ebx+318],[ebx+314],[ebx+31C]被修改的位置,发现在Image的OnMouseDown中修改了[ebx+318]
00447378 | push ebp |
00447379 | mov ebp,esp |
0044737B | push ebx |
0044737C | push esi |
0044737D | mov ebx,ecx |
0044737F | mov esi,eax |
00447381 | push 0 |
00447383 | mov cx,word ptr ds:[4473B4] |
0044738A | mov dl,2 |
0044738C | mov eax,ckme002_dump_scy.4473C0 | '注册尚未成功'
00447391 | call MessageDlg |
00447396 | test bl,bl |
00447398 | jne ckme002_dump_scy.4473A1 |
0044739A | add dword ptr ds:[esi+318],7 | 左键,[esi+318] + 7
004473A1 | cmp bl,1 |
004473A4 | jne ckme002_dump_scy.4473AD |
004473A6 | add dword ptr ds:[esi+318],1B | 右键,[esi+318] + 1B
004473AD | pop esi |
004473AE | pop ebx |
004473AF | pop ebp |
004473B0 | ret C |
四个图片逻辑一样,加的值大小不同,但是在图片2和图片3因为有OnMouseMove动作,所以不能够使用,只能选图片1或者图片4点击,当用户名长度为3时,图片四左键1次,右键两次,用户名>3时,图片1右键3次,图片4左键2次,之后[ebx+31C]的赋值,在右键Button部分就同时触发完成了
控件的点击事件,控件用鼠标点击,或者键盘的空格或回车键,还有快捷键等,都可能会产生这个事件,请参考 Click 方法。
https://www.cppfans.com/cbknowledge/reference/vcl.baseclasses/tcontrol_events.asp#OnClick
所以没有注册机,和输入有关的两个条件是,Edit2的长度,第一位,第六位,Edit1的长度,剩下的就是操作
1.创建文件X:\\ajj.126.c0m\\j\\o\\j\\o\\ok.txt 内容为指定内容
2.右键注册按钮五次
3.点击图片窗口空白处
4.Edit1输入长度为3x,若输入ajj,会弹出Lable3,Edit2输入x_xxx,xx,双击Edit2
5.第三张图片显示时,右下角移入鼠标
6.第二张图片显示时,左下角移入鼠标
7.点击第四张图片 右键两次,左键一次,如果长度>3,图4左键2次,图1右键三次
aLoNg3x.1
目的是移除底部俩个按钮
IDR结合ida看下,在两个对应按钮键位置就可以实现
Cancella按钮
00442EA8 | push ebp |
00442EA9 | mov ebp,esp |
......
00442EBE | lea edx,dword ptr ss:[ebp-4] |
00442EC1 | mov eax,dword ptr ds:[ebx+2E0] | TPrincpale.Codice
00442EC7 | call TConTrol.GetText |
00442ECC | mov eax,dword ptr ss:[ebp-4] |
00442ECF | call StrToInt |
00442ED4 | push eax |
00442ED5 | lea edx,dword ptr ss:[ebp-4] |
00442ED8 | mov eax,dword ptr ds:[ebx+2DC] | TPincpale.Nome
00442EDE | call TConTrol.GetText |
00442EE3 | mov eax,dword ptr ss:[ebp-4] | eax=Nome
00442EE6 | pop edx | edx=StrToInt(Codice)
00442EE7 | call along3x.1.442AF4 | 该位置为关键call
00442EEC | test al,al |
00442EEE | je along3x.1.442F0C |
00442EF0 | xor edx,edx |
00442EF2 | mov eax,dword ptr ds:[ebx+2D0] | TPrincipale.Cancella
00442EF8 | call TControl.SetVisible | 设置Cancella按钮不可见
00442EFD | mov dl,1 |
00442EFF | mov eax,dword ptr ds:[ebx+2CC] | TPrincpale.Ok
00442F05 | mov ecx,dword ptr ds:[eax] |
00442F07 | call TControl.SetEnabled | 启用OK按钮
00442F0A | jmp along3x.1.442F1C |
00442F0C | mov edx,along3x.1.442F48 | 关键位置失败跳转,
00442F11 | mov eax,dword ptr ds:[ebx+2E0] | TPincpale.Codice
00442F17 | call TControl.SetText | Codice置0
......
00442F3C | ret |
OK按钮
00442D64 | push ebp |
...... 传入的参数和另一个按钮一样.Codice和Nome,call的函数不同,不重复解释
00442DC1 | call along3x.1.442BA0 |
00442DC6 | test al,al |
00442DC8 | je along3x.1.442DD7 |
00442DCA | xor edx,edx |
00442DCC | mov eax,dword ptr ds:[ebx+2CC] | TPrincipale.Ok
00442DD2 | call TConTrol.SetEnabled | 设置Ok不可见
......
00442DF7 | ret |
还有一个OK按钮的Enable问题,在Codice和Nome的OnChange事件里,同时如果Cancella按钮不可见,Ok键也会直接启用
Nome.OnChange(Codice.OnChange基本一样,不重复解释)
00442E04 | push ebp |
......
00442E1C | mov eax,dword ptr ds:[ebx+2D0] | TPrincipale.Cancella
00442E22 | cmp byte ptr ds:[eax+47],0 | TButton.FVisible
00442E26 | jne along3x.1.442E37 | Cancella按钮是否可见
00442E28 | mov dl,1 |
00442E2A | mov eax,dword ptr ds:[ebx+2CC] | TPrincipale.Ok
00442E30 | mov ecx,dword ptr ds:[eax] |
00442E32 | call TControl.SetEnabled | 如果不可见,Enable Ok按钮
00442E35 | jmp along3x.1.442E80 |
00442E37 | lea edx,dword ptr ss:[ebp-4] |
00442E3A | mov eax,dword ptr ds:[ebx+2E0] | TPincpale.Codice
00442E40 | call TConTrol.GetText |
00442E45 | mov eax,dword ptr ss:[ebp-4] |
00442E48 | push eax |
00442E49 | lea edx,dword ptr ss:[ebp-8] |
00442E4C | mov eax,dword ptr ds:[ebx+2DC] | TPincpale.Nome
00442E52 | call TConTrol.GetText |
00442E57 | mov eax,dword ptr ss:[ebp-8] |
00442E5A | pop edx |
00442E5B | call along3x.1.442A3C | 关键call 是否启用OK
00442E60 | test al,al |
00442E62 | je along3x.1.442E73 |
00442E64 | mov dl,1 |
00442E66 | mov eax,dword ptr ds:[ebx+2CC] | TPrincipale.Ok
00442E6C | mov ecx,dword ptr ds:[eax] |
00442E6E | call TConTrol.SetEnabled |
00442E71 | jmp along3x.1.442E80 |
00442E73 | xor edx,edx |
00442E75 | mov eax,dword ptr ds:[ebx+2CC] | TPrincipale.Ok
00442E7B | mov ecx,dword ptr ds:[eax] |
00442E7D | call TConTrol.SetEnabled |
......
00442EA6 | ret |
00442C78 | push ebp |
...... 调用和传参逻辑和NomeOnChange相似,不重复解释
00442D0B | call along3x.1.442A3C | 关键call 是否启用OK
00442D10 | test al,al |
....... 后续也一样,如果返回非0,启用Ok,否则不启用
00442D62 | ret |
后续关注关键位置函数传参分别为
sub_00442AF4(*Nome,StrToInt(Codice))
sub_00442BA0(*Nome,*Codice)
00442AF4
00442AF4 | push ebp |
00442AF5 | mov ebp,esp |
00442AF7 | add esp,FFFFFFF8 |
00442AFA | push ebx |
00442AFB | push esi |
00442AFC | mov dword ptr ss:[ebp-8],edx | Codice
00442AFF | mov dword ptr ss:[ebp-4],eax | Nome
......
00442B18 | mov eax,dword ptr ss:[ebp-4] | Nome
00442B1B | call @LStrLen |
00442B20 | cmp eax,5 | Nome长度大于5
00442B23 | jle along3x.1.442B78 |
00442B25 | mov eax,dword ptr ss:[ebp-4] | Nome
00442B28 | movzx eax,byte ptr ds:[eax+4] | Nome[4]
00442B2C | mov ecx,7 |
00442B31 | xor edx,edx |
00442B33 | div ecx | Nome[4] % 7
00442B35 | mov eax,edx |
00442B37 | add eax,2 | Nome[4] % 7 + 2
00442B3A | call along3x.1.442A20 | (Nome[4] % 7 + 2)!
00442B3F | mov esi,eax |
00442B41 | xor ebx,ebx |
00442B43 | mov eax,dword ptr ss:[ebp-4] | Nome
00442B46 | call @LStrLen | eax = LStrLen(Nome)
00442B4B | test eax,eax |
00442B4D | jle along3x.1.442B65 |
00442B4F | mov edx,1 |
00442B54 | mov ecx,dword ptr ss:[ebp-4] | *Nome[i]
00442B57 | movzx ecx,byte ptr ds:[ecx+edx-1] |
00442B5C | imul ecx,esi |
00442B5F | add ebx,ecx | ebx += 阶乘*Nome[i]
00442B61 | inc edx |
00442B62 | dec eax | eax--
00442B63 | jne along3x.1.442B54 |
00442B65 | sub ebx,dword ptr ss:[ebp-8] | ebx = ebx-Codice
00442B68 | cmp ebx,7A69 | ebx == 7A69
00442B6E | jne along3x.1.442B74 |
00442B70 | mov bl,1 | 等于 bl =1
00442B72 | jmp along3x.1.442B7A |
00442B74 | xor ebx,ebx | 不等于 ebx = 0
00442B76 | jmp along3x.1.442B7A |
......
00442B9E | ret | return ebx
另一个关键函数
00442BA0 | push ebp |
00442BA1 | mov ebp,esp |
00442BA3 | push 0 |
00442BA5 | push 0 |
00442BA7 | push 0 |
00442BA9 | push ebx |
00442BAA | push esi |
00442BAB | mov esi,edx | int(Codice)
00442BAD | mov dword ptr ss:[ebp-4],eax | Nome
......
00442BC6 | xor ebx,ebx |
00442BC8 | lea edx,dword ptr ss:[ebp-8] |
00442BCB | mov eax,esi | int(Codice)
00442BCD | call IntToStr |
00442BD2 | lea eax,dword ptr ss:[ebp-C] |
00442BD5 | mov edx,dword ptr ss:[ebp-8] | str(Codice)
00442BD8 | call @LStrLAsg | 复制了一份到 [ebp-C]
00442BDD | mov eax,dword ptr ss:[ebp-8] | str(Codice)
00442BE0 | call @LStrLen |
00442BE5 | cmp eax,5 | len(str(Codice)) > 5?
00442BE8 | jle along3x.1.442C4A |
00442BEA | mov eax,dword ptr ss:[ebp-8] | str(Codice)
00442BED | call @LStrLen |
00442BF2 | mov esi,eax | esi = len(Codice)
00442BF4 | cmp esi,1 |
00442BF7 | jl along3x.1.442C28 |
00442BF9 | lea eax,dword ptr ss:[ebp-C] | str(Codice)
00442BFC | call UniqueString | [ebp-C] = str(Codice)
00442C01 | lea eax,dword ptr ds:[eax+esi-1] | *[ebp-C][esi-1]
00442C05 | push eax |
00442C06 | mov eax,dword ptr ss:[ebp-8] | str(Codice)
00442C09 | movzx eax,byte ptr ds:[eax+esi-1] | Codice[esi-1]
00442C0E | imul eax | Codice[esi-1]平方
00442C10 | movsx eax,ax |
00442C13 | imul esi | Codice[esi-1]平方*esi
00442C15 | mov ecx,19 | Codice[esi-1]平方*esi%19
00442C1A | cdq |
00442C1B | idiv ecx |
00442C1D | add edx,41 | Codice[esi-1]平方*esi%19+41
00442C20 | pop eax |
00442C21 | mov byte ptr ds:[eax],dl | *[ebp-C][esi-1] = char(Codice[esi-1]平方*esi%19+41)
00442C23 | dec esi | esi--
00442C24 | test esi,esi |
00442C26 | jne along3x.1.442BF9 |
00442C28 | mov eax,dword ptr ss:[ebp-C] | 转换后的码
00442C2B | mov edx,dword ptr ss:[ebp-4] | Nome
00442C2E | call StrCmp |
00442C33 | jne along3x.1.442C4C |
00442C35 | mov eax,dword ptr ss:[ebp-4] | Nome
00442C38 | mov edx,dword ptr ss:[ebp-C] | 转换后的码
00442C3B | call StrCmp |
00442C40 | jne along3x.1.442C46 |
00442C42 | mov bl,1 | 相等 return 1
00442C44 | jmp along3x.1.442C4C |
00442C46 | xor ebx,ebx |
00442C48 | jmp along3x.1.442C4C |
........
00442C75 | ret |
可能纯看比较乱,逻辑就是计算输入的Codice,调试下比较方便
package main
import (
"fmt"
)
func factorial(x int) int {
if x > 0 {
return x * factorial(x-1)
} else {
return 1
}
}
func GetNome(codice string) {
if len(codice) > 5 {
// 转换为字节数组
CodiceBytes := []byte(codice)
for i := len(CodiceBytes); i > 0; i-- {
hexValue := int(CodiceBytes[i-1])
tmp := (hexValue*hexValue*i)%0x19 + 0x41
character := rune(tmp)
CodiceBytes[i-1] = byte(character)
}
// 将字节数组转换回字符串
Nome := string(CodiceBytes)
fmt.Printf("Ok按钮组合\n\tNome:%s\n\tCodice:%s\n", Nome, codice)
}
}
func GetCodice(nome string) {
if len(nome) > 5 {
sum := 0
for i := 0; i < len(nome); i++ {
sum += int(nome[i]) * factorial(int(nome[4])%7+2)
}
Codice := sum - 31337
fmt.Printf("Cancella按钮组合\n\tNome:%s\n\tCodice:%d\n", nome, Codice)
}
}
func main() {
nome := "Dawn12"
codice := "123456"
GetNome(codice)
GetCodice(nome)
}
aLoNg3x.2
目的和.1一样,和之前操作一样拉入IDR,ida和dbg
先查看三个按钮的事件,大致逻辑是,Register成功后,Register会消失,出现Again按钮,解决Again达成目的
Register按钮,成功后Nome会被锁定
00442F28 | push ebp |
......
00442F45 | lea edx,dword ptr ss:[ebp-8] |
00442F48 | mov eax,dword ptr ds:[ebx+2DC] | TPincpale.Codice
00442F4E | call TControl.GetText |
00442F53 | mov eax,dword ptr ss:[ebp-8] |
00442F56 | lea edx,dword ptr ss:[ebp-4] |
00442F59 | call @ValLong | hex(Codice)
00442F5E | mov esi,eax |
00442F60 | cmp dword ptr ss:[ebp-4],0 |
00442F64 | je along3x.2.442F9D |
00442F66 | mov eax,along3x.2.443038 | 443038:"You MUST insert a valid Long Integer Value in the Code Editor... Thank you :)"
00442F6B | call ShowMessage |
00442F70 | lea edx,dword ptr ss:[ebp-8] |
00442F73 | mov eax,dword ptr ds:[ebx+2DC] | TPincpale.Codice
00442F79 | call TControl.GetText |
00442F7E | mov eax,dword ptr ss:[ebp-8] |
00442F81 | call TWindowDesigner::SelectAll(void) |
00442F86 | mov dword ptr ds:[445830],eax | 这里有一次赋值,必须要返回1
00442F8B | mov edx,along3x.2.443090 | 0
00442F90 | mov eax,dword ptr ds:[ebx+2DC] | TPincpale.Codice
00442F96 | call TControl.SetText |
00442F9B | jmp along3x.2.44300C |
00442F9D | test esi,esi |
00442F9F | jle along3x.2.442FFB |
00442FA1 | lea edx,dword ptr ss:[ebp-8] |
00442FA4 | mov eax,dword ptr ds:[ebx+2D8] | TPincpale.Nome
00442FAA | call TControl.GetText |
00442FAF | mov ecx,dword ptr ss:[ebp-8] | Nome
00442FB2 | mov edx,esi | ValLong(Codice)
00442FB4 | mov eax,dword ptr ds:[445830] | BSS
00442FB9 | call along3x.2.4429A8 | 关键位置
00442FBE | test al,al |
00442FC0 | je along3x.2.442FF2 |
00442FC2 | xor edx,edx |
00442FC4 | mov eax,dword ptr ds:[ebx+2CC] | TPincpale.Registerz
00442FCA | call TControl.SetVisible |
00442FCF | mov dl,1 |
00442FD1 | mov eax,dword ptr ds:[ebx+2E8] | TPoncpale.Again
00442FD7 | call TControl.SetVisible |
00442FDC | xor edx,edx |
00442FDE | mov eax,dword ptr ds:[ebx+2D8] | TPincpale.Nome
00442FE4 | mov ecx,dword ptr ds:[eax] |
00442FE6 | call TControl.SetEnabled |
00442FE9 | xor eax,eax |
00442FEB | mov dword ptr ds:[445830],eax |
00442FF0 | jmp along3x.2.44300C |
......
0044302E | ret |
关键位置函数
004429A8 | push ebp |
......
004429B1 | mov dword ptr ss:[ebp-8],ecx | Nome
004429B4 | mov dword ptr ss:[ebp-4],edx | ValLong(Codice)
004429B7 | mov edi,eax | [00445830]
......
004429CF | mov eax,dword ptr ss:[ebp-8] | Nome
004429D2 | call @LStrLen |
004429D7 | cmp eax,4 | 长度大于4
004429DA | jle along3x.2.442A62 |
004429E0 | xor ebx,ebx |
004429E2 | mov eax,dword ptr ss:[ebp-8] |
004429E5 | call @LStrLen |
004429EA | test eax,eax |
004429EC | jle along3x.2.442A26 |
004429EE | mov dword ptr ss:[ebp-C],eax | [ebp-C] = len(Nome)
004429F1 | mov esi,1 |
004429F6 | mov eax,dword ptr ss:[ebp-8] |
004429F9 | call @LStrLen | eax = len(Nome)
004429FE | cmp eax,1 |
00442A01 | jl along3x.2.442A20 |
00442A03 | mov edx,dword ptr ss:[ebp-8] |
00442A06 | movzx edx,byte ptr ds:[edx+esi-1] | Nome[esi-1]
00442A0B | mov ecx,dword ptr ss:[ebp-8] |
00442A0E | movzx ecx,byte ptr ds:[ecx+eax-1] | Nome[eax-1]
00442A13 | imul edx,ecx | edx = ecx*edx
00442A16 | imul edx,edi | edx = edx*[00445830]
00442A19 | add ebx,edx | ebx += edx
00442A1B | dec eax | eax--
00442A1C | test eax,eax |
00442A1E | jne along3x.2.442A03 |
00442A20 | inc esi | esi++
00442A21 | dec dword ptr ss:[ebp-C] |
00442A24 | jne along3x.2.4429F6 |
00442A26 | mov eax,ebx |
00442A28 | cdq |
00442A29 | xor eax,edx |
00442A2B | sub eax,edx | abs32(eax)
00442A2D | mov ecx,A2C2A |
00442A32 | cdq |
00442A33 | idiv ecx |
00442A35 | mov ebx,edx | ebx = eax%A2C2A
00442A37 | mov eax,dword ptr ss:[ebp-4] | ValLong(Codice)
00442A3A | mov ecx,59 |
00442A3F | cdq |
00442A40 | idiv ecx | ValLong(Codice)/59
00442A42 | mov ecx,eax |
00442A44 | mov eax,dword ptr ss:[ebp-4] |
00442A47 | mov esi,50 |
00442A4C | cdq |
00442A4D | idiv esi |
00442A4F | add ecx,edx | +ValLong(Codice)%59
00442A51 | inc ecx | ++
00442A52 | mov dword ptr ss:[ebp-4],ecx |
00442A55 | cmp ebx,dword ptr ss:[ebp-4] | ecx==ebx
......
00442A89 | ret |
可以结合ida看下
先要使Codice小于1,成功触发一次SelectAll(00442A8C),使函数返回非0赋值给[00445830],计算才能成功进行,否则求和的ebx始终为0,无法与计算的ecx相等,没有在网上找到这个SelectAll的信息,去调试和静态看下,逻辑和刚才分析的函数差不多,也是遍历计算
看了一下Again按钮的操作似乎和Register完全一样,调用的函数也相同,操作了一下,真成了,好像真的是Again,没再多注意了,至于Cancella按钮应该是无用的,似乎会弹框"Great”,但是目标是清除按钮,也没做研究了。
注册机
package main
import (
"fmt"
)
func main() {
FakeCodie := "Dawn123" //第一次输入用于触发赋值及弹窗的的内容
Nome := "Dawn123"
if len(FakeCodie) < 5 {
print("FakeCodie 长度大于5!")
} else {
val := TestNome(FakeCodie)
ebx := GetEbx(val, Nome)
Codie := GetX(ebx)
fmt.Printf("FakeCodie: %s,Nome: %s,Codice: %d\n", FakeCodie, Nome, Codie)
}
}
//计算赋值[00445830]的值(00442A8C)
func TestNome(Nome string) int {
sum := 891
for i := 1; i < len(Nome); i++ {
sum += int(Nome[i-1]) * (int(Nome[i])%0x11 + 1)
}
if sum%29000 != 0 {
fmt.Printf("FakeCodie合法\n")
return sum % 29000
} else {
print("Wrong")
return 0
}
}
//计算根据Nome的值(004429A8)
func GetEbx(val int, nome string) int {
sum := 0
for i := 0; i < len(nome); i++ {
for j := len(nome); j > 0; j-- {
sum += val * int(nome[i]) * int(nome[j-1])
}
}
return sum % 666666
}
//逆运算解方程,求出输入的Codice
func GetX(n int) (res int) {
for x := 0; ; x++ {
if (x%80 + x/89 + 1) == n {
return x
}
}
}
Andrénalin.1
VB5程序,拉入VBDecompliner
似乎就一个事件,直接是字符串比较,输入就过了
Andrénalin.2
这个有两个事件,一个是Text2_Change,也就是Name,主要功能是 Name必须不能为空,为空不能点OK
然后直接是验证,先看了VBDec的伪代码,逻辑是
for i:=0;i<len(Name);i++{
sum+=Name[i]
}
sum *= 1234567890
str(sum)[8] = "-"
但是计算输进去不对,还是需要自己看下
00401FF0 | push ebp |
00401FF1 | mov ebp,esp |
00401FF3 | sub esp,C |
00401FF6 | push <JMP.&__vbaExceptHandler> |
00401FFB | mov eax,dword ptr fs:[0] |
00402001 | push eax |
00402002 | mov dword ptr fs:[0],esp |
00402009 | sub esp,118 |
0040200F | push ebx |
00402010 | mov ebx,dword ptr ss:[ebp+8] |
00402013 | mov eax,ebx |
00402015 | push esi |
00402016 | and ebx,FFFFFFFE |
00402019 | push edi |
0040201A | mov dword ptr ss:[ebp-C],esp |
0040201D | and eax,1 |
00402020 | mov edi,dword ptr ds:[ebx] |
00402022 | mov dword ptr ss:[ebp-8],andrénalin.2.401000 |
00402029 | push ebx |
0040202A | mov dword ptr ss:[ebp-4],eax |
0040202D | mov dword ptr ss:[ebp+8],ebx |
00402030 | call dword ptr ds:[edi+4] |
00402033 | xor esi,esi |
00402035 | push ebx |
00402036 | mov dword ptr ss:[ebp-24],esi |
00402039 | mov dword ptr ss:[ebp-34],esi |
0040203C | mov dword ptr ss:[ebp-44],esi |
0040203F | mov dword ptr ss:[ebp-54],esi |
00402042 | mov dword ptr ss:[ebp-58],esi |
00402045 | mov dword ptr ss:[ebp-5C],esi |
00402048 | mov dword ptr ss:[ebp-6C],esi |
0040204B | mov dword ptr ss:[ebp-7C],esi |
0040204E | mov dword ptr ss:[ebp-8C],esi |
00402054 | mov dword ptr ss:[ebp-9C],esi |
0040205A | mov dword ptr ss:[ebp-AC],esi |
00402060 | mov dword ptr ss:[ebp-BC],esi |
00402066 | mov dword ptr ss:[ebp-EC],esi |
0040206C | mov dword ptr ss:[ebp-108],esi |
00402072 | mov dword ptr ss:[ebp-118],esi |
00402078 | call dword ptr ds:[edi+2FC] |
0040207E | lea ecx,dword ptr ss:[ebp-5C] |
00402081 | push eax |
00402082 | push ecx |
00402083 | call dword ptr ds:[<&__vbaObjSet>] |
00402089 | mov ebx,eax |
0040208B | lea eax,dword ptr ss:[ebp-58] |
0040208E | push eax |
0040208F | push ebx |
00402090 | mov edx,dword ptr ds:[ebx] |
00402092 | call dword ptr ds:[edx+A0] |
00402098 | cmp eax,esi |
0040209A | jge andrénalin.2.4020AE |
0040209C | push A0 |
004020A1 | push andrénalin.2.401C20 |
004020A6 | push ebx |
004020A7 | push eax |
004020A8 | call dword ptr ds:[<&__vbaHresultCheckObj>] |
004020AE | mov eax,dword ptr ss:[ebp-58] |
004020B1 | mov dword ptr ss:[ebp-58],esi |
004020B4 | mov esi,dword ptr ds:[<&__vbaVarMove>] |
004020BA | lea edx,dword ptr ss:[ebp-6C] |
004020BD | lea ecx,dword ptr ss:[ebp-44] |
004020C0 | mov dword ptr ss:[ebp-64],eax |
004020C3 | mov dword ptr ss:[ebp-6C],8 |
004020CA | call esi |
004020CC | lea ecx,dword ptr ss:[ebp-5C] |
004020CF | call dword ptr ds:[<&__vbaFreeObj>] |
004020D5 | mov eax,1 |
004020DA | lea ecx,dword ptr ss:[ebp-AC] |
004020E0 | mov dword ptr ss:[ebp-A4],eax |
004020E6 | mov dword ptr ss:[ebp-B4],eax |
004020EC | lea edx,dword ptr ss:[ebp-44] |
004020EF | push ecx |
004020F0 | lea eax,dword ptr ss:[ebp-6C] |
004020F3 | mov ebx,2 |
004020F8 | push edx |
004020F9 | push eax |
004020FA | mov dword ptr ss:[ebp-AC],ebx |
00402100 | mov dword ptr ss:[ebp-BC],ebx |
00402106 | call dword ptr ds:[<&__vbaLenVar>] |
0040210C | lea ecx,dword ptr ss:[ebp-BC] |
00402112 | push eax |
00402113 | lea edx,dword ptr ss:[ebp-118] |
00402119 | push ecx |
0040211A | lea eax,dword ptr ss:[ebp-108] |
00402120 | push edx |
00402121 | lea ecx,dword ptr ss:[ebp-24] |
00402124 | push eax |
00402125 | push ecx |
00402126 | call dword ptr ds:[<&__vbaVarForInit>] |
0040212C | mov edi,dword ptr ds:[<&__vbaFreeVarList>] |
00402132 | test eax,eax |
00402134 | je andrénalin.2.4021D6 |
0040213A | lea edx,dword ptr ss:[ebp-6C] |
0040213D | lea eax,dword ptr ss:[ebp-24] |
00402140 | push edx |
00402141 | push eax |
00402142 | mov dword ptr ss:[ebp-64],1 |
00402149 | mov dword ptr ss:[ebp-6C],ebx |
0040214C | call dword ptr ds:[<&__vbaI4Var>] |
00402152 | lea ecx,dword ptr ss:[ebp-44] |
00402155 | push eax |
00402156 | lea edx,dword ptr ss:[ebp-7C] |
00402159 | push ecx |
0040215A | push edx |
0040215B | call dword ptr ds:[<&rtcMidCharVar>] |
00402161 | lea eax,dword ptr ss:[ebp-7C] |
00402164 | lea ecx,dword ptr ss:[ebp-58] |
00402167 | push eax |
00402168 | push ecx |
00402169 | call dword ptr ds:[<&__vbaStrVarVal>] |
0040216F | push eax |
00402170 | call dword ptr ds:[<&rtcAnsiValueBstr>] |
00402176 | mov word ptr ss:[ebp-B4],ax |
0040217D | lea edx,dword ptr ss:[ebp-34] |
00402180 | lea eax,dword ptr ss:[ebp-BC] |
00402186 | push edx |
00402187 | lea ecx,dword ptr ss:[ebp-8C] |
0040218D | push eax |
0040218E | push ecx |
0040218F | mov dword ptr ss:[ebp-BC],ebx |
00402195 | call dword ptr ds:[<&__vbaVarAdd>] |
0040219B | mov edx,eax |
0040219D | lea ecx,dword ptr ss:[ebp-34] |
004021A0 | call esi |
004021A2 | lea ecx,dword ptr ss:[ebp-58] |
004021A5 | call dword ptr ds:[<&__vbaFreeStr>] |
004021AB | lea edx,dword ptr ss:[ebp-7C] |
004021AE | lea eax,dword ptr ss:[ebp-6C] |
004021B1 | push edx |
004021B2 | push eax |
004021B3 | push ebx |
004021B4 | call edi |
004021B6 | add esp,C |
004021B9 | lea ecx,dword ptr ss:[ebp-118] |
004021BF | lea edx,dword ptr ss:[ebp-108] |
004021C5 | lea eax,dword ptr ss:[ebp-24] |
004021C8 | push ecx |
004021C9 | push edx |
004021CA | push eax |
004021CB | call dword ptr ds:[<&__vbaVarForNext>] |
004021D1 | jmp andrénalin.2.402132 |
004021D6 | lea ecx,dword ptr ss:[ebp-34] |
004021D9 | lea edx,dword ptr ss:[ebp-AC] |
004021DF | push ecx |
004021E0 | lea eax,dword ptr ss:[ebp-6C] |
004021E3 | push edx |
004021E4 | push eax |
004021E5 | mov dword ptr ss:[ebp-A4],499602D2 |
004021EF | mov dword ptr ss:[ebp-AC],3 |
004021F9 | call dword ptr ds:[<&__vbaVarMul>] |
004021FF | mov edx,eax |
00402201 | lea ecx,dword ptr ss:[ebp-34] |
00402204 | call esi |
00402206 | mov ebx,dword ptr ds:[<&__vbaMidStmtVar>] |
0040220C | lea ecx,dword ptr ss:[ebp-34] |
0040220F | push ecx |
00402210 | push 4 |
00402212 | lea edx,dword ptr ss:[ebp-AC] |
00402218 | push 1 |
0040221A | push edx |
0040221B | mov dword ptr ss:[ebp-A4],andrénalin.2.401C3 |
00402225 | mov dword ptr ss:[ebp-AC],8 |
0040222F | call ebx |
00402231 | lea eax,dword ptr ss:[ebp-34] |
00402234 | lea ecx,dword ptr ss:[ebp-AC] |
0040223A | push eax |
0040223B | push 9 |
0040223D | push 1 |
0040223F | push ecx |
00402240 | mov dword ptr ss:[ebp-A4],andrénalin.2.401C3 |
0040224A | mov dword ptr ss:[ebp-AC],8 |
00402254 | call ebx |
00402256 | mov eax,dword ptr ss:[ebp+8] |
00402259 | push eax |
0040225A | mov edx,dword ptr ds:[eax] |
0040225C | call dword ptr ds:[edx+304] |
00402262 | push eax |
00402263 | lea eax,dword ptr ss:[ebp-5C] |
00402266 | push eax |
00402267 | call dword ptr ds:[<&__vbaObjSet>] |
0040226D | mov ebx,eax |
0040226F | lea edx,dword ptr ss:[ebp-58] |
00402272 | push edx |
00402273 | push ebx |
00402274 | mov ecx,dword ptr ds:[ebx] |
00402276 | call dword ptr ds:[ecx+A0] |
0040227C | test eax,eax |
0040227E | jge andrénalin.2.402292 |
00402280 | push A0 |
00402285 | push andrénalin.2.401C20 |
0040228A | push ebx |
0040228B | push eax |
0040228C | call dword ptr ds:[<&__vbaHresultCheckObj>] |
00402292 | mov eax,dword ptr ss:[ebp-58] |
00402295 | lea ecx,dword ptr ss:[ebp-34] |
00402298 | mov dword ptr ss:[ebp-64],eax |
0040229B | lea eax,dword ptr ss:[ebp-6C] |
0040229E | push eax |
0040229F | push ecx |
004022A0 | mov dword ptr ss:[ebp-58],0 |
004022A7 | mov dword ptr ss:[ebp-6C],8008 |
004022AE | call dword ptr ds:[<&__vbaVarTstEq>] |
004022B4 | lea ecx,dword ptr ss:[ebp-5C] |
004022B7 | mov ebx,eax |
004022B9 | call dword ptr ds:[<&__vbaFreeObj>] |
004022BF | lea ecx,dword ptr ss:[ebp-6C] |
004022C2 | call dword ptr ds:[<&__vbaFreeVar>] |
004022C8 | test bx,bx |
004022CB | je andrénalin.2.402391 |
004022D1 | call dword ptr ds:[<&rtcBeep>] |
004022D7 | mov ebx,dword ptr ds:[<&__vbaVarDup>] |
004022DD | mov ecx,80020004 |
004022E2 | mov dword ptr ss:[ebp-94],ecx |
004022E8 | mov eax,A |
004022ED | mov dword ptr ss:[ebp-84],ecx |
004022F3 | lea edx,dword ptr ss:[ebp-BC] |
004022F9 | lea ecx,dword ptr ss:[ebp-7C] |
004022FC | mov dword ptr ss:[ebp-9C],eax |
00402302 | mov dword ptr ss:[ebp-8C],eax |
00402308 | mov dword ptr ss:[ebp-B4],andrénalin.2.401CA | 401CA8:L"RiCHTiG !"
00402312 | mov dword ptr ss:[ebp-BC],8 |
0040231C | call ebx |
0040231E | lea edx,dword ptr ss:[ebp-AC] |
00402324 | lea ecx,dword ptr ss:[ebp-6C] |
00402327 | mov dword ptr ss:[ebp-A4],andrénalin.2.401C3 |
00402331 | mov dword ptr ss:[ebp-AC],8 |
0040233B | call ebx |
0040233D | lea edx,dword ptr ss:[ebp-9C] |
00402343 | lea eax,dword ptr ss:[ebp-8C] |
00402349 | push edx |
0040234A | lea ecx,dword ptr ss:[ebp-7C] |
0040234D | push eax |
0040234E | push ecx |
0040234F | lea edx,dword ptr ss:[ebp-6C] |
00402352 | push 30 |
00402354 | push edx |
00402355 | call dword ptr ds:[<&rtcMsgBox>] |
0040235B | lea edx,dword ptr ss:[ebp-EC] |
00402361 | lea ecx,dword ptr ss:[ebp-54] |
00402364 | mov dword ptr ss:[ebp-E4],eax |
0040236A | mov dword ptr ss:[ebp-EC],3 |
00402374 | call esi |
00402376 | lea eax,dword ptr ss:[ebp-9C] |
0040237C | lea ecx,dword ptr ss:[ebp-8C] |
00402382 | push eax |
00402383 | lea edx,dword ptr ss:[ebp-7C] |
00402386 | push ecx |
00402387 | lea eax,dword ptr ss:[ebp-6C] |
0040238A | push edx |
0040238B | push eax |
0040238C | jmp andrénalin.2.402446 |
00402391 | mov ebx,dword ptr ds:[<&__vbaVarDup>] |
00402397 | mov ecx,80020004 |
0040239C | mov dword ptr ss:[ebp-94],ecx |
004023A2 | mov eax,A |
004023A7 | mov dword ptr ss:[ebp-84],ecx |
004023AD | lea edx,dword ptr ss:[ebp-BC] |
004023B3 | lea ecx,dword ptr ss:[ebp-7C] |
004023B6 | mov dword ptr ss:[ebp-9C],eax |
004023BC | mov dword ptr ss:[ebp-8C],eax |
004023C2 | mov dword ptr ss:[ebp-B4],andrénalin.2.401D9 | 401D9C:L"LEiDER Falsch ! "
004023CC | mov dword ptr ss:[ebp-BC],8 |
004023D6 | call ebx |
004023D8 | lea edx,dword ptr ss:[ebp-AC] |
004023DE | lea ecx,dword ptr ss:[ebp-6C] |
004023E1 | mov dword ptr ss:[ebp-A4],andrénalin.2.401CC | 401CC0:L"Leider Falsch! Nochmal veruschen ! Wenn Du es nicht schaffen solltest, schreib mir ! Andrenalin@gmx.net"
004023EB | mov dword ptr ss:[ebp-AC],8 |
004023F5 | call ebx |
004023F7 | lea ecx,dword ptr ss:[ebp-9C] |
004023FD | lea edx,dword ptr ss:[ebp-8C] |
00402403 | push ecx |
00402404 | lea eax,dword ptr ss:[ebp-7C] |
00402407 | push edx |
00402408 | push eax |
00402409 | lea ecx,dword ptr ss:[ebp-6C] |
0040240C | push 10 |
0040240E | push ecx |
0040240F | call dword ptr ds:[<&rtcMsgBox>] |
00402415 | lea edx,dword ptr ss:[ebp-EC] |
0040241B | lea ecx,dword ptr ss:[ebp-54] |
0040241E | mov dword ptr ss:[ebp-E4],eax |
00402424 | mov dword ptr ss:[ebp-EC],3 |
0040242E | call esi |
00402430 | lea edx,dword ptr ss:[ebp-9C] |
00402436 | lea eax,dword ptr ss:[ebp-8C] |
0040243C | push edx |
0040243D | lea ecx,dword ptr ss:[ebp-7C] |
00402440 | push eax |
00402441 | lea edx,dword ptr ss:[ebp-6C] |
00402444 | push ecx |
00402445 | push edx |
00402446 | push 4 |
00402448 | call edi |
0040244A | add esp,14 |
0040244D | mov dword ptr ss:[ebp-4],0 |
00402454 | push andrénalin.2.4024C3 |
00402459 | jmp andrénalin.2.40248F |
0040245B | lea ecx,dword ptr ss:[ebp-58] |
0040245E | call dword ptr ds:[<&__vbaFreeStr>] |
00402464 | lea ecx,dword ptr ss:[ebp-5C] |
00402467 | call dword ptr ds:[<&__vbaFreeObj>] |
0040246D | lea eax,dword ptr ss:[ebp-9C] |
00402473 | lea ecx,dword ptr ss:[ebp-8C] |
00402479 | push eax |
0040247A | lea edx,dword ptr ss:[ebp-7C] |
0040247D | push ecx |
0040247E | lea eax,dword ptr ss:[ebp-6C] |
00402481 | push edx |
00402482 | push eax |
00402483 | push 4 |
00402485 | call dword ptr ds:[<&__vbaFreeVarList>] |
0040248B | add esp,14 |
0040248E | ret |
0040248F | lea ecx,dword ptr ss:[ebp-118] |
00402495 | lea edx,dword ptr ss:[ebp-108] |
0040249B | push ecx |
0040249C | push edx |
0040249D | push 2 |
0040249F | call dword ptr ds:[<&__vbaFreeVarList>] |
004024A5 | mov esi,dword ptr ds:[<&__vbaFreeVar>] |
004024AB | add esp,C |
004024AE | lea ecx,dword ptr ss:[ebp-24] |
004024B1 | call esi |
004024B3 | lea ecx,dword ptr ss:[ebp-34] |
004024B6 | call esi |
004024B8 | lea ecx,dword ptr ss:[ebp-44] |
004024BB | call esi |
004024BD | lea ecx,dword ptr ss:[ebp-54] |
004024C0 | jmp esi |
004024C2 | ret |