-
-
[讨论]实战自己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//eaxedi
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期)
赞赏
- [求助]写idapyhton时碰到 将字符串‘f0’转换成int 类型的问题 3432
- [原创]手工消息断点的一个小例子 9394
- [分享]另辟蹊径找关键字符串 9602
- [讨论]实战自己idc 9510