1. 序言
Delphi菜鸟,从未用过Delphi。前一段时间随机拿来研究的,再过点时间恐怕就会忘了,所以写下来,请大牛指点。
没用PEID查壳,直接拖IDA里去了,结果有如下段:
CODE 00401000 0049D000 R . X . L para 0001 public CODE 32 0000 0000 0001 FFFFFFFF FFFFFFFF
DATA 0049D000 004A0000 R W . . L para 0002 public DATA 32 0000 0000 0001 FFFFFFFF FFFFFFFF
BSS 004A0000 004A1000 R W . . L para 0003 public 32 0000 0000 0001 FFFFFFFF FFFFFFFF
.idata 004A1000 004A4000 R W . . L para 0004 public DATA 32 0000 0000 0001 FFFFFFFF FFFFFFFF
.tls 004A4000 004A5000 R W . . L para 0005 public 32 0000 0000 0001 FFFFFFFF FFFFFFFF
.rdata 004A5000 004A6000 R . . . L para 0006 public DATA 32 0000 0000 0001 FFFFFFFF FFFFFFFF
.jwx0 004A6000 004B1000 R W . . L para 0007 public DATA 32 0000 0000 0001 FFFFFFFF FFFFFFFF
.jwx1 0054F000 005CE000 R W X . L para 0008 public CODE 32 0000 0000 0001 FFFFFFFF FFFFFFFF
比较奇怪的是jwx0和jwx1,一个数据段,一个代码段,名字以前没见过,感觉是作者自己写的。起初怀疑这两个段是什么壳用的,但鉴于已有CODE段了(放眼望去,基本是DELPHI的库函数等),因此个人觉得是作者自创的什么保护机制了。
2.查看关键算法(大牛跳过)
算法什么的查找还算简单,用DeDe查看下事件按钮,一般都是ButtonClick之类的,下个断点再跟下,想看的算法就出来了。
3. 算法逆向(大牛可忽略,不过最后有个小问题)
算法的逆向稍有些特殊,《加密与解密(三)》中p76说道,delphi采用__fastcall规范传递参数时,最左边的三个不大于4个字节(DWORD)的参数分别放在eac,edx,ecx寄存器,寄存器用完之后,多余的参数按照从左至右的PASCAL方式来压栈。
因此在这个地方多加注意,算法的逆向也只是时间问题了。但本人实践发现,F5显示的参数顺序有时候是有问题的,特别是在对函数的多层封装中。因此,完全依赖工具也会走弯路的。不知其他朋友是否发现这个问题?
4.保护机制的分析(大牛请看)
用ollydbg跟了下,看到jwx1中最主要的是一个jmp 到CODE中的一个地址0x0049A105去,而这个地址的引用居然出现了106次之多。为了近距离观察这个loc_开头的地址,在该位置创建了函数,变为sub函数,使用F5观察下内容(需要Alt+K调整栈偏移成正的)如下:
void __usercall sub_49A105(unsigned __int8 _CF<cf>, char _ZF<zf>, char _SF<sf>, unsigned __int8 _OF<of>, int a5<eax>, int a6<edx>, int a7, int a8, int a9, int a10, double a11)
{
__int16 v12; // dx@22
int v17; // kr08_4@29
char v18; // al@32
int v19; // eax@32
int v21; // esi@1
char v22; // zf@1
DWORD v23; // eax@1
int v24; // edx@1
DWORD v25; // ebx@1
signed int v26; // ecx@1
int v27; // edi@1
signed int v28; // eax@5
signed int v29; // ecx@5
int v30; // edi@9
char v31; // bl@9
int v32; // esi@9
char v33; // dl@10
unsigned __int8 v34; // dl@10
int v39; // eax@10
char v40; // al@13
__int16 v41; // dx@41
signed int v42; // ett@41
char v45; // al@48
unsigned int v46; // [sp-7Ah] [bp-92h]@1
int v47; // [sp-76h] [bp-8Eh]@14
int v48; // [sp-72h] [bp-8Ah]@1
int v49; // [sp-6Eh] [bp-86h]@1
int v50; // [sp-52h] [bp-6Ah]@1
signed __int32 v51; // [sp-32h] [bp-4Ah]@19
char v52; // [sp-2Eh] [bp-46h]@20
__int16 v53; // [sp-2Ch] [bp-44h]@21
char v54; // [sp-2Ah] [bp-42h]@21
int v55; // [sp-26h] [bp-3Eh]@27
__int16 v56; // [sp-22h] [bp-3Ah]@27
int v57; // [sp-20h] [bp-38h]@28
__int16 v58; // [sp-1Ch] [bp-34h]@28
unsigned int v59; // [sp-1Ah] [bp-32h]@29
int v60; // [sp-16h] [bp-2Eh]@29
__int16 v61; // [sp-Ch] [bp-24h]@18
char v62[6]; // [sp+12h] [bp-6h]@15
void *v63; // [sp+18h] [bp+0h]@18
v49 = a6;
v48 = a5;
__asm { pushf }
v46 = 0;
v21 = v50;
v23 = GetCurrentThreadId();
v25 = v23;
v26 = 256;
v27 = v24;
do
{
if ( !v26 )
break;
v22 = *(_DWORD *)v27 == v23;
v27 += 4;
--v26;
}
while ( !v22 );
if ( !v22 )
{
v28 = v26;
v29 = 256;
v27 = v24;
do
{
if ( !v29 )
break;
_ZF = *(_DWORD *)v27 == v28;
v27 += 4;
--v29;
}
while ( !_ZF );
*(_DWORD *)(v27 - 4) = v25;
}
v30 = v24 + 16 * (v27 - v24) + 960;
v31 = v21;
v32 = v46 + v21;
while ( 1 )
{
v33 = __ROL__(v31 + *(_BYTE *)v32 + 1, 7);
v34 = __ROL__(v33 + 1, 1);
++v34;
++v32;
_CF = __CFADD__(v34, v31);
_OF = __OFADD__(v34, v31);
_ZF = v34 + v31 == 0;
_SF = (char)(v34 + v31) < 0;
v31 += v34;
v39 = v34;
switch ( v34 )
{
case 0u:
__asm { fistp dword ptr [esp+0] }
break;
case 1u:
__asm { mov eax, cr6 }
*(_DWORD *)&v62[2] = _EAX;
break;
case 2u:
_EDX = *(_DWORD *)&v54;
__asm { mov dr7, edx }
break;
case 3u:
case 0xBu:
_CF = __CFADD__((_WORD)v63, v61);
_OF = __OFADD__((_WORD)v63, v61);
_ZF = (_WORD)v63 + v61 == 0;
_SF = (signed __int16)((_WORD)v63 + v61) < 0;
v61 += (signed __int16)v63;
__asm { pushfw }
break;
case 5u:
__asm { f2xm1 }
break;
case 6u:
LOWORD(v42) = HIWORD(v46);
HIWORD(v42) = v46;
v41 = v42 % (signed __int16)v47;
LOWORD(v47) = v42 / (signed __int16)v47;
HIWORD(v46) = v41;
break;
case 7u:
__asm { fld1 }
break;
case 8u:
*(_WORD *)&v62[4] = **(_WORD **)&v62[2];
break;
case 9u:
HIWORD(v46) += v46;
break;
case 0xAu:
__asm { fstp tbyte ptr [esp] }
break;
case 0xCu:
case 0x1Au:
*(_DWORD *)&v62[2] = **(_DWORD **)&v62[2];
break;
case 0xDu:
_CF = BYTE2(v39) != 0;
_OF = BYTE2(v39) != 0;
UNDEF(_ZF);
UNDEF(_SF);
HIWORD(v46) = (char)v46 * SBYTE2(v46);
__asm { pushfw }
break;
case 0xEu:
*(_BYTE *)v51 = v52;
break;
case 0xFu:
_EAX = v46;
__asm { mov cr6, eax }
break;
case 0x10u:
case 0x27u:
v51 = __readfsdword(v51);
break;
case 0x11u:
case 0x22u:
case 4u:
continue;
case 0x12u:
case 0x13u:
__asm { fsubr dword ptr [esp+0] }
break;
case 0x14u:
*(_WORD *)v55 = v56;
break;
case 0x15u:
__asm { fldlg2 }
break;
case 0x16u:
__asm { ftst }
break;
case 0x17u:
*MK_FP(__GS__, v57) = v58;
break;
case 0x18u:
v45 = *(_BYTE *)v32++;
v31 += ~(~(v31 + v45 - 82) - 62);
break;
case 0x19u:
__asm { fcos }
break;
case 0x1Bu:
v46 = *(_DWORD *)v46;
break;
case 0x1Cu:
__asm { fldpi }
break;
case 0x1Du:
_CF = (unsigned __int8)(v59 * (unsigned __int64)(unsigned int)v60 >> 32) != 0;
_OF = (unsigned __int8)(v59 * (unsigned __int64)(unsigned int)v60 >> 32) != 0;
UNDEF(_ZF);
UNDEF(_SF);
v17 = v59 * v60;
v59 = v59 * (unsigned __int64)(unsigned int)v60 >> 32;
v60 = v17;
__asm { pushfw }
break;
case 0x1Eu:
__ES__ = (unsigned __int16)v46;
break;
case 0x1Fu:
__asm { fst qword ptr [esp+0] }
break;
case 0x20u:
_CF = __CFSHL__(v53, v54);
UNDEF(_OF);
_ZF = v53 << v54 == 0;
_SF = (signed __int16)(v53 << v54) < 0;
*(_WORD *)&v54 = v53 << v54;
__asm { pushfw }
break;
case 0x21u:
v18 = *(_BYTE *)v32++;
v19 = (unsigned __int8)-(char)(((unsigned __int8)(v31 + v18 - 112) ^ 0xC8) - 90);
v31 += v19;
HIWORD(v57) = *(_BYTE *)(v30 + 4 * v19);
break;
case 0x23u:
*(int *)((char *)&v47 + 2) = *(_QWORD *)&v46 >> v48;
__asm { pushfw }
break;
case 0x24u:
*(unsigned int *)((char *)&v46 + 2) = v46 >> v47;
break;
case 0x25u:
_ECX = *(_DWORD *)&v52;
__asm { mov dr4, ecx }
break;
case 0x26u:
v40 = *(_BYTE *)v32++;
v31 += ~(~(v31 + v40 - 82) - 62);
break;
case 0x28u:
v12 = (unsigned int)(v53 * *(signed __int16 *)&v54) >> 16;
_CF = (unsigned __int8)((unsigned int)(v53 * *(signed __int16 *)&v54) >> 16) != 0;
_OF = (unsigned __int8)((unsigned int)(v53 * *(signed __int16 *)&v54) >> 16) != 0;
UNDEF(_ZF);
UNDEF(_SF);
*(_WORD *)&v54 *= v53;
v53 = v12;
__asm { pushfw }
break;
case 0x29u:
_CF = BYTE2(v39) != 0;
_OF = BYTE2(v39) != 0;
UNDEF(_ZF);
UNDEF(_SF);
HIWORD(v46) = (unsigned __int8)v46 * BYTE2(v46);
__asm { pushfw }
break;
case 0x2Au:
__asm { fnclex }
break;
case 0x2Bu:
__asm { fcomp dword ptr [esp+0] }
break;
case 0x2Cu:
__asm { fnstsw ax }
LOWORD(v57) = _AX;
break;
case 0x2Du:
v47 += v46;
break;
case 0x2Eu:
HIWORD(v46) = *(_WORD *)v46;
break;
}
}
}
对应的代码(部分,由于实在太长没补全):
CODE:0049A105 sub_49A105 proc near ; CODE XREF: .jwx1:005BE04Cj
CODE:0049A105 ; .jwx1:005BE072j ...
CODE:0049A105
CODE:0049A105 var_92 = byte ptr -92h
CODE:0049A105 var_86 = dword ptr -86h
CODE:0049A105 var_82 = dword ptr -82h
CODE:0049A105 anonymous_0 = byte ptr -46h
CODE:0049A105 anonymous_1 = word ptr -42h
CODE:0049A105 var_16 = dword ptr -16h
CODE:0049A105 var_12 = dword ptr -12h
CODE:0049A105 var_6 = byte ptr -6
CODE:0049A105 arg_4 = dword ptr 8
CODE:0049A105 arg_10 = qword ptr 14h
CODE:0049A105
CODE:0049A105 ; FUNCTION CHUNK AT CODE:00499C9D SIZE 00000009 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:00499CAD SIZE 00000009 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:00499D0C SIZE 00000013 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:00499D2C SIZE 0000000D BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:00499D73 SIZE 00000013 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:00499D8F SIZE 00000010 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:00499DC8 SIZE 00000012 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:00499DE5 SIZE 00000009 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:00499E38 SIZE 00000008 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:00499E5F SIZE 00000011 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:00499E85 SIZE 00000009 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:00499EAF SIZE 0000000A BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:00499ED8 SIZE 0000000D BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:00499F3B SIZE 00000007 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:00499FC5 SIZE 00000007 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049A0B6 SIZE 0000001C BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049A0EB SIZE 00000008 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049A0FC SIZE 00000009 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049A297 SIZE 00000007 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049A7CA SIZE 0000000F BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049A848 SIZE 00000016 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049A8D1 SIZE 00000009 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049A910 SIZE 00000012 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049A936 SIZE 00000007 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049A9B2 SIZE 00000006 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049A9C0 SIZE 00000011 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049A9F5 SIZE 0000000F BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049AA7C SIZE 0000000B BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049AA99 SIZE 0000000B BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049AACC SIZE 00000016 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049AAEB SIZE 00000007 BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049AB03 SIZE 0000000F BYTES
CODE:0049A105 ; FUNCTION CHUNK AT CODE:0049AB2E SIZE 0000000A BYTES
CODE:0049A105 ; FUNCTION CHUNK AT .jwx1:005C237A SIZE 0000000A BYTES
CODE:0049A105
CODE:0049A105 0 05C push ecx
CODE:0049A106 0 06E push ebx
CODE:0049A107 0 072 push edi
CODE:0049A108 0 076 push esp
CODE:0049A109 0 07A push ebp
CODE:0049A10A 0 07E push esi
CODE:0049A10B 0 082 push edx
CODE:0049A10C 0 086 push eax
CODE:0049A10D 0 08A pushf
CODE:0049A10E 0 08E push 0
CODE:0049A113 0 092 mov esi, [esp+28h]
CODE:0049A117 0 092 cld
CODE:0049A118 0 092 mov edx, offset unk_4A6000
CODE:0049A11D 0 092 call ds:__imp_GetCurrentThreadId
CODE:0049A123 0 092 mov ebx, eax
CODE:0049A125 0 092 mov ecx, 100h
CODE:0049A12A 0 092 mov edi, edx
CODE:0049A12C 0 092 repne scasd
CODE:0049A12E 0 092 jz short loc_49A13D
CODE:0049A130 0 092 mov eax, 100h
CODE:0049A135 0 092 xchg eax, ecx
CODE:0049A136 0 092 mov edi, edx
CODE:0049A138 0 092 repne scasd
CODE:0049A13A 0 092 mov [edi-4], ebx
CODE:0049A13D
CODE:0049A13D loc_49A13D: ; CODE XREF: sub_49A105+29j
CODE:0049A13D 0 092 mov ebp, edi
CODE:0049A13F 0 092 sub edi, edx
CODE:0049A141 0 092 shl edi, 1
CODE:0049A143 0 092 lea edi, [edx+edi*8+3C0h]
CODE:0049A14A
CODE:0049A14A loc_49A14A: ; CODE XREF: CODE:00499CD9j
CODE:0049A14A 0 092 mov ebx, esi
CODE:0049A14C 0 092 add esi, [esp]
CODE:0049A14F
CODE:0049A14F loc_49A14F: ; CODE XREF: CODE:00499C8Fj
CODE:0049A14F ; CODE:00499C98j ...
CODE:0049A14F 0 092 mov dl, [esi]
CODE:0049A151 0 092 add dl, bl
CODE:0049A153 0 092 inc dl
CODE:0049A155 0 092 rol dl, 7
CODE:0049A158 0 092 inc dl
CODE:0049A15A 0 092 rol dl, 1
CODE:0049A15C 0 092 inc dl
CODE:0049A15E 0 092 add esi, 1
CODE:0049A161 0 092 add bl, dl
CODE:0049A163 0 092 movzx eax, dl
CODE:0049A166 0 092 jmp off_49A2B6[eax*4]
CODE:0049A16D
CODE:0049A16D loc_49A16D: ; DATA XREF: CODE:0049A2C6o
CODE:0049A16D 0 092 push esp
CODE:0049A16E 0 096 jmp loc_49A14F
CODE:0049A16E ; ---------------------------------------------------------------------------
CODE:0049A173 0 096 db 97h
CODE:0049A174 0 096 dd 1F76h
CODE:0049A178 0 096 a_4d_2d_2d_2d_2 db '%.4d-%.2d-%.2d %.2d:%.2d:%.2d',0
CODE:0049A196 0 096 align 4
CODE:0049A198 0 096 push 0E9F1D453h
CODE:0049A19D 0 09A jmp loc_5C237A ; 查看痕迹11 time related
CODE:0049A1A2 ; ---------------------------------------------------------------------------
CODE:0049A1A2 0 09A pop ecx
CODE:0049A1A3 0 096 pop small word ptr es:[ecx]
CODE:0049A1A7 0 094 jmp loc_49A14F
CODE:0049A1AC ; ---------------------------------------------------------------------------
CODE:0049A1AC
CODE:0049A1AC loc_49A1AC: ; CODE XREF: sub_49A105+61j
CODE:0049A1AC ; DATA XREF: CODE:0049A36Eo
CODE:0049A1AC 0 092 pop edx
CODE:0049A1AD 0 08E push small word ptr es:[edx]
CODE:0049A1B1 0 090 jmp loc_49A14F
CODE:0049A1B6 ; ---------------------------------------------------------------------------
CODE:0049A1B6 0 090 pop ecx
CODE:0049A1B7 0 08C push dword ptr gs:[ecx]
CODE:0049A1BA 0 090 jmp loc_49A14F
CODE:0049A1BF ; ---------------------------------------------------------------------------
CODE:0049A1BF 0 090 pop ecx
CODE:0049A1C0 0 08C pop ax
CODE:0049A1C2 0 08A mov ss:[ecx], al
CODE:0049A1C5 0 08A jmp loc_49A14F
CODE:0049A1C5 ; ---------------------------------------------------------------------------
CODE:0049A1CA 0 08A db 0DFh
CODE:0049A1CB ; ---------------------------------------------------------------------------
CODE:0049A1CB 0 08A sub al, 24h
CODE:0049A1CD 0 08A jmp loc_49A14F
CODE:0049A1CD ; ---------------------------------------------------------------------------
CODE:0049A1D2 0 08A db 59h
CODE:0049A1D3 ; ---------------------------------------------------------------------------
CODE:0049A1D3 0 08A push small word ptr cs:[ecx]
CODE:0049A1D7 0 08C jmp loc_49A14F
CODE:0049A1DC ; ---------------------------------------------------------------------------
CODE:0049A1DC 0 08C pop cx
CODE:0049A1DE 0 08A jmp loc_49A14F
CODE:0049A1E3 ; ---------------------------------------------------------------------------
CODE:0049A1E3 0 08A pop eax
CODE:0049A1E4 0 086 pop dword ptr ss:[eax]
CODE:0049A1E7 0 082 jmp loc_49A14F
CODE:0049A1EC ; ---------------------------------------------------------------------------
CODE:0049A1EC db 66h
CODE:0049A1EC 0 082 push ds
CODE:0049A1EE 0 084 jmp loc_49A14F
CODE:0049A1F3 ; ---------------------------------------------------------------------------
CODE:0049A1F3 0 084 mov edx, cr1
CODE:0049A1F6 0 084 push edx
CODE:0049A1F7 0 088 jmp loc_49A14F
CODE:0049A1FC ; ---------------------------------------------------------------------------
CODE:0049A1FC 0 088 pop dx
CODE:0049A1FE 0 086 pop ax
CODE:0049A200 0 084 pop cx
CODE:0049A202 0 082 div cx
CODE:0049A205 0 082 push ax
CODE:0049A207 0 084 push dx
CODE:0049A209 0 086 jmp loc_49A14F
CODE:0049A20E ; ---------------------------------------------------------------------------
CODE:0049A20E 0 086 pop ecx
CODE:0049A20F 0 082 not ecx
CODE:0049A211 0 082 not [esp+82h+var_82]
CODE:0049A214 0 082 and [esp+82h+var_82], ecx
CODE:0049A217 0 082 pushfw
CODE:0049A219 0 084 jmp loc_49A14F
CODE:0049A21E ; ---------------------------------------------------------------------------
CODE:0049A21E
CODE:0049A21E loc_49A21E: ; CODE XREF: sub_49A105+61j
CODE:0049A21E ; DATA XREF: CODE:0049A34Eo
CODE:0049A21E 0 092 lodsb
CODE:0049A21F 0 092 add al, bl
CODE:0049A221 0 092 sub al, 52h
CODE:0049A223 0 092 not al
CODE:0049A225 0 092 sub al, 3Eh
CODE:0049A227 0 092 not al
CODE:0049A229 0 092 add bl, al
CODE:0049A22B 0 092 push ax
CODE:0049A22D 0 094 jmp loc_49A14F
CODE:0049A232 ; ---------------------------------------------------------------------------
CODE:0049A232
CODE:0049A232 loc_49A232: ; CODE XREF: sub_49A105+61j
CODE:0049A232 ; DATA XREF: CODE:0049A36Ao
CODE:0049A232 0 092 pop ecx
CODE:0049A233 0 08E add dword ptr [esp+8Eh+var_92+4], ecx
CODE:0049A236 0 08E jmp loc_49A14F
CODE:0049A23B ; ---------------------------------------------------------------------------
CODE:0049A23B 0 08E pop edx
CODE:0049A23C 0 08A mov dr5, edx
CODE:0049A23F 0 08A jmp loc_49A14F
CODE:0049A244 ; ---------------------------------------------------------------------------
CODE:0049A244 0 08A pop eax
CODE:0049A245 0 086 mov dr3, eax
CODE:0049A248 0 086 jmp loc_49A14F
CODE:0049A24D ; ---------------------------------------------------------------------------
CODE:0049A24D 0 086 fadd [esp+86h+var_86]
CODE:0049A250 0 086 jmp loc_49A14F
CODE:0049A255 ; ---------------------------------------------------------------------------
CODE:0049A255 0 086 pop eax
CODE:0049A256 0 082 push small word ptr gs:[eax]
CODE:0049A25A 0 084 jmp loc_49A14F
CODE:0049A25F ; ---------------------------------------------------------------------------
CODE:0049A25F 0 084 mov dx, fs
CODE:0049A262 0 084 push dx
CODE:0049A264 0 086 jmp loc_49A14F
CODE:0049A269 ; ---------------------------------------------------------------------------
CODE:0049A269 0 086 fprem
CODE:0049A26B 0 086 jmp loc_49A14F
CODE:0049A270 ; ---------------------------------------------------------------------------
CODE:0049A270 0 086 fst [esp+86h+var_86]
CODE:0049A273 0 086 jmp loc_49A14F
CODE:0049A278 ; ---------------------------------------------------------------------------
CODE:0049A278 0 086 fldln2
CODE:0049A27A 1 086 jmp loc_49A14F
CODE:0049A27F ; ---------------------------------------------------------------------------
CODE:0049A27F 1 086 fprem1
CODE:0049A281 1 086 jmp loc_49A14F
CODE:0049A286 ; ---------------------------------------------------------------------------
CODE:0049A286 1 086 pop eax
CODE:0049A287 1 082 mov cr2, eax
CODE:0049A28A 1 082 jmp loc_49A14F
CODE:0049A28A sub_49A105 endp ; sp-analysis failed
CODE:0049A28A
CODE:0049A28F ; ---------------------------------------------------------------------------
CODE:0049A28F fisub word ptr [esp]
CODE:0049A292 jmp loc_49A14F
CODE:0049A297 ; ---------------------------------------------------------------------------
CODE:0049A297 ; START OF FUNCTION CHUNK FOR sub_49A105
CODE:0049A297
CODE:0049A297 loc_49A297: ; CODE XREF: sub_49A105+61j
CODE:0049A297 ; DATA XREF: CODE:0049A35Eo
CODE:0049A297 0 0CA fnclex
CODE:0049A299 0 0CA jmp loc_49A14F
CODE:0049A299 ; END OF FUNCTION CHUNK FOR sub_49A105
CODE:0049A29E ; ---------------------------------------------------------------------------
CODE:0049A29E pop ecx
CODE:0049A29F pop dword ptr fs:[ecx]
CODE:0049A2A2 jmp loc_49A14F
CODE:0049A2A7 ; ---------------------------------------------------------------------------
CODE:0049A2A7 push ebx
CODE:0049A2A7 ; ---------------------------------------------------------------------------
CODE:0049A2A8 db 0Fh
CODE:0049A2A9 db 0ACh ;
CODE:0049A2AA db 8Bh ;
CODE:0049A2AB db 0C0h ;
下面还有很多类似的,省略了。
在调试中,每次程序运行某个新功能(如点击一个按钮),都会执行该段代码。个人感觉,是传说中的一种保护机制+花指令,不知道大牛能否指点下。
比如,DeDe中显示的某个按钮对应的RVA地址是0049A2AC,内容如下:
loc_49A2AC: ; DATA XREF: CODE:00499B64o
CODE:0049A2AC push 7BA49400h
CODE:0049A2B1 jmp loc_5BE122 ;
loc_5BE122: ; CODE XREF: CODE:0049A2B1j
.jwx1:005BE122 ; .jwx1:005BF33Dj
.jwx1:005BE122 push offset dword_4AE970
.jwx1:005BE127 jmp sub_49A105
基本每个按钮都类似,两次jmp跳转后到了sub_49A105,然后该函数内部经历颠来倒去的执行后,再要执行一段pushf起始、popf+retn结束的代码,才执行程序真正的算法的代码。比如ollydbg中Ctrl+F9,到达0x005becd5(此时ollydbg的反汇编已经出错,或者一旦移动指令的滚动条,就出错了,保护起作用了?)
.jwx1:005BECD5 pushf ; function:view
.jwx1:005BECD6 neg eax
.jwx1:005BECD8 lea eax, [eax+69FB4EBDh]
.jwx1:005BECDE inc edx
.jwx1:005BECDF neg edi
.jwx1:005BECE1 neg esi
.jwx1:005BECE3 xor ecx, 9EDF567h
.jwx1:005BECE9 neg edx
.jwx1:005BECEB not eax
.jwx1:005BECED ror edi, 16h
.jwx1:005BECF0 not ebx
.jwx1:005BECF2 not ecx
.jwx1:005BECF4 rol ebx, 2
.jwx1:005BECF7 xor eax, 0F9728541h
.jwx1:005BECFC dec ecx
.jwx1:005BECFD not ecx
.jwx1:005BECFF add ebx, 434F8044h
.jwx1:005BED05 neg ecx
.jwx1:005BED07 rol edx, 16h
.jwx1:005BED0A not edx
.jwx1:005BED0C xor esi, 6E86D853h
.jwx1:005BED12 bswap ebx
.jwx1:005BED14 sub ecx, 54CCA5EFh
.jwx1:005BED1A rol ebx, 1Eh
.jwx1:005BED1D sub edx, 36E0F994h
.jwx1:005BED23 xor edx, 61305FE6h
.jwx1:005BED29 lea edi, [edi+695E8B0Eh]
.jwx1:005BED2F lea ebx, [ebx+55BB756h]
.jwx1:005BED35 neg ebp
.jwx1:005BED37 xor ebp, 0F0A55AF4h
.jwx1:005BED3D inc esi
.jwx1:005BED3E neg ebp
.jwx1:005BED40 not esi
.jwx1:005BED42 dec ebp
.jwx1:005BED43 rol ebp, 17h
.jwx1:005BED46 bswap ebp
.jwx1:005BED48 neg esi
.jwx1:005BED4A ror edi, 8
.jwx1:005BED4D xor dword ptr [esp], 8D5h
.jwx1:005BED54 rol esi, 11h
.jwx1:005BED57 popf
.jwx1:005BED58 retn
.jwx1:005BED58 ; ---------------------------------------------------------------------------
上述这段代码执行后,程序执行正常的程序部分(位于CODE节中)
pushf和popf之间的代码是无效代码么?
如果创建函数,F5结果如下:
int __usercall sub_5BECD5<eax>(char _CF<cf>, char _ZF<zf>, char _SF<sf>, char _OF<of>, int a5<eax>)
{
int result; // eax@1
__asm { pushf }
result = ~(1778077373 - a5) ^ 0xF9728541;
__asm { popf }
return result;
}
这样看来还是有些用的。。。
执行完该正常部分函数后,又回到如下代码:
.jwx1:005BE31D push 5557A4h
.jwx1:005BE322 jmp sub_49A105
可见最后又回到了sub_49A105。sub_49A105这个位置的代码几乎就是中枢神经的位置了。有点像派遣函数的作用。似乎所有的程序正常功能的使用必须通过sub_49A105才能执行。
此外,sub_49A105的F5经常出现问题,可能是对应的汇编代码实在比较特殊吧(好多花指令的手法么?)。
基本的保护机制已经分析完毕,看看高手知道或者用过这种保护方式的,指点下吧,比如代码怎么写的。
[课程]FART 脱壳王!加量不加价!FART作者讲授!