首页
社区
课程
招聘
[原创]Reverse crackme:作者称他自己写不出keyfile
发表于: 2008-12-8 01:39 5567

[原创]Reverse crackme:作者称他自己写不出keyfile

2008-12-8 01:39
5567
原页面
http://www.crackmes.de/users/malfunction/digital_arithmetic/

断断续续花了4天时间分析完了,XX的,对函数的处理比较全面完整,虽然简单,但是烦,很烦,分析比较麻烦,不过对跟踪的影响不极大.
本只想搞个简单的爆破,没料到卡飞了,放进killhim后前两2天还是累的时候轻松看看。
昨天稍微深入被函数压缩搞的心烦意乱,今个饭毕后暴走往完搞了.简单简单,权当练手.完整的分析了

整理分析出的东西弄个key花了2、3小时,总结出文章却搞到凌晨了,XX,该写个自动复制注释语句并合理链接的东西

在OD里面载入到函数里面比较麻烦,分析的是复制出来的一堆code,吐口气赞赞OD跳转指引和enter的好处,快刀斩乱麻这种简单的干扰
顺便,自己写code和逆向的区别在于一个是符号比标示符多,一个是标示符比符号多.

基本上每个调用都会
xchg [&API],eax;cmp byte ptr [eax], 0xcc;je over;xchg [&API],eax;
注意修改,不然卡蹦

每个proc都会处理,极度繁琐

主要有2种花
call ????;直接类似jmp修改解码流程

call ????;
qqqqq
bbbbbb
????:
call ????;
ssssssss
eeeeeeeeee
????:
call ???
前面2个call是入参用的,qqqqbbbb、ssssseeee即为call ???的参数

利用name 作为跳转表的索引,这样name错误时就执行到invalid name code了

一些cmp用sub xxx,0; add xxx,0代替

典型的编译器优化后加减法lea xxx,[yyy+-zzzz],再有很多糟蹋性能的code,自己猜测该是因为大量使用了宏处理。

进入就是乱糟糟的,loopd循环0x401000开始的0x23dd数据安装字节异或0x9a

接下来跳转到前面一点点;异或code,该是asm编的

00403376    FC              CLD
00403377    E8 88DCFFFF     CALL    digital_.00401004                ; 载入库,初始化函数

401004里面是这种格式的循环

        jmp xxxx;
return:
        dd 0x0;
address:
        dd size;
argc:
        db size dup ??;
xxxx:
        mov esi,address
        lodsd
        mov ecx,eax
        mov edi,esi;
read:
        test ecx,ecx;
        JE      finshed;
        LODS    BYTE PTR DS:[ESI]
        XOR     AL,44;address+4指定地址,size指定大小,字节异或0x44
        STOS    BYTE PTR ES:[EDI]
        DEC     ECX
        JMP     read;
finshed:
        push argc;此处是压参,而非只一个push
        xchg [&API],eax
        cmp  byte ptr [eax], 0xcc;检测int3断点
        je   over
        xchg [&API],eax
        call API
        mov  return,eax;

其中API为LoadLibraryA或GetProcAddress.参数即为argc,GetProcAddress会压入LoadLibraryA的return
over处一个rep把空间中所有数据清空,可直接把所有jmp over的跳转替换为无效指令
0x401004结束后所有GetProcAddress的return中就保存了argc中那名称API的地址
return序列即为IMT

接下来空参数调用COMDLG32.GetOpenFileNameA,这样除了设置了lasterror无任何作用

然后是USER32.DialogBoxParamA,窗口过程为40256C

最后直接ExitProcess

窗口过程中只处理
INITDIALOG
COMMAND
CLOSE 3个消息
过程分别为:
得到本进程handle、LoadIcon、SendMessage(SETICON)、GetDlgItem(NameOfkeyFile)、SendMessage(LIMITTEXT,hwnd=GetDlgItem)
单击Browse则调用0x401718;单击OK则调用0x40268f,返回值不能为FALSE(NULL),TURE则越过EndDialog;
EndDialog

0x40268f和0x401718类似,均为一个检测调试器的router
首先解码一data,然后调用一个设置返回地址为异常处理过程后除零的proc,若被调试则异常过程里面的code无法运行,即破坏了堆栈无法正常执行;后面的跳转,若ecx为0,则运行到错误的opcode,不然返回去循环解码:

0040269B    60              PUSHAD;异常和int3断点检测code开始.
00401719    BE 15194000     MOV     ESI,digital_.00401915;需被解码code的结尾地址
0040171E    B9 85010000     MOV     ECX,185;大小
00401723    8B15 9A194000   MOV     EDX,DWORD PTR DS:[40199A]
00401729    BF 94194000     MOV     EDI,digital_.00401994;此处为解码code所用数据的结尾地址
0040172E    BB 7D020000     MOV     EBX,27D;所用数据大小,
                                           ;注意大小刚好到前面那个pushad
                                           ;这样不能在这段code中下int3断点,会解出乱码
