吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 24523|回复: 66
收起左侧

[原创] 【160 crackme 之52 】 注册码算法分析

  [复制链接]
6767 发表于 2017-8-22 07:22
本帖最后由 6767 于 2017-12-24 21:18 编辑

160CM 里面的三个5星难度之一

052.esgis.1

UPX 0.89 - 3.xx -> Markus & Laszlo ver. [ 0.76 ] <- from file.
A classic viusal C++ programe, compiled at 1998.

Headers

长文预警
本文大概有三千个字

先上图;

SuccessfulCracked
SuccessfulCracked.png

使用linxue的脱壳机去掉packer,或者使用通用oep大法,upx主要是压缩没有加密,反正也不难。
追踪 引用字符串找到函数结点;

int __thiscall sub_401C20(void *this) {
    void *_this; // ebp@1
    unsigned int len_plus1; // kr20_4@1
    char *v3; // edi@1
    int v4; // eax@1
    int Ntimes64; // esi@3
    int ii; // edi@3
    int result; // eax@6
    signed int j; // esi@7
    unsigned int *guessPtr; // edi@7
    signed int i; // eax@9
    DWORD Type; // [sp+10h] [bp-608h]@1
    DWORD cbData; // [sp+14h] [bp-604h]@1
    HKEY phkResult; // [sp+18h] [bp-600h]@1
    int guessHex; // [sp+1Ch] [bp-5FCh]@5
    char v15; // [sp+20h] [bp-5F8h]@5
    char v16; // [sp+24h] [bp-5F4h]@5
    char v17; // [sp+28h] [bp-5F0h]@5
    int C0_FF_0[2]; // [sp+2Ch] [bp-5ECh]@1
    int v19; // [sp+34h] [bp-5E4h]@3
    char userString[500]; // [sp+3Ch] [bp-5DCh]@1
    BYTE tmp; // [sp+230h] [bp-3E8h]@1
    CHAR guessString; // [sp+424h] [bp-1F4h]@1

    _this = this;
    memset(userString, 0, sizeof(userString));
    memset(&guessString, 0, 0x1F4u);
    memset(&tmp, 0, 0x1F4u);
    getStrFromTextBox(this + 92, userString, 100);
    getStrFromTextBox(_this + 172, &guessString, 100);
    strcpy(&tmp, userString);
    _strrev(&tmp);                                // input1 reversed
    strcat(userString, &tmp);                     // normal+reversed str
    RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", &phkResult);
    Type = 1;
    cbData = 256;
    RegQueryValueExA(phkResult, "ProductID", 0, &Type, &tmp, &cbData);
    Type = 1;
    strcat(userString, &tmp);
    cbData = 256;
    RegQueryValueExA(phkResult, "RegisteredOwner", 0, &Type, &tmp, &cbData);
    strcat(userString, &tmp);                     // 1234_4321_4321_4321
    len_plus1 = strlen(userString) + 1;
    setConst_4016E0(C0_FF_0);
    memset(&userString[len_plus1 - 1], 0, 76u);
    v3 = &userString[len_plus1 + 75];
    *v3 = 0;
    v3[2] = 0;
    v4 = 64 - (len_plus1 & 0x3F);
    userString[len_plus1 - 1] = 0x80u;
    if ( v4 <= 7 )
        v4 += 64;
    Ntimes64 = v4 + len_plus1;
    ii = 0;
    for ( *(&v19 + v4 + len_plus1) = 8 * strlen(userString); ii < Ntimes64; ii += 64 )
        MD5like_401700(&userString[ii], C0_FF_0);       // MD5 like
    //
    C0_FF_0[0] = LOWORD(C0_FF_0[0]);
    if ( sscanf(&guessString, "%lx%lx%lx%lx", &guessHex, &v15, &v16, &v17) == 4 ) { // guess text like :'0x12341234 0x12341234 0x12341234 0x12341234'
        j = 0;
        guessPtr = &guessHex;
        do {
            rolN_401B90(guessPtr, 0xBADC0DE / (j++ + 0x50));
            ++guessPtr;
        } while ( j < 3 );
        i = 0;
        while ( *(&guessHex + i * 4) == C0_FF_0 ) {
            ++i;
            if ( i >= 4 )
                return msgbox_4100A8("... Man, you're good enough to join CORE! ...", "Welcome", 0x40u);
        }
        result = msgbox_4100A8("... Better luck next time ...", "Failed", 0x30u);
    } else {
        result = msgbox_4100A8("... Hmmm, you don't even pass the first threshold ...", "Failed", 0x30u);
    }
    return result;
}

主要函数就在这个block里。
内存地址:0x19ed24
inputtext1.会操作3次得到一个4倍长度的strings1(Win10注册表是空,直接复制3次),inputtext2以%lx的方式读入4个,然后调用sub_401B90循环移位N次得到一个16bytes的字符串,与strings1 的类似MD5摘要结果进行比较。

input1->(like MD5 digest)——┐
                          cmp---(Y/N)
input2->(ROL+strange+1)___」

MD5 like func

使用PEid的Krypto 插件检查算法会发现有且仅有md5算法,
地址块 :dword_41B0B0;

所有的常数(F G H I)里面的都是对的,包括UPX0:setConst_4016E0函数 sets initial magic number;
但是,怎么看这个函数都不是正常的标准md5,也没有动力去分析一个修改过的md5;
考虑到在UPX0:00401E56还and了一个0xffff,表明直接爆破md5是不可能的了;
不过可以在内存地址里得到摘要值;

对应于 "0000"的输入,摘要值是

0019ED34  |BB A2 00 00 B8 2E 9A A3  |  42 25 88 E8 70 B8 C4 9D|  ........B%..p...

这16bytes数据;

ROL strange array

这个函数是最有意思的函数;开始的时候发现它每次循环修改2 int,
c[0,1],c[1,2],c[2,3],
循环3次刚刚好全部的16bytes

查看反汇编伪代码

char *__cdecl rolN_401B90(unsigned int *ptr, int const1)
{
  char *result; // eax@1
  int cnt; // ebx@1
  unsigned int Lsi; // esi@1
  unsigned int Hdi; // edi@1
  unsigned __int64 tt0; // rax@2
  int t1; // esi@2
  int t2; // edi@2
  unsigned __int64 tt; // rax@2

  result = ptr;
  cnt = const1;
  Lsi = *ptr;
  Hdi = ptr[1];
  if ( const1 )
  {
    do
    {
      tt0 = 2 * __PAIR__(Hdi, Lsi);
      LODWORD(tt0) = ((2 * Lsi) | (Hdi >> 31)) & 4;
      t1 = tt0 | (Hdi >> 31);
      t2 = HIDWORD(tt0);
      tt = tt0 << 11;
      LODWORD(tt) = t1 & 0x2000 ^ tt;
      tt <<= 18;
      LODWORD(tt) = t1 & 0x80000000 ^ tt;
      tt *= 2i64;
      Lsi = tt ^ t1;
      Hdi = HIDWORD(tt) ^ t2;
      --cnt;//IDA监控点
    }
    while ( cnt );
    result = ptr;
  }
  *result = Lsi;
  *(result + 1) = Hdi;
  return result;
}

不好意思,研究了好久发现,这个代码是错误的,但是只有试过才大概了解到一大堆位运算在干嘛;
在这个地方卡了好久,花时间修改导出的C代码,发现是错误的计算结果;

经过汇编跟踪比较,发现伪代码错误,放弃;

用IDA dump脚本监控前几百次运行是这样的:

   ebx,         esi,     edi,  
