lies2014 发表于 2022-10-5 03:55

新160个CrackMe 007--Reg.exe注册算法分析

本帖最后由 lies2014 于 2022-10-5 03:59 编辑

    CrackMe程序运行后输入用户名和序列号,提示重启验证。


    如何找到验证Call和真码比较简单,在这里我就不在赘述,大家可以参考以下教程:
    文字教程:https://www.bilibili.com/read/cv18424843
    视频教程:https://www.bilibili.com/video/BV1oa411z7rs

    因为代码看起来比较复杂,上面两个教程都没有对注册算法进行分析。以往我总是满足于能够爆破而不思进取,搞得自己一直没有进步,这次终于国庆节长假有点时间,而某些原因又限制了出行不敢乱跑,终于潜下心来,打算痛改前非,勇攀高峰,刀口向内,自我革命,花了一天时间做了分析,并写下了人生第一个没啥X用的注册机。
    具体的代码分析之前,先讲讲分析过程中个人的一些心得:动态调试是算法分析的一大利器,分析之前先以步过的方式大致的看一下每一个Call的参数及输出结果,有些调用很明显就能看出功能,可以跳过省下不少时间;动态分析目前Windows平台下x64dbg无疑是最好用的工具之一,而且现在很多都是64位的程序,OD已经力不从心了,而x64dbg一直在频繁的改进,我自从用了x64dbg以后就再也没有碰过OD了,早用早受益;x64dbg也有局限,这时可以结合IDA,将IDA分析的结果导出Map供x64dbg使用,可以看到x64dbg分析不出的一些信息,比如一些高级语言的函数,这也是事半功倍的;分析过程中及时做好代码注释,以前过分相信自己的记忆,分析过程中只看不记,总觉得回头看到就能想起,现实是随着年老色衰,往往是几秒前问候过的代码都觉得陌生,尤其是Call进去后的第一行代码注释,往往很多地方调用,来来回回翻看很不方便,如果有注释点击Call进去看就知道这段代码的功能了。
    以下是注册算法的主要部分:
0045C61D      lea edx,dword ptr ss:      
0045C620      mov eax,dword ptr ss:      用户名"lies2022"
0045C623      call <reg.sub_45BE3C>      计算用户名MD5(32)
0045C628      lea eax,dword ptr ss:      前一个Call返回的MD5
0045C62B      lea edx,dword ptr ss:      
0045C62E      call reg.45BEB0      MD5转字符串
0045C633      lea edx,dword ptr ss:      "f3b715cab9553c8aaff743c61562a308"
0045C636      mov eax,dword ptr ss:      到期时间"110512"
0045C639      call <reg.sub_45BE3C>      到期时间MD5
0045C63E      lea eax,dword ptr ss:      前一个Call返回的MD5
0045C641      lea edx,dword ptr ss:      
0045C644      call reg.45BEB0      MD5转字符串
0045C649      lea eax,dword ptr ss:      "316a6f4ced05edfc00f35e2699f0b762"
0045C64C      mov ecx,dword ptr ss:      
0045C64F      mov edx,dword ptr ss:      
0045C652      call <reg.@System@@LStrCat3$qqrv>      前两个MD5字符串合并
0045C657      mov eax,dword ptr ss:      "f3b715cab9553c8aaff743c61562a308316a6f4ced05edfc00f35e2699f0b762"
0045C65A      lea edx,dword ptr ss:      
0045C65D      call <reg.sub_45BE3C>      合并串MD5
0045C662      lea eax,dword ptr ss:      
0045C665      lea edx,dword ptr ss:      
0045C668      call reg.45BEB0      合并串MD5转字符串
0045C66D      lea eax,dword ptr ss:      "45a5199feb18a39980fe17a5da4dad98"
0045C670      mov edx,dword ptr ss:      
0045C673      call <reg.@System@@LStrLAsg$qqrpvpxv>      
0045C678      lea eax,dword ptr ss:      
0045C67B      push eax      
0045C67C      mov ecx,0x2      取2位
0045C681      mov edx,0x1      从第1位开始
0045C686      mov eax,dword ptr ss:      "110512"
0045C689      call <reg.Delphi_Copy_404880>      从第1位开始取2位
0045C68E      mov eax,dword ptr ss:      
0045C691      call <reg.Delphi_StrToInt_408528>      字符串转整数
0045C696      mov ebx,eax      ebx=11
0045C698      lea eax,dword ptr ss:      
0045C69B      push eax      
0045C69C      mov ecx,0x2      
0045C6A1      mov edx,0x3      
0045C6A6      mov eax,dword ptr ss:      
0045C6A9      call <reg.Delphi_Copy_404880>      
0045C6AE      mov eax,dword ptr ss:      
0045C6B1      call <reg.Delphi_StrToInt_408528>      
0045C6B6      mov esi,eax      esi=5
0045C6B8      lea eax,dword ptr ss:      
0045C6BB      push eax      
0045C6BC      mov ecx,0x2      
0045C6C1      mov edx,0x5      
0045C6C6      mov eax,dword ptr ss:      
0045C6C9      call <reg.Delphi_Copy_404880>      
0045C6CE      mov eax,dword ptr ss:      
0045C6D1      call <reg.Delphi_StrToInt_408528>      
0045C6D6      mov edi,eax      edi=12
0045C6D8      lea eax,dword ptr ss:      
0045C6DB      push eax      
0045C6DC      lea edx,dword ptr ss:      
0045C6DF      mov eax,ebx      11
0045C6E1      call reg.45C044      转二进制
0045C6E6      mov eax,dword ptr ss:      "00001011"
0045C6E9      mov ecx,0x7      
0045C6EE      mov edx,0x2      
0045C6F3      call <reg.Delphi_Copy_404880>      第2位开始取7位
0045C6F8      push dword ptr ss:      "0001011"
0045C6FB      lea eax,dword ptr ss:      
0045C6FE      push eax      
0045C6FF      lea edx,dword ptr ss:      
0045C702      mov eax,esi      5
0045C704      call reg.45C044      转二进制
0045C709      mov eax,dword ptr ss:      "00000101"
0045C70C      mov ecx,0x4      
0045C711      mov edx,0x5      
0045C716      call <reg.Delphi_Copy_404880>      第5位开始取4位
0045C71B      push dword ptr ss:      "0101"
0045C71E      lea eax,dword ptr ss:      
0045C721      push eax      
0045C722      lea edx,dword ptr ss:      
0045C725      mov eax,edi      12
0045C727      call reg.45C044      转二进制
0045C72C      mov eax,dword ptr ss:      "00001100"
0045C72F      mov ecx,0x5      
0045C734      mov edx,0x4      
0045C739      call <reg.Delphi_Copy_404880>      第4位开始取5位
0045C73E      push dword ptr ss:      "01100"
0045C741      lea eax,dword ptr ss:      
0045C744      mov edx,0x3      
0045C749      call <reg.@System@@LStrCatN$qqrv>      上面三个串合并"0001011010101100"
0045C74E      lea eax,dword ptr ss:      
0045C751      mov edx,dword ptr ss:      
0045C754      mov dl,byte ptr ds:      
0045C757      mov byte ptr ds:,dl      
0045C75A      mov byte ptr ds:,0x1      二进制串取第3位ASCII,前面插入1(0130)
0045C75D      lea edx,dword ptr ss:      ^低位1表示长度
0045C760      lea eax,dword ptr ss:      
0045C763      call <reg.@System@@PStrCpy$qqrp28System@%SmallString$iuc$255%t1>      
0045C768      lea eax,dword ptr ss:      
0045C76E      mov edx,dword ptr ss:      
0045C771      mov dl,byte ptr ds:      
0045C774      mov byte ptr ds:,dl      
0045C777      mov byte ptr ds:,0x1      二进制串取第4位ASCII,前面插入1(0131)
0045C77A      lea edx,dword ptr ss:      
0045C780      lea eax,dword ptr ss:      
0045C783      mov cl,0x2      
0045C785      call <reg.@System@@PStrNCat$qqrv>      合并上面两串(023031)
0045C78A      lea edx,dword ptr ss:      ^第1位2表示长度
0045C78D      lea eax,dword ptr ss:      
0045C793      call <reg.@System@@PStrCpy$qqrp28System@%SmallString$iuc$255%t1>      
0045C798      lea eax,dword ptr ss:      
0045C79E      mov edx,dword ptr ss:      
0045C7A1      mov dl,byte ptr ds:      
0045C7A4      mov byte ptr ds:,dl      二进制串取第5位ASCII,前面插入1(0130)
0045C7A7      mov byte ptr ds:,0x1      
0045C7AA      lea edx,dword ptr ss:      
0045C7B0      lea eax,dword ptr ss:      
0045C7B6      mov cl,0x3      
0045C7B8      call <reg.@System@@PStrNCat$qqrv>      
0045C7BD      lea edx,dword ptr ss:      
0045C7C3      lea eax,dword ptr ss:      
0045C7C9      call <reg.@System@@PStrCpy$qqrp28System@%SmallString$iuc$255%t1>      
0045C7CE      lea eax,dword ptr ss:      
0045C7D4      mov edx,dword ptr ss:      
0045C7D7      mov dl,byte ptr ds:      二进制串第9位
0045C7DA      mov byte ptr ds:,dl      
0045C7DD      mov byte ptr ds:,0x1      
0045C7E0      lea edx,dword ptr ss:      
0045C7E6      lea eax,dword ptr ss:      
0045C7EC      mov cl,0x4      
0045C7EE      call <reg.@System@@PStrNCat$qqrv>      
0045C7F3      lea edx,dword ptr ss:      
0045C7F9      lea eax,dword ptr ss:      
0045C7FF      call <reg.@System@@PStrCpy$qqrp28System@%SmallString$iuc$255%t1>      
0045C804      lea eax,dword ptr ss:      
0045C80A      mov edx,dword ptr ss:      
0045C80D      mov dl,byte ptr ds:      二进制串第10位
0045C810      mov byte ptr ds:,dl      
0045C813      mov byte ptr ds:,0x1      
0045C816      lea edx,dword ptr ss:      
0045C81C      lea eax,dword ptr ss:      
0045C822      mov cl,0x5      
0045C824      call <reg.@System@@PStrNCat$qqrv>      
0045C829      lea edx,dword ptr ss:      
0045C82F      lea eax,dword ptr ss:      
0045C835      call <reg.@System@@PStrCpy$qqrp28System@%SmallString$iuc$255%t1>      
0045C83A      lea eax,dword ptr ss:      
0045C840      mov edx,dword ptr ss:      
0045C843      mov dl,byte ptr ds:      二进制串第13位
0045C846      mov byte ptr ds:,dl      
0045C849      mov byte ptr ds:,0x1      
0045C84C      lea edx,dword ptr ss:      
0045C852      lea eax,dword ptr ss:      
0045C858      mov cl,0x6      
0045C85A      call <reg.@System@@PStrNCat$qqrv>      
0045C85F      lea edx,dword ptr ss:      
0045C865      lea eax,dword ptr ss:      
0045C86B      call <reg.@System@@PStrCpy$qqrp28System@%SmallString$iuc$255%t1>      
0045C870      lea eax,dword ptr ss:      
0045C876      mov edx,dword ptr ss:      
0045C879      mov dl,byte ptr ds:      二进制串第14位
0045C87C      mov byte ptr ds:,dl      
0045C87F      mov byte ptr ds:,0x1      
0045C882      lea edx,dword ptr ss:      
0045C888      lea eax,dword ptr ss:      
0045C88E      mov cl,0x7      
0045C890      call <reg.@System@@PStrNCat$qqrv>      
0045C895      lea edx,dword ptr ss:      
0045C89B      lea eax,dword ptr ss:      
0045C8A1      call <reg.@System@@PStrCpy$qqrp28System@%SmallString$iuc$255%t1>      
0045C8A6      lea eax,dword ptr ss:      
0045C8AC      mov edx,dword ptr ss:      
0045C8AF      mov dl,byte ptr ds:      二进制串第15位
0045C8B2      mov byte ptr ds:,dl      
0045C8B5      mov byte ptr ds:,0x1      
0045C8B8      lea edx,dword ptr ss:      
0045C8BE      lea eax,dword ptr ss:      
0045C8C4      mov cl,0x8      
0045C8C6      call <reg.@System@@PStrNCat$qqrv>      上面8位合并"01010110"
0045C8CB      lea edx,dword ptr ss:      带长度的"01010110"
0045C8D1      lea eax,dword ptr ss:      
0045C8D4      call <reg.unknown_libname_76>      LStrFromPCharLen
0045C8D9      mov eax,dword ptr ss:      "01010110"
0045C8DC      call <reg.sub_45BF94>      循环读取二进制串,遇1则将剩余循环次数n做1<<n,结果累加
0045C8E1      lea ecx,dword ptr ss:      0x56
0045C8E4      mov edx,0x2      
0045C8E9      call <reg.@Sysutils@IntToHex$qqrii>      
0045C8EE      mov eax,dword ptr ss:      "56"
0045C8F1      push eax      
0045C8F2      lea eax,dword ptr ss:      
0045C8F5      mov edx,dword ptr ss:      "0001011010101100"
0045C8F8      mov dl,byte ptr ds:      
0045C8FA      mov byte ptr ds:,dl      二进制串第1位(30)
0045C8FD      mov byte ptr ds:,0x1      长度1
0045C900      lea edx,dword ptr ss:      
0045C903      lea eax,dword ptr ss:      
0045C906      call <reg.@System@@PStrCpy$qqrp28System@%SmallString$iuc$255%t1>      
0045C90B      lea eax,dword ptr ss:      
0045C911      mov edx,dword ptr ss:      
0045C914      mov dl,byte ptr ds:      
0045C917      mov byte ptr ds:,dl      二进制串第2位(30)
0045C91A      mov byte ptr ds:,0x1      
0045C91D      lea edx,dword ptr ss:      
0045C923      lea eax,dword ptr ss:      
0045C926      mov cl,0x2      
0045C928      call <reg.@System@@PStrNCat$qqrv>      合并上面两串(023031)
0045C92D      lea edx,dword ptr ss:      ^第1位2表示长度
0045C930      lea eax,dword ptr ss:      
0045C936      call <reg.@System@@PStrCpy$qqrp28System@%SmallString$iuc$255%t1>      
0045C93B      lea eax,dword ptr ss:      
0045C941      mov edx,dword ptr ss:      
0045C944      mov dl,byte ptr ds:      
0045C947      mov byte ptr ds:,dl      二进制串第6位(31)
0045C94A      mov byte ptr ds:,0x1      
0045C94D      lea edx,dword ptr ss:      
0045C953      lea eax,dword ptr ss:      
0045C959      mov cl,0x3      
0045C95B      call <reg.@System@@PStrNCat$qqrv>      
0045C960      lea edx,dword ptr ss:      
0045C966      lea eax,dword ptr ss:      
0045C96C      call <reg.@System@@PStrCpy$qqrp28System@%SmallString$iuc$255%t1>      
0045C971      lea eax,dword ptr ss:      
0045C977      mov edx,dword ptr ss:      
0045C97A      mov dl,byte ptr ds:      
0045C97D      mov byte ptr ds:,dl      二进制串第7位(31)
0045C980      mov byte ptr ds:,0x1      
0045C983      lea edx,dword ptr ss:      
0045C989      lea eax,dword ptr ss:      
0045C98F      mov cl,0x4      
0045C991      call <reg.@System@@PStrNCat$qqrv>      
0045C996      lea edx,dword ptr ss:      
0045C99C      lea eax,dword ptr ss:      
0045C9A2      call <reg.@System@@PStrCpy$qqrp28System@%SmallString$iuc$255%t1>      
0045C9A7      lea eax,dword ptr ss:      
0045C9AD      mov edx,dword ptr ss:      
0045C9B0      mov dl,byte ptr ds:      
0045C9B3      mov byte ptr ds:,dl      二进制串第8位(30)
0045C9B6      mov byte ptr ds:,0x1      
0045C9B9      lea edx,dword ptr ss:      
0045C9BF      lea eax,dword ptr ss:      
0045C9C5      mov cl,0x5      
0045C9C7      call <reg.@System@@PStrNCat$qqrv>      
0045C9CC      lea edx,dword ptr ss:      
0045C9D2      lea eax,dword ptr ss:      
0045C9D8      call <reg.@System@@PStrCpy$qqrp28System@%SmallString$iuc$255%t1>      
0045C9DD      lea eax,dword ptr ss:      
0045C9E3      mov edx,dword ptr ss:      
0045C9E6      mov dl,byte ptr ds:      
0045C9E9      mov byte ptr ds:,dl      二进制串第11位(31)
0045C9EC      mov byte ptr ds:,0x1      
0045C9EF      lea edx,dword ptr ss:      
0045C9F5      lea eax,dword ptr ss:      
0045C9FB      mov cl,0x6      
0045C9FD      call <reg.@System@@PStrNCat$qqrv>      
0045CA02      lea edx,dword ptr ss:      
0045CA08      lea eax,dword ptr ss:      
0045CA0E      call <reg.@System@@PStrCpy$qqrp28System@%SmallString$iuc$255%t1>      
0045CA13      lea eax,dword ptr ss:      
0045CA19      mov edx,dword ptr ss:      
0045CA1C      mov dl,byte ptr ds:      
0045CA1F      mov byte ptr ds:,dl      二进制串第12位(30)
0045CA22      mov byte ptr ds:,0x1      
0045CA25      lea edx,dword ptr ss:      
0045CA2B      lea eax,dword ptr ss:      
0045CA31      mov cl,0x7      
0045CA33      call <reg.@System@@PStrNCat$qqrv>      
0045CA38      lea edx,dword ptr ss:      
0045CA3E      lea eax,dword ptr ss:      
0045CA44      call <reg.@System@@PStrCpy$qqrp28System@%SmallString$iuc$255%t1>      
0045CA49      lea eax,dword ptr ss:      
0045CA4F      mov edx,dword ptr ss:      
0045CA52      mov dl,byte ptr ds:      
0045CA55      mov byte ptr ds:,dl      二进制串第16位(30)
0045CA58      mov byte ptr ds:,0x1      
0045CA5B      lea edx,dword ptr ss:      
0045CA61      lea eax,dword ptr ss:      
0045CA67      mov cl,0x8      
0045CA69      call <reg.@System@@PStrNCat$qqrv>      上面8位合并"00110100"
0045CA6E      lea edx,dword ptr ss:      带长度的"00110100"
0045CA74      lea eax,dword ptr ss:      
0045CA7A      call <reg.unknown_libname_76>      
0045CA7F      mov eax,dword ptr ss:      "00110100"
0045CA85      call <reg.sub_45BF94>      循环读取二进制串,遇1则将剩余循环次数n做1<<n,结果累加
0045CA8A      lea ecx,dword ptr ss:      0x34
0045CA90      mov edx,0x2      
0045CA95      call <reg.@Sysutils@IntToHex$qqrii>      
0045CA9A      mov edx,dword ptr ss:      "34"
0045CAA0      lea eax,dword ptr ss:      
0045CAA3      pop ecx      "56"上一次结果
0045CAA4      call <reg.@System@@LStrCat3$qqrv>      两串合并"3456"
0045CAA9      lea eax,dword ptr ss:      
0045CAAF      mov ecx,dword ptr ss:      "f3b715cab9553c8aaff743c61562a308"用户名MD5
0045CAB2      mov edx,dword ptr ss:      "3456"
0045CAB5      call <reg.@System@@LStrCat3$qqrv>      
0045CABA      mov eax,dword ptr ss:      "3456f3b715cab9553c8aaff743c61562a308"
0045CAC0      lea edx,dword ptr ss:      
0045CAC3      call <reg.sub_45C244>      将eax按位读取,与dl最后1位亦或为1则(dl^0x18)>>1||0x80,为0则dl>>1(dl初始0),结果转为16进制字符串"EA"
0045CAC8      lea eax,dword ptr ss:      
0045CACB      push eax      
0045CACC      lea eax,dword ptr ss:      
0045CAD2      mov ecx,dword ptr ss:      上个Call结果"EA"
0045CAD5      mov edx,dword ptr ss:      "3456"
0045CAD8      call <reg.@System@@LStrCat3$qqrv>      "3456"+"EA"
0045CADD      mov eax,dword ptr ss:      "3456EA"
0045CAE3      lea edx,dword ptr ss:      
0045CAE6      call <reg.sub_45BE3C>      MD5(32)
0045CAEB      lea eax,dword ptr ss:      
0045CAEE      lea edx,dword ptr ss:      
0045CAF4      call reg.45BEB0      MD5转字符串
0045CAF9      mov eax,dword ptr ss:      "6189a4059d33687fea8dfe485d4e07c8"
0045CAFF      mov ecx,0x2      
0045CB04      mov edx,0x8      
0045CB09      call <reg.Delphi_Copy_404880>      第8位开始取2位"59"
0045CB0E      lea eax,dword ptr ss:      
0045CB14      mov ecx,dword ptr ss:      "45a5199feb18a39980fe17a5da4dad98"合并串MD5
0045CB17      mov edx,dword ptr ss:      "f3b715cab9553c8aaff743c61562a308"用户名MD5
0045CB1A      call <reg.@System@@LStrCat3$qqrv>      合并前面2字符串
0045CB1F      mov eax,dword ptr ss:      "f3b715cab9553c8aaff743c61562a30845a5199feb18a39980fe17a5da4dad98"
0045CB25      lea edx,dword ptr ss:      
0045CB28      call <reg.sub_45C244>      将eax按位读取,与dl最后1位亦或为1则(dl^0x18)>>1||0x80,为0则dl>>1(dl初始0),结果转为16进制字符串"6E"
0045CB2D      lea eax,dword ptr ss:      
0045CB33      mov ecx,dword ptr ss:      "45a5199feb18a39980fe17a5da4dad98"合并串MD5
0045CB36      mov edx,dword ptr ss:      "316a6f4ced05edfc00f35e2699f0b762"到期时间MD5
0045CB39      call <reg.@System@@LStrCat3$qqrv>      
0045CB3E      mov eax,dword ptr ss:      "316a6f4ced05edfc00f35e2699f0b76245a5199feb18a39980fe17a5da4dad98"
0045CB44      lea edx,dword ptr ss:      
0045CB47      call <reg.sub_45C244>      将eax按位读取,与dl最后1位亦或为1则(dl^0x18)>>1||0x80,为0则dl>>1(dl初始0),结果转为16进制字符串"30"
0045CB4C      push dword ptr ss:      
0045CB4F      push dword ptr ss:      
0045CB52      push dword ptr ss:      
0045CB55      lea eax,dword ptr ss:      
0045CB5B      mov edx,dword ptr ss:      "45a5199feb18a39980fe17a5da4dad98"
0045CB5E      mov dl,byte ptr ds:      从第8位开始取1位(取第8位)
0045CB61      call <reg.unknown_libname_73>      LStrFromPCharLen取1位
0045CB66      push dword ptr ss:      "f"
0045CB6C      lea eax,dword ptr ss:      
0045CB72      mov edx,dword ptr ss:      
0045CB75      mov dl,byte ptr ds:      取第16位
0045CB78      call <reg.unknown_libname_73>      
0045CB7D      push dword ptr ss:      "9"
0045CB83      push dword ptr ss:      
0045CB86      lea eax,dword ptr ss:      
0045CB8C      mov edx,dword ptr ss:      
0045CB8F      mov dl,byte ptr ds:      取第24位
0045CB92      call <reg.unknown_libname_73>      
0045CB97      push dword ptr ss:      "5"
0045CB9D      lea eax,dword ptr ss:      
0045CBA3      mov edx,dword ptr ss:      
0045CBA6      mov dl,byte ptr ds:      取第12位
0045CBA9      call <reg.unknown_libname_73>      
0045CBAE      push dword ptr ss:      "8"
0045CBB4      push dword ptr ss:      "30"来自0045CB47
0045CBB7      lea eax,dword ptr ss:      
0045CBBD      mov edx,0x9      9:'\t'
0045CBC2      call <reg.@System@@LStrCatN$qqrv>      将上面数个字符连接,Call后出现真码
0045CBC7      mov eax,dword ptr ss:      "EA345659f96E5830"
0045CBCD      lea edx,dword ptr ss:      
0045CBD0      call <reg.@Sysutils@UpperCase$qqrx17System@AnsiString>      转换成大写
0045CBD5      mov eax,dword ptr ss:      
0045CBD8      mov edx,dword ptr ss:      "EA345659F96E5830"真码

    0045C62 call <reg.sub_45BE3C>这个调用是计算MD5的,实际上我并未跟进去,只是动态调试的时候看着像是MD5,用工具验证了一下确实结果一样,所以之前就说过动态调试的重要性,这些算法给源代码我都未必能看懂,何况是反汇编,如果硬磕估计会影响某些功能。
    注册算法中0045C67C-0045CAA4之间的代码尽管很长,其实就是用有效期算出一个4位字符串,而有效期是一个固定的“110512”,因此这个结果字符串也是固定的“3456”,我们在最后写注册机的时候直接使用即可,不必复现计算过程。这部分Call里面我就不详细的说明了,Call的作用我已经在代码后面注明,感兴趣的可以自己跟进去看一下。
    CrackMe是用Delphi编写的,IDA已经分析出了一些函数名,函数具体功能可以在网络上很方便的查到。
    0045CAC call <reg.sub_45C244>是对输入串做计算,输出一个2位字符串,算法如下:
0045C274      mov eax,dword ptr ss:      "3456f3b715cab9553c8aaff743c61562a308"
0045C277      call <reg.unknown_libname_78>      取长度0x24
0045C27C      and eax,0x80000001      结果0
0045C281      jns reg.45C288      
0045C283      dec eax      
0045C284      or eax,0xFFFFFFFE      
0045C287      inc eax      
0045C288      dec eax      结果-1
0045C289      jne reg.45C298      
0045C28B      lea eax,dword ptr ss:      
0045C28E      mov edx,reg.45C360      45C360:L"0"
0045C293      call <reg.@System@@LStrCat$qqrv>      
0045C298      mov eax,dword ptr ss:      "3456f3b715cab9553c8aaff743c61562a308"
0045C29B      call <reg.unknown_libname_78>      取长度0x24
0045C2A0      mov esi,eax      
0045C2A2      sar esi,0x1      结果0x12
0045C2A4      jns reg.45C2A9      
0045C2A6      adc esi,0x0      
0045C2A9      test esi,esi      
0045C2AB      jle reg.45C2F2      
0045C2AD      mov edi,0x1      
0045C2B2      lea ebx,dword ptr ss:      
0045C2B8      push 0x1F4      
0045C2BD      lea eax,dword ptr ss:      
0045C2C3      push eax      
0045C2C4      mov eax,edi      
0045C2C6      dec eax      
0045C2C7      mov edx,eax      
0045C2C9      add edx,edx      
0045C2CB      inc edx      
0045C2CC      mov ecx,0x2      
0045C2D1      mov eax,dword ptr ss:      "3456f3b715cab9553c8aaff743c61562a308"
0045C2D4      call <reg.Delphi_Copy_404880>      从edx位取2位
0045C2D9      mov eax,dword ptr ss:      取出的2位
0045C2DF      xor ecx,ecx      
0045C2E1      mov edx,0x10      
0045C2E6      call <reg.sub_45C118>      StrToInt
0045C2EB      mov byte ptr ds:,al      
0045C2ED      inc edi      
0045C2EE      inc ebx      
0045C2EF      dec esi      
0045C2F0      jne reg.45C2B8      以上循环将字符串转为数字
0045C2F2      mov eax,dword ptr ss:      "3456f3b715cab9553c8aaff743c61562a308"
0045C2F5      call <reg.unknown_libname_78>      取长度0x24
0045C2FA      sar eax,0x1      
0045C2FC      jns reg.45C301      
0045C2FE      adc eax,0x0      
0045C301      lea edx,dword ptr ss:      0x3456f3b715cab9553c8aaff743c61562a308
0045C307      mov ecx,eax      
0045C309      mov eax,0xFF      
0045C30E      xchg edx,eax      
0045C30F      call reg.45C09C      将eax按位读取,与dl最后1位亦或为1则(dl^0x18)>>1||0x80(dl初始0)
0045C314      mov ebx,eax      
0045C316      mov ecx,dword ptr ss:      
0045C319      xor eax,eax      
0045C31B      mov al,bl      
0045C31D      mov edx,0x2      
0045C322      call <reg.@Sysutils@IntToHex$qqrii>      将上面Call结果转为16进制字符串

    到这里涉及计算的部分就结束了,剩下的部分就是把前面的计算结果拼起来,生成16位字符串,最后转换成大写的序列号。
    最后写注册机,想起原来看到过一个aardio的国人开发的小巧的编程语言,早就想试试,就用他吧。于是花了半天时间学习了一下语法,敲下了总共三十行代码,边学边做平均五分钟一行的速度,是不是太笨了?不过出来的东西感觉还不错,是我喜欢的简洁明了。
    注册机代码:
function ToHex(src){
        var data = 0;
        len = string.len(src);
        for(i = 1; len; 2){
                one = tonumber('0x' + string.slice(src, i, i + 1,));
                for(j = 1; 8){
                        if((((one >> (j - 1)) & 1) ^ (data & 1)) == 1){
                                data = ((data ^ 0x18) >> 1) | 0x80;
                        }
                        else{
                                data = data >> 1;
                        }
                }       
        }
        return string.format("%02X",data);
}

mainForm.button.oncommand = function(id,event){
        if(mainForm.edit.text == ''){mainForm.edit2.text = '请输入用户名';}
        else{
        usermd5 = crypt.md5(mainForm.edit.text, 0);
        datemd5 = crypt.md5('110512', 0);
        catmd5 = crypt.md5(usermd5 + datemd5);
        Key = ToHex('3456' + usermd5);
        Key = Key + '3456' + string.slice(crypt.md5('3456' + Key), 8, 9) + string.slice(catmd5,8,8) +
       string.slice(catmd5,15,15) + ToHex(usermd5 + catmd5) + string.slice(catmd5,24,24) +
       string.slice(catmd5,12,12) + ToHex(datemd5 + catmd5);
        mainForm.edit2.text = Key;
        file = io.open('reg.dll', 'w');
        file.write('UserName=', mainForm.edit.text, '\n');
        file.write('SN=', Key, '\n');
        file.close();
        }
}
    编译好后,验证一下,注册机输入用户名,生成注册码后自动生成注册需要的reg.dll文件(其实就是个文本文件)。

    reg.dll复制到CrackMe同目录,运行CrackMe,大功告成!

    附件包含CrackMe及注册机。

