zoukankan      html  css  js  c++  java
  • 【win32汇编】 0x02 变量的定义和使用

        在汇编中,变量都是放在.data或者.data?中的,其中分为全局变量和局部变量。
        全局变量:
            .data
            wHour    dw ?    #未初始化的word类型
            wMinute    dw    10     #初始化为10的word类型
            word_Buffer    dw    100 dup(1,2)    #200个字
            szBuffer byte 1024 dup(?)    #1024字节的缓冲区
            szText    db    'Hello World'    #字符串11个字节
            szText    db    'Hello World',0dh,0ah,'Hello again',0dh,0ah,0    #0dh,0ah为换行符
            (.data?段中无法指定初始化值,默认初始值为0)
        局部变量
            简述:在进入子程序的时候,通过修改栈指针esp来留出需要的空间,在用ret返回的时候就通过恢复esp来丢弃这个空间
            local    loc1[1024]:byte    #定义了1024自己长的局部变量loc1
            local    loc2    #dword(默认)的局部变量
            local    loc3:WNDCLASS    #一个WNDCLASS的数据结构
        注:可以使用sizeof和lengthof来计算变量的长度
        例:
            szHello    db    'Hello',0dh,0ah
                    db    'World',0
            sizeof szHello的值为7
            改为stlen来计算这个字符串长度
        变量是利用指针来操作的
            lea eax,[ebp-4] 计算出地址放到eax中
            但是在invoke伪指令参数用到局部变量的时候不能用lea指令,只能用addr来代替从而获得变量的地址
            但是,这里又会有莫名其妙的问题:
                invoke Test,eax,addr szHello
                这句会被翻译成:
                lea eax,[ebx-4]
                push eax
                push eax
                call Test
            所以说eax不能用在addr的前面
            
        下面还有一个例子是对局部变量的分析

        源代码:

     1         ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
     2         ;数据段
     3         ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
     4             .data
     5         szCaption     db '来自deadfish', 0
     6         szText         db 'Hello, win32 assembly lanuage', 0
     7 
     8         ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
     9         ;代码段
    10         ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    11             .code
    12         start:
    13             call TestPro
    14             invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK
    15             invoke ExitProcess,NULL
    16         ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    17         ;子程序
    18         ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    19         TestPro    proc
    20                 local @loc1:dword,@loc2:word
    21                 local @loc3:byte
    22                 ;总共定义了7个字节的局部变量
    23                 mov eax,@loc1
    24                 mov    ax,@loc2
    25                 mov al,@loc3
    26                 ret
    27         TestPro endp

        反汇编之后:

     1         00401000 >/$  E8 1A000000   call 02_1.0040101F
     2         00401005  |.  6A 00         push 0x0                                 ; /Style = MB_OK|MB_APPLMODAL
     3         00401007  |.  68 00304000   push 02_1.00403000                       ; |Title = "来自deadfish"
     4         0040100C  |.  68 0D304000   push 02_1.0040300D                       ; |Text = "Hello, win32 assembly lanuage"
     5         00401011  |.  6A 00         push 0x0                                 ; |hOwner = NULL
     6         00401013  |.  E8 1A000000   call <jmp.&user32.MessageBoxA>           ; MessageBoxA
     7         00401018  |.  6A 00         push 0x0                                 ; /ExitCode = 0x0
     8         0040101A  .  E8 19000000   call <jmp.&kernel32.ExitProcess>         ; ExitProcess
     9         0040101F  /$  55            push ebp                                 ;保存ebp的值
    10         00401020  |.  8BEC          mov ebp,esp                                 ;把esp的值保存到ebp中 所以ebp的值很重要,不能随意改动,否则在退出子程序的是会出错
    11         00401022  |.  83C4 F8       add esp,-0x8                             ;从栈申请8字节的空间给局部变量
    12         00401025  |.  8B45 FC       mov eax,[local.1]                         ;赋值    这里就是通过ebp来指向局部变量的
    13         00401028  |.  66:8B45 FA    mov ax,word ptr ss:[ebp-0x6]
    14         0040102C  |.  8A45 F9       mov al,byte ptr ss:[ebp-0x7]
    15         0040102F  |.  C9            leave                                     ;完成恢复功能,这里相当于   mov esp,ebp          pop ebp
    16         00401030  .  C3            retn    
    17         00401031      CC            int3
    18         00401032   $- FF25 08204000 jmp dword ptr ds:[<&user32.MessageBoxA>] ;  user32.MessageBoxA
    19         00401038   .- FF25 00204000 jmp dword ptr ds:[<&kernel32.ExitProcess>;  kernel32.ExitProcess

         然后再变量中还有一个要注意的:
            .data
            bTest1 db 12h
            wTest1 dw 1234h
            dTest1 dd 12345678h
            ...
            .code
            ...
            mov al,bTest    ;al=12h
            mov ax,word ptr wTest1    ;ax = 3412h
            mov eax,dword ptr dTest1    ;eax = 78563412h
            这样在运行之后的现象是因为.data的东西是按照高数据高地址的(8086汇编中就可以知道了)
            要避免这种情况,用movzx代替mov即可

  • 相关阅读:
    设计模式
    显示WiFi密码
    05-变量
    04-杂谈
    03-杂谈
    02-杂谈
    01-linux介绍、命令
    14-python--inner
    13-python--bibao
    11-python-iterator
  • 原文地址:https://www.cnblogs.com/driedfish/p/5414147.html
Copyright © 2011-2022 走看看