| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1394 人关注过本帖
标题:呕心沥血两小时 终于弄的差不多了
只看楼主 加入收藏
信箱有效
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:蒙面侠
威 望:9
帖 子:1102
专家分:4268
注 册:2012-6-19
结帖率:100%
收藏
 问题点数:0 回复次数:15 
呕心沥血两小时 终于弄的差不多了
好累啊 眼都花了。。。

最近我连睡觉都拿汇编书当枕头 ,果然有点效果。
那个帖子太长了 我就自己发个小贴。
编译的EXE在 https://bbs.bccn.net/thread-375040-1-1.html  一楼。

完全以zklhp编译的EXE为目标,如果用其他的编译器,结果大概会有不同。
比如如果用VC,或者大概也许不会有and   esp, 0FFFFFFF0h这个使esp后4位为0。
即使用同一个编译器 ,加上不同的编译参数,结果也可能不同。比如是否使用ebp指针。

复制一遍
程序代码:
#include <stdio.h>
#include <string.h>

int main(void)
{
    char a[64] = {0};
    strcpy(a, "我用这个数组放一个字符串");
    printf("a是:%s\n", a);
  
    {
        //这是个大括号里面
        char b[64] = {0};
        strcpy(b, a);
        printf("b是:%s\n", b);
    }
    //理论上到这里b就释放了
  
    char c[64] = "这里再有一个字符串应该是不增加堆栈大小才对";
    printf("c是:%s\n", c);

    return 0;
}


分析参数和局部变量这些问题,如果仅靠看源码或者凭已有知识进行的想象,还是很难了解透彻。
编译好EXE以后,进行反汇编,这个是最直接最快捷最有效的了。

下面就是我花了2个小时一条一条琢磨出来的。
这些指令 ,单单的任挑一条出来,都可以查百度查资料知道是什么意思,
困难的是几条指令合起来是什么意思。。。

都进行了分段和注释,明天再总结,今天头
程序代码:
.text:004013B7 ; Attributes: bp-based frame
.text:004013B7
.text:004013B7 sub_4013B7      proc near               ; CODE XREF: sub_401000+B4p
.text:004013B7
.text:004013B7 var_DC          = dword ptr -0DCh
.text:004013B7 var_D8          = dword ptr -0D8h
.text:004013B7 var_CC          = byte ptr -0CCh
.text:004013B7 var_8C          = byte ptr -8Ch
.text:004013B7 var_61          = byte ptr -61h
.text:004013B7 var_4C          = byte ptr -4Ch
.text:004013B7
.text:004013B7                 push    ebp
.text:004013B8                 mov     ebp, esp
.text:004013BA                 push    edi
.text:004013BB                 push    esi
.text:004013BC                 push    ebx
.text:004013BD                 and     esp, 0FFFFFFF0h        ;调整堆栈指针使之按16字节对齐
.text:004013C0                 sub     esp, 0D0h        ;开辟堆栈空间,大小为D0
.text:004013C6                 call    sub_4019B4



.text:004013CB                 lea     ebx, [esp+0DCh+var_4C]
.text:004013D2                 mov     al, 0            ;填充内容为0
.text:004013D4                 mov     edx, 40h            ;数量40h
.text:004013D9                 mov     edi, ebx
.text:004013DB                 mov     ecx, edx
.text:004013DD                 rep stosb            ;从地址[esp+0DCh+var_4C]开始初始化40h个字节内容为0。




.text:004013DF                 lea     eax, [esp+0DCh+var_4C]
.text:004013E6                 mov     edx, eax
.text:004013E8                 mov     ebx, offset aTSO ; "我用这个数组放一个字符串"
.text:004013ED                 mov     eax, 19h            ;19h个字节的数据
.text:004013F2                 mov     edi, edx
.text:004013F4                 mov     esi, ebx
.text:004013F6                 mov     ecx, eax
.text:004013F8                 rep movsb    ;    ;将19h个字节的字符串数据传送到堆栈地址[esp+0DCh+var_4C]为开始地址。


   
.text:004013FA                 lea     eax, [esp+0DCh+var_4C]
.text:00401401                 mov     [esp+0DCh+var_D8], eax    ;传参数二
.text:00401405                 mov     [esp+0DCh+var_DC], offset aAGS ; "a是:%s\n";传参数一
.text:0040140C                 call    sub_40138C        ;调用printf函数



.text:00401411                 lea     ebx, [esp+0DCh+var_CC]
.text:00401415                 mov     al, 0
.text:00401417                 mov     edx, 40h
.text:0040141C                 mov     edi, ebx
.text:0040141E                 mov     ecx, edx
.text:00401420                 rep stosb    ;用0初始化堆栈地址[esp+0DCh+var_CC]开始的40h个字节的空间。


