您的位置:首页精文荟萃破解文章 → diy pe教学4

diy pe教学4

时间:2004/10/15 0:58:00来源:本站整理作者:蓝点我要评论(0)

 看到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&

相关阅读 Windows错误代码大全 Windows错误代码查询激活windows有什么用Mac QQ和Windows QQ聊天记录怎么合并 Mac QQ和Windows QQ聊天记录Windows 10自动更新怎么关闭 如何关闭Windows 10自动更新windows 10 rs4快速预览版17017下载错误问题Win10秋季创意者更新16291更新了什么 win10 16291更新内容windows10秋季创意者更新时间 windows10秋季创意者更新内容kb3150513补丁更新了什么 Windows 10补丁kb3150513是什么

文章评论
发表评论

热门文章 去除winrar注册框方法

最新文章 比特币病毒怎么破解 比去除winrar注册框方法 华为无线路由器HG522-C破解教程(附超级密码JEB格式文件京东电子书下载和阅读限制破解教UltraISO注册码全集(最新)通过Access破解MSSQL获得数据

人气排行 华为无线路由器HG522-C破解教程(附超级密码JEB格式文件京东电子书下载和阅读限制破解教UltraISO注册码全集(最新)qq相册密码破解方法去除winrar注册框方法(适应任何版本)怎么用手机破解收费游戏华为无线猫HG522破解如何给软件脱壳基础教程