0,00255F35,00000001,00000002,0000000200000001
1,00255F35,00000002,00000004,0000000400000002
2,00255F34,00000004,00000009,0000000900000004*
3,00255F33,00000008,00000012,0000001200000008
4,00255F32,00000010,00000024,0000002400000010
5,00255F31,00000020,00000048,0000004800000020
6,00255F30,00000040,00000090,0000009000000040
7,00255F2F,00000080,00000120,0000012000000080
8,00255F2E,00000100,00000240,0000024000000100
9,00255F2D,00000200,00000480,0000048000000200
A,00255F2C,00000400,00000900,0000090000000400
B,00255F2B,00000800,00001200,0000120000000800
C,00255F2A,00001000,00002400,0000240000001000
D,00255F29,00002000,00004801,0000480100002000*
E,00255F28,00004000,00009002,0000900200004000
Try Brute force

这里走歪了;

这个函数 接受 4 uint,运行后和md5like 的摘要比较,得到是否正确;
前面说到了,直接用导出的fake C code是不能用的,于是我们想要爆破的话,直接用汇编代码来运行就好了嘛;

这里主要写内联汇编,把rolN_401B90 函数的汇编代码提取出来,在vs2015里改写接口部分,

__declspec(naked)
char* __cdecl rolN_401B90(unsigned int *Cptr, int Cconst1) {

        //checked match original funcs
#define ptr 4
#define const1 8

        __asm {
                mov     eax, [esp + ptr]
                        push    ebx
                        mov     ebx, [esp + 4 + const1]
                        push    esi
                        mov     esi, [eax]
                        push    edi
            ...MORE...
            RETZERO:; CODE XREF : __allshl + 3j
                        xor     eax, eax
                        xor     edx, edx
                        retn
        }
#undef ptr 
#undef const1
}

运行了一个测试,发现是正确的;
于是写了一个爆破Generator function 来初始化输入值,每10000次打个log;
结果是,原始汇编代码运行1W次时间,4~5minutes,

如果要爆破完16bytes,需要集群了,emm.....
有没有土豪赞助我一车GTX1080和i7 7700K 吗

直接爆破不行,就需要分析这个汇编blocks在干嘛,这里现在看来是最最重要的

