加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

assembly – 为什么带有jmp指令的shellcode工作,为什么标签不能

发布时间:2020-12-16 09:46:48 所属栏目:百科 来源:网络整理
导读:我有两个汇编代码,如下所示 file:a.asm section .textglobal _start_start: mov eax,4 mov ebx,1 mov ecx,mesg mov edx,10 int 0x80 mov eax,1 int 0x80mesg db "KingKong",0xa 和另一个汇编代码 档案:b.asm section .textglobal _start_start: jmp mesgpr
我有两个汇编代码,如下所示

file:a.asm

section .text
global _start
_start: mov eax,4
        mov ebx,1
        mov ecx,mesg
        mov edx,10
        int 0x80
        mov eax,1
        int 0x80
mesg    db      "KingKong",0xa

和另一个汇编代码

档案:b.asm

section .text
global _start

_start: jmp mesg

prgm:   mov eax,1
        pop ecx
        mov edx,1
        int 0x80
mesg:   call prgm
        db "KingKong",0xa

在获取这两个代码的十六进制并将其放入此C包装器之后

char *b = "xb8x04x00x00x00xbbx01x00x00x00xb9x7dx80x04x08xbax0ax00x00x00xcdx80xb8x01x00x00x00xcdx80x4bx69x6ex67x4bx6fx6ex67x0a";

char *b = "xe9x19x00x00x00xb8x04x00x00x00xbbx01x00x00x00x59xbax0ax00x00x00xcdx80xb8x01x00x00x00xcdx80xe8xe2xffxffxffx4bx69x6ex67x4bx6fx6ex67x0a";
int main()
{
        (*(int (*)(void))a)();
}

第一个汇编代码(b)按预期打印’KingKong’,但第二个汇编代码打印垃圾.像显示的那样

root@bt:~/Arena# ./a
?root@bt:~/Arena#
root@bt:~/Arena# ./b
KingKong

由(第一个)产生的输出是这个奇怪的字符,而第二个(b)按预期打印kingkong.
现在有人可以解释为什么第二个汇编代码工作而第一个汇编代码没有.

编辑:
从答案我看到第一个程序硬编码地址.即使是第二种方法也使用标签,比如jmp mesg,现在不会使这个指令使程序与第一种程序非常相似,并不是它们都使用标签来决定位置.我所知道的是,为了使代码位置独立,我们需要使用esp或ebp寄存器和相对寻址方案.不要第二个程序的jmp指令使它像第一个程序一样.

解决方法

mesg的地址可以根据程序在内存中的布局方式而有所不同.

以下内容将对特定地址进行硬编码,并且无法可靠地(或根本不)工作:

mov ecx,mesg

作为参考,第一种方法硬编码以下地址:

mov ecx,0x804807d

第二种方法确实有效,因为它使用调用指令的返回地址在运行时计算出mesg的地址.

换句话说,第一个版本仅在加载到特定地址时才有效,而第二个版本仅为position-independent.

值得注意的是,第二版中出现的jmp和调用指令使用相对寻址,这意味着操作码指定到目标的距离而不是目标的地址.这使得这些指令无论在内存中的位置如何都可以工作.

如果检查操作码,您将看到jmp被编码为

e9 19 00 00 00

(即跳转0x19,或2510,字节向前),并将调用编码为

e8 e2 ff ff ff

其中0xffffffe2是一个小的负数(-30).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读