PS:把2个合在一起,只为说明二个router是类似的
004026B6    0FB607          MOVZX   EAX,BYTE PTR DS:[EDI]
004026B9    31C2            XOR     EDX,EAX
004026BB    29C2            SUB     EDX,EAX
004026BD    4F              DEC     EDI
004026BE    4B              DEC     EBX
004026BF    85DB            TEST    EBX,EBX
004026C1  ^ 75 F3           JNZ     SHORT digital_.004026B6
004026C3    8B06            MOV     EAX,DWORD PTR DS:[ESI]
004026C5    29D0            SUB     EAX,EDX
004026C7    31D0            XOR     EAX,EDX
004026C9    8906            MOV     DWORD PTR DS:[ESI],EAX
这儿用call代替跳转+修改异常处理返回地址来检测调试器:
004026CB    E8 24000000     CALL    digital_.004026F4
004026D0    8B5424 0C       MOV     EDX,DWORD PTR SS:[ESP+C];esp+c指向上一个异常处理过程
004026D4    C782 B8000000 0>MOV     DWORD PTR DS:[EDX+B8],digital_.0x402706>;[[esp+c]+0xb8]为触发异常地址,修改返回地址
004026DE    C742 18 5501000>MOV     DWORD PTR DS:[EDX+18],155;不了解的
004026E5    29C0            SUB     EAX,EAX
004026E7    8942 04         MOV     DWORD PTR DS:[EDX+4],EAX
004026EA    8942 08         MOV     DWORD PTR DS:[EDX+8],EAX
004026ED    8942 0C         MOV     DWORD PTR DS:[EDX+C],EAX
004026F0    8942 10         MOV     DWORD PTR DS:[EDX+10],EAX
004026F3    C3              RETN
004026F4    64:FF35 0000000>PUSH    DWORD PTR FS:[0]
004026FB    64:8925 0000000>MOV     DWORD PTR FS:[0],ESP
00402702    31C0            XOR     EAX,EAX
00402704    F7F0            DIV     EAX;不知为何"忽略除零"后硬件断点无法断在解码完成执行时,简单方法是在KiUserExceptionDispatcher 下条件断点判断ecx.得在Dispatcher第一个指令下断: mov ecx, [esp + 4];hmm,还有个法子,因为被压缩函数要用的数据需要初始化,若破坏执行流程则函数就会在执行过程中异常,这个异常就可以断下来了,更简单的ctrl + *;再可以阻止它穿裤子,清理了穿裤子的code
00402706    64:8F05 0000000>POP     DWORD PTR FS:[0]

0040178A    83C4 04         ADD     ESP,4
0040178D    4E              DEC     ESI
0040178E    49              DEC     ECX;极其缓慢的解码
0040178F  ^ 75 98           JNZ     SHORT digital_.00401729;

连环2个
jnz
jnz
后面那个jnz跳转到的目标为乱码,而同时cpu对"75 ??"只解码其后的一bytes,简单的混淆。
前面的jnz用来循环解码,解码完后第二个jnz被覆盖了.
解压出来的数据起始为
00401A21    61              POPAD
00401A22    8F05 E31C4000   POP     DWORD PTR DS:[40????]            ;
pop的把返回地址送到目标指针
0040271B    E8 05000000     CALL    digital_.0040????
00402720    E9 5D020000     JMP     digital_.0040????
call把下一指令地址压栈,这样函数结束时的retn就会返回到jmp.jmp跳到穿裤子code(压缩)
之后的router在结束时会再把数据压回去,即妨碍了执行一次程序流程然后附加进程直接看code
结束之后的retn是用一个重定向的跳转:
jmp [???????];????????处储存着重定向后的返回地址

注意上面那段是这个crackme频繁使用的proc和router的内部处理

PS:
补充下,Browse主要过程为
004018B4    FF15 BE164000   CALL    NEAR DWORD PTR DS:[4016BE]       ; COMDLG32.GetOpenFileNameA004018DC    50              PUSH    EAX
004018DD    6A 66           PUSH    66; EditOfKeyFile
004018DF    53              PUSH    EBX
004018E0    FF15 5E114000   CALL    NEAR DWORD PTR DS:[40115E]       ; USER32.SetDlgItemTextA

根据编码习惯推测一应检测都在"OK"过程中完成,故单刀直入 0x40268f router

保存下的code如下
0x40268f router:
00402714    61              POPAD;异常和int3断点检测code结束
00402715    8F05 0D2A4000   POP     DWORD PTR DS:[402A0D]            ; digital_.0040266B
0040271B    E8 05000000     CALL    digital_.00402725
00402720    E9 5D020000     JMP     digital_.00402982
00402725    55              PUSH    EBP;            ok的消息router开始
00402726    89E5            MOV     EBP,ESP
00402728    81EC BC000000   SUB     ESP,0BC
0040272E    FC              CLD ;设置cld.可以认识为 按照c数组的格式来修改counter访问数据了
0040272F    C785 50FFFFFF 0>MOV     DWORD PTR SS:[EBP-B0],0   ; ebp - 0xb0 ,ret
00402739    8D45 DC         LEA     EAX,DWORD PTR SS:[EBP-24]; ebp-24 ,name buffer
0040273C    50              PUSH    EAX
0040273D    FF75 08         PUSH    DWORD PTR SS:[EBP+8]     ;hDlg
00402740    E8 51F8FFFF     CALL    digital_.00401F96        ;分析1 读取name
00402745    85C0            TEST    EAX,EAX
00402747    0F84 2B020000   JE      digital_.00402978; 0x402978为函数执行错误返回;
0040274D    8D85 48FFFFFF   LEA     EAX,DWORD PTR SS:[EBP-B8]; fileSizes
00402753    8D9D 4CFFFFFF   LEA     EBX,DWORD PTR SS:[EBP-B4]; fileSizes/0xc
00402759    53              PUSH    EBX
0040275A    50              PUSH    EAX
0040275B    FF75 08         PUSH    DWORD PTR SS:[EBP+8]     ;hDlg
0040275E    E8 45F2FFFF     CALL    digital_.004019A8;          分析2 读取keyFile
00402763    85C0            TEST    EAX,EAX
00402765    0F84 0D020000   JE      digital_.00402978; 0x402978为函数执行错误返回
0040276B    8985 44FFFFFF   MOV     DWORD PTR SS:[EBP-BC],EAX; ebp - 0xbc, hMem
00402771    8B85 48FFFFFF   MOV     EAX,DWORD PTR SS:[EBP-B8]; ebp - 0xb8, fileSizes
00402777    83C0 40         ADD     EAX,40
0040277A    C1E8 03         SHR     EAX,3
0040277D    83C0 04         ADD     EAX,4
00402780    8985 58FFFFFF   MOV     DWORD PTR SS:[EBP-A8],EAX; ebp - 0xa8,((fileSizes + 0x40) >> 0x3 )+0x4;
00402786    8705 BB144000   XCHG    DWORD PTR DS:[4014BB],EAX
0040278C    8038 CC         CMP     BYTE PTR DS:[EAX],0CC
0040278F    0F84 CB1D0000   JE      digital_.00404560
00402795    8705 BB144000   XCHG    DWORD PTR DS:[4014BB],EAX
0040279B    6A 04           PUSH    4
0040279D    68 00100000     PUSH    1000
004027A2    50              PUSH    EAX  ;用((fileSizes + 0x40) >> 0x3 )+0x4作为hSpace的size
004027A3    6A 00           PUSH    0
004027A5    FF15 BB144000   CALL    NEAR DWORD PTR DS:[4014BB]       ; kernel32.VirtualAlloc
004027AB    85C0            TEST    EAX,EAX
004027AD    0F84 9D010000   JE      digital_.00402950
004027B3    8985 54FFFFFF   MOV     DWORD PTR SS:[EBP-AC],EAX;//ebp - 0xac 申请到的空间地址hSpace
004027B9    FFB5 48FFFFFF   PUSH    DWORD PTR SS:[EBP-B8];fileSizes/0xc
004027BF    FFB5 58FFFFFF   PUSH    DWORD PTR SS:[EBP-A8];((fileSizes + 0x40) >> 0x3 )+0x4;
004027C5    50              PUSH    EAX
004027C6    FFB5 44FFFFFF   PUSH    DWORD PTR SS:[EBP-BC]; hMem
004027CC    E8 10050000     CALL    digital_.00402CE1                ;分析3 判断keyFile是否符合条件
004027D1    85C0            TEST    EAX,EAX
004027D3    0F84 24010000   JE      digital_.004028FD ;释放hMem和hSpace
004027D9    8705 11164000   XCHG    DWORD PTR DS:[401611],EAX
004027DF    8038 CC         CMP     BYTE PTR DS:[EAX],0CC
004027E2    0F84 781D0000   JE      digital_.00404560
004027E8    8705 11164000   XCHG    DWORD PTR DS:[401611],EAX
004027EE    FF15 11164000   CALL    NEAR DWORD PTR DS:[401611]       ; kernel32.IsDebuggerPresent,简单的判断
004027F4    85C0            TEST    EAX,EAX
004027F6    0F85 641D0000   JNZ     digital_.00404560
004027FC    8D45 DC         LEA     EAX,DWORD PTR SS:[EBP-24]; ebp - 0x24,name buffer
004027FF    50              PUSH    EAX
00402800    E8 23070000     CALL    digital_.00402F28                 ; 分析5 初始化unknow ()中的随机子 *(0x401000)
00402805    8D85 64FFFFFF   LEA     EAX,DWORD PTR SS:[EBP-9C]         ;要被使用的序列
0040280B    50              PUSH    EAX
0040280C    E8 4A080000     CALL    digital_.0040305B                 ;分析6 初始化序列
00402811    8D45 84         LEA     EAX,DWORD PTR SS:[EBP-7C]         ;使用上面修改后的随即子初始化
00402814    50              PUSH    EAX
00402815    E8 41080000     CALL    digital_.0040305B
0040281A    8D45 A4         LEA     EAX,DWORD PTR SS:[EBP-5C]
0040281D    50              PUSH    EAX
0040281E    E8 38080000     CALL    digital_.0040305B                 ;隔0x20字节为一个起点.
00402823    B9 0A000000     MOV     ECX,0A

00402828    51              PUSH    ECX                               ;保护ecx
00402829    8D5D DC         LEA     EBX,DWORD PTR SS:[EBP-24]         ;ebp - 0x24,name buffer
0040282C    8D85 5CFFFFFF   LEA     EAX,DWORD PTR SS:[EBP-A4]         ;依据被处理后的name buffer被初始化的8个字节
00402832    50              PUSH    EAX
00402833    53              PUSH    EBX
00402834    E8 2D020000     CALL    digital_.00402A66                 ;分析7  ebp - 0xa4设置为一个 key?
00402839    8DB5 5CFFFFFF   LEA     ESI,DWORD PTR SS:[EBP-A4]         ;依据被处理后的name buffer被初始化的8个字节
0040283F    8D85 64FFFFFF   LEA     EAX,DWORD PTR SS:[EBP-9C]         ;被name buffer随即子初始化的序列起点
00402845    8D7D C4         LEA     EDI,DWORD PTR SS:[EBP-3C]         ;
00402848    57              PUSH    EDI                        ;array2
00402849    50              PUSH    EAX                        ;array1
0040284A    56              PUSH    ESI                        ;array0
0040284B    E8 97090000     CALL    digital_.004031E7                  ;分析8 根据序列array1和array0填充array2 ret.
00402850    8D75 C4         LEA     ESI,DWORD PTR SS:[EBP-3C]
00402853    8D45 84         LEA     EAX,DWORD PTR SS:[EBP-7C]
00402856    8D7D CC         LEA     EDI,DWORD PTR SS:[EBP-34]
00402859    57              PUSH    EDI
0040285A    50              PUSH    EAX
0040285B    56              PUSH    ESI
0040285C    E8 86090000     CALL    digital_.004031E7                        ;分析8
00402861    8D75 CC         LEA     ESI,DWORD PTR SS:[EBP-34]
00402864    8D45 A4         LEA     EAX,DWORD PTR SS:[EBP-5C]
00402867    8D7D C4         LEA     EDI,DWORD PTR SS:[EBP-3C]
0040286A    57              PUSH    EDI
0040286B    50              PUSH    EAX
0040286C    56              PUSH    ESI
0040286D    E8 75090000     CALL    digital_.004031E7                        ;分析8  ;利用前面初始化完成的数据确定ret序列
00402872    8D85 5CFFFFFF   LEA     EAX,DWORD PTR SS:[EBP-A4]    ;8字节序列
00402878    8D55 D4         LEA     EDX,DWORD PTR SS:[EBP-2C]    ;在name buffer - 0x8
0040287B    52              PUSH    EDX                          ;unknow     
0040287C    FFB5 54FFFFFF   PUSH    DWORD PTR SS:[EBP-AC]        ;申请到的空间地址hSpace
00402882    FFB5 48FFFFFF   PUSH    DWORD PTR SS:[EBP-B8]        ;fileSizes/0xc
00402888    FFB5 44FFFFFF   PUSH    DWORD PTR SS:[EBP-BC]        ;hMem
0040288E    50              PUSH    EAX                          ;Coverage
0040288F    E8 53F4FFFF     CALL    digital_.00401CE7                        ;分析9  判断ret序列是否符合条件
00402894    8D75 C4         LEA     ESI,DWORD PTR SS:[EBP-3C]    ;ret序列
00402897    8D7D D4         LEA     EDI,DWORD PTR SS:[EBP-2C]    ;分析9 unknow
0040289A    B9 08000000     MOV     ECX,8
0040289F    F3:A6           REPE    CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI];
004028A1    59              POP     ECX
004028A2    75 59           JNZ     SHORT digital_.004028FD;     分析9 unknow必须ret序列中数据一致
004028A4    49              DEC     ECX
004028A5  ^ 75 81           JNZ     SHORT digital_.00402828;循环判断8次
004028A7    C785 50FFFFFF 0>MOV     DWORD PTR SS:[EBP-B0],1 ; ret = TURE
004028B1    6A 40           PUSH    40
004028B3    E8 10000000     CALL    digital_.004028C8 ; finshed
;-------------------下面是无效code:其实是数据,MessageBox的参数
004028B8    43              INC     EBX
004028B9    6F              OUTS    DX,DWORD PTR ES:[EDI]            ; I/O 命令
004028BA    6E              OUTS    DX,BYTE PTR ES:[EDI]             ; I/O 命令
004028BB    67:72 61        JB      SHORT digital_.0040291F          ; 多余的前缀
004028BE    74 75           JE      SHORT digital_.00402935
004028C0    6C              INS     BYTE PTR ES:[EDI],DX             ; I/O 命令
004028C1    61              POPAD
004028C2    74 69           JE      SHORT digital_.0040292D
004028C4    6F              OUTS    DX,DWORD PTR ES:[EDI]            ; I/O 命令
004028C5    6E              OUTS    DX,BYTE PTR ES:[EDI]             ; I/O 命令
004028C6    73 00           JNB     SHORT digital_.004028C8
;------------------------
004028C8    E8 26000000     CALL    digital_.004028F3
;----------------------下面是无效code
004028CD    43              INC     EBX
004028CE    6F              OUTS    DX,DWORD PTR ES:[EDI]            ; I/O 命令
004028CF    6E              OUTS    DX,BYTE PTR ES:[EDI]             ; I/O 命令
004028D0    67:72 61        JB      SHORT digital_.00402934          ; 多余的前缀
004028D3    74 75           JE      SHORT digital_.0040294A
004028D5    6C              INS     BYTE PTR ES:[EDI],DX             ; I/O 命令
004028D6    61              POPAD
004028D7    74 69           JE      SHORT digital_.00402942
004028D9    6F              OUTS    DX,DWORD PTR ES:[EDI]            ; I/O 命令
004028DA    6E              OUTS    DX,BYTE PTR ES:[EDI]             ; I/O 命令
004028DB    73 21           JNB     SHORT digital_.004028FE
004028DD    2059 6F         AND     BYTE PTR DS:[ECX+6F],BL
004028E0    75 72           JNZ     SHORT digital_.00402954
004028E2    206B 65         AND     BYTE PTR DS:[EBX+65],CH
004028E5    79 20           JNS     SHORT digital_.00402907
004028E7    6973 20 636F727>IMUL    ESI,DWORD PTR DS:[EBX+20],72726F>
004028EE    65:637421 00    ARPL    WORD PTR GS:[ECX],SI
;---------------------
004028F3    6A 00           PUSH    0
004028F5    FF15 B8114000   CALL    NEAR DWORD PTR DS:[4011B8]       ; USER32.MessageBoxA
004028FB    EB 2B           JMP     SHORT digital_.00402928
004028FD    6A 10           PUSH    10
004028FF    E8 06000000     CALL    digital_.0040290A;假call
;--------------------------下面的code无效
00402904    45              INC     EBP
00402905    72 72           JB      SHORT digital_.00402979
00402907    6F              OUTS    DX,DWORD PTR ES:[EDI]            ; I/O 命令
00402908    72 00           JB      SHORT digital_.0040290A
;--------------------------------
0040290A    E8 11000000     CALL    digital_.00402920
;---------------------------------下面的code无效
0040290F    49              DEC     ECX
00402910    6E              OUTS    DX,BYTE PTR ES:[EDI]             ; I/O 命令
00402911    76 61           JBE     SHORT digital_.00402974
00402913    6C              INS     BYTE PTR ES:[EDI],DX             ; I/O 命令
00402914    696420 6B 65796>IMUL    ESP,DWORD PTR DS:[EAX+6B],696679>
0040291C    6C              INS     BYTE PTR ES:[EDI],DX             ; I/O 命令
0040291D    65:2100         AND     DWORD PTR GS:[EAX],EAX
;---------------------------------------
00402920    6A 00           PUSH    0
00402922    FF15 B8114000   CALL    NEAR DWORD PTR DS:[4011B8]       ; USER32.MessageBoxA
00402928    8705 12154000   XCHG    DWORD PTR DS:[401512],EAX
0040292E    8038 CC         CMP     BYTE PTR DS:[EAX],0CC
00402931    0F84 291C0000   JE      digital_.00404560
00402937    8705 12154000   XCHG    DWORD PTR DS:[401512],EAX
0040293D    68 00800000     PUSH    8000
00402942    6A 00           PUSH    0
00402944    FFB5 54FFFFFF   PUSH    DWORD PTR SS:[EBP-AC]            ;hSpace的释放
0040294A    FF15 12154000   CALL    NEAR DWORD PTR DS:[401512]       ; kernel32.VirtualFree
00402950    8705 12154000   XCHG    DWORD PTR DS:[401512],EAX
00402956    8038 CC         CMP     BYTE PTR DS:[EAX],0CC
00402959    0F84 011C0000   JE      digital_.00404560
0040295F    8705 12154000   XCHG    DWORD PTR DS:[401512],EAX
00402965    68 00800000     PUSH    8000
0040296A    6A 00           PUSH    0
0040296C    FFB5 44FFFFFF   PUSH    DWORD PTR SS:[EBP-BC]              ;hMem的释放
00402972    FF15 12154000   CALL    NEAR DWORD PTR DS:[401512]       ; kernel32.VirtualFree
00402978    8B85 50FFFFFF   MOV     EAX,DWORD PTR SS:[EBP-B0]; return ret;
0040297E    C9              LEAVE
0040297F    C2 0400         RETN    4;注意retn 4是为了平衡刚才的假call
--
00402982    60              PUSHAD; 包含异常并有int3断点检测code开始 PS:压缩code
00402983    BE 14274000     MOV     ESI,digital_.00402714;起始地址
00402988    B9 6B020000     MOV     ECX,26B;size
0040298D    BA 6B528C5A     MOV     EDX,5A8C526B;这儿赋给edx的值是前面计算 所用数据得到的值;若这儿也是动态计算的,便可随便改解出code,因为会被正确的保存和读取。
00402992    8B06            MOV     EAX,DWORD PTR DS:[ESI]
00402994    31D0            XOR     EAX,EDX
00402996    01D0            ADD     EAX,EDX
00402998    8906            MOV     DWORD PTR DS:[ESI],EAX
0040299A    BF 9B264000     MOV     EDI,digital_.0040269B
0040299F    BB 63030000     MOV     EBX,363
004029A4    0FB607          MOVZX   EAX,BYTE PTR DS:[EDI]
004029A7    01C2            ADD     EDX,EAX
004029A9    31C2            XOR     EDX,EAX
004029AB    47              INC     EDI
004029AC    4B              DEC     EBX
004029AD    85DB            TEST    EBX,EBX
004029AF  ^ 75 F3           JNZ     SHORT digital_.004029A4
004029B1    E8 24000000     CALL    digital_.004029DA;此处又是一个假call,类似于上面那router开首,不过这是解码反过来
004029B6    8B5424 0C       MOV     EDX,DWORD PTR SS:[ESP+C]
004029BA    C782 B8000000 E>MOV     DWORD PTR DS:[EDX+B8],digital_.0>
004029C4    C742 18 5501000>MOV     DWORD PTR DS:[EDX+18],155
004029CB    29C0            SUB     EAX,EAX
004029CD    8942 04         MOV     DWORD PTR DS:[EDX+4],EAX
004029D0    8942 08         MOV     DWORD PTR DS:[EDX+8],EAX
004029D3    8942 0C         MOV     DWORD PTR DS:[EDX+C],EAX
004029D6    8942 10         MOV     DWORD PTR DS:[EDX+10],EAX
004029D9    C3              RETN
004029DA    64:FF35 0000000>PUSH    DWORD PTR FS:[0]
004029E1    64:8925 0000000>MOV     DWORD PTR FS:[0],ESP
004029E8    31C0            XOR     EAX,EAX
004029EA    F7F0            DIV     EAX;一样奇怪的需要shift+F9一次
004029EC    64:8F05 0000000>POP     DWORD PTR FS:[0]
004029F3    83C4 04         ADD     ESP,4
004029F6    46              INC     ESI
004029F7    49              DEC     ECX
004029F8  ^ 75 98           JNZ     SHORT digital_.00402992
004029FA    8915 032A4000   MOV     DWORD PTR DS:[402A03],EDX
004029FA    8915 032A4000   MOV     DWORD PTR DS:[402A03],EDX
00402A00    61              POPAD;异常和int3断点检测code结束
00402A01    EB 04           JMP     SHORT digital_.00402A07
00402A03    E1 3D           LOOPDE  SHORT digital_.00402A42
00402A05    FE              ???                                      ; 未知命令
00402A06    5D              POP     EBP
00402A07  ^ FF25 0D2A4000   JMP     NEAR DWORD PTR DS:[402A0D]       ; digital_.00402725函数返回了

总结起来为
比较name是否valid,取得name放入 (ebp-24)[0x1f]序列 ,name buffer
比较keyFile是否可以载入,然后相关数据分别放入:
ebp - 0xbc, hMem;
EBP-B8,fileSizes
ebp - 0xb8, fileSizes/0xc;
ebp - 0xa8,((fileSizes + 0x40) >> 0x3 )+0x4;
以hMem, hSpace, ((fileSizes + 0x40) >> 0x3 )+0x4, fileSizes/0xc作为proc3(array0, array1, times, len)的参数,用文件大小来决定是否符合要求。同时hSpace会被依据hMem填充
以ebp - 0x24,name buffer为参数初始化unknow ()中的随即子
EBP-9C 至 EBP-3C 的数据被使用随即子初始化.
完成后进入一共8次的循环:
分析7利用初始化完成的数据初始化一个8字节序列.
分析8会利用初始化完成数据和8字节序列生成ret序列.
接着ret序列与分析9利用hSpace、Coverage(8字节序列)、hMem、Filesize/0xc生成的unknow序列比较,相同则下一次循环

完全符合要求时TURE返回.

digital_.00401F96被内部压缩了,直接帖出解压后的流程
分析1:
0040200F    61              POPAD
00402010    8F05 68214000   POP     DWORD PTR DS:[402168]            ; digital_.00402745
00402016    E8 05000000     CALL    digital_.00402020
0040201B    E9 BD000000     JMP     digital_.004020DD
00402020    55              PUSH    EBP
00402021    89E5            MOV     EBP,ESP
00402023    8705 04114000   XCHG    DWORD PTR DS:[401104],EAX
00402029    8038 CC         CMP     BYTE PTR DS:[EAX],0CC
0040202C    0F84 2E250000   JE      digital_.00404560
00402032    8705 04114000   XCHG    DWORD PTR DS:[401104],EAX
00402038    6A 21           PUSH    21
0040203A    FF75 0C         PUSH    DWORD PTR SS:[EBP+C];name缓冲区
0040203D    6A 65           PUSH    65  ;EditOfName
0040203F    FF75 08         PUSH    DWORD PTR SS:[EBP+8]     ;hDlg
00402042    FF15 04114000   CALL    NEAR DWORD PTR DS:[401104]       ; USER32.GetDlgItemTextA
00402048    85C0            TEST    EAX,EAX;
0040204A    75 33           JNZ     SHORT digital_.0040207F;没有失败时跳过去
0040204C    6A 10           PUSH    10
0040204E    E8 06000000     CALL    digital_.00402059
;---------------------下面的code无效
00402053    45              INC     EBP
00402054    72 72           JB      SHORT digital_.004020C8
00402056    6F              OUTS    DX,DWORD PTR ES:[EDI]            ; I/O 命令
00402057    72 00           JB      SHORT digital_.00402059
;--------------------------------
00402059    E8 15000000     CALL    digital_.00402073
;------------------------------下面的code无效
0040205E    50              PUSH    EAX
0040205F    6C              INS     BYTE PTR ES:[EDI],DX             ; I/O 命令
00402060    65:61           POPAD                                    ; 多余的前缀
00402062    73 65           JNB     SHORT digital_.004020C9
00402064    2065 6E         AND     BYTE PTR SS:[EBP+6E],AH
00402067    74 65           JE      SHORT digital_.004020CE
00402069    72 20           JB      SHORT digital_.0040208B
0040206B    61              POPAD
0040206C    206E 61         AND     BYTE PTR DS:[ESI+61],CH
0040206F    6D              INS     DWORD PTR ES:[EDI],DX            ; I/O 命令
00402070    65:2100         AND     DWORD PTR GS:[EAX],EAX
;------------------------------------
00402073    6A 00           PUSH    0
00402075    FF15 B8114000   CALL    NEAR DWORD PTR DS:[4011B8]       ; USER32.MessageBoxA name太短
0040207B    31C0            XOR     EAX,EAX
0040207D    EB 5A           JMP     SHORT digital_.004020D9
0040207F    83F8 06         CMP     EAX,6;正常时的流程
00402082    72 2B           JB      SHORT digital_.004020AF;name小于6字节则错误返回
00402084    50              PUSH    EAX
00402085    FF75 0C         PUSH    DWORD PTR SS:[EBP+C];name缓冲区塞进0x401e5b处理
00402088    E8 CEFDFFFF     CALL    digital_.00401E5B;           分析10
0040208D    B9 20000000     MOV     ECX,20
00402092    31D2            XOR     EDX,EDX
00402094    8B5D 0C         MOV     EBX,DWORD PTR SS:[EBP+C]
~~~~~~~~~~~~~
00402097    85C9            TEST    ECX,ECX;
00402099    74 0D           JE      SHORT digital_.004020A8;20个字符比较完时可以正常返回
0040209B    49              DEC     ECX
0040209C    0FB60413        MOVZX   EAX,BYTE PTR DS:[EBX+EDX];ebx namebuffer,edx counter
004020A0    42              INC     EDX;
004020A1    FF2485 6C214000 JMP     NEAR DWORD PTR DS:[EAX*4+40216C];40216c处的跳转表附在结尾,若跳到4020af则invalid name
004020A8    B8 01000000     MOV     EAX,1
004020AD    EB 2A           JMP     SHORT digital_.004020D9;
~~~~~~~~~~~~~
004020AF    6A 10           PUSH    10;
004020B1    E8 06000000     CALL    digital_.004020BC;invalid name
;---------------------------------------下面的code无效
004020B6    45              INC     EBP
004020B7    72 72           JB      SHORT digital_.0040212B
004020B9    6F              OUTS    DX,DWORD PTR ES:[EDI]            ; I/O 命令
004020BA    72 00           JB      SHORT digital_.004020BC
;----------------------------------------
004020BC    E8 0E000000     CALL    digital_.004020CF
;-------------------------------------------下面的code无效
004020C1    49              DEC     ECX
004020C2    6E              OUTS    DX,BYTE PTR ES:[EDI]             ; I/O 命令
004020C3    76 61           JBE     SHORT digital_.00402126
004020C5    6C              INS     BYTE PTR ES:[EDI],DX             ; I/O 命令
004020C6    696420 6E 616D6>IMUL    ESP,DWORD PTR DS:[EAX+6E],21656D>
004020CE    006A 00         ADD     BYTE PTR DS:[EDX],CH
;-----------------------------------------
;0x4020cf   6a00            push    0;
004020D1    FF15 B8114000   CALL    NEAR DWORD PTR DS:[4011B8]       ; USER32.MessageBoxA
004020D7    31C0            XOR     EAX,EAX;返回FALSE
004020D9    C9              LEAVE    ;跳转到此处为正常返回,eax = TURE;
004020DA    C2 0800         RETN    8
-----
004020DD    60              PUSHAD;压缩
004020DE    BE 0F204000     MOV     ESI,digital_.0040200F
004020E3    B9 CB000000     MOV     ECX,0CB
004020E8    BA 6B528C5A     MOV     EDX,5A8C526B
004020ED    8B06            MOV     EAX,DWORD PTR DS:[ESI]
004020EF    31D0            XOR     EAX,EDX
004020F1    01D0            ADD     EAX,EDX
004020F3    8906            MOV     DWORD PTR DS:[ESI],EAX
004020F5    BF 961F4000     MOV     EDI,digital_.00401F96
004020FA    BB C3010000     MOV     EBX,1C3
004020FF    0FB607          MOVZX   EAX,BYTE PTR DS:[EDI]
00402102    01C2            ADD     EDX,EAX
00402104    31C2            XOR     EDX,EAX
00402106    47              INC     EDI
00402107    4B              DEC     EBX
00402108    85DB            TEST    EBX,EBX
0040210A  ^ 75 F3           JNZ     SHORT digital_.004020FF
0040210C    E8 24000000     CALL    digital_.00402135
00402111    8B5424 0C       MOV     EDX,DWORD PTR SS:[ESP+C]
00402115    C782 B8000000 4>MOV     DWORD PTR DS:[EDX+B8],digital_.0>
0040211F    C742 18 5501000>MOV     DWORD PTR DS:[EDX+18],155
00402126    29C0            SUB     EAX,EAX
00402128    8942 04         MOV     DWORD PTR DS:[EDX+4],EAX
0040212B    8942 08         MOV     DWORD PTR DS:[EDX+8],EAX
0040212E    8942 0C         MOV     DWORD PTR DS:[EDX+C],EAX
00402131    8942 10         MOV     DWORD PTR DS:[EDX+10],EAX
00402134    C3              RETN
00402135    64:FF35 0000000>PUSH    DWORD PTR FS:[0]
0040213C    64:8925 0000000>MOV     DWORD PTR FS:[0],ESP
00402143    31C0            XOR     EAX,EAX
00402145    F7F0            DIV     EAX
00402147    64:8F05 0000000>POP     DWORD PTR FS:[0]
0040214E    83C4 04         ADD     ESP,4
00402151    46              INC     ESI
00402152    49              DEC     ECX
00402153  ^ 75 98           JNZ     SHORT digital_.004020ED
00402155    8915 5E214000   MOV     DWORD PTR DS:[40215E],EDX
0040215B    61              POPAD
0040215C    EB 04           JMP     SHORT digital_.00402162