.text:00401422                 lea     eax, [esp+0DCh+var_4C]
.text:00401429                 mov     [esp+0DCh+var_D8], eax    ;把刚才传送到堆栈内的字符串数据地址作为strcpy的第2参数
.text:0040142D                 lea     eax, [esp+0DCh+var_CC]    ;将刚初始化的40h个字节的堆栈空间首地址作为strcpy的第1参数传递
.text:00401431                 mov     [esp+0DCh+var_DC], eax
.text:00401434                 call    strcpy        ;

   
.text:00401439                 lea     eax, [esp+0DCh+var_CC]   
.text:0040143D                 mov     [esp+0DCh+var_D8], eax        ;传二参
.text:00401441                 mov     [esp+0DCh+var_DC], offset aBGS ; "b是:%s\n"  ;传一参
.text:00401448                 call    sub_40138C    ;调用printf函数



.text:0040144D                 lea     edx, [esp+0DCh+var_8C]
.text:00401451                 mov     ebx, offset aTQOJB ; "这里再有一个字符串应该是不增加堆栈大小?...
.text:00401456                 mov     eax, 2Bh        ;需传送的字节数为2bh
.text:0040145B                 mov     edi, edx        ;目的
.text:0040145D                 mov     esi, ebx        ;源
.text:0040145F                 mov     ecx, eax        ;计数2bh
.text:00401461                 rep movsb        ;把字符串传送至堆栈[esp+0DCh+var_8C]开始的2bh个字节中。




.text:00401463                 lea     ebx, [esp+0DCh+var_61]
.text:00401467                 mov     al, 0
.text:00401469                 mov     edx, 15h
.text:0040146E                 mov     edi, ebx
.text:00401470                 mov     ecx, edx
.text:00401472                 rep stosb    ;用0初始化堆栈地址[esp+0DCh+var_61]开始的15h个字节



.text:00401474                 lea     eax, [esp+0DCh+var_8C]       
.text:00401478                 mov     [esp+0DCh+var_D8], eax            ;传二参
.text:0040147C                 mov     [esp+0DCh+var_DC], offset aCGS ; "c是:%s\n"  ;传一参
.text:00401483                 call    sub_40138C        ;调用printf函数



.text:00401488                 mov     eax, 0return 0


.text:0040148D                 lea     esp, [ebp-0Ch]    ;平衡堆栈
.text:00401490                 pop     ebx
.text:00401491                 pop     esi
.text:00401492                 pop     edi
.text:00401493                 pop     ebp        ;平衡堆栈 对应开头的4个PUSH
.text:00401494                 retn
.text:00401494 sub_4013B7      endp
.text:00401494




搜索更多相关主题的帖子: include 编译器 
2012-08-11 02:29
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
学习

The quieter you become, the more you can hear
2012-08-11 07:45
小习小习
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:蒙面侠
威 望:6
帖 子:1467
专家分:4792
注 册:2012-7-2
收藏
得分:0 
同上

实现自己既定的目标,必须能耐得住寂寞单干。
2012-08-11 07:51
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
看来你真的在发粪。

梅尚程荀
马谭杨奚







                                                       
2012-08-11 08:59
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
应该发汇编版啊 呵呵

膜拜大作 膜拜大牛
2012-08-11 11:58
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
lea     esp, [ebp-0Ch]    ;平衡堆栈

这个语句应该多说一下

要恢复 肯定是要恢复到sub     esp, 0D0h的地方 但我存ebp之后又有三个寄存器压栈 所以得减去这三个寄存器共12字节 这样放在esp里才合适
2012-08-11 12:09
qq418336855
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2012-8-11
收藏
得分:0 
   一点都看不懂、
2012-08-11 15:03
qq418336855
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2012-8-11
收藏
得分:0 
  strcpy(a, "我用这个数组放一个字符串");
     这些字也是程序里面的?  还是楼主自己加的呢?  可以告诉我下?  我现在什么都还不懂   只能抄下你们的  先熟悉下  跟你们一样的写   能写好我就成功了、
2012-08-11 15:20
qq418336855
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2012-8-11
收藏
得分:0 
#include <stdio.h>                         #include <stdio.h>
#include <string.h>                        #include <string.h>

int main(void)                             int main(void)
{                                          {
    char a[64] = {0};                          char a[64] = {0};
    strcpy(a, "我用这个数组放一个字符串");     strcpy(a, "我用这个数组放一个字符串");
    printf("a是:%s\n", a);                    printf("a是: %s\n", a);
      
    {                                          {
        //这是个大括号里面                          //这是个大括号里面
        char b[64] = {0};                           char b[64] = {0};
        strcpy(b, a);                               strcpy(b, a);
        printf("b是:%s\n", b);                     printf("b是: %s\n", b);
    }                                          }
    //理论上到这里b就释放了                    //理论上到这里b就释放了
  
    char c[64] = "这里再有一个字符串应该是不   char c[64] = "这里再有一个字符串应该是不
    printf("c是:%s\n", c);                    printf("c是: %s\n", c);

    return 0;                                  return 0;
}                                           }
       我发现我抄完之后  好多符号的都熟悉了、
2012-08-11 15:30
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
误导了罢 这帖讨论的其实是汇编 跟C语言的关系不大。。
2012-08-11 15:32
快速回复:呕心沥血两小时 终于弄的差不多了
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.035688 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved