首页
社区
课程
招聘
[讨论]实战自己idc
发表于: 2009-11-15 21:09 9509

[讨论]实战自己idc

2009-11-15 21:09
9509

为了测试自己写的idc version2 : show_variable_of_win32api.inc

用pdf2Word练手:
1.        先把pdf2Word脱壳,用ida载入后,看看import 表,发现有MessageBoxA,MessageBoxW
     
2.        加载我的show_variable_of_win32api.inc,会提示要求输入

在这里我输入感兴趣的MessageBoxA,接下来输入2来表示MessageBoxA第二个参数lptext

回车后,一路按yes,该脚本会生成一个记载push给相应函数的值的log文件。(主要push的是直接数,就会在log文件中提示相应的字符串,并在push处设为绿色底色;

在push处设为红色底色,并加注释为”need to further analyze”,提示需要调试才能知道实际push的字符串)

再来看看生成的log文件。
pdf2word_Unpack_MessageBoxA_2 has been created
pdf2word_Unpack.exe
MessageBoxA is in function's name:
sub_405C70
call MessageBoxA at seg000:00405D38
addr is seg000:00405D32
>>Tip string is
->Please register VeryPDF PDF2Word v3.0!
/---------------------------------------------------/
MessageBoxA is in function's name:
sub_405C70
call MessageBoxA at seg000:00405D9F
addr is seg000:00405D99
>>Tip string is
->Thank you registered VeryPDF PDF2Word v3.0.Thank you.----看到重要提示了(显示成功消息)地址是00405D9F
跳过去看看

看看结构左面是通向准确的分支,右面是错误的。然后看跳的地方代码如下
seg000:00405D56
seg000:00405D56 loc_405D56:                             ; CODE XREF: sub_405C70+5A j
seg000:00405D56                 mov     esi, [esp+0E4h+hWnd]
seg000:00405D5D                 push    0C8h            ; cchMax
seg000:00405D62                 mov     ecx, 32h
seg000:00405D67                 xor     eax, eax
seg000:00405D69                 mov     edi, offset byte_6D36FC
seg000:00405D6E                 push    offset byte_6D36FC ; lpString
seg000:00405D73                 push    3FBh            ; nIDDlgItem
seg000:00405D78                 push    esi             ; hDlg
seg000:00405D79                 rep stosd
seg000:00405D7B                 call    ds:GetDlgItemTextA
seg000:00405D81                 push    offset byte_6D36FC
seg000:00405D86                 call    sub_405620//所谓的关键call
seg000:00405D8B                 add     esp, 4
seg000:00405D8E                 test    eax, eax  //(比较返回的eax是否为0)
seg000:00405D90                 jz      short loc_405DD6(为0验证失败)
从下往上看:分析后,有了思路,只要在seg000:00405D86                 call    sub_405620//所谓的关键call,返回的eax不为0 ,就可以验证成功,大家可以看到在上面的00405D67处的xor  eax, eax,将eax已经清零了,也就是说在xor  eax, eax,和,test eax,eax之间如果eax值不变化的,铁定验证失败。
看到中间有2个call,一个是call GetDlgItemTextA
GetDlgItemText function retrieves the title or text associated with a control in a dialog box.
UINT GetDlgItemText(
    HWND hDlg,        // handle of dialog box
    int nIDDlgItem,        // identifier of control
    LPTSTR lpString,        // address of buffer for text //可以到此处看看到底获取了什么字符串
    int nMaxCount         // maximum size of string
   );
因此内存地址6D36FC将用来存放获得的数据,在调试时,应当关注
seg000:00405D69 mov     edi, offset byte_6D36FC//将edi作为指针指向内存6D36FC
seg000:00405D6E push    offset byte_6D36FC ; lpString

我用od调试(因为方便),00405D7B下断
seg000:00405D7B  call    ds:GetDlgItemTextA
seg000:00405D81  push    offset byte_6D36FC//又将取得的字符串push给关键call
seg000:00405D86   call    sub_405620//所谓的关键call
转到sub_405620看看

seg000:00405620 sub_405620 proc near
seg000:00405620
seg000:00405620 Str= byte ptr -18h
seg000:00405620 var_17= byte ptr -17h
seg000:00405620 var_C= byte ptr -0Ch
seg000:00405620 var_B= byte ptr -0Bh
seg000:00405620 arg_0= dword ptr  4
seg000:00405620
seg000:00405620 sub     esp, 18h
seg000:00405623 or      ecx, 0FFFFFFFFh//ecx=0FFFFFFFFh
seg000:00405626 xor     eax, eax //eax清零 eax是验证的关键标志
seg000:00405628 push    ebx
seg000:00405629 push    esi
seg000:0040562A mov     esi, [esp+20h+arg_0]// arg_0是6D36FC(放字符串的内存地址)
                                                                                //esi指向该内存
seg000:0040562E push    edi                                //保存edi
seg000:0040562F mov     edi, esi                        //edi也指向该内存
seg000:00405631 repne scasb                //scasb Compare AL with byte at ES:(E)DI and set status flags
                                                        REPNE/REPNZ - Repeat Not Equal / Repeat Not Zero
seg000:00405633 not     ecx
seg000:00405635 dec     ecx        //得到字符串长度
seg000:00405636 cmp     ecx, 14h//与20(14h)比较
seg000:00405639 jz      short loc//长度为20的跳到short loc否则就如下情况发生
------------------------
seg000:0040563B pop     edi
seg000:0040563C pop     esi
seg000:0040563D pop     ebx
seg000:0040563E add     esp, 18h
seg000:00405641 retn  //在这段里没有出现eax的变化,不是我们想要的同时得出
                                        字符串的成都必须为20

看我们应该去的
seg000:00405642
seg000:00405642 loc_405642:
seg000:00405642 mov     al, [esi]//取字符串第一位al
seg000:00405644 mov     cl, [esi+1] //取字符串第2位cl
seg000:00405647 lea     edx, [esp+24h+Str] //将局部变量str的地址传给edx
seg000:0040564B xor     bl, bl//bl清零bl=0
seg000:0040564D push    edx             ; Str//将str地址 入栈
                                                                                  //后面的mov命令不移动栈顶
seg000:0040564E mov     [esp+28h+var_C], al//局部变量var_c=al字符串第一位
seg000:00405652 mov     [esp+28h+var_B], bl//局部变量var_b=bl=0
seg000:00405656 mov     [esp+28h+Str], cl//局部变量str=cl字符串第二位
seg000:0040565A mov     [esp+28h+var_17], bl//局部变量var_17=bl=0
seg000:0040565E call    _atoi         // 此时的栈顶是str的地址,因此载入的是存放第二位的地址int atoi ( const char * str )将字符串转化为整型数,返回eax
seg000:00405663 mov     edi, eax//eaxedi
seg000:00405665 lea     eax, [esp+28h+var_C]//放1位数据的地址传给eax
seg000:00405669 push    eax             ; Str压栈
seg000:0040566A call    _atoi                //调用,
seg000:0040566F add     edi, eax        //2位+1位的值
seg000:00405671 add     esp, 8
seg000:00405674 cmp     edi, 0Bh//2位+1位的值和13(0bh) 比
seg000:00405677 jz      short loc_
不等就到下面,看到xor eax,eax 又将eax清零,验证失败。
seg000:00405679 pop     edi
seg000:0040567A pop     esi
seg000:0040567B xor     eax, eax
seg000:0040567D pop     ebx
seg000:0040567E add     esp, 18h
seg000:00405681 retn
准确应跳到这
seg000:00405682
seg000:00405682 loc_405682:
seg000:00405682 mov     cl, [esi+12h]
seg000:00405685 mov     dl, [esi+13h]
seg000:00405688 lea     eax, [esp+24h+Str]
seg000:0040568C mov     [esp+24h+var_C], cl
seg000:00405690 push    eax             ; Str
seg000:00405691 mov     [esp+28h+var_B], bl
seg000:00405695 mov     [esp+28h+Str], dl
seg000:00405699 mov     [esp+28h+var_17], bl
seg000:0040569D call    _atoi
seg000:004056A2 lea     ecx, [esp+28h+var_C]
seg000:004056A6 mov     edi, eax
seg000:004056A8 push    ecx             ; Str
seg000:004056A9 call    _atoi
seg000:004056AE add     edi, eax
seg000:004056B0 add     esp, 8
seg000:004056B3 cmp     edi, 0Eh
seg000:004056B6 jz      short loc_40
这段代码和上面分析的类似:用红色标示关键代码
是要求19(13h)位和20(14h)位相加=14(0eh)

seg000:004056C1
seg000:004056C1 loc_4056C1:
seg000:004056C1 mov     dl, [esi+5]                        6位
seg000:004056C4 mov     al, [esi+0Dh]                13位
seg000:004056C7 lea     ecx, [esp+24h+Str]
seg000:004056CB mov     [esp+24h+var_C], dl
seg000:004056CF push    ecx             ; Str
seg000:004056D0 mov     [esp+28h+var_B], bl
seg000:004056D4 mov     [esp+28h+Str], al
seg000:004056D8 mov     [esp+28h+var_17], bl
seg000:004056DC call    _atoi
seg000:004056E1 lea     edx, [esp+28h+var_C]
seg000:004056E5 mov     edi, eax
seg000:004056E7 push    edx             ; Str
seg000:004056E8 call    _atoi
seg000:004056ED add     edi, eax
seg000:004056EF add     esp, 8
seg000:004056F2 cmp     edi, 9
seg000:004056F5 jz      short loc_
这段要求6位+13位=9

eg000:00405700
seg000:00405700 loc_405700:
seg000:00405700 cmp     byte ptr [esi+0Ch], 56h         12位和V(56h)比较
seg000:00405704 jz      short loc_
12位要等于V

seg000:0040570F
seg000:0040570F loc_40570F:
seg000:0040570F mov     cl, [esi+0Eh]  14位和3(33h)要相等
seg000:00405712 xor     eax, eax
seg000:00405714 cmp     cl, 33h
seg000:00405717 pop     edi
seg000:00405718 pop     esi
seg000:00405719 pop     ebx
seg000:0040571A setz    al                        Sets the byte in the operand to 1 if the Zero Flag is set,
                                                        otherwise sets the operand to 0.如果cmp cl, 33h相等
                                                                al置1 这就是我想要的                                                               
seg000:0040571D add     esp, 18h
seg000:00405720 retn
seg000:00405720 sub_405620 endp
seg000:00405720

总结一下://算法
sn[]
len=20
sn[0]+sn[1]=11;1bit+2bit=11
sn[0x12]+sn[0x13]=sn[18]+sn[19]=bit19+bit20=14
sn[5h]+sn[dh]=sn[5]+sn[13]=bit6+bit14=9
sn[0ch]=sn[12]=bit13=V(56h)
sn[0eh]=sn[14]=bit15=3(33h)

明天写个注册机


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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (2)
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
哈 这个算做广告么?
2010-4-10 03:56
0
雪    币: 79
活跃值: (35)
能力值: ( LV2,RANK:150 )
在线值:
发帖
回帖
粉丝
3
IDA本身也会分析很多API的参数,我很感兴趣你的API参数资料从哪里来的?
2010-6-5 15:38
0
游客
登录 | 注册 方可回帖
返回
//