老文章档案 · 2003 年

diy pe教学4

破解教程 · 破解杂谈 · 2003-09-16 · 作者:pll621 人气: · 出处:赢政天下整理收藏)

看到kanxun发布的这个搜索版,我测试了一下,所有补丁的动作都在w32dsm.dll里面,更改了程序的入口使其一开始就loadlibary w32dsm.dll,然后w32dsm.dll 会修改原程序相关的指令,主要与弹出搜索dialog的api是createdialogparam,加载w32dsm.dll和没有加载,其消息函数的地址,和显示的资源都不一样,这个有搜索edit,和button的dialog资源在w32dsm.dll里面,当而且w32dsm.dll还有专门处理搜索的消息函数,其他处理函数和原来程序函数功能一致没有什么变化,

我现在将这个搜索消息函数分析一下,给有兴趣把killer版10的w32asm也加上这个功能的朋友做参考,希望大家迎难而上,多多实践

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:10002298(C)

|

:100022AD 3D11010000 cmp eax, 00000111==>比较消息是否是wm_command

:100022B2 7525 jne 100022D9===>不是完蛋

:100022B4 8B4510 mov eax, dword ptr [ebp+10]

:100022B7 663D6318 cmp ax, 1863==>比较子参量是否点击search按钮

:100022BB 7518 jne 100022D5

:100022BD 6860180000 push 00001860

:100022C2 68FF550000 push 000055FF

:100022C7 FF7508 push [ebp+08]

:100022CA E89F020000 call 1000256E==>做search的功能

:100022CF C9 leave

:100022D0 C21000 ret 0010

call到这里

:1000256E 55 push ebp

:1000256F 8BEC mov ebp, esp

:10002571 FF750C push [ebp+0C]===>identifier of control

:10002574 FF7508 push [ebp+08]==> handle of dialog box

* Reference To: USER32.GetDlgItem, Ord:0100h

|

:10002577 E838050000 Call 10002AB4

:1000257C A310660010 mov dword ptr [10006610], eax==>这样会得到search文本框的handle

:10002581 6800020000 push 00000200==>最大字符支持512个

:10002586 68EC680010 push 100068EC===>拷贝你要搜索的字符到这个buffer

:1000258B FF7510 push [ebp+10]==>identifier of control

:1000258E FF7508 push [ebp+08]==>handle of dialog box

* Reference To: USER32.GetDlgItemTextA, Ord:0102h

|

:10002591 E824050000 Call 10002ABA==》这个函数大家都知道干什么

:10002596 0BC0 or eax, eax

:10002598 7506 jne 100025A0==>判断是否有字符拷贝,没有就不搜索了

:1000259A 33C0 xor eax, eax

:1000259C C9 leave

:1000259D C20C00 ret 000C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:10002598(C)

|

:100025A0 6A00 push 00000000

:100025A2 6A00 push 00000000

:100025A4 688B010000 push 0000018B===>发送一个LB_GETCOUNT消息给下面的list框,需要得到有多少个需要比较

:100025A9 FF3510660010 push dword ptr [10006610]

* Reference To: USER32.SendMessageA, Ord:0210h

|

:100025AF E830050000 Call 10002AE4

:100025B4 A30C660010 mov dword ptr [1000660C], eax==>返回list列表的个数到这个地址

:100025B9 6A00 push 00000000

:100025BB 6A00 push 00000000

:100025BD 6888010000 push 00000188==>发送LB_GETCURSEL消息给list筐,目的是得到现在选中字串的index

:100025C2 FF3510660010 push dword ptr [10006610]

* Reference To: USER32.SendMessageA, Ord:0210h

|

:100025C8 E817050000 Call 10002AE4

:100025CD 83F8FF cmp eax, FFFFFFFF==》比较是否有没有选中list框中的某个字串,如果有的话返回的是选中的字串index,没有选中返回ffffffff(-1)

:100025D0 7502 jne 100025D4==>有字窜选中,跳到100025D4

:100025D2 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:100025D0(C)

|

:100025D4 A308660010 mov dword ptr [10006608], eax==>给这个变量清零,这个变量是代表搜索的次数

:100025D9 A3F8650010 mov dword ptr [100065F8], eax==>给这个变量清零,这个变量其实是表示你需要搜索字串的实际index

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:10002664(U)

|

:100025DE FF0508660010 inc dword ptr [10006608]==》搜索的index加1