前面调试可以看到全部是位运行,既然是数学,这里使用符号传递来尝试分析;事实证明这个方法是正确的。

 ; char* __declspec(naked) __cdecl rolN_401B90(unsigned int *ptr, int const1)
 rolN_401B90     proc near               ; CODE XREF: sub_401C20+284p
 ;ptr             = dword ptr  4
 ;const1          = dword ptr  8
                 mov     eax, [esp+ptr]
                 push    ebx
                 mov     ebx, [esp+4+const1];cnt;

                 push    esi
                 mov     esi, [eax];c[0]
                 push    edi
                 mov     edi, [eax+4];c[1]

                 test    ebx, ebx
                 jbe     short loc_401C15
                 push    ebp

 loop1:                             ; CODE XREF: rolN_401B90+7Ej
                 mov     ebp, edi
                 mov     ecx, 1     ;ecx=1;
                 shr     ebp, 1Fh
                 mov     [esp+10h+const1], ebp;get c[1].bit31;
                 mov     eax, esi
                 mov     edx, edi
                 xor     ebp, ebp       ;ebp=0
                 call    __allshl;            edx,eax <<1
                 ;eax=c[0]<<1
                 ;edx=c[1]<<1|c[0]>>31;
                 mov     ecx, [esp+10h+const1];ecx=c[1]>>31
                 or      ebp, edx       ; mov ebp,edx;
                                        ;ebp=c[1]<<1 | c[0]>>31;
                 or      ecx, eax       ;ecx=c[1]>>31|(c[0]<<1);
                 xor     edx, edx       ;edx=0;
                 mov     esi, ecx       ;esi=c[1]>>31|(c[0]<<1);
                 mov     ecx, 11        ;ecx=11
                 mov     eax, esi       ;eax=c[1]>>31|(c[0]<<1);
                 mov     edi, ebp       ;edi=c[1]<<1 | c[0]>>31 ;
                 and     eax, 4         ;eax=(c[1]>>31|(c[0]<<1)) & 4;
                 call    __allshl
                 ;eax=((c[1].bit31|(c[0]<<1)) & 4)<<11
                 ;eax=((c[1]>>31  |(c[0]<<1)) & 4)<<11
                 ;eax=((c[0]<<1) & 4)<<11
                 ;eax=( c[0]&2 ) <<12
                 ;edx=0
                 mov     ecx, esi       ;ecx=c[1]>>31|(c[0]<<1)
                 xor     ebp, ebp       ;ebp=0
                 and     ecx, 2000h     ;ecx=(c[1]>>31|(c[0]<<1)) & 0x2000
                                        ;ecx=(c[0]<<1) & 0x2000 
                 xor     edx, ebp       ;NOP  ;ebp==0
                 xor     eax, ecx       ;eax=(((c[0]<<1) & 4)<<11) ^ (c[0]<<1 & 0x2000)
                                        ;eax=(    ( c[0]&2 ) <<12) ^ (c[0]<<1 & 0x2000)
                 mov     ecx, 12h       ;ecx=18;
                 call    __allshl
                 ;eax=( (( c[0]&2 ) <<12) ^ (c[0]<<1 & 0x2000)) <<  18 
                 ;edx=( (( c[0]&2 ) <<12) ^ (c[0]<<1 & 0x2000)) >>  14   Always edx==0
                 ;
                 mov     ecx, esi       ;ecx=c[1]>>31|(c[0]<<1);
                 xor     edx, ebp       ;NOP,ebp==0;
                 and     ecx, 80000000h ;ecx=c[1].bit31|(c[0]<<1) & 0x8000_0000;
                                        ;ecx=(c[0]<<1) & 0x8000_0000;
                 xor     eax, ecx       
                 ;eax=(  ((( c[0]&2 ) <<12) ^ (c[0]<<1 & 0x2000))<<18 )^( (c[0]<<1) & 0x8000_0000 )
                 mov     ecx, 1         ;ecx=1
                 call    __allshl
                 ;eax=((  ((( c[0]&2 ) <<12) ^ (c[0]<<1 & 0x2000))<<18 )^( (c[0]<<1) & 0x8000_0000 ))<<1;
                 ;edx=(  ((( c[0]&2 ) <<12) ^ (c[0]<<1 & 0x2000)) >> 14)<<1 |( (((( c[0]&2 ) <<12) ^ (c[0]<<1 & 0x2000))<<18 )^( (c[0]<<1) & 0x8000_0000 ) )>>31

                 xor     esi, eax
                ;c[0]=(c[1]>>31|(c[0]<<1))   ^(   ((((( c[0]&2 ) <<12) ^ (c[0]<<1 & 0x2000))<<18 )^( (c[0]<<1) & 0x8000_0000 ))<<1  )
                ;                           ^ ((c[0].bit1<<31 ^ c[0].bit12<<31 ^ c[0].bit30<<31 )<<1)
                ;c[0]=(c[1]>>31|(c[0]<<1)) ^ 0
                ;c[0]= c[1]>>31|(c[0]<<1)

                 xor     edi, edx
                ;c[1]=(c[1]<<1 | c[0]>>31)   ^( (  ((( c[0]&2 ) <<12) ^ (c[0]<<1 & 0x2000)) >> 14)<<1 |( (((( c[0]&2 ) <<12) ^ (c[0]<<1 & 0x2000))<<18 )^( (c[0]<<1) & 0x8000_0000 ) )>>31 )
                ;                               (        c[0].bit1<<13^  c[0].bit12<<13    )>>14  <<1
                ;c[1]=(c[1]<<1 | c[0]>>31)   ^(        0                                              |(c[0].bit1<<31 ^ c[0].bit12<<31 ^ c[0].bit30<<31 )>>31)
                ;c[1]=(c[1]<<1 | c[0]>>31)   ^(c[0].bit1 ^ c[0].bit12 ^ c[0].bit30 )
                ;c[1]=(c[1]<<1 | c[0]>>31)   ^(c[0]>>1 ^c[0]>>12 ^c[0]>>30)&1
                ;c[1]= c[1]<<1 ^ (c[0]>>31 ^c[0]>>1 ^c[0]>>12 ^c[0]>>30)&1
                 dec     ebx
                 jnz     short loop1
                 mov     eax, [esp+10h+ptr]
                 pop     ebp

 loc_401C15:                             ; CODE XREF: rolN_401B90+12j
                 mov     [eax], esi
                 mov     [eax+4], edi
                 pop     edi
                 pop     esi
                 pop     ebx
                 retn
                endp

 __allshl        proc near               ; CODE XREF: rolN_401B90+29p
                                         ; rolN_401B90+46p ...
                ; cmp     cl, 40h
                ; jnb     short RETZERO
                ; cmp     cl, 20h
                ; jnb     short MORE32
                 shld    edx, eax, cl
                 shl     eax, cl
                 retn
 ; ---------------------------------------------------------------------------
 MORE32:                                 ; CODE XREF: __allshl+8j
                 mov     edx, eax
                 xor     eax, eax
                 and     cl, 1Fh
                 shl     edx, cl
                 retn
 ; ---------------------------------------------------------------------------
 RETZERO:                                ; CODE XREF: __allshl+3j
                 xor     eax, eax
                 xor     edx, edx
                 retn
                endp

