能力值:
( LV2,RANK:10 )
|
-
-
2 楼
老惯例,自己帮顶!
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
我已经自行解决了这个问题,我真是个大菜鸟,不过通过此次成功,学到不少东西,有这方面经验的请加16905556与我交流,共同进步!
|
能力值:
( LV4,RANK:50 )
|
-
-
4 楼
你应该把整个过程写下来,供大家一起学习。
同时也是你前期成果的总结
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
呵呵,前端时间这个论坛进不去了,现在才放上去,各位见笑了!
序:
手头有个别人用delphi做的软件,使用过程中发现有bug存在,闲来无事决定对此bug进行修改,由于bug比较简单,不到半天时间全部搞定。
Bug现状:
程序要求刷卡次数为0或小于0,提示卡片无效。点击刷卡认证按钮后提示刷卡认证成功,然而刷卡次数没有减一,造成再次刷卡后刷卡次数为0或负数没能及时显示出来,造成刷卡次数判断失误。
所用工具软件:
1, Ollydbg脱壳,修改书写代码
2, peid查壳
3, dede分析delphi程序
处理方法与步骤:
主要操作步骤是:首先得获取刷卡次数编辑框的当前次数,次数减1,将减1后的次数填入编辑框。此步骤必须刷卡认证成功时执行,如果刷卡后出现任何错误都不执行此操作。
第一步:先用查壳工具查壳,发现加壳为弱壳,脱壳之。(脱壳相对简单,此处不再叙述)
第二步:将脱壳后的程序用dede分析,尽快得到关键点及程序流程。分析结果如下:
0064EDD2 8D55DC lea edx, [ebp-$24]
0064EDD5 8B8684030000 mov eax, [esi+$0384]//剩余次数控件
* Reference to: Controls.TControl.GetText(TControl):TCaption;
|
0064EDDB E868C3E1FF call 0046B148
0064EDE0 8B45DC mov eax, [ebp-$24]
* Reference to: SysUtils.StrToInt(AnsiString):Integer;
|
0064EDE3 E8A4AADBFF call 0040988C
0064EDE8 48 dec eax
0064EDE9 7D1D jnl 0064EE08//关键判断
0064EDEB 6A10 push $10
* Possible String Reference to: '提示信息'
|
0064EDED B93CF36400 mov ecx, $0064F33C
* Possible String Reference to: '卡片已过期!'
|
0064EDF2 BAA8F36400 mov edx, $0064F3A8
* Reference to TApplication instance
|
0064EDF7 A1A4A16600 mov eax, dword ptr [$0066A1A4]
0064EDFC 8B00 mov eax, [eax]
* Reference to: Forms.TApplication.MessageBox(TApplication;PChar;PChar;Longint):Integer;
|
0064EDFE E861D2E3FF call 0048C064
中间省略很多代码
* Reference to: DB.TDataSet.Close(TDataSet);
|
0064F1FB E894FEE6FF call 004BF094
0064F200 6A40 push $40
* Possible String Reference to: '提示信息'
|
0064F202 B93CF36400 mov ecx, $0064F33C
* Possible String Reference to: '刷卡认证完成!'
|
0064F207 BA7CF56400 mov edx, $0064F57C
* Reference to TApplication instance
|
0064F20C A1A4A16600 mov eax, dword ptr [$0066A1A4]
0064F211 8B00 mov eax, [eax]
* Reference to: Forms.TApplication.MessageBox(TApplication;PChar;PChar;Longint):Integer;
|
0064F213 E84CCEE3FF call 0048C064
0064F218 33C0 xor eax, eax
0064F21A 5A pop edx
0064F21B 59 pop ecx
0064F21C 59 pop ecx
0064F21D 648910 mov fs:[eax], edx
****** FINALLY //Clicked事件结束
|
* Possible String Reference to: '_^[?]?
|
0064F220 6834F36400 push $0064F334
0064F225 8D8564FFFFFF lea eax, [ebp+$FFFFFF64]
* Reference to: System.@LStrClr(void;void);
根据上面分析,只需要将红色部分代码加以修改即可。
第三步:开始添加处理代码,经过分析代码如下:
006626C7 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP
006626CA |. 8D55 F8 LEA EDX,DWORD PTR SS:[EBP-8]//局部变量
006626CD |. 8BB3 84030000 MOV ESI,DWORD PTR DS:[EBX+384]
//编辑框控件
006626D3 |. 8BC6 MOV EAX,ESI
006626D5 |. E8 6E8AE0FF CALL Sport4.0046B148//得到控件文本
006626DA |. 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
006626DD |. E8 AA71DAFF CALL Sport4.0040988C//转换文本成数值
006626E2 |. 48 DEC EAX//减一操作
006626E3 |. 8D55 FC LEA EDX,DWORD PTR SS:[EBP-4]
006626E6 |. E8 3570DAFF CALL Sport4.00409720//将数值转换成字符串
006626EB |. 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4]
006626EE |. 8BC6 MOV EAX,ESI
006626F0 |. E8 838AE0FF CALL Sport4.0046B178
//将减一后的字符串赋值到编辑框
以上关键地方是各个delphi内部导入函数的地址,就是call后面的地址。这些地址可以从上面分析其代码部分得到。
第四步:找到代码段空余部分,填入这些代码,空余代码就是代码段部分全部为00的地方,我找到地址006626C4启示的地方写入代码。利用16进制文件编辑软件winhex将16进制代码拷入就行。
第五步:把提示messbox框的代码追加到新加入的代码后面,让其处理完减一操作后弹出认证成功的提示框,然后在弹出提示框后用jmp命令跳转回原来的代码执行位置继续执行。加messagebox和jmp部分代码如下:
006626F9 . 33C0 XOR EAX,EAX
006626FB . 6A 40 PUSH 40
006626FD . B9 3CF36400 MOV ECX,Sport1.0064F33C
00662702 . BA 7CF56400 MOV EDX,Sport1.0064F57C
00662707 . A1 A4A16600 MOV EAX,DWORD PTR DS:[66A1A4]
0066270C . 8B00 MOV EAX,DWORD PTR DS:[EAX]
0066270E . E8 5199E2FF CALL Sport1.0048C064
00662713 . 33C0 XOR EAX,EAX
00662715 . 5A POP EDX
00662716 . 59 POP ECX
00662717 . 59 POP ECX
00662718 . 64:8910 MOV DWORD PTR FS:[EAX],EDX
0066271B . 68 18F26400 PUSH Sport1.0064F218//跳转到原来代码位置
00662720 . C3 RETN
第六步:修改原来程序流程,将代码转入写入的代码部分执行,修改前的代码可以通过上面dede分析过的代码查看,修改后的代码如下:
0064F1FB . E8 94FEE6FF CALL Sport1.004BF094//这里是原来的代码
0064F200 . 33C0 XOR EAX,EAX//此行可以不要
0064F202 E9 BD340100 JMP Sport1.006626C4//跳入新写入代码部分
0064F207 EB 0F JMP SHORT Sport1.0064F218//红色部分无用代码
0064F209 90 NOP
0064F20A 90 NOP
0064F20B 90 NOP
0064F20C A1 A4A16600 MOV EAX,DWORD PTR DS:[66A1A4]
0064F211 . 8B00 MOV EAX,DWORD PTR DS:[EAX]
0064F213 . E8 4CCEE3FF CALL Sport1.0048C064
0064F218 > 33C0 XOR EAX,EAX//执行完自己写的代码后返回到此
0064F21A . 5A POP EDX//下面代码为程序原有代码
0064F21B . 59 POP ECX
0064F21C . 59 POP ECX
0064F21D . 64:8910 MOV DWORD PTR FS:[EAX],EDX
0064F220 . 68 34F36400 PUSH Sport1.0064F334
0064F225 > 8D85 64FFFFFF LEA EAX,DWORD PTR SS:[EBP-9C]
总结:
PEDIY其实并不难,关键要有耐心,第一次修改PE实现自己的功能,感觉挺有成就感(高手别笑),由于自己还是菜鸟,以后需要学习的东西还很多很多。此文如有不对之处还希望高手批评指正,谢谢!
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
这里代码没有颜色,红色部分显示不出来,想仔细看的朋友可以去我的博客看,那里跟这里一样,可是有颜色,我博客地址是http://21jhf.52blog.net/
|