00402162   /FF25 68214000   JMP     NEAR DWORD PTR DS:[402168]       ; digital_.00402745,返回。402020函数结束

得到用户名,必须大于6byte。name长度为times,0x401e5b处理完name后,以name为case循环20次switch来判断是否valid.

name算法为
bool nameValid (int hDlg,char* name)
{
        if ((len = USER32.GetDlgItemTextA)<6)
        {
                return FALSE;
        }
        0x401e5bproc (len, name);//分析10
        int counter = 0;
        while (counter++ < 20)
        {
                switch (name[counter]);//分析见下
        }
}
name中的字符需符合
0x2b>char>0x28
0x30>char>0x2E
0x3b>char>0x31
.......
不能指向0x4020af

跳转表
0040216C ;    004020AF    004020AF    004020AF    004020AF
0040217C ;    004020AF    004020AF    004020AF    004020AF
0040218C ;    004020AF    004020AF    004020AF    004020AF
0040219C ;    004020AF    004020AF    004020AF    004020AF
004021AC ;    004020AF    004020AF    004020AF    004020AF
004021BC ;    004020AF    004020AF    004020AF    004020AF
004021CC ;    004020AF    004020AF    004020AF    004020AF
004021DC ;    004020AF    004020AF    004020AF    004020AF
004021EC ;    00402097    004020AF    004020AF    004020AF
004021FC ;    004020AF    004020AF    004020AF    004020AF
0040220C ;    00402097    00402097    004020AF    004020AF
0040221C ;    004020AF    00402097    00402097    004020AF
0040222C ;    00402097    00402097    00402097    00402097
0040223C ;    00402097    00402097    00402097    00402097
0040224C ;    00402097    00402097    004020AF    004020AF
0040225C ;    00402097    004020AF    00402097    004020AF
0040226C ;    004020AF    00402097    00402097    00402097
0040227C ;    00402097    00402097    00402097    00402097
0040228C ;    00402097    00402097    00402097    00402097
0040229C ;    00402097    00402097    00402097    00402097
004022ac ;    00402097    00402097    00402097    00402097
004022BC ;    00402097    00402097    00402097    00402097
004022CC ;    00402097    00402097    00402097    00402097
004022DC ;    004020AF    00402097    004020AF    004020AF
004022EC ;    004020AF    00402097    00402097    00402097
004022FC ;    00402097    00402097    00402097    00402097
0040230C ;    00402097    00402097    00402097    00402097
0040231C ;    00402097    00402097    00402097    00402097
0040232C ;    00402097    00402097    00402097    00402097
0040233C ;    00402097    00402097    00402097    00402097
0040234C ;    00402097    00402097    00402097    004020AF
0040235C ;    004020AF    004020AF    004020AF    004020AF
0040236C ;    004020AF    004020AF    004020AF    004020AF
0040237C ;    004020AF    004020AF    004020AF    004020AF
0040238C ;    004020AF    004020AF    004020AF    004020AF
0040239C ;    004020AF    004020AF    004020AF    004020AF
004023AC ;    004020AF    004020AF    004020AF    004020AF
004023BC ;    004020AF    004020AF    004020AF    004020AF
004023CC ;    004020AF    004020AF    004020AF    004020AF
004023DC ;    004020AF    004020AF    004020AF    004020AF
004023EC ;    004020AF    004020AF    004020AF    004020AF
004023FC ;    004020AF    004020AF    004020AF    004020AF
0040240C ;    004020AF    004020AF    004020AF    004020AF
0040241C ;    004020AF    004020AF    004020AF    004020AF
0040242C ;    004020AF    004020AF    004020AF    004020AF
0040243C ;    004020AF    004020AF    004020AF    004020AF
0040244C ;    004020AF    004020AF    004020AF    004020AF
0040245C ;    004020AF    004020AF    004020AF    004020AF
0040246C ;    004020AF    004020AF    004020AF    004020AF
0040247C ;    004020AF    004020AF    004020AF    004020AF
0040248C ;    004020AF    004020AF    004020AF    004020AF
0040249C ;    004020AF    004020AF    004020AF    004020AF
004024AC ;    004020AF    004020AF    004020AF    004020AF
004024BC ;    004020AF    004020AF    004020AF    004020AF
004024CC ;    004020AF    004020AF    004020AF    004020AF
004024DC ;    004020AF    004020AF    004020AF    004020AF
004024EC ;    004020AF    004020AF    004020AF    004020AF
004024FC ;    004020AF    004020AF    004020AF    004020AF
0040250C ;    004020AF    004020AF    004020AF    004020AF
0040251C  ;   004020AF    004020AF    004020AF    004020AF
0040252C ;    004020AF    004020AF    004020AF    004020AF
0040253C ;    004020AF    004020AF    004020AF    004020AF
0040254C  ;   004020AF    004020AF    004020AF    004020AF
0040255C ;    004020AF    004020AF    004020AF    004020AF

一个就显得长了,分析1-10放在附件

可用用户名和keyFile实在是懒得做了,权当是resever me了一把
文件size必须为0xc的倍数.
每个双字都必须大于size/0xc + 0x40

文件大小第一轮判断:
文件每个0xc bytes中第三个双字除以32后作为x,hSpace[x]被双子&0x1f后得到的位设置位.同时第二次设置hSpace中同一个位(hSpace的大小为文件size/0xc)
同时hSpace序列开始2个int必须初始化为NULL
若(size/0xc)&0x1f不为空,则1000 0000 0000 0000 0000 0000 0000 0000b算术右移 (len & 0x1f) -1,结果再循环右移 (len & 0x1f),hSpace序列的最后一位必须为位移结果。
第二轮:
hSpace前2个int 置0xffffffff,这限制了hMem中每0xc bytes中前2 int的取值
对于hMem,2个序列ebx、esi都指向开头,然后
每0xc bytes前2个int若符合hSpace[hMem[int] >> 0x5] | (hMem[int] & 0x1f)之后不设置任何值,则esi递增一组数据
前2 int未设置时任何位时int用hSpace[hMem[int] >> 0x5] | (hMem[int] & 0x1f)设置一位,然后判断ebx是否已经追上esi,是则递增esi一组数据,否则ebx指向的和esi指向的一组数据交换,并递增ebx一组数据
而最后处理完size/0xc组数据时,最后一个处理必须是esi的递增.

rand子的初始化是把0x20字节name buffer里8个int加到一起,这是rand子

name随机序列的初始化(0x9c-0x3c):
0x20字节一组.
前0x18个字节被初始化为"8765432187...."
每个0x8字节如下处理:
(((rand * 0x3f3fd + 0x269ec3) >> 0x10 ) & 0x7ffff) & 0x7得到一个数字,重复次再一个数字,这二数字指向的byte交换.注意rand是个全局变量,每次循环被赋值为(rand * 0x3f3fd + 0x269ec3)
前0x18个字节依次处理,循环0x64次
0x18后的0x8字节rand计算方式不变.使用方式,rand ((rand * 0x3f3fd + 0x269ec3) >> 0x10 )返回的数字mod 6然后 & 0xff得到一字节,从0-7依次循环置完.

3组name随机序列皆如此处理

然后是最后的判断,这段循环10次
初始化8字节数组并处理name buffer:
name buffer每个byte的处理,int temp加上前面的temp,然后取从尾部开始计量的2、3位(0开始计量)来作为后一个byte的值.temp 初始值为0xac
ebp - 0xa4的前8个字符被处理完name buffer序列的最后8字符 & 0xff后倒序覆盖.
分析9和结果已经在前面总结了,hmm.

菜人整理笔记的产物,有误就指正

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 59
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
你搞错了 ,明明是76543210序列,你却写成87654321
2009-6-5 09:13
0
雪    币: 319
活跃值: (49)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
晕S,好长啊,看的头晕了。。。。。。。。。。。
2009-6-5 14:35
0
雪    币: 51
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
...猛人~都是
2009-6-6 18:01
0
游客
登录 | 注册 方可回帖
返回
//