注册 登录
编程论坛 汇编论坛

程序段中的变量

vfdff 发布于 2008-10-14 23:49, 1543 次点击
Windows应用程序捆绑核心编程 张争秋 清华大学出版社 page189
中使用一个子文件定义了一个汇编子程序
;文件:attach.asm.
;常量定义.
.const

;代码段开始.
.code

;以“_”开头,并以 API 函数名相接的,是用来贮存通过 GetProcAddress 得到的 API 线形地址.
    attach_start            equ        $
        OEP                             dd                0
    hLibUser32            dd        ?
    _GetProcAddress            dd        0
    _LoadLibrary            dd        0
    _FreeLibrary            dd        0
    _ExitProcess            dd        0
    _MessageBox            dd        0
    szLibUser32            db        "user32", 0
    szProcLoadLibrary        db        "LoadLibraryA", 0
    szProcFreeLibrary        db        "FreeLibrary", 0
    szProcExitProcess        db        "ExitProcess", 0
    szProcMessageBox        db        "MessageBoxA", 0
     _szAppTitle            db        "Shellcode Test", 0
        _szShowText                     db           "Shellcode Done!",0
    ;真正的代码开始.
     attach_code_start        equ        $
        call Attachment
;-----------------------------------------------------------------------------
;附加段的子程序处理模块.
Attachment proc
    ;以下是经典的查找 kernel32.dll 的基地址的代码.
        pop ebp
        sub ebp, offset Attachment
     mov    eax, [esp]
    and    eax, 0FFFF0000h
@@chk:
    cmp    dword ptr [eax], 00905A4Dh    
    je    @@fnd                
    sub    eax, 1000h            
    jmp    @@chk                
@@fnd:
    ;以下的涉及到 PE 格式的操作.
    push     ebp
    push     ebx
    push     esi
    push     edi
    mov    ebp, eax
    add    eax, [eax][IMAGE_DOS_HEADER.e_lfanew]
    mov    edi, [eax][IMAGE_NT_HEADERS.OptionalHeader.DataDirectory]
    add    edi, ebp
    mov    esi, [edi][IMAGE_EXPORT_DIRECTORY.AddressOfNames]
    add    esi, ebp
    ;在 kernel32.dll 里面查找 GetProcAddress 的API 的线形地址.
    xor    edx, edx
@@name:
    mov    eax, [esi]
    add    eax, ebp
@@chgp:    ; GetProcAddress()
    cmp    dword ptr [eax+00h], "PteG"    ; GetP
    jne    @@next
    cmp    dword ptr [eax+04h], "Acor"    ; rocA
    jne    @@next
    cmp    dword ptr [eax+08h], "erdd"    ; ddre
    jne    @@next
    cmp    word ptr [eax+0Ch], "ss"    ; ss
    jne    @@next
    mov    eax, [edi][IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals]
    add    eax, ebp
    movzx ebx, word ptr [edx*2+eax]
    mov    eax, [edi][IMAGE_EXPORT_DIRECTORY.AddressOfFunctions]
    add    eax, ebp
    mov    eax, [ebx*4+eax]
    add    eax, ebp
    ; 找到GetProcAddress 的线形地址并保存.
    mov    [_GetProcAddress], eax
@@next:
    add    esi, 4
    inc    edx
    cmp    edx, [edi][IMAGE_EXPORT_DIRECTORY.NumberOfNames]
    jne    @@name
    ;下面的是通过 GetProcAddress 获得一些API 的线形地址,并储存起来,供后面使用.
    _call    [_GetProcAddress], ebp, offset szProcFreeLibrary
    mov    [_FreeLibrary], eax
    _call    [_GetProcAddress], ebp, offset szProcExitProcess
    mov    [_ExitProcess], eax
    _call    [_GetProcAddress], ebp, offset szProcLoadLibrary
    mov    [_LoadLibrary], eax
    ;载入 user32.dll ,并储存它的句柄.
    _call    eax, offset szLibUser32
    mov    [hLibUser32], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcMessageBox
     mov    [_MessageBox], eax
        ;调用加壳函数    
    _call ShellFunc
    ;返回原程序入口点
     mov eax, dword ptr [OEP]
    jmp eax
    _call    [_FreeLibrary], [hLibUser32]
    _call    [_ExitProcess], 0
Attachment endp
;-----------------------------------------------------------------------------
;计算加壳代码的长度.
attach_size    equ    $ - offset attach_start

我有一个疑问:
(1)变量 hLibUser32 dd ? 怎么被定义在程序段中,不是说程序段中的变量是不能修改的吗 ??
但是语句 mov    [hLibUser32], eax 却对其赋值?
9 回复
#2
ONEPROBLEM2008-10-15 07:42
按理代码段确实是不可写的,但,如果它是在栈中呢?
#3
zklhp2008-10-15 12:38
[bo][un]ONEPROBLEM[/un] 在 2008-10-15 07:42 的发言:[/bo]

按理代码段确实是不可写的,但,如果它是在栈中呢?


可以在链接时改变属性 这种程序一般都这样

偶也这么干过 用段融合来减少程序体积 必须让代码段可写
#4
zklhp2008-10-15 12:39
[bo][un]ONEPROBLEM[/un] 在 2008-10-15 07:42 的发言:[/bo]

按理代码段确实是不可写的,但,如果它是在栈中呢?


在栈中?

什么意思?
#5
vfdff2008-10-15 14:06
回复 3# zklhp 的帖子
让代码段可写 ?是由什么连接器的 ?
#6
zklhp2008-10-15 14:44
[bo][un]vfdff[/un] 在 2008-10-15 14:06 的发言:[/bo]

让代码段可写 ?是由什么连接器的 ?


连接选项里有

好象是 /section:.text,rw  s是共享

建议楼主看看windows方面的书 这些很多书都讲过的

btw 偶传的那些就不错 呵呵
#7
vfdff2008-11-01 13:10
回复 6# 的帖子
我知道 #pragma comment(linker, "/SECTION: 是定义共享段
但是 上面的  汇编子程序  中你能看到这个 代码段 是属于共享段?还是凭常识得到的 ?
#8
cnhanxiao2008-11-01 13:18
其实就是段覆盖技术,别名段。用一个数据段覆盖代码段,那这个代码段就可写了——其实写的还是数据段。
#9
你们都要疼我哦2008-11-01 23:20
这个是壳中常用的方法,壳把代码压缩了,在解压缩的过程中,肯定要把压缩过的代码解压回去,就必须要对代码段有写权限.通过设置读写属性来实现的.
#10
vfdff2008-11-02 15:45
回复 8# 的帖子
现在 操作系统支持虚拟内存,应该使用  交换技术吧
以前才使用 覆盖技术
不知道您这里的 段覆盖技术  和 覆盖技术  是不是一样?
1