首页
社区
课程
招聘
[原创][原创]逆向分析 160个CrackMe五星052
发表于: 2023-12-30 11:03 14038

[原创][原创]逆向分析 160个CrackMe五星052

2023-12-30 11:03
14038

#逆向分析 160个CrackMe 052

闲来无事,工作上有调整,等待来年安排,日常的学习还是不能松懈,好久没搞2进制了,最近正在刷pwn和CrackMe,看到了一个160集合感觉不错,刷了几周了,做了20多个了吧,也不知道哪个好,随便搞了下,感觉这5星级的还是挺有意思的,故分析发文。

160个CrackMe破解思路合集

环境:win10 x64 chs

工具:x64dbg IDA BinaryNinja

编译器:gcc

52

那些在xp上好有用的工具都不太兼容win10,魔改版的LoadPE + ImportREC 修复的exe时灵时不灵的。

还好x64dbg仅有的一个插件解决了这个问题。

x64dbg + esp定律找到OEP,使用x64dbg自带的Scylla,三下五除二搞定。

x64dbg

脱壳后的exe

第一种办法就是 IDA根据导入表MessageBox函数,交叉引用找到算法。

第二种就是通过OD或者x64dbg动态调试,弹出对话框后,暂停进程,调用栈回溯,也能找到算法函数。

这里我就不过多赘述。

直接拖入IDA,通过导入表MessageBoxA的交叉引用找到4处引用,2个函数。

第一个函数是MFC封装的MsgBox函数,根据它的交叉引用很快找到了数据处理和比较的地方。

封装的MsgBox

根据MsgBox交叉引用,找到处理函数

代码分析:

获取name和code分别保存

name + strrev(name) + ProductID(项的值) + RegisterOwner(项的值);由于是win10没有注册表项, 最终结果是 name + strrev(name) + strrev(name) + strrev(name) ;

初始化md5的state

name[-1] = 0x80 ;数据对齐64字节,存储len * 8

循环Md5Tramsform

保留state[0] 低16位,关键跳比较的就是state[0]的数据

读取code中的4个UINT

分别对 UINT[0] UINT[1];UINT[1]UINT[2];UINT[2]UINT[3] 运算

比较 UINT[0] 和 state[0] 如果相等则成功;

关键函数Encode函数

代码解读,直接c代码把

简化后的Encode

简化后其实就2步骤,根据低32位还原高32位;然后循环右移1位

Decode代码可得

验证结果

几组组NS供验证:

helloworld : 7db37660 ae4c5d05 d2783eea 1d6514f2

pediy.com : b3f21c39 e8ca4483 4146d6f6 5644545b

int __thiscall sub_4100A8(_DWORD *this, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
  const CHAR *v4; // eax
  HWND v6; // ecx
 
  v4 = lpCaption;
  if ( !lpCaption )
    v4 = (const CHAR *)*((_DWORD *)AfxGetModuleState() + 4);
  if ( this )
    v6 = (HWND)this[7];
  else
    v6 = 0;
  return MessageBoxA(v6, lpText, v4, uType);
}
int __thiscall sub_4100A8(_DWORD *this, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
  const CHAR *v4; // eax
  HWND v6; // ecx
 
  v4 = lpCaption;
  if ( !lpCaption )
    v4 = (const CHAR *)*((_DWORD *)AfxGetModuleState() + 4);
  if ( this )
    v6 = (HWND)this[7];
  else
    v6 = 0;
  return MessageBoxA(v6, lpText, v4, uType);
}
UPX0:00401C20 sub     esp, 608h
UPX0:00401C26 push    ebx
UPX0:00401C27 push    ebp
UPX0:00401C28 push    esi
UPX0:00401C29 mov     ebp, ecx
UPX0:00401C2B push    edi
UPX0:00401C2C mov     ecx, 7Dh ; '}'
UPX0:00401C31 xor     eax, eax
UPX0:00401C33 lea     edi, [esp+3Ch]
UPX0:00401C37 rep stosd
UPX0:00401C39 mov     ecx, 7Dh ; '}'
UPX0:00401C3E lea     edi, [esp+424h]
UPX0:00401C45 rep stosd
UPX0:00401C47 mov     ecx, 7Dh ; '}'
UPX0:00401C4C lea     edi, [esp+230h]
UPX0:00401C53 rep stosd
UPX0:00401C55 lea     eax, [esp+3Ch]
UPX0:00401C59 push    64h ; 'd'
UPX0:00401C5B push    eax
UPX0:00401C5C lea     ecx, [ebp+5Ch]
UPX0:00401C5F call    MfcGetText                      ;  获取Name的字符串 name = esp + 3c
UPX0:00401C64 lea     ecx, [esp+424h]
UPX0:00401C6B push    64h ; 'd'
UPX0:00401C6D push    ecx
UPX0:00401C6E lea     ecx, [ebp+0ACh]
UPX0:00401C74 call    MfcGetText                      ; 获取Code的字符串存在 esp + 0x424
UPX0:00401C79 lea     edi, [esp+3Ch]
UPX0:00401C7D or      ecx, 0FFFFFFFFh
UPX0:00401C80 xor     eax, eax
UPX0:00401C82 lea     edx, [esp+230h]
UPX0:00401C89 repne scasb
UPX0:00401C8B not     ecx                             ; 求name长度
UPX0:00401C8D sub     edi, ecx
UPX0:00401C8F mov     eax, ecx
UPX0:00401C91 mov     esi, edi
UPX0:00401C93 mov     edi, edx
UPX0:00401C95 shr     ecx, 2
UPX0:00401C98 rep movsd                               ; name复制到esp+230h
UPX0:00401C9A mov     ecx, eax
UPX0:00401C9C and     ecx, 3
UPX0:00401C9F rep movsb
UPX0:00401CA1 lea     ecx, [esp+230h]
UPX0:00401CA8 push    ecx
UPX0:00401CA9 call    __strrev                        ; 将name反转
UPX0:00401CAE lea     edi, [esp+234h]
UPX0:00401CB5 or      ecx, 0FFFFFFFFh
UPX0:00401CB8 xor     eax, eax
UPX0:00401CBA add     esp, 4
UPX0:00401CBD repne scasb
UPX0:00401CBF not     ecx                             ; 求反转后长度
UPX0:00401CC1 sub     edi, ecx
UPX0:00401CC3 lea     edx, [esp+3Ch]
UPX0:00401CC7 mov     esi, edi
UPX0:00401CC9 mov     ebx, ecx
UPX0:00401CCB mov     edi, edx
UPX0:00401CCD or      ecx, 0FFFFFFFFh
UPX0:00401CD0 repne scasb
UPX0:00401CD2 mov     ecx, ebx
UPX0:00401CD4 dec     edi
UPX0:00401CD5 shr     ecx, 2
UPX0:00401CD8 rep movsd                               ; strcat(name,strrev(name))
UPX0:00401CDA mov     ecx, ebx
UPX0:00401CDC lea     eax, [esp+18h]
UPX0:00401CE0 and     ecx, 3
UPX0:00401CE3 push    eax
UPX0:00401CE4 push    offset aSoftwareMicros          ; "SOFTWARE\\Microsoft\\Windows\\CurrentVe"...
UPX0:00401CE9 push    80000002h
UPX0:00401CEE rep movsb
UPX0:00401CF0 call    ds:RegOpenKeyA                  ; 打开注册表
UPX0:00401CF6 mov     ebx, ds:RegQueryValueExA        ; 查询ProductID
UPX0:00401CFC lea     ecx, [esp+14h]
UPX0:00401D00 lea     edx, [esp+230h]
UPX0:00401D07 push    ecx
UPX0:00401D08 mov     ecx, [esp+1Ch]
UPX0:00401D0C lea     eax, [esp+14h]
UPX0:00401D10 push    edx
UPX0:00401D11 push    eax
UPX0:00401D12 push    0
UPX0:00401D14 push    offset aProductid               ; "ProductID"
UPX0:00401D19 mov     dword ptr [esp+24h], 1
UPX0:00401D21 mov     dword ptr [esp+28h], 100h
UPX0:00401D29 push    ecx
UPX0:00401D2A call    ebx ; RegQueryValueExA          ; 查询ProductID
UPX0:00401D2C lea     edi, [esp+230h]
UPX0:00401D33 or      ecx, 0FFFFFFFFh
UPX0:00401D36 xor     eax, eax
UPX0:00401D38 lea     edx, [esp+3Ch]
UPX0:00401D3C repne scasb
UPX0:00401D3E not     ecx
UPX0:00401D40 sub     edi, ecx
UPX0:00401D42 mov     dword ptr [esp+10h], 1
UPX0:00401D4A mov     esi, edi
UPX0:00401D4C mov     edi, edx
UPX0:00401D4E mov     edx, ecx
UPX0:00401D50 or      ecx, 0FFFFFFFFh
UPX0:00401D53 repne scasb
UPX0:00401D55 mov     ecx, edx
UPX0:00401D57 dec     edi
UPX0:00401D58 shr     ecx, 2
UPX0:00401D5B rep movsd                               ; 将查询的字符串strcat到name
UPX0:00401D5D mov     ecx, edx
UPX0:00401D5F lea     eax, [esp+14h]
UPX0:00401D63 and     ecx, 3
UPX0:00401D66 push    eax
UPX0:00401D67 mov     eax, [esp+1Ch]
UPX0:00401D6B lea     edx, [esp+14h]
UPX0:00401D6F rep movsb
UPX0:00401D71 lea     ecx, [esp+234h]
UPX0:00401D78 mov     dword ptr [esp+18h], 100h
UPX0:00401D80 push    ecx
UPX0:00401D81 push    edx
UPX0:00401D82 push    0
UPX0:00401D84 push    offset aRegisteredowne          ; "RegisteredOwner"
UPX0:00401D89 push    eax
UPX0:00401D8A call    ebx ; RegQueryValueExA          ; 查询RegisteredOwner
UPX0:00401D8C lea     edi, [esp+230h]
UPX0:00401D93 or      ecx, 0FFFFFFFFh
UPX0:00401D96 xor     eax, eax
UPX0:00401D98 lea     edx, [esp+3Ch]
UPX0:00401D9C repne scasb
UPX0:00401D9E not     ecx                             ; 求注册表查询字符串长度
UPX0:00401DA0 sub     edi, ecx
UPX0:00401DA2 mov     esi, edi
UPX0:00401DA4 mov     ebx, ecx
UPX0:00401DA6 mov     edi, edx
UPX0:00401DA8 or      ecx, 0FFFFFFFFh
UPX0:00401DAB repne scasb
UPX0:00401DAD mov     ecx, ebx
UPX0:00401DAF dec     edi
UPX0:00401DB0 shr     ecx, 2
UPX0:00401DB3 rep movsd
UPX0:00401DB5 mov     ecx, ebx
UPX0:00401DB7 and     ecx, 3
UPX0:00401DBA rep movsb                               ; 将查询的字符串strcat到name
UPX0:00401DBC lea     edi, [esp+3Ch]                  ; 由于win10缺少这几个注册表项,其得到的name= name + strrev(name) +strrev(name) + strrev(name)
UPX0:00401DC0 or      ecx, 0FFFFFFFFh                 ; 如果xp下应该是 name + strrev(name) + ProducID(查询得到字符串) + RegisterOwner(查询的字符串)
UPX0:00401DC3 repne scasb
UPX0:00401DC5 not     ecx                             ; 求组合后的长度
UPX0:00401DC7 lea     eax, [esp+2Ch]
UPX0:00401DCB dec     ecx
UPX0:00401DCC push    eax
UPX0:00401DCD mov     esi, ecx
UPX0:00401DCF call    Md5InitState                    ; 初始化md5的4个state
UPX0:00401DD4 lea     edx, [esp+esi+40h]
UPX0:00401DD8 mov     ecx, 13h
UPX0:00401DDD xor     eax, eax
UPX0:00401DDF mov     edi, edx
UPX0:00401DE1 rep stosd                               ; 清空name后面19 * 4 字节
UPX0:00401DE3 add     esp, 4
UPX0:00401DE6 inc     esi
UPX0:00401DE7 stosw
UPX0:00401DE9 mov     ecx, esi
UPX0:00401DEB stosb
UPX0:00401DEC and     ecx, 3Fh                        ; 对齐数据64
UPX0:00401DEF mov     eax, 40h ; '@'                  ; 对齐数据64
UPX0:00401DF4 sub     eax, ecx                        ; 对齐数据64
UPX0:00401DF6 mov     byte ptr [edx], 80h ; '€'       ; name最后结尾赋值0x80
UPX0:00401DF9 cmp     eax, 7                          ; 对齐数据64
UPX0:00401DFC jg      short loc_401E01
UPX0:00401DFE add     eax, 40h ; '@'                  ; 对齐数据64
UPX0:00401E01
UPX0:00401E01 loc_401E01:                             ; CODE XREF: UPX0:00401DFC↑j
UPX0:00401E01 add     esi, eax
UPX0:00401E03 lea     edi, [esp+3Ch]
UPX0:00401E07 or      ecx, 0FFFFFFFFh
UPX0:00401E0A xor     eax, eax
UPX0:00401E0C repne scasb
UPX0:00401E0E not     ecx
UPX0:00401E10 dec     ecx
UPX0:00401E11 xor     edi, edi
UPX0:00401E13 shl     ecx, 3                          ; 长度*8
UPX0:00401E16 test    esi, esi
UPX0:00401E18 mov     [esp+esi+34h], ecx              ; 添加长度数据
UPX0:00401E1C jle     short loc_401E37
UPX0:00401E1E
UPX0:00401E1E loc_401E1E:                             ; CODE XREF: UPX0:00401E35↓j
UPX0:00401E1E lea     edx, [esp+2Ch]
UPX0:00401E22 lea     eax, [esp+edi+3Ch]
UPX0:00401E26 push    edx
UPX0:00401E27 push    eax
UPX0:00401E28 call    Md5Transform                    ; md5Transform
UPX0:00401E2D add     edi, 40h ; '@'                  ; 递增64字节
UPX0:00401E30 add     esp, 8
UPX0:00401E33 cmp     edi, esi
UPX0:00401E35 jl      short loc_401E1E                ; for(i=0;i < esi(对齐长度);i +=64)
UPX0:00401E37
UPX0:00401E37 loc_401E37:                             ; CODE XREF: UPX0:00401E1C↑j
UPX0:00401E37 mov     ebx, [esp+2Ch]
UPX0:00401E3B lea     ecx, [esp+28h]
UPX0:00401E3F lea     edx, [esp+24h]
UPX0:00401E43 push    ecx
UPX0:00401E44 lea     eax, [esp+24h]
UPX0:00401E48 push    edx
UPX0:00401E49 lea     ecx, [esp+24h]
UPX0:00401E4D push    eax
UPX0:00401E4E push    ecx
UPX0:00401E4F lea     edx, [esp+434h]                
UPX0:00401E56 and     ebx, 0FFFFh                     ; 将state[0]的高位抹去
UPX0:00401E5C push    offset aLxLxLxLx                ; "%lx%lx%lx%lx"
UPX0:00401E61 push    edx
UPX0:00401E62 mov     [esp+44h], ebx
UPX0:00401E66 call    _sscanf                         ; 从code字符串中获取4个UINT数据
UPX0:00401E6B add     esp, 18h
UPX0:00401E6E cmp     eax, 4                          ; 不够4个就报错
UPX0:00401E71 jz      short loc_401E91
UPX0:00401E73 push    30h ; '0'
UPX0:00401E75 push    offset aFailed                  ; "Failed"
UPX0:00401E7A push    offset aHmmmYouDonTEve          ; "... Hmmm, you don't even pass the first"...
UPX0:00401E7F mov     ecx, ebp
UPX0:00401E81 call    MfcMsgBox
UPX0:00401E86 pop     edi
UPX0:00401E87 pop     esi
UPX0:00401E88 pop     ebp
UPX0:00401E89 pop     ebx
UPX0:00401E8A add     esp, 608h
UPX0:00401E90 retn
UPX0:00401E91 ; ---------------------------------------------------------------------------
UPX0:00401E91
UPX0:00401E91 loc_401E91:                             ; CODE XREF: UPX0:00401E71↑j
UPX0:00401E91 xor     esi, esi
UPX0:00401E93 lea     edi, [esp+1Ch]
UPX0:00401E97
UPX0:00401E97 loc_401E97:                             ; CODE XREF: UPX0:00401EB3↓j
UPX0:00401E97 mov     eax, 0BADC0DEh                  ; for(i=0;i < 3;i++)
UPX0:00401E9C lea     ecx, [esi+50h]
UPX0:00401E9F cdq
UPX0:00401EA0 idiv    ecx                             ; loop_cnt = 0xbadc0de / (i + 80)
UPX0:00401EA2 push    eax
UPX0:00401EA3 push    edi
UPX0:00401EA4 call    Encode                          ; 算法关键:将4个UINT做3轮ENcode
UPX0:00401EA9 add     esp, 8
UPX0:00401EAC inc     esi
UPX0:00401EAD add     edi, 4
UPX0:00401EB0 cmp     esi, 3
UPX0:00401EB3 jl      short loc_401E97                ; for(i=0;i < 3;i++)
UPX0:00401EB5 xor     eax, eax
UPX0:00401EB7
UPX0:00401EB7 loc_401EB7:                             ; CODE XREF: UPX0:00401EC9↓j
UPX0:00401EB7 mov     edx, [esp+eax+1Ch]
UPX0:00401EBB mov     ecx, [esp+eax+2Ch]
UPX0:00401EBF cmp     edx, ecx
UPX0:00401EC1 jnz     short loc_401EE9
UPX0:00401EC3 add     eax, 4
UPX0:00401EC6 cmp     eax, 10h
UPX0:00401EC9 jl      short loc_401EB7
UPX0:00401ECB push    40h ; '@'
UPX0:00401ECD push    offset aWelcome                 ; "Welcome"
UPX0:00401ED2 push    offset aManYouReGoodEn          ; "... Man, you're good enough to join COR"...
UPX0:00401ED7 mov     ecx, ebp
UPX0:00401ED9 call    MfcMsgBox
UPX0:00401EDE pop     edi
UPX0:00401EDF pop     esi
UPX0:00401EE0 pop     ebp
UPX0:00401EE1 pop     ebx
UPX0:00401EE2 add     esp, 608h
UPX0:00401EE8 retn
UPX0:00401EE9 ; ---------------------------------------------------------------------------
UPX0:00401EE9
UPX0:00401EE9 loc_401EE9:                             ; CODE XREF: UPX0:00401EC1↑j
UPX0:00401EE9 push    30h ; '0'
UPX0:00401EEB push    offset aFailed                  ; "Failed"
UPX0:00401EF0 push    offset aBetterLuckNext          ; "... Better luck next time ..."
UPX0:00401EF5 mov     ecx, ebp
UPX0:00401EF7 call    MfcMsgBox
UPX0:00401EFC pop     edi
UPX0:00401EFD pop     esi
UPX0:00401EFE pop     ebp
UPX0:00401EFF pop     ebx
UPX0:00401F00 add     esp, 608h
UPX0:00401F06 retn
UPX0:00401C20 sub     esp, 608h
UPX0:00401C26 push    ebx
UPX0:00401C27 push    ebp
UPX0:00401C28 push    esi
UPX0:00401C29 mov     ebp, ecx
UPX0:00401C2B push    edi
UPX0:00401C2C mov     ecx, 7Dh ; '}'
UPX0:00401C31 xor     eax, eax
UPX0:00401C33 lea     edi, [esp+3Ch]
UPX0:00401C37 rep stosd
UPX0:00401C39 mov     ecx, 7Dh ; '}'
UPX0:00401C3E lea     edi, [esp+424h]
UPX0:00401C45 rep stosd
UPX0:00401C47 mov     ecx, 7Dh ; '}'
UPX0:00401C4C lea     edi, [esp+230h]
UPX0:00401C53 rep stosd
UPX0:00401C55 lea     eax, [esp+3Ch]
UPX0:00401C59 push    64h ; 'd'
UPX0:00401C5B push    eax
UPX0:00401C5C lea     ecx, [ebp+5Ch]
UPX0:00401C5F call    MfcGetText                      ;  获取Name的字符串 name = esp + 3c
UPX0:00401C64 lea     ecx, [esp+424h]
UPX0:00401C6B push    64h ; 'd'
UPX0:00401C6D push    ecx
UPX0:00401C6E lea     ecx, [ebp+0ACh]
UPX0:00401C74 call    MfcGetText                      ; 获取Code的字符串存在 esp + 0x424
UPX0:00401C79 lea     edi, [esp+3Ch]
UPX0:00401C7D or      ecx, 0FFFFFFFFh
UPX0:00401C80 xor     eax, eax
UPX0:00401C82 lea     edx, [esp+230h]
UPX0:00401C89 repne scasb
UPX0:00401C8B not     ecx                             ; 求name长度
UPX0:00401C8D sub     edi, ecx
UPX0:00401C8F mov     eax, ecx
UPX0:00401C91 mov     esi, edi
UPX0:00401C93 mov     edi, edx
UPX0:00401C95 shr     ecx, 2
UPX0:00401C98 rep movsd                               ; name复制到esp+230h
UPX0:00401C9A mov     ecx, eax
UPX0:00401C9C and     ecx, 3
UPX0:00401C9F rep movsb
UPX0:00401CA1 lea     ecx, [esp+230h]
UPX0:00401CA8 push    ecx
UPX0:00401CA9 call    __strrev                        ; 将name反转
UPX0:00401CAE lea     edi, [esp+234h]
UPX0:00401CB5 or      ecx, 0FFFFFFFFh
UPX0:00401CB8 xor     eax, eax
UPX0:00401CBA add     esp, 4
UPX0:00401CBD repne scasb
UPX0:00401CBF not     ecx                             ; 求反转后长度
UPX0:00401CC1 sub     edi, ecx
UPX0:00401CC3 lea     edx, [esp+3Ch]
UPX0:00401CC7 mov     esi, edi
UPX0:00401CC9 mov     ebx, ecx
UPX0:00401CCB mov     edi, edx
UPX0:00401CCD or      ecx, 0FFFFFFFFh
UPX0:00401CD0 repne scasb
UPX0:00401CD2 mov     ecx, ebx
UPX0:00401CD4 dec     edi
UPX0:00401CD5 shr     ecx, 2
UPX0:00401CD8 rep movsd                               ; strcat(name,strrev(name))
UPX0:00401CDA mov     ecx, ebx
UPX0:00401CDC lea     eax, [esp+18h]
UPX0:00401CE0 and     ecx, 3
UPX0:00401CE3 push    eax
UPX0:00401CE4 push    offset aSoftwareMicros          ; "SOFTWARE\\Microsoft\\Windows\\CurrentVe"...
UPX0:00401CE9 push    80000002h
UPX0:00401CEE rep movsb
UPX0:00401CF0 call    ds:RegOpenKeyA                  ; 打开注册表
UPX0:00401CF6 mov     ebx, ds:RegQueryValueExA        ; 查询ProductID
UPX0:00401CFC lea     ecx, [esp+14h]
UPX0:00401D00 lea     edx, [esp+230h]
UPX0:00401D07 push    ecx
UPX0:00401D08 mov     ecx, [esp+1Ch]
UPX0:00401D0C lea     eax, [esp+14h]
UPX0:00401D10 push    edx
UPX0:00401D11 push    eax
UPX0:00401D12 push    0
UPX0:00401D14 push    offset aProductid               ; "ProductID"
UPX0:00401D19 mov     dword ptr [esp+24h], 1
UPX0:00401D21 mov     dword ptr [esp+28h], 100h
UPX0:00401D29 push    ecx
UPX0:00401D2A call    ebx ; RegQueryValueExA          ; 查询ProductID
UPX0:00401D2C lea     edi, [esp+230h]
UPX0:00401D33 or      ecx, 0FFFFFFFFh
UPX0:00401D36 xor     eax, eax
UPX0:00401D38 lea     edx, [esp+3Ch]
UPX0:00401D3C repne scasb
UPX0:00401D3E not     ecx
UPX0:00401D40 sub     edi, ecx
UPX0:00401D42 mov     dword ptr [esp+10h], 1
UPX0:00401D4A mov     esi, edi
UPX0:00401D4C mov     edi, edx
UPX0:00401D4E mov     edx, ecx
UPX0:00401D50 or      ecx, 0FFFFFFFFh
UPX0:00401D53 repne scasb
UPX0:00401D55 mov     ecx, edx
UPX0:00401D57 dec     edi
UPX0:00401D58 shr     ecx, 2
UPX0:00401D5B rep movsd                               ; 将查询的字符串strcat到name
UPX0:00401D5D mov     ecx, edx
UPX0:00401D5F lea     eax, [esp+14h]
UPX0:00401D63 and     ecx, 3
UPX0:00401D66 push    eax
UPX0:00401D67 mov     eax, [esp+1Ch]
UPX0:00401D6B lea     edx, [esp+14h]
UPX0:00401D6F rep movsb
UPX0:00401D71 lea     ecx, [esp+234h]
UPX0:00401D78 mov     dword ptr [esp+18h], 100h
UPX0:00401D80 push    ecx
UPX0:00401D81 push    edx
UPX0:00401D82 push    0
UPX0:00401D84 push    offset aRegisteredowne          ; "RegisteredOwner"
UPX0:00401D89 push    eax
UPX0:00401D8A call    ebx ; RegQueryValueExA          ; 查询RegisteredOwner
UPX0:00401D8C lea     edi, [esp+230h]
UPX0:00401D93 or      ecx, 0FFFFFFFFh
UPX0:00401D96 xor     eax, eax
UPX0:00401D98 lea     edx, [esp+3Ch]
UPX0:00401D9C repne scasb
UPX0:00401D9E not     ecx                             ; 求注册表查询字符串长度
UPX0:00401DA0 sub     edi, ecx
UPX0:00401DA2 mov     esi, edi
UPX0:00401DA4 mov     ebx, ecx
UPX0:00401DA6 mov     edi, edx
UPX0:00401DA8 or      ecx, 0FFFFFFFFh
UPX0:00401DAB repne scasb
UPX0:00401DAD mov     ecx, ebx
UPX0:00401DAF dec     edi
UPX0:00401DB0 shr     ecx, 2
UPX0:00401DB3 rep movsd
UPX0:00401DB5 mov     ecx, ebx
UPX0:00401DB7 and     ecx, 3
UPX0:00401DBA rep movsb                               ; 将查询的字符串strcat到name
UPX0:00401DBC lea     edi, [esp+3Ch]                  ; 由于win10缺少这几个注册表项,其得到的name= name + strrev(name) +strrev(name) + strrev(name)
UPX0:00401DC0 or      ecx, 0FFFFFFFFh                 ; 如果xp下应该是 name + strrev(name) + ProducID(查询得到字符串) + RegisterOwner(查询的字符串)
UPX0:00401DC3 repne scasb
UPX0:00401DC5 not     ecx                             ; 求组合后的长度
UPX0:00401DC7 lea     eax, [esp+2Ch]
UPX0:00401DCB dec     ecx
UPX0:00401DCC push    eax
UPX0:00401DCD mov     esi, ecx
UPX0:00401DCF call    Md5InitState                    ; 初始化md5的4个state
UPX0:00401DD4 lea     edx, [esp+esi+40h]
UPX0:00401DD8 mov     ecx, 13h
UPX0:00401DDD xor     eax, eax
UPX0:00401DDF mov     edi, edx
UPX0:00401DE1 rep stosd                               ; 清空name后面19 * 4 字节
UPX0:00401DE3 add     esp, 4
UPX0:00401DE6 inc     esi
UPX0:00401DE7 stosw
UPX0:00401DE9 mov     ecx, esi
UPX0:00401DEB stosb
UPX0:00401DEC and     ecx, 3Fh                        ; 对齐数据64
UPX0:00401DEF mov     eax, 40h ; '@'                  ; 对齐数据64
UPX0:00401DF4 sub     eax, ecx                        ; 对齐数据64
UPX0:00401DF6 mov     byte ptr [edx], 80h ; '€'       ; name最后结尾赋值0x80
UPX0:00401DF9 cmp     eax, 7                          ; 对齐数据64
UPX0:00401DFC jg      short loc_401E01
UPX0:00401DFE add     eax, 40h ; '@'                  ; 对齐数据64
UPX0:00401E01
UPX0:00401E01 loc_401E01:                             ; CODE XREF: UPX0:00401DFC↑j
UPX0:00401E01 add     esi, eax
UPX0:00401E03 lea     edi, [esp+3Ch]
UPX0:00401E07 or      ecx, 0FFFFFFFFh
UPX0:00401E0A xor     eax, eax
UPX0:00401E0C repne scasb
UPX0:00401E0E not     ecx
UPX0:00401E10 dec     ecx
UPX0:00401E11 xor     edi, edi
UPX0:00401E13 shl     ecx, 3                          ; 长度*8
UPX0:00401E16 test    esi, esi
UPX0:00401E18 mov     [esp+esi+34h], ecx              ; 添加长度数据
UPX0:00401E1C jle     short loc_401E37
UPX0:00401E1E
UPX0:00401E1E loc_401E1E:                             ; CODE XREF: UPX0:00401E35↓j
UPX0:00401E1E lea     edx, [esp+2Ch]
UPX0:00401E22 lea     eax, [esp+edi+3Ch]
UPX0:00401E26 push    edx
UPX0:00401E27 push    eax
UPX0:00401E28 call    Md5Transform                    ; md5Transform
UPX0:00401E2D add     edi, 40h ; '@'                  ; 递增64字节
UPX0:00401E30 add     esp, 8
UPX0:00401E33 cmp     edi, esi
UPX0:00401E35 jl      short loc_401E1E                ; for(i=0;i < esi(对齐长度);i +=64)
UPX0:00401E37
UPX0:00401E37 loc_401E37:                             ; CODE XREF: UPX0:00401E1C↑j
UPX0:00401E37 mov     ebx, [esp+2Ch]
UPX0:00401E3B lea     ecx, [esp+28h]
UPX0:00401E3F lea     edx, [esp+24h]
UPX0:00401E43 push    ecx
UPX0:00401E44 lea     eax, [esp+24h]
UPX0:00401E48 push    edx
UPX0:00401E49 lea     ecx, [esp+24h]
UPX0:00401E4D push    eax
UPX0:00401E4E push    ecx
UPX0:00401E4F lea     edx, [esp+434h]                
UPX0:00401E56 and     ebx, 0FFFFh                     ; 将state[0]的高位抹去
UPX0:00401E5C push    offset aLxLxLxLx                ; "%lx%lx%lx%lx"
UPX0:00401E61 push    edx
UPX0:00401E62 mov     [esp+44h], ebx
UPX0:00401E66 call    _sscanf                         ; 从code字符串中获取4个UINT数据
UPX0:00401E6B add     esp, 18h
UPX0:00401E6E cmp     eax, 4                          ; 不够4个就报错
UPX0:00401E71 jz      short loc_401E91
UPX0:00401E73 push    30h ; '0'
UPX0:00401E75 push    offset aFailed                  ; "Failed"
UPX0:00401E7A push    offset aHmmmYouDonTEve          ; "... Hmmm, you don't even pass the first"...
UPX0:00401E7F mov     ecx, ebp
UPX0:00401E81 call    MfcMsgBox
UPX0:00401E86 pop     edi
UPX0:00401E87 pop     esi
UPX0:00401E88 pop     ebp
UPX0:00401E89 pop     ebx
UPX0:00401E8A add     esp, 608h
UPX0:00401E90 retn
UPX0:00401E91 ; ---------------------------------------------------------------------------
UPX0:00401E91
UPX0:00401E91 loc_401E91:                             ; CODE XREF: UPX0:00401E71↑j
UPX0:00401E91 xor     esi, esi
UPX0:00401E93 lea     edi, [esp+1Ch]
UPX0:00401E97
UPX0:00401E97 loc_401E97:                             ; CODE XREF: UPX0:00401EB3↓j
UPX0:00401E97 mov     eax, 0BADC0DEh                  ; for(i=0;i < 3;i++)
UPX0:00401E9C lea     ecx, [esi+50h]
UPX0:00401E9F cdq
UPX0:00401EA0 idiv    ecx                             ; loop_cnt = 0xbadc0de / (i + 80)
UPX0:00401EA2 push    eax
UPX0:00401EA3 push    edi
UPX0:00401EA4 call    Encode                          ; 算法关键:将4个UINT做3轮ENcode
UPX0:00401EA9 add     esp, 8
UPX0:00401EAC inc     esi
UPX0:00401EAD add     edi, 4
UPX0:00401EB0 cmp     esi, 3
UPX0:00401EB3 jl      short loc_401E97                ; for(i=0;i < 3;i++)
UPX0:00401EB5 xor     eax, eax
UPX0:00401EB7
UPX0:00401EB7 loc_401EB7:                             ; CODE XREF: UPX0:00401EC9↓j
UPX0:00401EB7 mov     edx, [esp+eax+1Ch]
UPX0:00401EBB mov     ecx, [esp+eax+2Ch]
UPX0:00401EBF cmp     edx, ecx
UPX0:00401EC1 jnz     short loc_401EE9
UPX0:00401EC3 add     eax, 4
UPX0:00401EC6 cmp     eax, 10h
UPX0:00401EC9 jl      short loc_401EB7
UPX0:00401ECB push    40h ; '@'
UPX0:00401ECD push    offset aWelcome                 ; "Welcome"
UPX0:00401ED2 push    offset aManYouReGoodEn          ; "... Man, you're good enough to join COR"...
UPX0:00401ED7 mov     ecx, ebp
UPX0:00401ED9 call    MfcMsgBox
UPX0:00401EDE pop     edi
UPX0:00401EDF pop     esi
UPX0:00401EE0 pop     ebp
UPX0:00401EE1 pop     ebx
UPX0:00401EE2 add     esp, 608h
UPX0:00401EE8 retn
UPX0:00401EE9 ; ---------------------------------------------------------------------------
UPX0:00401EE9
UPX0:00401EE9 loc_401EE9:                             ; CODE XREF: UPX0:00401EC1↑j
UPX0:00401EE9 push    30h ; '0'
UPX0:00401EEB push    offset aFailed                  ; "Failed"
UPX0:00401EF0 push    offset aBetterLuckNext          ; "... Better luck next time ..."
UPX0:00401EF5 mov     ecx, ebp
UPX0:00401EF7 call    MfcMsgBox
UPX0:00401EFC pop     edi
UPX0:00401EFD pop     esi
UPX0:00401EFE pop     ebp
UPX0:00401EFF pop     ebx
UPX0:00401F00 add     esp, 608h
UPX0:00401F06 retn
UPX0:00401B90 Encode proc near                        ; CODE XREF: UPX0:00401EA4↓p
UPX0:00401B90
UPX0:00401B90 arg_0= dword ptr  4
UPX0:00401B90 arg_4= dword ptr  8
UPX0:00401B90
UPX0:00401B90 mov     eax, [esp+arg_0]
UPX0:00401B94 push    ebx
UPX0:00401B95 mov     ebx, [esp+4+arg_4]
UPX0:00401B99 push    esi
UPX0:00401B9A mov     esi, [eax]
UPX0:00401B9C push    edi
UPX0:00401B9D mov     edi, [eax+4]
UPX0:00401BA0 test    ebx, ebx
UPX0:00401BA2 jbe     short loc_401C15
UPX0:00401BA4 push    ebp                             ; edi = 32位UINT
UPX0:00401BA4                                         ; esi = 32位UINT
UPX0:00401BA5
UPX0:00401BA5 loc_401BA5:                             ; CODE XREF: Encode+7E↓j
UPX0:00401BA5 mov     ebp, edi                        ; for(i=0;i<loop_cnt;i++)
UPX0:00401BA5                                         ; 第一步就是实现2个UINT的循环左移1
UPX0:00401BA7 mov     ecx, 1
UPX0:00401BAC shr     ebp, 1Fh
UPX0:00401BAF mov     [esp+10h+arg_4], ebp            ; 取高32位最高位,保存一下
UPX0:00401BB3 mov     eax, esi
UPX0:00401BB5 mov     edx, edi
UPX0:00401BB7 xor     ebp, ebp
UPX0:00401BB9 call    __allshl                        ; 2个UINT实现左移1
UPX0:00401BBE mov     ecx, [esp+10h+arg_4]            ; 再将保存的的高32位的最高一位给低32位的最低位,实现循环左移
UPX0:00401BC2 or      ebp, edx
UPX0:00401BC4 or      ecx, eax
UPX0:00401BC6 xor     edx, edx
UPX0:00401BC8 mov     esi, ecx                        ; 循环左移结束
UPX0:00401BCA mov     ecx, 0Bh                        ; 后面就是取低32位的第2 13 31位做亦或
UPX0:00401BCF mov     eax, esi
UPX0:00401BD1 mov     edi, ebp
UPX0:00401BD3 and     eax, 4                          ; 取低32位数据 2
UPX0:00401BD6 call    __allshl                        ; 循环做移动1111 + 2 = 13
UPX0:00401BDB mov     ecx, esi
UPX0:00401BDD xor     ebp, ebp
UPX0:00401BDF and     ecx, 2000h                      ; 取低32位数据 13
UPX0:00401BE5 xor     edx, ebp
UPX0:00401BE7 xor     eax, ecx                        ; 然后 亦或
UPX0:00401BE9 mov     ecx, 12h                        ; 循环做移动18位  13 + 18 = 31
UPX0:00401BEE call    __allshl
UPX0:00401BF3 mov     ecx, esi
UPX0:00401BF5 xor     edx, ebp
UPX0:00401BF7 and     ecx, 80000000h                  ; 取低32位数据 31
UPX0:00401BFD xor     eax, ecx                        ; eax = eax ^ 31位的值
UPX0:00401BFF mov     ecx, 1
UPX0:00401C04 call    __allshl                        ; 左移动一位将,亦或结果存入edx
UPX0:00401C09 xor     esi, eax                        ; eax 不管是0还是0x8000000左移1位后总是0
UPX0:00401C0B xor     edi, edx                        ; 高32位的最后一位和亦或结果做亦或
UPX0:00401C0D dec     ebx
UPX0:00401C0E jnz     short loc_401BA5                ; for(i=0;i<loop_cnt;i++)
UPX0:00401C0E                                         ; 第一步就是实现2个UINT的循环左移1
UPX0:00401C10 mov     eax, [esp+10h+arg_0]
UPX0:00401C14 pop     ebp
UPX0:00401C15
UPX0:00401C15 loc_401C15:                             ; CODE XREF: Encode+12↑j
UPX0:00401C15 mov     [eax], esi
UPX0:00401C17 mov     [eax+4], edi
UPX0:00401C1A pop     edi
UPX0:00401C1B pop     esi
UPX0:00401C1C pop     ebx
UPX0:00401C1D retn
UPX0:00401C1D Encode endp
UPX0:00401B90 Encode proc near                        ; CODE XREF: UPX0:00401EA4↓p
UPX0:00401B90
UPX0:00401B90 arg_0= dword ptr  4
UPX0:00401B90 arg_4= dword ptr  8
UPX0:00401B90
UPX0:00401B90 mov     eax, [esp+arg_0]
UPX0:00401B94 push    ebx
UPX0:00401B95 mov     ebx, [esp+4+arg_4]
UPX0:00401B99 push    esi
UPX0:00401B9A mov     esi, [eax]
UPX0:00401B9C push    edi
UPX0:00401B9D mov     edi, [eax+4]
UPX0:00401BA0 test    ebx, ebx
UPX0:00401BA2 jbe     short loc_401C15
UPX0:00401BA4 push    ebp                             ; edi = 32位UINT
UPX0:00401BA4                                         ; esi = 32位UINT

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 5
支持
分享
最新回复 (4)
雪    币: 3070
活跃值: (30876)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2023-12-31 22:48
1
雪    币: 1231
活跃值: (1067)
能力值: ( LV7,RANK:155 )
在线值:
发帖
回帖
粉丝
3

看到有人问,就顺便放上来了。

上传的附件:
2024-1-8 18:57
2
雪    币: 35726
活跃值: (7155)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
西班牙还有9000多个CrackMe没人分析呢。。
2024-1-8 22:35
0
雪    币: 9
活跃值: (1344)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
多谢分享
2024-3-22 10:21
0
游客
登录 | 注册 方可回帖
返回
//