:100025E4 A108660010 mov eax, dword ptr [10006608]

:100025E9 3B050C660010 cmp eax, dword ptr [1000660C]==>和listist列表的个数比较,看是否已经全部搜索晚所有的列出的字串

:100025EF 7507 jne 100025F8==>没有搜索完,继续搜索

:100025F1 33C0 xor eax, eax

:100025F3 A308660010 mov dword ptr [10006608], eax==>已经搜索到最后的list了,把搜索的index清空,准备重头搜索

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:100025EF(C)

|

:100025F8 3B05F8650010 cmp eax, dword ptr [100065F8]==>比较是否和实际搜索到的index相等

:100025FE 7519 jne 10002619==>不等跳到10002619

:10002600 6A00 push 00000000

:10002602 50 push eax====>相等,搜索到字传的index

:10002603 6886010000 push 00000186==>发一个LB_SETCURSEL消息给list框,然后返回,这样那条蓝条就会停在搜索到的字串上

:10002608 FF3510660010 push dword ptr [10006610]

* Reference To: USER32.SendMessageA, Ord:0210h

|

:1000260E E8D1040000 Call 10002AE4

:10002613 33C0 xor eax, eax

:10002615 C9 leave

:10002616 C20C00 ret 000C===>已经搜索到需要找得字串,返回,

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:100025FE(C)比较是否和实际搜索到的index不相等,跳过来的

|

:10002619 68EC6A0010 push 10006AEC==》得到的字串放到这个变量里面

:1000261E 50 push eax==>这里是现在搜索到那个字串的index了

:1000261F 6889010000 push 00000189==>发送LB_GETTEXT 消息给list框,告诉它我们现在搜索到eax值的index,list把这个index对应的字串

放到10006AEC这个地址里去,我们等下好比较是否GetDlgItemTextA得到搜索框的字串和这个地址的是否相等

:10002624 FF3510660010 push dword ptr [10006610]

* Reference To: USER32.SendMessageA, Ord:0210h

|

:1000262A E8B5040000 Call 10002AE4

:1000262F 0BC0 or eax, eax==如果成功的话eax是拷贝字串的数目

:10002631 7431 je 10002664==》失败就跳到比较下一条index

:10002633 68EC680010 push 100068EC===>这个是我们现在index字串的地址

:10002638 68EC6A0010 push 10006AEC==>这个是GetDlgItemTextA得到字串保存的地址

:1000263D E821030000 call 10002963===>想都不要想就知道这个call是比较上面两个字窜是否相等

:10002642 0BC0 or eax, eax

:10002644 741E je 10002664==》不相等跳到比较下一条index

:10002646 6A00 push 00000000

:10002648 FF3508660010 push dword ptr [10006608]===>现在index和GetDlgItemTextA得到字串相等,把那个蓝条放到这个index上

:1000264E 6886010000 push 00000186==》LB_SETCURSEL

:10002653 FF3510660010 push dword ptr [10006610]

* Reference To: USER32.SendMessageA, Ord:0210h

|

:10002659 E886040000 Call 10002AE4

:1000265E 33C0 xor eax, eax

:10002660 C9 leave

:10002661 C20C00 ret 000C==>找到一个,比较完成,返回

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:10002631(C), :10002644(C)

|

:10002664 E975FFFFFF jmp 100025DE===>跳到把[10006608]的值加1,比较下一个index是否相等

好了,怎么搜索的原理我已经分析玩了,怎么diy 这个pe,我还有有些想法的,到了killer的10版以后creatdialog这些功能都在w32path这个dll里面了,如果

补丁的话,需要做的事情很多,首先更改资源,增加一个edit控件,一个button,增加捕获这个事件的功能,然后参照上面的程序,做相应的动作,需要的工作量太大了(如果有毅力有横心还是能完成的:)),我现在没有足够的时间来干这个工作,那个朋友有兴趣,可以试试,做不下去的话可以email质询我,我尽力帮忙,造福大家的事情就靠你们了,:)

--------------------------------------------------------------------------------

标 题:diype5 (20千字)

发信人:pll621

时 间:2002-8-25 16:18:25

详细信息:

前言:看雪提供了一个老外作的w32asm,带搜索这个很实用的功能,不过是在8.93版上补丁的,很多kill版的实用功能都没有,我用着不习惯