简单来说,
被操作的2个uint 会循环N次,
每次操作

c[1]=(c[1]<<1 | c[0]>>31)   ^(c[0]>>1 ^c[0]>>12 ^c[0]>>30)&1
c[0]= c[1]>>31|(c[0]<<1)

差不多就是两个uint32 相互循环移位,附加c[1]一个特殊的最低位XOR,条件是c[0]的c[0].bit1 ^ c[0].bit12 ^ c[0].bit30 的异或 ;

得到这个算法以后写了个C代码测试,验证正确,结果又尝试了爆破,嗯,在编译器O2优化下 2mins/1W 计数;
不行,这个速度太慢了,于是按照逻辑写了个纯汇编的函数,手写的主要循环体优化后只有9行汇编代码,运行速度1mins/1W 计数,还是不够快

柳暗花明又一村

算法已知是迭代的,普通不能爆破,那就只能找算法的特性/漏洞了,比如通项函数什么的。
但是,上面的C表述基本不能看出什么;
于是就画了好几个算法运行的示意图

最后就这个看出端倪了。
draft1
draft1.jpg
可以回代运算(N+1)项得到第N项;

核心是 c[0]的n项的0~30bit在c[0]的n+1项的1~31bit, c[0]n项缺少的 31bit可以从c[0]的n+1项的31,13,2和c[1]的n+1项的最低位这四个东西异或得到;

C代码表述

char* rolN_reverse(uint32_t* ptr, int cnt) {
        uint32_t n[2], n_1[2];
        n[0] = ptr[0];
        n[1] = ptr[1];
        printf("[-]Get: %X %X\n", n[0], n[1]);
        for (int i = 0; i < cnt; i++) {
                n_1[0] = (n[0] >> 1 & 0x7fffffff)|((n[1]&1 ^ n[0]>>31^ n[0]>>13^ n[0]>>2)&1)<<31;

                n_1[1] = (n[1] >> 1 &0x7fffffff )|n[0]<<31;
                n[0] = n_1[0];
                n[1] = n_1[1];
        }
        printf("[-]Rev: %X %X\n", n[0], n[1]);
        ptr[0] = n[0];
        ptr[1] = n[1];
        return ptr;
}

写了个函数验证,结果正确;

不考虑奇怪的MD5,

最后把注册机(的½)写一下就是

#define V0 0xA2BB
#define V1 0XA39A2EB8
#define V2 0XE8882542
#define V3 0X9DC4B870

#define CV0 0x255f35
#define CV1 0x24e918
#define CV2 0x2475dd

uint32_t knownArray[4] = {V0,V1,V2,V3};
        rolN_reverse(knownArray + 2, CV2 );
        rolN_reverse(knownArray + 1, CV1);
        rolN_reverse(knownArray + 0, CV0);
        for (int i = 0; i < 4; i++) {
                printf(" 0x%X", knownArray);
        }