Hmily 发表于 2022-10-12 16:30

搜了下关键词论坛好像不少这题的算法分析:

练习笔记之160Crackme-007
https://www.52pojie.cn/thread-1629880-1-1.html
160个crackme-007注册机编写
https://www.52pojie.cn/thread-1496557-1-1.html
160个Crackme007之分析思路和注册算法分析详解
https://www.52pojie.cn/thread-1131694-1-1.html
160 crackme 之 007
https://www.52pojie.cn/thread-1352537-1-1.html
探讨crackMe160之007中破解问题
https://www.52pojie.cn/thread-488516-1-1.html

lies2014 发表于 2022-10-12 16:57

Hmily 发表于 2022-10-12 16:30
搜了下关键词论坛好像不少这题的算法分析:

练习笔记之160Crackme-007


谢谢大大关注,新160个CrackMe是有人重新整理过的,换掉了原版160 CrackMe中的一些题目,这题就是被换掉的,和你链接里那些都不一样,应该本论坛没有人分析过,新160的题目来自这里:https://www.zhihu.com/people/wanao-meng-tian/zvideos

29565633 发表于 2022-10-7 15:47

学习了,很有帮助的{:1_918:}

戰龍在野 发表于 2022-10-7 19:23

谢谢提供分享好好学习一下

ABC9758 发表于 2022-10-8 23:00

谢谢分享,收藏备用

Junlee 发表于 2022-10-9 01:13

学习了,受益匪浅

七月上H 发表于 2022-10-9 08:22

学习了,很有帮助的

syxf88888 发表于 2022-10-10 07:15

支持一下

Hmily 发表于 2022-10-12 16:59

lies2014 发表于 2022-10-12 16:57
谢谢大大关注,新160个CrackMe是有人重新整理过的,换掉了原版160 CrackMe中的一些题目,这题就是被换掉 ...

论坛应该都是来自这里

【反汇编练习】160个CrackME索引目录1~160建议收藏备用
https://www.52pojie.cn/thread-709699-1-1.html
页: [1] 2
查看完整版本: 新160个CrackMe 007--Reg.exe注册算法分析