于是就自己在原来作拖放和滚动版本基础上再加上搜索功能.其实这篇文章没有什么新的东西,也就是把我前面几篇文章提到的

技术全部用上,搞了个综合篇:)

说起来容易,做起来就.....

首先分析问题:

第一、从资源的角度上分析

w32asm一共有str、dlg、menu、code、data、exp、imp这七个dilog需要增加搜索功能

增加搜索功能就是每个dilog需要增加一个edit控件,一个标题为search的button控件(方法见diype系列前面的文章,我不重复讲相同的东西)

1、首先把我这个拖放版的资源释放出来(具体细节与文章内容无关,略去)

2、打开资源黑客,找到str、dlg这个7个dilog的资源,每个dilog都增加一个edit控件(把这个edit的id设为1568),再增加一个button(每个

dilog增加button的id都不同,我等一下列个表给大家),然后记下每个dialog的list控件的id,最后调整资源界面,让它们好看一点

第二、从编程的角度上去分析

1、资源添加好了,我们需要让它动起来,要做到和w32asm结合再一起,就需要找到w32asm的消息处理的进程,然后更改这个进程、加入我们需要

实现的功能,再windows系统里面,每个弹出的dilog都有自己的消息处理进程,和程序主消息处理进程不相干,也就是说我们上次作拖放功能的

消息进程和作搜索功能的消息进程不是一个进程、现找到消息处理进程地址是4981e3(怎么找消息进程的方法diype前面的文章有讲述),这7个

dialog共享这个消息进程,这样很好,省了很多事情

004981E3 . 55 PUSH EBP===>c++参数传递

004981E4 . 8BEC MOV EBP,ESP

004981E6 . 83C4 D8 ADD ESP,-28

004981E9 . 53 PUSH EBX

004981EA . 56 PUSH ESI

004981EB . 57 PUSH EDI

004981EC . 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C]==》[EBP+C]就是消息代码

004981EF . 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8]==》[EBP+8]接收消息窗口句柄

004981F2 . B8 E4D54C0>MOV EAX,kW32Dsm_.004CD5E4

004981F7 . E8 0CFC000>CALL kW32Dsm_.004A7E08

消息处理进程找到了,现在就加入我们的代码,更改如下:

004981E3 . 55 PUSH EBP

004981E4 . 8BEC MOV EBP,ESP

004981E6 . 83C4 D8 ADD ESP,-28

004981E9 . 53 PUSH EBX

004981EA . 56 PUSH ESI

004981EB . 57 PUSH EDI

004981EC . E9 9F720100 JMP pll621_9.004AF490==》跳到我们自己的代码段

004981F1 90 NOP

004981F2 > B8 E4D54C00 MOV EAX,pll621_9.004CD5E4

JMP pll621_9.004AF490自己的代码到这里:

004AF490 > 817D 0C 11010000 CMP DWORD PTR SS:[EBP+C],111==>比较消息是否是wm_command

004AF497 . 75 09 JNZ SHORT pll621_9.004AF4A2==》不是恢复源程序动作,然后返回

004AF499 . E9 32020000 JMP pll621_9.004AF6D0===》是就跳到比较子参量

004AF49E 90 NOP

004AF49F 90 NOP

004AF4A0 90 NOP

004AF4A1 90 NOP

004AF4A2 > 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C]==》恢复源程序动作

004AF4A5 . 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8]

004AF4A8 .^E9 458DFEFF JMP pll621_9.004981F2==》调回原程序执行

现在我们就需要知道点击了那个dilog的search按钮,判别就靠每个dialog的search按钮id是不同,我把我定义的按钮id

和dialog、和list控件id的值列表如下:

dialog str dlg menu code data exp imp

消息进程地址 4981e3 4981e3 4981e3 4981e3 4981e3 4981e3 4981e3

list控件id 55ff 5625 5624 5602 5603 55fe 55fd (16进制)

增加搜索按钮id 621 627 626 625 624 623 622 (16进制)

1569 1575 1574 1573 1572 1571 1570 (转成10进制,因为资源黑客是用10进制)

既然知道了每个dialog上面添加的search按钮的id都不同,那么我们就能为每个dialog作不同的处理了

JMP pll621_9.004AF6D0===》是就跳到比较子参量跳到这里:

004AF6D0 > 817D 10 21060000 CMP DWORD PTR SS:[EBP+10],621==》比较是否点击了str的search按钮