/*
[-]Get: E8882542 9DC4B870
[-]Rev: D4787858 54130406
[-]Get: A39A2EB8 D4787858
[-]Rev: 8C0D43AF 50B025BA
[-]Get: A2BB 8C0D43AF
[-]Rev: 2C6B2A6D EF4CABB9
 input:0000
 input:0x2C6B2A6D 0xEF4CABB9 0x50B025BA 0x54130406
*/    

所以,

SuccessfulCracked

成功完成任务;

期间各种奇奇怪怪的bug和错误歧途就不再描述了。。。

Summary

  • 内联汇编,x86 asm
  • Z3符号引擎 不知道能不能用上帮助分析,手动分析汇编逻辑还是太慢了;
  • 不要一条路走到黑,比如爆破什么的。~( ̄▽ ̄)~*
  • 笔和草稿纸需常备案头,in case of something;
  • ...

欢迎大家点评/闲聊

防止乱码 egis.1.Solved.7z (593.97 KB, 下载次数: 30) 在这里

撸了一个注册机, KeyGen.zip (72.78 KB, 下载次数: 45)


这个CM.052终于完整了

点评

吼啊吼啊!  发表于 2017-8-30 14:12

免费评分

参与人数 25吾爱币 +29 热心值 +25 收起 理由
pk8900 + 1 + 1 这个已经被我彻底征服了,用了三天时间,可以参照我的帖子。
lapop + 1 + 1 我很赞同!
webmarksman + 1 + 1 谢谢@Thanks!
小_Ta + 1 + 1 谢谢@Thanks!
MaxMadcc + 1 + 1 谢谢@Thanks!
白童话 + 1 + 1 热心回复!
dryzh + 1 + 1 用心讨论,共获提升!
hackeydg + 1 + 1 热心回复!
KaQqi + 1 我很赞同!
简直舒 + 1 + 1 我很赞同!
lies2014 + 1 + 1 用心讨论,共获提升!
小俊 + 1 + 1 热心回复!
whyida + 2 + 1 热心回复!
alienhh + 1 + 1 热心回复!
paopao1637 + 1 + 1 谢谢@Thanks!
610100 + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
C0d3r1iu + 1 + 1 我很赞同!
2864095098 + 1 + 1 热心回复!
helloword121 + 1 + 1 谢谢@Thanks!
SomnusXZY + 1 + 1 热心回复!
NO_25 + 1 + 1 用心讨论,共获提升!
kissyou + 1 + 1 谢谢@Thanks!
平淡最真 + 3 + 1 用心讨论,共获提升!
Three_fish + 1 + 1 谢谢@Thanks!
zbnysjwsnd8 + 2 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

whyida 发表于 2017-9-5 11:54
楼主是否可以贴暴力测试的代码。我测试没通过,感觉是指针问题。谢谢
[C] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <stdio.h>
 
#define V0 0x12345
#define V1 0X23456
#define V2 0X41A4309F
#define V3 0X6F6A7DCB
 
