【问题标题】:Local variable structure FASM局部变量结构 FASM
【发布时间】:2014-03-18 12:19:53
【问题描述】:

所以我正在阅读有关如何创建结构的手册..

一开始是这样的:

struc point X, Y
{
   .X dw X
   .Y dw Y
}



section '.code' code readable executable
main:
   push ebp
   mov ebp,esp

   PP Point 0, 0   ;Crashes here..

   mov esp, ebp
   pop ebp
   mov eax, 0x0
ret

所以我想得很好,因为它是一个局部变量,我需要 sub esp, sizeof(Point) 并且我做到了,但它仍然崩溃了..

所以我在 Point 结构中完成了它,而不是崩溃,它现在被删除了:

section '.data' data readable writeable
Response db 13, 10, "Value: %d", 13, 10, 0

struc Point X, Y
{
   sub esp, 0x8
   mov dword[esp + 0x00], X
   mov dword[esp + 0x04], Y
}



section '.code' code readable executable
main:
   push ebp
   mov ebp,esp

   PP Point 0, 0        ;create a point
   push PP
   call Point_Valid
   add esp, 0x04



   mov esp, ebp
   pop ebx

   call [getchar]

   mov eax, 0x00
ret


Point_Valid:
   push ebp
   mov ebp, esp

   mov eax, [ebp + 0x8]
   push eax              ;Not sure how to get Point from eax or Point.X..
   push Response
   call [printf]
   add esp, 0x08


   mov esp, ebp
   pop ebp
ret                         

但是,上面不仅失败了,还触发了这个:

从 Malware Defender for Windows 8.1 中

我不明白为什么 :S 但只有当我在结构中使用 sub esp 时才会发生这种情况。如果我使用.X dw X,它只会崩溃但不会触发恶意软件防御者。

任何想法如何实现将点传递给函数?还是创建一个本地点并将其传递给函数并访问其字段?

【问题讨论】:

    标签: assembly structure local-variables fasm


    【解决方案1】:

    在第一个示例中,您将 point 拼错为 Point,因此它没有汇编(除非您告诉汇编器忽略大小写)。

    如果我们忽略这一点,你在这里做什么:

    main:
    push ebp
    mov ebp,esp
    
    PP point 0, 0   ;Crashes here..
    
    mov esp, ebp
    pop ebp
    mov eax, 0x0
    

    和你写的差不多:

    main:
    push ebp
    mov ebp,esp
    
    dw 0,0
    
    mov esp, ebp
    pop ebp
    mov eax, 0x0
    

    它只是将这两个 0 字插入到您放置它们的指令“流”中。如果你组装这个然后反汇编你得到的输出:

    00000000  6655              push ebp
    00000002  6689E5            mov ebp,esp
    00000005  0000              add [bx+si],al  ; <- the first 0
    00000007  0000              add [bx+si],al  ; <- the second 0
    00000009  6689EC            mov esp,ebp
    0000000C  665D              pop ebp
    0000000E  66B800000000      mov eax,0x0
    00000014  C3                ret
    

    您的 pp 变量必须在其他地方声明,以便它永远不会出现在代码路径中(即 eip / rip 不应到达您的变量)。


    如果你真的需要一个堆栈分配的point,你可以使用virtual at

    virtual at esp-0x10  ; use whatever address is appropriate in your case
      pp point 1,2
    end virtual
    
    mov ax,[pp.X]
    

    请注意,这既不会为point 分配空间,也不会初始化point;它只是设置名称-地址映射。

    【讨论】:

      【解决方案2】:

      在这两种变体中,您定义了不同的事物。在第一个变体中,您在代码中创建数据,然后尝试执行它。只要变量包含随机指令(在调试器中检查),代码就会崩溃。我建议将变量移到程序的数据部分 - 默认情况下它必须驻留。

      在第二次尝试中,您将数据替换为指令(尽管此处不必使用结构),然后代码被正确执行。它是有效的代码。

      您的 AV 不喜欢此代码的事实是 AV 制造商的恕我直言问题。我的建议是完全卸载它。

      事实上,FASM 经常遇到问题,AV 假设什么是“好代码”,什么是病毒。请注意,所有这些都是误报。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多