004AF6D7 . 75 0A JNZ SHORT pll621_9.004AF6E3

004AF6D9 . B8 FF550000 MOV EAX,55FF============>点击了str的search按钮,那么保存str的list控件的id到eax

004AF6DE .^E9 D0FDFFFF JMP pll621_9.004AF4B3==》跳到搜索功能实现代码

004AF6E3 > 817D 10 22060000 CMP DWORD PTR SS:[EBP+10],622==》比较是否点击了imp的search按钮

004AF6EA . 75 0A JNZ SHORT pll621_9.004AF6F6

004AF6EC . B8 FD550000 MOV EAX,55FD============>点击了imp的search按钮,那么保存str的list控件的id到eax

004AF6F1 .^E9 BDFDFFFF JMP pll621_9.004AF4B3==》跳到搜索功能实现代码,以下代码功能类似,我就不一一写注释了

004AF6F6 > 817D 10 23060000 CMP DWORD PTR SS:[EBP+10],623

004AF6FD . 75 0A JNZ SHORT pll621_9.004AF709

004AF6FF . B8 FE550000 MOV EAX,55FE

004AF704 .^E9 AAFDFFFF JMP pll621_9.004AF4B3

004AF709 > 817D 10 24060000 CMP DWORD PTR SS:[EBP+10],624

004AF710 . 75 0A JNZ SHORT pll621_9.004AF71C

004AF712 . B8 03560000 MOV EAX,5603

004AF717 .^E9 97FDFFFF JMP pll621_9.004AF4B3

004AF71C > 817D 10 25060000 CMP DWORD PTR SS:[EBP+10],625

004AF723 . 75 0A JNZ SHORT pll621_9.004AF72F

004AF725 . B8 02560000 MOV EAX,5602

004AF72A .^E9 84FDFFFF JMP pll621_9.004AF4B3

004AF72F > 817D 10 26060000 CMP DWORD PTR SS:[EBP+10],626

004AF736 . 75 0A JNZ SHORT pll621_9.004AF742

004AF738 . B8 24560000 MOV EAX,5624

004AF73D .^E9 71FDFFFF JMP pll621_9.004AF4B3

004AF742 > 817D 10 27060000 CMP DWORD PTR SS:[EBP+10],627

004AF749 . 75 0A JNZ SHORT pll621_9.004AF755

004AF74B . B8 25560000 MOV EAX,5625

004AF750 .^E9 5EFDFFFF JMP pll621_9.004AF4B3

004AF755 >^E9 48FDFFFF JMP pll621_9.004AF4A2===》没有点击我们添加的search按钮,返回原程序

这七个dialog的search按钮区分代码也写好了,那么下一步就需要实现搜索功能了,

我大致讲一下实现搜索功能原理,

1、首先得到dialog里面list控件的handle,使用GetDlgItem函数实现

2、得到我们edit控件里面的字符保存到一个地址(也就是我们要搜索的字符),使用GetDlgItemtexta实现

3、通过list控件的handle使用sendmessage函数得到list控件一共有多少条需要我们搜索

4、把我们需要搜索的字符和list控件里面字符,一条一条比较,如果比较到最后了,就从头比较(这个比较函数,还得自己写,windows是没有相关的api)

5、如果list控件里面某一条包含我们需要搜索的字符,那么我们就认为找到了,就把那个兰条设置到找到的这条上

6、如果继续寻找就,把从当前位置往下,重复4、5部,直到全部搜索完毕,再重头搜索

7、所有对list的控制都靠list的handle和sendmessage函数实现

8、具体原理,看我昨天写的那篇对diype的一点想法文章

9、由于原程序没有上述的api函数、所以自己构造了GetDlgItem、GetDlgItemtexta、sendmessage三个函数(构造方法见diype3那篇文章)

程序用到的变量声明:

4aff00-------------list控件的handle

4aff04-------------list控件index的总数

4aff08-------------现在搜索到那一条index

4aff0c-------实际的index

4aff10-------作比较字符函数,保存原来的返回地址

4aff14-------目的字符比较指针

4AFD00-------源字符地址

4afc00-------目的字符地址

这里是实现搜索功能了的代码

004AF4B3 > 50 PUSH EAX ; /ControlID====》每个dialog的list控件的id都不同,所以我用eax作变量

004AF4B4 . 90 NOP ; |

004AF4B5 . 90 NOP ; |