#define CV0 0x255f35
#define CV1 0x24e918
#define CV2 0x2475dd
typedef unsigned __int32 uint32_t;
 int * rolN_reverse( int *Cptr,int Cconst1)
{  
/*
        uint32_t n[2], n_1[2];
        n[0] = ptr[0];
        n[1] = ptr[1];
        printf("[-]Get: %X %X\n", n[0], n[1]);
        for (int i = 0; i < cnt; i++) {
                n_1[0] = (n[0] >> 1 & 0x7fffffff)|((n[1]&1 ^ n[0]>>31^ n[0]>>13^ n[0]>>2)&1)<<31;
 
                n_1[1] = (n[1] >> 1 &0x7fffffff )|n[0]<<31;
                n[0] = n_1[0];
                n[1] = n_1[1];
        }
        printf("[-]Rev: %X %X\n", n[0], n[1]);
        ptr[0] = n[0];
        ptr[1] = n[1];
        return  ptr;
}       
*/
//        int b;
//v7=v1;
#define ptr 4
#define const1 8
        _asm  {
         
            mov     eax, [esp+ptr]
            push    ebx
            mov     ebx, [esp+const1];cnt;
            push    esi
            mov     esi, [eax];c[0]
            push    esi
            mov     edi, [eax+4];c[1]
            test    ebx, ebx
            push    ebp
        jbe     short loc_401C15
 loop1:                           
                 mov     ebp, edi
                 mov     ecx, 1    
                 shr     ebp, 1Fh
                 mov     [esp+10h+const1], ebp;
                 mov     eax, esi
                 mov     edx, edi
                 xor     ebp, ebp      
                  
                 ;call    __allshl;           
                 shld    edx, eax, cl
                 shl     eax, cl
 
                 mov     ecx, [esp+10h+const1]
                 or      ebp, edx      
                                         
                 or      ecx, eax      
                 xor     edx, edx      
                 mov     esi, ecx      
                 mov     ecx, 0Bh       
                 mov     eax, esi      
                 mov     edi, ebp      
                 and     eax, 4        
                  
                 ;call    __allshl
                 shld    edx, eax, cl
                 shl     eax, cl
 
                 mov     ecx, esi      
                 xor     ebp, ebp      
                 and     ecx, 2000h    
                                         
                 xor     edx, ebp      
                 xor     eax, ecx      
                                         
                 mov     ecx, 12h      
                  
                ;call    __allshl
                 shld    edx, eax, cl
                 shl     eax, cl
 
                 ;
                 mov     ecx, esi      
                 xor     edx, ebp      
                 and     ecx, 80000000h
                                         
                 xor     eax, ecx      
                  
                 mov     ecx, 1        
                 ;call    __allshl
                shld    edx, eax, cl
                shl     eax, cl
 
 
                 xor     esi, eax
 
 
                 xor     edi, edx
 
                 dec     ebx
                 jnz     short loop1
                 mov     eax, [esp+10h+ptr]
                 pop     ebp                        
 
         loc_401C15:                            
                 mov     [eax], esi
                 mov     [eax+4], edi
                 ;popad
                 ;pop     edi
                 ;pop     esi
                 ;pop     ebx
                 ;retn        
 
         
 
                  
        popad
                 
                 
                }
#undef ptr
#undef const1
}
 
int main()
{  
        int knownArray[4] = {V0,V1,V2,V3};
     
    rolN_reverse(knownArray + 2, CV2 );
    rolN_reverse(knownArray +1, CV1);
    rolN_reverse(knownArray +0, CV0);
     
    //for(int i = 0; i < 4; i++) {
        //       printf(" 0x%X", knownArray[i]);
        //}
         
    return 0;
}
whyida 发表于 2017-9-5 21:01
代码测试通过,谢谢楼主。
[C] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <stdio.h>
 
#define V0 0x12345
#define V1 0X23456
#define V2 0X34567
#define V3 0X45678
 
#define CV0 0x255f35
#define CV1 0x24e918
#define CV2 0x2475dd
 