004AF4B6 . 90 NOP ; |

004AF4B7 . 90 NOP ; |

004AF4B8 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd

004AF4BB . E8 96FFFFFF CALL pll621_9.004AF456 ; \GetDlgItem

004AF4C0 . A3 00FF4A00 MOV DWORD PTR DS:[4AFF00],EAX================》这样eax会得到list的handle

004AF4C5 . 68 00010000 PUSH 100 ; /Count = 100 (256.)====》最多只能搜索512个字符,记住不要超过了

,否则非法超作不要找我

004AF4CA . 68 00FD4A00 PUSH pll621_9.004AFD00 ; |Buffer = pll621_9.004AFD00

004AF4CF . 68 20060000 PUSH 620 ; |ControlID = 620 (1568.)

004AF4D4 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd

004AF4D7 . E8 74FFFFFF CALL pll621_9.004AF450 ; \GetDlgItemTextA

004AF4DC . 09C0 OR EAX,EAX

004AF4DE . 75 05 JNZ SHORT pll621_9.004AF4E5

004AF4E0 . 33C0 XOR EAX,EAX

004AF4E2 .^EB BE JMP SHORT pll621_9.004AF4A2

004AF4E4 90 NOP

004AF4E5 > 6A 00 PUSH 0 ; /lParam = 0

004AF4E7 . 6A 00 PUSH 0 ; |wParam = 0

004AF4E9 . 68 8B010000 PUSH 18B ; |Message = LB_GETCOUNT

004AF4EE . FF35 00FF4A00 PUSH DWORD PTR DS:[4AFF00] ; |hWnd = NULL

004AF4F4 . E8 63FFFFFF CALL pll621_9.004AF45C ; \SendMessageA

004AF4F9 . A3 04FF4A00 MOV DWORD PTR DS:[4AFF04],EAX

004AF4FE . 6A 00 PUSH 0 ; /lParam = 0

004AF500 . 6A 00 PUSH 0 ; |wParam = 0

004AF502 . 68 88010000 PUSH 188 ; |Message = LB_GETCURSEL

004AF507 . FF35 00FF4A00 PUSH DWORD PTR DS:[4AFF00] ; |hWnd = NULL

004AF50D . E8 4AFFFFFF CALL pll621_9.004AF45C ; \SendMessageA

004AF512 . 83F8 FF CMP EAX,-1

004AF515 . 75 02 JNZ SHORT pll621_9.004AF519

004AF517 . 33C0 XOR EAX,EAX

004AF519 > A3 08FF4A00 MOV DWORD PTR DS:[4AFF08],EAX

004AF51E . A3 0CFF4A00 MOV DWORD PTR DS:[4AFF0C],EAX

004AF523 > FF05 08FF4A00 INC DWORD PTR DS:[4AFF08]

004AF529 . A1 08FF4A00 MOV EAX,DWORD PTR DS:[4AFF08]

004AF52E . 3B05 04FF4A00 CMP EAX,DWORD PTR DS:[4AFF04]

004AF534 . 75 07 JNZ SHORT pll621_9.004AF53D

004AF536 . 33C0 XOR EAX,EAX

004AF538 . A3 08FF4A00 MOV DWORD PTR DS:[4AFF08],EAX

004AF53D > 3B05 0CFF4A00 CMP EAX,DWORD PTR DS:[4AFF0C]

004AF543 . 75 1A JNZ SHORT pll621_9.004AF55F

004AF545 . 6A 00 PUSH 0 ; /lParam = 0

004AF547 . 50 PUSH EAX ; |wParam

004AF548 . 68 86010000 PUSH 186 ; |Message = LB_SETCURSEL

004AF54D . FF35 00FF4A00 PUSH DWORD PTR DS:[4AFF00] ; |hWnd = NULL

004AF553 . E8 04FFFFFF CALL pll621_9.004AF45C ; \SendMessageA

004AF558 . 33C0 XOR EAX,EAX

004AF55A .^E9 43FFFFFF JMP pll621_9.004AF4A2

004AF55F > 68 00FC4A00 PUSH pll621_9.004AFC00 ; /lParam = 4AFC00

004AF564 . 50 PUSH EAX ; |wParam

004AF565 . 68 89010000 PUSH 189 ; |Message = LB_GETTEXT

004AF56A . FF35 00FF4A00 PUSH DWORD PTR DS:[4AFF00] ; |hWnd = NULL

004AF570 . E8 E7FEFFFF CALL pll621_9.004AF45C ; \SendMessageA

004AF575 . 09C0 OR EAX,EAX

004AF577 . 74 32 JE SHORT pll621_9.004AF5AB

004AF579 . 68 00FD4A00 PUSH pll621_9.004AFD00=========》传递参数;源字符地址指针

004AF57E . 68 00FC4A00 PUSH pll621_9.004AFC00=========》传递参数;目的字符指针

004AF583 . E8 65000000 CALL pll621_9.004AF5ED==============》这个call就是比较目的字符是否包含源字符

004AF588 . 85C0 TEST EAX,EAX=============》用eax作返回值,cracker们熟悉这样的格式,我也喜欢这样写,呵呵

004AF58A . 74 1F JE SHORT pll621_9.004AF5AB

004AF58C . 6A 00 PUSH 0 ; /lParam = 0

004AF58E . FF35 08FF4A00 PUSH DWORD PTR DS:[4AFF08] ; |wParam = 0

004AF594 . 68 86010000 PUSH 186 ; |Message = LB_SETCURSEL

004AF599 . FF35 00FF4A00 PUSH DWORD PTR DS:[4AFF00] ; |hWnd = NULL

004AF59F . E8 B8FEFFFF CALL pll621_9.004AF45C ; \SendMessageA

004AF5A4 . 33C0 XOR EAX,EAX

004AF5A6 .^E9 F7FEFFFF JMP pll621_9.004AF4A2====>找到一个合适的

004AF5AB >^E9 73FFFFFF JMP pll621_9.004AF523==》没有找到,重头开始

以上代码具体流程含义请参照我一点想法的那篇文章

因为老外用c++写的字符比较函数,翻译成汇编就又长又罗嗦,完全没有必要,我也没有这么多空间来装c++的垃圾代码,还好我的汇编功力还是勉强可以的,所以我就自己用汇编写了

一个字符比较函数如下:

也就是上面代码比较需要call的函数

CALL pll621_9.004AF5ED==============》这个call就是比较目的字符是否包含源字符:

call到这里

004AF5ED /$ 55 PUSH EBP

004AF5EE |. 8BC4 MOV EAX,ESP

004AF5F0 |. 5D POP EBP

004AF5F1 |. 60 PUSHAD

004AF5F2 |. 8BE8 MOV EBP,EAX==》以上都是保证堆栈合理用的

004AF5F4 |. 8B45 04 MOV EAX,DWORD PTR SS:[EBP+4]

004AF5F7 |. A3 10FF4A00 MOV DWORD PTR DS:[4AFF10],EAX

004AF5FC |. 33C0 XOR EAX,EAX

004AF5FE |. E8 8D000000 CALL pll621_9.004AF690===>这个函数是把两个需要比较的字符串都转换成大写,这样比较就不会区分大小写了

004AF603 |. 90 NOP

004AF604 |. 90 NOP

004AF605 |. 90 NOP

004AF606 |. 90 NOP

004AF607 |. 90 NOP

004AF608 |. 90 NOP

004AF609 |. 90 NOP

004AF60A |. 90 NOP

004AF60B |. 33C0 XOR EAX,EAX

004AF60D |. A3 14FF4A00 MOV DWORD PTR DS:[4AFF14],EAX

004AF612 |. 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C]

004AF615 |. B9 00000000 MOV ECX,0

004AF61A |. 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8]

004AF61D |> 8A06 /MOV AL,BYTE PTR DS:[ESI]

004AF61F |. 8B0D 14FF4A00 |MOV ECX,DWORD PTR DS:[4AFF14]

004AF625 |. 8A2439 |MOV AH,BYTE PTR DS:[ECX+EDI]

004AF628 |. 80FC 00 |CMP AH,0

004AF62B |. 74 2D |JE SHORT pll621_9.004AF65A

004AF62D |. 3AC4 |CMP AL,AH

004AF62F |. 75 0F |JNZ SHORT pll621_9.004AF640

004AF631 |. 47 |INC EDI

004AF632 |. 46 |INC ESI

004AF633 |. 8A06 |MOV AL,BYTE PTR DS:[ESI]

004AF635 |. 3C 00 |CMP AL,0

004AF637 |.^75 E4 |JNZ SHORT pll621_9.004AF61D

004AF639 |. B8 01000000 |MOV EAX,1

004AF63E |. EB 2A |JMP SHORT pll621_9.004AF66A

004AF640 |> FF05 14FF4A00 |INC DWORD PTR DS:[4AFF14]

004AF646 |. 8B75 0C |MOV ESI,DWORD PTR SS:[EBP+C]

004AF649 |. 8B0D 14FF4A00 |MOV ECX,DWORD PTR DS:[4AFF14]

004AF64F |. 8B7D 08 |MOV EDI,DWORD PTR SS:[EBP+8]

004AF652 |. 803C39 00 |CMP BYTE PTR DS:[ECX+EDI],0

004AF656 |. 74 02 |JE SHORT pll621_9.004AF65A

004AF658 |.^EB C3 \JMP SHORT pll621_9.004AF61D

004AF65A |> 61 POPAD

004AF65B |. B8 00000000 MOV EAX,0

004AF660 |. 83C4 0C ADD ESP,0C

004AF663 |. FF35 10FF4A00 PUSH DWORD PTR DS:[4AFF10]

004AF669 |. C3 RETN

004AF66A |> 61 POPAD

004AF66B |. B8 01000000 MOV EAX,1

004AF670 |. 83C4 0C ADD ESP,0C

004AF673 |. FF35 10FF4A00 PUSH DWORD PTR DS:[4AFF10]

004AF679 \. C3 RETN

转换大小写函数的代码:

004AF690 /$ 60 PUSHAD

004AF691 |. 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8]

004AF694 |> 8A06 /MOV AL,BYTE PTR DS:[ESI]

004AF696 |. 3C 00 |CMP AL,0 ; Switch (cases 0..7A)

004AF698 |. 74 14 |JE SHORT pll621_9.004AF6AE

004AF69A |. 3C 61 |CMP AL,61

004AF69C |. 73 02 |JNB SHORT pll621_9.004AF6A0

004AF69E |. EB 0B |JMP SHORT pll621_9.004AF6AB

004AF6A0 |> 3C 7A |CMP AL,7A

004AF6A2 |. 77 07 |JA SHORT pll621_9.004AF6AB

004AF6A4 |. 2C 20 |SUB AL,20 ; Cases 61 ('a'),62 ('b'),63 ('c'),64 ('d'),65 ('e'),66 ('f'),67 ('g'),68 ('h'),69 ('i'),6A ('j'),6B ('k'),6C ('l'),6D ('m'),6E ('n'),6F ('o'),70 ('p'),71 ('q'),72 ('r'),73 ('s'),74 ('t')... of>

004AF6A6 |. 90 |NOP

004AF6A7 |. 90 |NOP

004AF6A8 |. 90 |NOP

004AF6A9 |. 8806 |MOV BYTE PTR DS:[ESI],AL

004AF6AB |> 46 |INC ESI ; Default case of switch 004AF696

004AF6AC |.^EB E6 \JMP SHORT pll621_9.004AF694

004AF6AE |> 90 NOP ; Case 0 of switch 004AF696

004AF6AF |. 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C]

004AF6B2 |> 8A06 /MOV AL,BYTE PTR DS:[ESI]

004AF6B4 |. 3C 00 |CMP AL,0 ; Switch (cases 0..7A)

004AF6B6 |. 74 11 |JE SHORT pll621_9.004AF6C9

004AF6B8 |. 3C 61 |CMP AL,61

004AF6BA |. 73 02 |JNB SHORT pll621_9.004AF6BE

004AF6BC |. EB 08 |JMP SHORT pll621_9.004AF6C6

004AF6BE |> 3C 7A |CMP AL,7A

004AF6C0 |. 77 04 |JA SHORT pll621_9.004AF6C6

004AF6C2 |. 2C 20 |SUB AL,20 ; Cases 61 ('a'),62 ('b'),63 ('c'),64 ('d'),65 ('e'),66 ('f'),67 ('g'),68 ('h'),69 ('i'),6A ('j'),6B ('k'),6C ('l'),6D ('m'),6E ('n'),6F ('o'),70 ('p'),71 ('q'),72 ('r'),73 ('s'),74 ('t')... of>

004AF6C4 |. 8806 |MOV BYTE PTR DS:[ESI],AL

004AF6C6 |> 46 |INC ESI ; Default case of switch 004AF6B4

004AF6C7 |.^EB E9 \JMP SHORT pll621_9.004AF6B2