typedef unsigned __int32 uint32_t;
__declspec(naked) char * rolN_reverse(  uint32_t *Cptr,int Cconst1)
{  
/*
        uint32_t n[2], n_1[2];
        n[0] = ptr[0];
        n[1] = ptr[1];
        printf("[-]Get: %X %X\n", n[0], n[1]);
        for (int i = 0; i < cnt; i++) {
                n_1[0] = (n[0] >> 1 & 0x7fffffff)|((n[1]&1 ^ n[0]>>31^ n[0]>>13^ n[0]>>2)&1)<<31;
 
                n_1[1] = (n[1] >> 1 &0x7fffffff )|n[0]<<31;
                n[0] = n_1[0];
                n[1] = n_1[1];
        }
        printf("[-]Rev: %X %X\n", n[0], n[1]);
        ptr[0] = n[0];
        ptr[1] = n[1];
        return  ptr;
}       
*/
//        int b;
//v7=v1;
#define ptr 4
#define const1 8
        _asm  {
        mov eax, [esp+ptr]
        push    ebx
        mov ebx, [esp+4+const1]
        push    esi
        mov esi, [eax]
        push    edi
        mov edi, [eax+4]
        test    ebx, ebx
        jbe short loc_401C15
        push    ebp
 
loc_401BA5:             ; CODE XREF: sub_401B90+7Ej
        mov ebp, edi
        mov ecx, 1
        shr ebp, 1Fh
        mov [esp+10h+const1], ebp
        mov eax, esi
        mov edx, edi
        xor ebp, ebp
 
                ;call   __allshl
        shld    edx, eax, cl
                shl     eax, cl
                 
        mov ecx, [esp+10h+const1]
        or  ebp, edx
        or  ecx, eax
        xor edx, edx
        mov esi, ecx
        mov ecx, 0Bh
        mov eax, esi
        mov edi, ebp
        and eax, 4
         
        ;call   __allshl
 
        shld    edx, eax, cl
                shl     eax, cl
                 
        mov ecx, esi
        xor ebp, ebp
        and ecx, 2000h
        xor edx, ebp
        xor eax, ecx
        mov ecx, 12h
         
        ;call   __allshl
 
        shld    edx, eax, cl
                shl     eax, cl
         
        mov ecx, esi
        xor edx, ebp
        and ecx, 80000000h
        xor eax, ecx
        mov ecx, 1
         
        ;call   __allshl
 
        shld    edx, eax, cl
                shl     eax, cl
         
        xor esi, eax
        xor edi, edx
        dec ebx
        jnz short loc_401BA5
        mov eax, [esp+10h+ptr]
        pop ebp
 
loc_401C15:             ; CODE XREF: sub_401B90+12j
        mov [eax], esi
        mov [eax+4], edi
        pop edi
        pop esi
        pop ebx
        retn
 
                }
#undef ptr
#undef const1
}
 
int main()
{  
        uint32_t knownArray[4] = {V0,V1,V2,V3};
     
    rolN_reverse(knownArray + 0, CV0 );
    rolN_reverse(knownArray +1, CV1);
    rolN_reverse(knownArray +2, CV2);
     
    for(int i = 0; i < 4; i++) {
            
               printf(" 0x%X", knownArray[i]);
        }
         
    return 0;
}
zbnysjwsnd8 发表于 2017-8-22 09:09
好厉害啊
对了 五星难度和问号的 哪个难度高一些?
 楼主| 6767 发表于 2017-8-22 09:15
本帖最后由 6767 于 2017-8-22 10:14 编辑
zbnysjwsnd8 发表于 2017-8-22 09:09
好厉害啊
对了 五星难度和问号的 哪个难度高一些?

你可以做做那些带问号的,给出你的评分啊
不加壳的话,难点就自我校验,暗桩,强力的混淆算法这几个了。




看了看160里面其他两个5星的,都是2000年左右写的,宏观上结构和现在这个差不多。
zbnysjwsnd8 发表于 2017-8-22 09:16
6767 发表于 2017-8-22 09:15
你可以做做那些带问号的,给出你的评分啊
不加壳的话,难点就自我校验,暗桩,强力的混淆算 ...

我做的几个带问号的注册方式都是serial的
好像都挺简单的
没有这个难(应该是我做的太少了
zbnysjwsnd8 发表于 2017-8-22 09:21
6767 发表于 2017-8-22 09:15
你可以做做那些带问号的,给出你的评分啊
不加壳的话,难点就自我校验,暗桩,强力的混淆算 ...

第90个和第132个
这个是我做的带问号的
我觉得没有楼主你玩的这个CM难
huangxu 发表于 2017-8-22 11:28
来学习一下,谢谢
ufo2273810 发表于 2017-8-22 16:10
谢谢分享。
Hmily 发表于 2017-8-22 17:55
就凭那手工图也要加个精华鼓励一下!
guaiguai 发表于 2017-8-22 18:51
来学习了
Avenshy 发表于 2017-8-22 19:26
这图画的真好
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-18 18:39

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表