004AF6C9 |> 61 POPAD ; Case 0 of switch 004AF6B4

004AF6CA \. C3 RETN

以上两段段代码的含义请看附录:

不过上面两端代码写的没有什么章法,也没有什么规范,而且从程序员的角度来讲完全是三流的,如果用在单片机这个领域来看,那就更加不行了,单片机的空间是有限的,不能

这么乱写重复的代码浪费空间,还好我这里w32asm程序大,几个字节的区区空间还是有的,所以也懒得规划了,只要能正确运行就ok了,我想把代码简化的任务就教给兄弟们了,

wscn上,重新简化代码就是你的任务了,我只管大方向,不管小细节,:)好了,到现在为止,所有的功能都写完了,不知道比老外写的还有什么不足,主要是我自身的水平太烂

,没有什么更好的可以和大家交流的,以后我不会写这种重复技术的文章,除非觉得有什么新的东西可写,因为写重复的东西没有意义。谢谢大家

你的朋友:pll621

附录:

这里是我写的比较函数,和转换大小写函数的草本,有一点注释,但愿大家能看懂

这段是比较函数的草本:

xor eax,eax

mov [4aff14],eax

mov esi,[ebp+0c]===>esi是源字符串地址

mov ecx,0

mov edi,[ebp+08]==》edi是目的字符串地址

p3:

mov al,[esi]==》给al一个源字符

p1:

mov ecx,[4aff14]==》把现在比较的位置

mov ah,[edi+ecx]==》给一个目的字符

cmp ah,0===》比较是不是目的字符到头了

jz exit==》到头就退出

cmp al,ah==>比较源字符和目的字符

jnz p2==》不相等就把目的字符向后退一位,再比较

inc edi==》增加目的字符指针

inc esi==》增加源字符指针

mov al,[esi]

cmp al,0==>判断是否源字符到头了

jnz p3==>还没有到头,继续比较

mov eax,1==》到头了,证明找到

jmp find

p2:

INC DWORD PTR DS:[4AFF14]===目的字符向后退一位

mov esi,[ebp+0c]==重新定位esi和edi

mov ecx,[4aff14]

mov edi,[ebp+08]

cmp byte ptr [edi+ecx],0==》目的字符是否已经退到结尾了

jz exit

jmp p3

exit:

popa

mov eax,0

add esp,0c

push [4aff10]

ret

find:

popa

mov eax,1

add esp,0c

push [4aff10]

ret

这段是转化大小写函数的草本

这个操作很简单看看就明白,我写的时候连注释都懒得加

pusha

begain:

mov esi,[ebp+0c]

mov al,[esi]

cmp al,0

jz nextchange

cmp al,61

jae small

jmp next

small:

cmp al,7a

ja next

sub 20

mov [esi],al

next:

inc esi

jmp begain

begain1:

pusha

mov esi,[ebp+08]

mov al,[esi]

cmp al,0

jz exit

cmp al,61

jae small1

jmp next

small1:

cmp al,7a

ja next1

sub 20

mov [esi],al

next1:

inc esi

jmp begain1

exit:

popa

ret(出处:赢政天下整理收藏)

相关文章:

相关软件:

→ 特别推荐

→ 热点TOP10

我为人人《《==》》人人为我

关于我们 |

帮助(?)

| 广告服务 |

版权声明 |

商业合作 |

发展历程 |

加盟我们 |

联系我们

Copyright © 1999-2003

winzheng.com All Rights Reserved.

繁体版:由华琦数码技术提供

Powered

by:MeSky.Net

2003-2004 年,宽带刚刚普及,下载站的文章区是许多人学电脑的第一课堂。
🕰 → 🤖 从那时到现在

当年一篇教程能让一台电脑焕然一新;今天的效率工具换成了 AI。 想知道当下最可靠的 AI 模型怎么选?看 赢政指数——我们用了 28 年的选软件严谨,现在用来评测大模型。

档案性质声明:本页为赢政天下(1998-2011)老文章的历史档案复原, 内容反映当年发表时的原貌——包括当年的技术表述、软件版本与观点,部分方法在今天已不适用或不合规,仅作互联网历史记录与研究用途, 不提供任何形式的下载。原始数据经由公共网络存档(Internet Archive)复原。发现问题请联系我们
← 返回老文章档案 · 软件史档案馆 · 赢政天下站史